📄 gtkmenushell.c
字号:
gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); return TRUE; } } else deactivate = FALSE; /* If the button click was very fast, or we ended up on a submenu, * leave the menu up */ if (!deactivate || (menu_item && (menu_shell->active_menu_item == menu_item))) { deactivate = FALSE; menu_shell->ignore_leave = TRUE; } else deactivate = TRUE; if (deactivate) { gtk_menu_shell_deactivate (menu_shell); gtk_signal_emit (GTK_OBJECT (menu_shell), menu_shell_signals[SELECTION_DONE]); } } return TRUE;}static gintgtk_menu_shell_key_press (GtkWidget *widget, GdkEventKey *event){ GtkMenuShell *menu_shell; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); menu_shell = GTK_MENU_SHELL (widget); if (!menu_shell->active_menu_item && menu_shell->parent_menu_shell) return gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent *)event); if (gtk_bindings_activate (GTK_OBJECT (widget), event->keyval, event->state)) return TRUE; if (gtk_accel_groups_activate (GTK_OBJECT (widget), event->keyval, event->state)) return TRUE; return FALSE;}static gintgtk_menu_shell_enter_notify (GtkWidget *widget, GdkEventCrossing *event){ GtkMenuShell *menu_shell; GtkWidget *menu_item; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); menu_shell = GTK_MENU_SHELL (widget); if (menu_shell->active && !menu_shell->ignore_enter) { menu_item = gtk_get_event_widget ((GdkEvent*) event); if (!menu_item || !GTK_WIDGET_IS_SENSITIVE (menu_item)) return TRUE; if ((menu_item->parent == widget) && (menu_shell->active_menu_item != menu_item) && GTK_IS_MENU_ITEM (menu_item)) { if ((event->detail != GDK_NOTIFY_INFERIOR) && (GTK_WIDGET_STATE (menu_item) != GTK_STATE_PRELIGHT)) { gtk_menu_shell_select_item (menu_shell, menu_item); } } else if (menu_shell->parent_menu_shell) { gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); } } return TRUE;}static gintgtk_menu_shell_leave_notify (GtkWidget *widget, GdkEventCrossing *event){ GtkMenuShell *menu_shell; GtkMenuItem *menu_item; GtkWidget *event_widget; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (GTK_WIDGET_VISIBLE (widget)) { menu_shell = GTK_MENU_SHELL (widget); event_widget = gtk_get_event_widget ((GdkEvent*) event); if (!event_widget || !GTK_IS_MENU_ITEM (event_widget)) return TRUE; menu_item = GTK_MENU_ITEM (event_widget); if (menu_shell->ignore_leave) { menu_shell->ignore_leave = FALSE; return TRUE; } if (!GTK_WIDGET_IS_SENSITIVE (menu_item)) return TRUE; if ((menu_shell->active_menu_item == event_widget) && (menu_item->submenu == NULL)) { if ((event->detail != GDK_NOTIFY_INFERIOR) && (GTK_WIDGET_STATE (menu_item) != GTK_STATE_NORMAL)) { gtk_menu_shell_deselect (menu_shell); } } else if (menu_shell->parent_menu_shell) { gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); } } return TRUE;}static voidgtk_menu_shell_add (GtkContainer *container, GtkWidget *widget){ gtk_menu_shell_append (GTK_MENU_SHELL (container), widget);}static voidgtk_menu_shell_remove (GtkContainer *container, GtkWidget *widget){ GtkMenuShell *menu_shell; gint was_visible; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_MENU_SHELL (container)); g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (widget)); was_visible = GTK_WIDGET_VISIBLE (widget); menu_shell = GTK_MENU_SHELL (container); menu_shell->children = g_list_remove (menu_shell->children, widget); gtk_widget_unparent (widget); /* queue resize regardless of GTK_WIDGET_VISIBLE (container), * since that's what is needed by toplevels. */ if (was_visible) gtk_widget_queue_resize (GTK_WIDGET (container));}static voidgtk_menu_shell_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data){ GtkMenuShell *menu_shell; GtkWidget *child; GList *children; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_MENU_SHELL (container)); g_return_if_fail (callback != NULL); menu_shell = GTK_MENU_SHELL (container); children = menu_shell->children; while (children) { child = children->data; children = children->next; (* callback) (child, callback_data); }}static voidgtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell){ g_return_if_fail (menu_shell != NULL); g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); if (menu_shell->active) { menu_shell->button = 0; menu_shell->active = FALSE; if (menu_shell->active_menu_item) { gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item)); menu_shell->active_menu_item = NULL; } if (menu_shell->have_grab) { menu_shell->have_grab = FALSE; gtk_grab_remove (GTK_WIDGET (menu_shell)); } if (menu_shell->have_xgrab) { menu_shell->have_xgrab = FALSE; gdk_pointer_ungrab (GDK_CURRENT_TIME); gdk_keyboard_ungrab (GDK_CURRENT_TIME); } }}static gintgtk_menu_shell_is_item (GtkMenuShell *menu_shell, GtkWidget *child){ GtkWidget *parent; g_return_val_if_fail (menu_shell != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), FALSE); g_return_val_if_fail (child != NULL, FALSE); parent = child->parent; while (parent && GTK_IS_MENU_SHELL (parent)) { if (parent == (GtkWidget*) menu_shell) return TRUE; parent = GTK_MENU_SHELL (parent)->parent_menu_shell; } return FALSE;}static GtkWidget*gtk_menu_shell_get_item (GtkMenuShell *menu_shell, GdkEvent *event){ GtkWidget *menu_item; menu_item = gtk_get_event_widget ((GdkEvent*) event); while (menu_item && !GTK_IS_MENU_ITEM (menu_item)) menu_item = menu_item->parent; if (menu_item && gtk_menu_shell_is_item (menu_shell, menu_item)) return menu_item; else return NULL;}/* Handlers for action signals */voidgtk_menu_shell_select_item (GtkMenuShell *menu_shell, GtkWidget *menu_item){ g_return_if_fail (menu_shell != NULL); g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); gtk_menu_shell_deselect (menu_shell); menu_shell->active_menu_item = menu_item; gtk_menu_item_set_placement (GTK_MENU_ITEM (menu_shell->active_menu_item), MENU_SHELL_CLASS (menu_shell)->submenu_placement); gtk_menu_item_select (GTK_MENU_ITEM (menu_shell->active_menu_item)); /* This allows the bizarre radio buttons-with-submenus-display-history * behavior */ if (GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu) gtk_widget_activate (menu_shell->active_menu_item);}voidgtk_menu_shell_deselect (GtkMenuShell *menu_shell){ g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); if (menu_shell->active_menu_item) { gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item)); menu_shell->active_menu_item = NULL; }}voidgtk_menu_shell_activate_item (GtkMenuShell *menu_shell, GtkWidget *menu_item, gboolean force_deactivate){ GSList *slist, *shells = NULL; gboolean deactivate = force_deactivate; g_return_if_fail (menu_shell != NULL); g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); if (!deactivate) deactivate = GTK_MENU_ITEM_CLASS (GTK_OBJECT (menu_item)->klass)->hide_on_activate; gtk_widget_ref (GTK_WIDGET (menu_shell)); if (deactivate) { GtkMenuShell *parent_menu_shell = menu_shell; do { gtk_widget_ref (GTK_WIDGET (parent_menu_shell)); shells = g_slist_prepend (shells, parent_menu_shell); parent_menu_shell = (GtkMenuShell*) parent_menu_shell->parent_menu_shell; } while (parent_menu_shell); shells = g_slist_reverse (shells); gtk_menu_shell_deactivate (menu_shell); /* flush the x-queue, so any grabs are removed and * the menu is actually taken down */ gdk_flush (); } gtk_widget_activate (menu_item); for (slist = shells; slist; slist = slist->next) { gtk_signal_emit (slist->data, menu_shell_signals[SELECTION_DONE]); gtk_widget_unref (slist->data); } g_slist_free (shells); gtk_widget_unref (GTK_WIDGET (menu_shell));}/* Distance should be +/- 1 */static voidgtk_menu_shell_move_selected (GtkMenuShell *menu_shell, gint distance){ if (menu_shell->active_menu_item) { GList *node = g_list_find (menu_shell->children, menu_shell->active_menu_item); GList *start_node = node; if (distance > 0) { node = node->next; while (node != start_node && (!node || !GTK_WIDGET_IS_SENSITIVE (node->data) || !GTK_WIDGET_VISIBLE (node->data) )) { if (!node) node = menu_shell->children; else node = node->next; } } else { node = node->prev; while (node != start_node && (!node || !GTK_WIDGET_IS_SENSITIVE (node->data) || !GTK_WIDGET_VISIBLE (node->data) )) { if (!node) node = g_list_last (menu_shell->children); else node = node->prev; } } if (node) gtk_menu_shell_select_item (menu_shell, node->data); }}static voidgtk_real_menu_shell_move_current (GtkMenuShell *menu_shell, GtkMenuDirectionType direction){ GtkMenuShell *parent_menu_shell = NULL; gboolean had_selection; had_selection = menu_shell->active_menu_item != NULL; if (menu_shell->parent_menu_shell) parent_menu_shell = GTK_MENU_SHELL (menu_shell->parent_menu_shell); switch (direction) { case GTK_MENU_DIR_PARENT: if (parent_menu_shell) { if (GTK_MENU_SHELL_CLASS (GTK_OBJECT (parent_menu_shell)->klass)->submenu_placement == GTK_MENU_SHELL_CLASS (GTK_OBJECT (menu_shell)->klass)->submenu_placement) gtk_menu_shell_deselect (menu_shell); else gtk_menu_shell_move_selected (parent_menu_shell, -1); } break; case GTK_MENU_DIR_CHILD: if (menu_shell->active_menu_item && GTK_BIN (menu_shell->active_menu_item)->child && GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu) { menu_shell = GTK_MENU_SHELL (GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu); if (menu_shell->children) gtk_menu_shell_select_item (menu_shell, menu_shell->children->data); } else { /* Try to find a menu running the opposite direction */ while (parent_menu_shell && (GTK_MENU_SHELL_CLASS (GTK_OBJECT (parent_menu_shell)->klass)->submenu_placement == GTK_MENU_SHELL_CLASS (GTK_OBJECT (menu_shell)->klass)->submenu_placement)) parent_menu_shell = GTK_MENU_SHELL (parent_menu_shell->parent_menu_shell); if (parent_menu_shell) gtk_menu_shell_move_selected (parent_menu_shell, 1); } break; case GTK_MENU_DIR_PREV: gtk_menu_shell_move_selected (menu_shell, -1); if (!had_selection && !menu_shell->active_menu_item && menu_shell->children) gtk_menu_shell_select_item (menu_shell, g_list_last (menu_shell->children)->data); break; case GTK_MENU_DIR_NEXT: gtk_menu_shell_move_selected (menu_shell, 1); if (!had_selection && !menu_shell->active_menu_item && menu_shell->children) gtk_menu_shell_select_item (menu_shell, menu_shell->children->data); break; } }static voidgtk_real_menu_shell_activate_current (GtkMenuShell *menu_shell, gboolean force_hide){ if (menu_shell->active_menu_item && GTK_WIDGET_IS_SENSITIVE (menu_shell->active_menu_item) && GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL) { gtk_menu_shell_activate_item (menu_shell, menu_shell->active_menu_item, force_hide); }}static voidgtk_real_menu_shell_cancel (GtkMenuShell *menu_shell){ gtk_menu_shell_deactivate (menu_shell); gtk_signal_emit (GTK_OBJECT (menu_shell), menu_shell_signals[SELECTION_DONE]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -