📄 gtkmenu.c
字号:
g_return_if_fail (GTK_IS_MENU (menu)); widget = GTK_WIDGET (menu); menu_shell = GTK_MENU_SHELL (menu); menu_shell->parent_menu_shell = parent_menu_shell; menu_shell->active = TRUE; menu_shell->button = button; /* If we are popping up the menu from something other than, a button * press then, as a heuristic, we ignore enter events for the menu * until we get a MOTION_NOTIFY. */ current_event = gtk_get_current_event(); if (current_event) { if ((current_event->type != GDK_BUTTON_PRESS) && (current_event->type != GDK_ENTER_NOTIFY)) menu_shell->ignore_enter = TRUE; gdk_event_free (current_event); } if (menu->torn_off) { gtk_menu_tearoff_bg_copy (menu); /* We force an unrealize here so that we don't trigger redrawing/ * clearing code - we just want to reveal our backing pixmap. */ gtk_menu_reparent (menu, menu->toplevel, TRUE); } menu->parent_menu_item = parent_menu_item; menu->position_func = func; menu->position_func_data = data; menu_shell->activate_time = activate_time; gtk_menu_position (menu); /* We need to show the menu _here_ because code expects to be * able to tell if the menu is onscreen by looking at the * GTK_WIDGET_VISIBLE (menu) */ gtk_widget_show (GTK_WIDGET (menu)); gtk_widget_show (menu->toplevel); /* Find the last viewable ancestor, and make an X grab on it */ parent = GTK_WIDGET (menu); xgrab_shell = NULL; while (parent) { gboolean viewable = TRUE; GtkWidget *tmp = parent; while (tmp) { if (!GTK_WIDGET_MAPPED (tmp)) { viewable = FALSE; break; } tmp = tmp->parent; } if (viewable) xgrab_shell = parent; parent = GTK_MENU_SHELL (parent)->parent_menu_shell; } if (xgrab_shell && (!GTK_MENU_SHELL (xgrab_shell)->have_xgrab)) { GdkCursor *cursor = gdk_cursor_new (GDK_ARROW); if ((gdk_pointer_grab (xgrab_shell->window, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, cursor, activate_time) == 0)) { if (gdk_keyboard_grab (xgrab_shell->window, TRUE, activate_time) == 0) GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE; else { gdk_pointer_ungrab (activate_time); } } gdk_cursor_destroy (cursor); } gtk_grab_add (GTK_WIDGET (menu));}voidgtk_menu_popdown (GtkMenu *menu){ GtkMenuShell *menu_shell; g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); menu_shell = GTK_MENU_SHELL (menu); menu_shell->parent_menu_shell = NULL; menu_shell->active = FALSE; menu_shell->ignore_enter = FALSE; if (menu_shell->active_menu_item) { if (menu->old_active_menu_item) gtk_widget_unref (menu->old_active_menu_item); menu->old_active_menu_item = menu_shell->active_menu_item; gtk_widget_ref (menu->old_active_menu_item); } gtk_menu_shell_deselect (menu_shell); /* The X Grab, if present, will automatically be removed when we hide * the window */ gtk_widget_hide (menu->toplevel); if (menu->torn_off) { if (GTK_BIN (menu->toplevel)->child) { gtk_menu_reparent (menu, menu->tearoff_window, FALSE); } else { /* We popped up the menu from the tearoff, so we need to * release the grab - we aren't actually hiding the menu. */ if (menu_shell->have_xgrab) { gdk_pointer_ungrab (GDK_CURRENT_TIME); gdk_keyboard_ungrab (GDK_CURRENT_TIME); } } } else gtk_widget_hide (GTK_WIDGET (menu)); menu_shell->have_xgrab = FALSE; gtk_grab_remove (GTK_WIDGET (menu));}GtkWidget*gtk_menu_get_active (GtkMenu *menu){ GtkWidget *child; GList *children; g_return_val_if_fail (menu != NULL, NULL); g_return_val_if_fail (GTK_IS_MENU (menu), NULL); if (!menu->old_active_menu_item) { child = NULL; children = GTK_MENU_SHELL (menu)->children; while (children) { child = children->data; children = children->next; if (GTK_BIN (child)->child) break; child = NULL; } menu->old_active_menu_item = child; if (menu->old_active_menu_item) gtk_widget_ref (menu->old_active_menu_item); } return menu->old_active_menu_item;}voidgtk_menu_set_active (GtkMenu *menu, guint index){ GtkWidget *child; GList *tmp_list; g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); tmp_list = g_list_nth (GTK_MENU_SHELL (menu)->children, index); if (tmp_list) { child = tmp_list->data; if (GTK_BIN (child)->child) { if (menu->old_active_menu_item) gtk_widget_unref (menu->old_active_menu_item); menu->old_active_menu_item = child; gtk_widget_ref (menu->old_active_menu_item); } }}voidgtk_menu_set_accel_group (GtkMenu *menu, GtkAccelGroup *accel_group){ g_return_if_fail (GTK_IS_MENU (menu)); if (menu->accel_group != accel_group) { if (menu->accel_group) gtk_accel_group_unref (menu->accel_group); menu->accel_group = accel_group; if (menu->accel_group) gtk_accel_group_ref (menu->accel_group); }}GtkAccelGroup*gtk_menu_get_accel_group (GtkMenu *menu){ g_return_val_if_fail (GTK_IS_MENU (menu), NULL); return menu->accel_group;}GtkAccelGroup*gtk_menu_ensure_uline_accel_group (GtkMenu *menu){ GtkAccelGroup *accel_group; g_return_val_if_fail (GTK_IS_MENU (menu), NULL); if (!quark_uline_accel_group) quark_uline_accel_group = g_quark_from_static_string ("GtkMenu-uline-accel-group"); accel_group = gtk_object_get_data_by_id (GTK_OBJECT (menu), quark_uline_accel_group); if (!accel_group) { accel_group = gtk_accel_group_new (); gtk_accel_group_attach (accel_group, GTK_OBJECT (menu)); gtk_object_set_data_by_id_full (GTK_OBJECT (menu), quark_uline_accel_group, accel_group, (GtkDestroyNotify) gtk_accel_group_unref); } return accel_group;}GtkAccelGroup*gtk_menu_get_uline_accel_group (GtkMenu *menu){ g_return_val_if_fail (GTK_IS_MENU (menu), NULL); return gtk_object_get_data_by_id (GTK_OBJECT (menu), quark_uline_accel_group);}voidgtk_menu_reposition (GtkMenu *menu){ g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); if (GTK_WIDGET_DRAWABLE (menu) && !menu->torn_off) gtk_menu_position (menu);}void gtk_menu_set_tearoff_state (GtkMenu *menu, gboolean torn_off){ g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); if (menu->torn_off != torn_off) { menu->torn_off = torn_off; if (menu->torn_off) { if (GTK_WIDGET_VISIBLE (menu)) gtk_menu_popdown (menu); if (!menu->tearoff_window) { GtkWidget *attach_widget; gchar *title; menu->tearoff_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_app_paintable (menu->tearoff_window, TRUE); gtk_signal_connect (GTK_OBJECT (menu->tearoff_window), "event", GTK_SIGNAL_FUNC (gtk_menu_window_event), GTK_OBJECT (menu)); gtk_widget_realize (menu->tearoff_window); title = gtk_object_get_data (GTK_OBJECT (menu), "gtk-menu-title"); if (!title) { attach_widget = gtk_menu_get_attach_widget (menu); if (GTK_IS_MENU_ITEM (attach_widget)) { GtkWidget *child = GTK_BIN (attach_widget)->child; if (GTK_IS_LABEL (child)) gtk_label_get (GTK_LABEL (child), &title); } } if (title) gdk_window_set_title (menu->tearoff_window->window, title); gdk_window_set_decorations (menu->tearoff_window->window, GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE); gtk_window_set_policy (GTK_WINDOW (menu->tearoff_window), FALSE, FALSE, TRUE); } gtk_menu_reparent (menu, menu->tearoff_window, FALSE); gtk_menu_position (menu); gtk_widget_show (GTK_WIDGET (menu)); gtk_widget_show (menu->tearoff_window); } else { gtk_widget_hide (menu->tearoff_window); gtk_menu_reparent (menu, menu->toplevel, FALSE); } }}void gtk_menu_set_title (GtkMenu *menu, const gchar *title){ g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); gtk_object_set_data_full (GTK_OBJECT (menu), "gtk-menu-title", g_strdup (title), (GtkDestroyNotify) g_free);}voidgtk_menu_reorder_child (GtkMenu *menu, GtkWidget *child, gint position){ GtkMenuShell *menu_shell; g_return_if_fail (GTK_IS_MENU (menu)); g_return_if_fail (GTK_IS_MENU_ITEM (child)); menu_shell = GTK_MENU_SHELL (menu); if (g_list_find (menu_shell->children, child)) { menu_shell->children = g_list_remove (menu_shell->children, child); menu_shell->children = g_list_insert (menu_shell->children, child, position); if (GTK_WIDGET_VISIBLE (menu_shell)) gtk_widget_queue_resize (GTK_WIDGET (menu_shell)); } }static voidgtk_menu_realize (GtkWidget *widget){ GdkWindowAttr attributes; gint attributes_mask; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, widget); widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); gtk_menu_paint(widget);}static voidgtk_menu_size_request (GtkWidget *widget, GtkRequisition *requisition){ GtkMenu *menu; GtkMenuShell *menu_shell; GtkWidget *child; GList *children; guint max_toggle_size; guint max_accel_width; GtkRequisition child_requisition; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); g_return_if_fail (requisition != NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -