?? cellwidget.c
字號:
{ int width; /* The key widget is slaved so we need to update all of the pointers to the objects derived from our drawing area */ key_widget->pixmap = pixmap; key_widget->cairo = cairo; key_widget->pixmap_gc = pixmap_gc; key_widget->pango = pango; /* Right-to-left mode affects keyboard placement */ width = cell_width * KEY_WIDGET_COLS - KEY_WIDGET_BORDER; if (!right_to_left) key_widget_configure(key_widget, cell_cols * cell_width - width, 1, width, cell_height); else key_widget_configure(key_widget, 0, 1, width, cell_height);}static gboolean configure_event(void)/* Create a new backing pixmap of the appropriate size */{ int new_cols; /* Do nothing if we are not visible */ if (!drawing_area || !drawing_area->window || !GTK_WIDGET_VISIBLE(drawing_area)) return TRUE; /* Backing pixmap */ if (pixmap) { int old_width, old_height; /* Do not update if the size has not changed */ gdk_drawable_get_size(key_widget->pixmap, &old_width, &old_height); if (old_width == drawing_area->allocation.width && old_height == drawing_area->allocation.height) return TRUE; g_object_unref(pixmap); } pixmap = gdk_pixmap_new(drawing_area->window, drawing_area->allocation.width, drawing_area->allocation.height, -1); trace("%dx%d", drawing_area->allocation.width, drawing_area->allocation.height); /* GDK graphics context */ if (pixmap_gc) g_object_unref(pixmap_gc); pixmap_gc = gdk_gc_new(GDK_DRAWABLE(pixmap)); /* Cairo context */ if (cairo) cairo_destroy(cairo); cairo = gdk_cairo_create(GDK_DRAWABLE(pixmap)); /* Set font size */ pango_font_description_set_absolute_size(pango_font_desc, PANGO_SCALE * (cell_height - CELL_BASELINE - 2)); /* Get the background color */ color_bg = window->style->bg[0]; color_bg_dark = window->style->bg[1]; /* Cursor */ cell_widget_set_cursor(TRUE); /* If the cell dimensions changed, repack */ if (window_embedded) { new_cols = (drawing_area->allocation.width - cell_widget_scrollbar_width() - 6) / cell_width; if (new_cols != cell_cols) pack_cells(1, new_cols); } /* If we are embedded we won't be able to resize the window so we can't honor the maximum rows preference */ if (window_embedded) cell_rows_pref = drawing_area->allocation.height / cell_height; /* Update the key widget with new values */ configure_keys(); /* Render the cells */ cell_widget_render(); return TRUE;}static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event)/* Redraw the drawing area from the backing pixmap */{ if (!pixmap) return FALSE; gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE;}static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event){ check_cell(event->x, event->y, NULL); return FALSE;}static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event){ /* Tablet PC gets grab leave-notify event when starting to draw. Ignore this if we are still drawing. */ if (event->mode == GDK_CROSSING_GRAB || drawing || cross_out) return FALSE; old_cc = current_cell; current_cell = -1; finish_cell(old_cc); if (inserting) { inserting = FALSE; dirty_cell(old_cc); dirty_cell(old_cc - 1); } invalid = TRUE; cell_widget_set_cursor(FALSE); render_dirty(); start_timeout(); return FALSE;}static void scrollbar_value_changed(void)/* The cell widget has been scrolled */{ double value; value = gtk_range_get_value(GTK_RANGE(scrollbar)); if ((int)value == cell_row_view) return; cell_row_view = value; cell_widget_render();}/* Widget*/void cell_widget_enable_xinput(int on)/* Enable Xinput devices. We set everything to screen mode despite the fact that we actually want window coordinates. Window mode just seems to break everything and we get window coords with screen mode anyway! */{ GList *list; GdkDevice *device; int i, mode; gtk_widget_set_extension_events(drawing_area, on ? GDK_EXTENSION_EVENTS_ALL : GDK_EXTENSION_EVENTS_NONE); mode = on ? GDK_MODE_SCREEN : GDK_MODE_DISABLED; list = gdk_devices_list(); for (i = 0; (device = (GdkDevice*)g_list_nth_data(list, i)); i++) gdk_device_set_mode(device, mode); xinput_enabled = on; g_debug(on ? "Xinput events enabled" : "Xinput events disabled");}int cell_widget_update_colors(void){ GdkColor old_active, old_inactive, old_ink, old_select; old_active = color_active; old_inactive = color_inactive; old_ink = color_ink; old_select = color_select; color_active = custom_active_color; color_inactive = custom_inactive_color; color_ink = custom_ink_color; color_select = custom_select_color; if (style_colors) { color_active = window->style->base[0]; color_ink = window->style->text[0]; color_inactive = window->style->bg[1]; } return !gdk_colors_equal(&old_active, &color_active) || !gdk_colors_equal(&old_inactive, &color_inactive) || !gdk_colors_equal(&old_ink, &color_ink) || !gdk_colors_equal(&old_select, &color_select);}const char *cell_widget_word(void)/* Return the current word and the current cell's position in that word FIXME this function ignores wide chars */{ static char buf[64]; int i, min, max; memset(buf, 0, sizeof (buf)); if (cell_offscreen(old_cc)) return buf; /* Find the start of the word */ for (min = old_cc - 1; min >= 0 && cells[min].ch && g_ascii_isalnum(cells[min].ch) && cells[min].ch < 0x7f; min--); /* Find the end of the word */ for (max = old_cc + 1; max < cell_rows * cell_cols && cells[max].ch && g_ascii_isalnum(cells[max].ch) && cells[max].ch < 0x7f; max++); /* Copy the word to a buffer */ for (++min, i = 0; i < max - min && i < (int)sizeof (buf) - 1; i++) buf[i] = cells[min + i].ch; buf[old_cc - min] = 0; buf[i] = 0; return buf;}void cell_widget_clear(void){ int resized; stop_timeout(); free_cells(); /* Restore cells if we just finished training */ if (training) { cells = cells_saved; cell_rows = cell_rows_saved; cell_cols = cell_cols_saved; cell_row_view = cell_row_view_saved; training = FALSE; resized = pack_cells(cell_rows, cell_cols); /* Show the on-screen keyboard */ if (check_clear()) { show_keys = keyboard_enabled; is_clear = TRUE; } } /* Clear cells otherwise */ else { resized = pack_cells(1, cell_cols); /* Show the on-screen keyboard */ show_keys = keyboard_enabled; is_clear = TRUE; } /* Only re-render when we aren't going to get a configure event */ if (!resized) cell_widget_render();}void cell_widget_train(void){ UnicodeBlock *block; int i, pos, range; stop_timeout(); /* Save cells */ if (!training) { cells_saved = cells; cell_rows_saved = cell_rows; cell_cols_saved = cell_cols; cell_row_view_saved = cell_row_view; cells = NULL; cell_row_view = 0; } /* Clear if not training any block */ if (training_block < 0) { free_cells(); pack_cells(1, cell_cols); cell_widget_render(); return; } /* Pack the Unicode block's characters into the cell grid */ block = unicode_blocks + training_block; range = block->end - block->start + 1; training = TRUE; pack_cells((range + cell_cols - 1) / cell_cols, cell_cols); /* Preset all of the characters for training */ for (i = 0, pos = 0; i < range; i++) { short ch; ch = block->start + i; if (char_disabled(ch)) continue; cells[pos].ch = ch; cells[pos].alts[0] = NULL; cells[pos++].flags = 0; } range = pos; for (; pos < cell_rows * cell_cols; pos++) clear_cell(pos); pack_cells(1, cell_cols); unclear(FALSE); cell_widget_render();}void cell_widget_pack(void){ int cols; if (training) { cell_widget_train(); return; } cols = cell_cols_pref; if (window_docked) { GdkScreen *screen; screen = gtk_window_get_screen(GTK_WINDOW(window)); cols = (gdk_screen_get_width(screen) - cell_widget_scrollbar_width() - 6) / cell_width; } if (!pack_cells(0, cols)) set_size_request(TRUE); if (is_clear) show_keys = keyboard_enabled; /* Right-to-left mode may have changed so we need to reconfigure the on-screen keyboard */ configure_keys(); cell_widget_render(); trace("%dx%d, scrollbar %d", cell_cols, cell_rows, cell_widget_scrollbar_width());}int cell_widget_insert(void){ gunichar2 *utf16; int i, j, slot, chars; if (training) return FALSE; chars = 0; /* Prepare for sending key events */ key_event_update_mappings(); /* Need to send the keys out in reverse order for right_to_left mode because the cells are displayed with columns reversed */ if (right_to_left) for (i = cell_cols - 1; i < cell_rows * cell_cols; i--) { if (cells[i].ch) { chars++; send_cell_key(i); } if (i % cell_cols == 0) i += cell_cols * 2; } else for (i = 0; i < cell_rows * cell_cols; i++) { if (!cells[i].ch) continue; chars++; send_cell_key(i); } /* If nothing was entered, send Enter key event */ if (!chars) { key_event_send_enter(); return FALSE; } /* Create a UTF-16 string representation */ utf16 = g_malloc(sizeof (**history) * (chars + 1)); for (i = 0, j = 0; i < cell_rows * cell_cols; i++) if (cells[i].ch)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -