?? cellwidget.c
字號(hào):
rows = cell_rows; if (i == cell_cols && cell_rows > 1 && !cells[(cell_rows - 1) * cell_cols - 1].ch) rows--; cells[cell_rows * cell_cols - 1].ch = 0; cells[cell_rows * cell_cols - 1].alts[0] = NULL; pack_cells(0, cell_cols); cell_widget_render();}static void send_cell_key(int cell)/* Send the key event for the cell */{ int i; if (!cells[cell].ch) return; /* Collect stats and train on corrections */ if (cells[cell].ch != ' ') { if (cells[cell].ch != cells[cell].sample.ch) corrections++; if (train_on_input && !(cells[cell].flags & CELL_SHIFTED) && cells[cell].sample.len) { cells[cell].sample.ch = cells[cell].ch; train_sample(&cells[cell].sample, FALSE); } characters++; } /* Update the usage time for the sample that matched this character */ for (i = 0; i < ALTERNATES && cells[cell].alts[i]; i++) { if (!sample_valid(cells[cell].alts[i], cells[cell].alt_used[i])) break; if (cells[cell].alts[i]->ch == cells[cell].ch) { promote_sample(cells[cell].alts[i]); break; } demote_sample(cells[cell].alts[i]); } key_event_send_char(cells[cell].ch);}/* Events*//* Hold click area radius */#define HOLD_CLICK_WIDTH 3./* Mask for possible buttons used by the eraser */#define ERASER_BUTTON_MASK (GDK_MOD5_MASK | GDK_BUTTON1_MASK | \ GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | \ GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)static int menu_cell, alt_menu_alts[ALTERNATES];static void training_menu_reset(void){ untrain_char(cells[menu_cell].ch); render_cell(menu_cell);}static void alt_menu_selection_done(GtkWidget *widget){ gtk_widget_destroy(widget);}static void alt_menu_activate(GtkWidget *widget, int *alt){ cells[menu_cell].ch = *alt; cells[menu_cell].flags |= CELL_VERIFIED; cells[menu_cell].flags &= ~CELL_SHIFTED; render_cell(menu_cell);}static void alt_menu_delete(void){ delete_cell(menu_cell);}static void alt_menu_show_ink(void){ cells[menu_cell].flags ^= CELL_SHOW_INK; render_cell(menu_cell);}static void alt_menu_change_case(void){ if (g_unichar_isupper(cells[menu_cell].ch)) { cells[menu_cell].ch = g_unichar_tolower(cells[menu_cell].ch); cells[menu_cell].flags |= CELL_SHIFTED; render_cell(menu_cell); } else if (g_unichar_islower(cells[menu_cell].ch)) { cells[menu_cell].ch = g_unichar_toupper(cells[menu_cell].ch); cells[menu_cell].flags |= CELL_SHIFTED; render_cell(menu_cell); } else g_debug("Cannot change case, not an alphabetic character");}static gboolean scrollbar_scroll_event(GtkWidget *widget, GdkEventScroll *event){ check_cell(event->x, event->y, event->device); return FALSE;}static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event){ if (scrollbar && GTK_WIDGET_VISIBLE(scrollbar)) gtk_widget_event(scrollbar, (GdkEvent*)event); return FALSE;}static void context_menu_position(GtkMenu *menu, gint *x, gint *y, gboolean *push_in)/* Positions the two-column context menu so that the column divide is at the cursor rather than the upper left hand point */{ if (cells[menu_cell].alts[0]) *x -= GTK_WIDGET(menu)->requisition.width / 2; *push_in = TRUE;}static void show_context_menu(int button, int time)/* Popup the cell context menu for the current cell */{ GtkWidget *menu, *widget; int i, pos; /* Training menu is the same for all cells */ if (training) { if (!char_trained(cells[current_cell].ch)) return; menu_cell = current_cell; gtk_menu_popup(GTK_MENU(training_menu), 0, 0, 0, 0, button, time); return; } /* Can't delete blanks */ if (!cells[current_cell].ch) return; /* Construct an alternates menu for the current button */ menu = gtk_menu_new(); menu_cell = current_cell; /* Menu -> Delete */ widget = gtk_menu_item_new_with_label("Delete"); g_signal_connect(G_OBJECT(widget), "activate", G_CALLBACK(alt_menu_delete), NULL); gtk_menu_attach(GTK_MENU(menu), widget, 0, 1, 0, 1); /* Menu -> Show Ink */ if (cells[menu_cell].sample.ch) { const char *label; label = cells[menu_cell].flags & CELL_SHOW_INK ? "Hide ink" : "Show ink"; widget = gtk_menu_item_new_with_label(label); g_signal_connect(G_OBJECT(widget), "activate", G_CALLBACK(alt_menu_show_ink), NULL); gtk_menu_attach(GTK_MENU(menu), widget, 0, 1, 1, 2); } /* Menu -> Change case */ if (g_unichar_isupper(cells[menu_cell].ch) || g_unichar_islower(cells[menu_cell].ch)) { const char *string = "To upper"; if (g_unichar_isupper(cells[menu_cell].ch)) string = "To lower"; widget = gtk_menu_item_new_with_label(string); g_signal_connect(G_OBJECT(widget), "activate", G_CALLBACK(alt_menu_change_case), NULL); gtk_menu_attach(GTK_MENU(menu), widget, 0, 1, 2, 3); } /* Menu -> Alternates */ for (i = 0, pos = 0; i < ALTERNATES && cells[current_cell].alts[i]; i++) { char *str; if (!sample_valid(cells[current_cell].alts[i], cells[current_cell].alt_used[i])) continue; str = va("%C\t%d%%", cells[current_cell].alts[i]->ch, cells[current_cell].alt_ratings[i]); alt_menu_alts[i] = cells[current_cell].alts[i]->ch; widget = gtk_check_menu_item_new_with_label(str); if (cells[current_cell].ch == cells[current_cell].alts[i]->ch) gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(widget), TRUE); g_signal_connect(G_OBJECT(widget), "activate", G_CALLBACK(alt_menu_activate), alt_menu_alts + i); gtk_menu_attach(GTK_MENU(menu), widget, 1, 2, pos, pos + 1); pos++; } g_signal_connect(G_OBJECT(menu), "selection-done", G_CALLBACK(alt_menu_selection_done), NULL); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu), 0, 0, (GtkMenuPositionFunc)context_menu_position, 0, button, time);}static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event)/* Mouse button is pressed over drawing area */{ /* Pass on event to the on-screen keyboard */ if (show_keys && key_widget_button_press(widget, event, key_widget)) return TRUE; /* Don't process double clicks */ if (event->type != GDK_BUTTON_PRESS) return TRUE; /* Check validity every time */ check_cell(event->x, event->y, event->device); if (invalid) return TRUE; /* If we are drawing and we get a button press event it is possible that we never received a button release event for some reason. This is a fix for Zaurus drawing connected lines. */ if (drawing) stop_drawing(); /* If we have pressed with the eraser, erase the cell */ if (eraser || event->button == 2) { erase_cell(current_cell); return TRUE; } /* Draw/activate insert with left click */ if (event->button == 1) { if (inserting) potential_insert = TRUE; else if (cells[current_cell].ch) { start_hold(); } else draw(event->x, event->y); /* We are now counting on getting valid coordinates here so save in case we are doing a potential insert/hold and we don't get a motion event in between */ cursor_x = event->x; cursor_y = event->y; return TRUE; } /* Right-click opens context menu */ else if (event->button == 3 && current_cell >= 0 && !inserting && (!input || !input->len)) { show_context_menu(event->button, event->time); return TRUE; } return FALSE;}static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event)/* Mouse button is released over drawing area */{ /* Pass on event to the on-screen keyboard */ if (show_keys && key_widget_button_release(widget, event, key_widget)) return TRUE; /* Only handle left-clicks */ if (event->button != 1) return TRUE; /* Complete an insertion */ if (potential_insert && inserting) { insert_cell(current_cell); potential_insert = FALSE; return TRUE; } /* Cancel a hold-click */ if (potential_hold) { potential_hold = FALSE; draw(cursor_x, cursor_y); } stop_drawing(); return TRUE;}static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event)/* Mouse is moved over drawing area */{ GdkModifierType state; double x, y; /* Fetch event coordinates */ x = event->x; y = event->y; if (xinput_enabled) { gdk_device_get_state(event->device, event->window, NULL, &state); gdk_event_get_coords((GdkEvent*)event, &x, &y); }#if GTK_CHECK_VERSION(2, 12, 0) /* Process a hint event (GTK >= 2.12) */ gdk_event_request_motions(event);#else /* Process a hint event (GTK <= 2.10) */ else if (event->is_hint) { int nx, ny; gdk_window_get_pointer(event->window, &nx, &ny, &state); x = nx; y = ny; }#endif /* If we are getting invalid output from this device with XInput enabled, try disabling it */ if ((x < 0 || x > drawing_area->allocation.width || y < 0 || y > drawing_area->allocation.width) && event->device->mode != GDK_MODE_DISABLED && xinput_enabled) { g_warning("Extended input device is generating invalid " "coordinates, disabled"); gdk_device_set_mode(event->device, GDK_MODE_DISABLED); return TRUE; } /* Check where the pointer is */ check_cell(x, y, event->device); /* Cancel a potential insert */ if (potential_insert) { if (!inserting) { potential_insert = FALSE; draw(cursor_x, cursor_y); } else return TRUE; } /* Cancel a potential hold-click */ if (potential_hold) { double dx, dy; dx = x - cursor_x; dy = y - cursor_y; if (dx < -HOLD_CLICK_WIDTH || dx > HOLD_CLICK_WIDTH || dy < -HOLD_CLICK_WIDTH || dy > HOLD_CLICK_WIDTH) { potential_hold = FALSE; draw(cursor_x, cursor_y); } else return TRUE; } cursor_x = x; cursor_y = y; /* Record and draw new segment */ if (drawing) { draw(cursor_x, cursor_y); render_segment(input, current_cell, input->len - 1, input->strokes[input->len - 1]->len - 2, NULL); } /* Erasing with the eraser. We get MOD5 rather than a button for the eraser being pressed on a Tablet PC. */ else if (!invalid && (cross_out || (eraser && (state & ERASER_BUTTON_MASK)))) erase_cell(current_cell); /* Plain motion restarts the finish countdown */ start_timeout(); return TRUE;}static void configure_keys(void)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -