📄 gtkmenuitem.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <string.h>#include "gtkaccellabel.h"#include "gtkmain.h"#include "gtkmenu.h"#include "gtkmenubar.h"#include "gtkmenuitem.h"#include "gtksignal.h"#define BORDER_SPACING 3#define SELECT_TIMEOUT 75#define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)enum { ACTIVATE, ACTIVATE_ITEM, LAST_SIGNAL};static void gtk_menu_item_class_init (GtkMenuItemClass *klass);static void gtk_menu_item_init (GtkMenuItem *menu_item);static void gtk_menu_item_destroy (GtkObject *object);static void gtk_menu_item_size_request (GtkWidget *widget, GtkRequisition *requisition);static void gtk_menu_item_size_allocate (GtkWidget *widget, GtkAllocation *allocation);static void gtk_menu_item_paint (GtkWidget *widget, GdkRectangle *area);static void gtk_menu_item_draw (GtkWidget *widget, GdkRectangle *area);static gint gtk_menu_item_expose (GtkWidget *widget, GdkEventExpose *event);static void gtk_real_menu_item_select (GtkItem *item);static void gtk_real_menu_item_deselect (GtkItem *item);static void gtk_real_menu_item_activate_item (GtkMenuItem *item);static gint gtk_menu_item_select_timeout (gpointer data);static void gtk_menu_item_select_timeout_unlocked (gpointer data);static void gtk_menu_item_position_menu (GtkMenu *menu, gint *x, gint *y, gpointer user_data);static void gtk_menu_item_show_all (GtkWidget *widget);static void gtk_menu_item_hide_all (GtkWidget *widget);static void gtk_menu_item_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);static GtkItemClass *parent_class;static guint menu_item_signals[LAST_SIGNAL] = { 0 };static guint32 last_submenu_deselect_time = 0;GtkTypegtk_menu_item_get_type (void){ static GtkType menu_item_type = 0; if (!menu_item_type) { static const GtkTypeInfo menu_item_info = { "GtkMenuItem", sizeof (GtkMenuItem), sizeof (GtkMenuItemClass), (GtkClassInitFunc) gtk_menu_item_class_init, (GtkObjectInitFunc) gtk_menu_item_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; menu_item_type = gtk_type_unique (gtk_item_get_type (), &menu_item_info); gtk_type_set_chunk_alloc (menu_item_type, 16); } return menu_item_type;}static voidgtk_menu_item_class_init (GtkMenuItemClass *klass){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; GtkItemClass *item_class; object_class = (GtkObjectClass*) klass; widget_class = (GtkWidgetClass*) klass; container_class = (GtkContainerClass*) klass; item_class = (GtkItemClass*) klass; parent_class = gtk_type_class (gtk_item_get_type ()); menu_item_signals[ACTIVATE] = gtk_signal_new ("activate", GTK_RUN_FIRST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkMenuItemClass, activate), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); menu_item_signals[ACTIVATE_ITEM] = gtk_signal_new ("activate_item", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkMenuItemClass, activate_item), gtk_signal_default_marshaller, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, menu_item_signals, LAST_SIGNAL); object_class->destroy = gtk_menu_item_destroy; widget_class->activate_signal = menu_item_signals[ACTIVATE]; widget_class->size_request = gtk_menu_item_size_request; widget_class->size_allocate = gtk_menu_item_size_allocate; widget_class->draw = gtk_menu_item_draw; widget_class->expose_event = gtk_menu_item_expose; widget_class->show_all = gtk_menu_item_show_all; widget_class->hide_all = gtk_menu_item_hide_all; container_class->forall = gtk_menu_item_forall; item_class->select = gtk_real_menu_item_select; item_class->deselect = gtk_real_menu_item_deselect; klass->activate = NULL; klass->activate_item = gtk_real_menu_item_activate_item; klass->toggle_size = 0; klass->hide_on_activate = TRUE;}static voidgtk_menu_item_init (GtkMenuItem *menu_item){ menu_item->submenu = NULL; menu_item->accelerator_signal = menu_item_signals[ACTIVATE]; menu_item->toggle_size = 0; menu_item->accelerator_width = 0; menu_item->show_toggle_indicator = FALSE; menu_item->show_submenu_indicator = FALSE; menu_item->submenu_direction = GTK_DIRECTION_RIGHT; menu_item->submenu_placement = GTK_TOP_BOTTOM; menu_item->right_justify = FALSE; menu_item->timer = 0;}GtkWidget*gtk_menu_item_new (void){ return GTK_WIDGET (gtk_type_new (gtk_menu_item_get_type ()));}GtkWidget*gtk_menu_item_new_with_label (const gchar *label){ GtkWidget *menu_item; GtkWidget *accel_label; menu_item = gtk_menu_item_new (); accel_label = gtk_accel_label_new (label); gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5); gtk_container_add (GTK_CONTAINER (menu_item), accel_label); gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), menu_item); gtk_widget_show (accel_label); return menu_item;}static voidgtk_menu_item_destroy (GtkObject *object){ GtkMenuItem *menu_item; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (object)); menu_item = GTK_MENU_ITEM (object); if (menu_item->submenu) gtk_widget_destroy (menu_item->submenu); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);}static voidgtk_menu_item_detacher (GtkWidget *widget, GtkMenu *menu){ GtkMenuItem *menu_item; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (widget)); menu_item = GTK_MENU_ITEM (widget); g_return_if_fail (menu_item->submenu == (GtkWidget*) menu); menu_item->submenu = NULL;}voidgtk_menu_item_set_submenu (GtkMenuItem *menu_item, GtkWidget *submenu){ g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); if (menu_item->submenu != submenu) { gtk_menu_item_remove_submenu (menu_item); menu_item->submenu = submenu; gtk_menu_attach_to_widget (GTK_MENU (submenu), GTK_WIDGET (menu_item), gtk_menu_item_detacher); if (GTK_WIDGET (menu_item)->parent) gtk_widget_queue_resize (GTK_WIDGET (menu_item)); }}voidgtk_menu_item_remove_submenu (GtkMenuItem *menu_item){ g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); if (menu_item->submenu) gtk_menu_detach (GTK_MENU (menu_item->submenu));}voidgtk_menu_item_set_placement (GtkMenuItem *menu_item, GtkSubmenuPlacement placement){ g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); menu_item->submenu_placement = placement;}voidgtk_menu_item_configure (GtkMenuItem *menu_item, gint show_toggle_indicator, gint show_submenu_indicator){ g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); menu_item->show_toggle_indicator = (show_toggle_indicator == TRUE); menu_item->show_submenu_indicator = (show_submenu_indicator == TRUE);}voidgtk_menu_item_select (GtkMenuItem *menu_item){ g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); gtk_item_select (GTK_ITEM (menu_item));}voidgtk_menu_item_deselect (GtkMenuItem *menu_item){ g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); gtk_item_deselect (GTK_ITEM (menu_item));}voidgtk_menu_item_activate (GtkMenuItem *menu_item){ g_return_if_fail (menu_item != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); gtk_signal_emit (GTK_OBJECT (menu_item), menu_item_signals[ACTIVATE]);}static voidgtk_menu_item_accel_width_foreach (GtkWidget *widget, gpointer data){ guint *width = data; if (GTK_IS_ACCEL_LABEL (widget)) { guint w; w = gtk_accel_label_get_accel_width (GTK_ACCEL_LABEL (widget)); *width = MAX (*width, w); } else if (GTK_IS_CONTAINER (widget)) gtk_container_foreach (GTK_CONTAINER (widget), gtk_menu_item_accel_width_foreach, data);}static voidgtk_menu_item_size_request (GtkWidget *widget, GtkRequisition *requisition){ GtkMenuItem *menu_item; GtkBin *bin; guint accel_width; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (widget)); g_return_if_fail (requisition != NULL); bin = GTK_BIN (widget); menu_item = GTK_MENU_ITEM (widget); requisition->width = (GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness + BORDER_SPACING) * 2; requisition->height = (GTK_CONTAINER (widget)->border_width + widget->style->klass->ythickness) * 2; if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) { GtkRequisition child_requisition; gtk_widget_size_request (bin->child, &child_requisition); requisition->width += child_requisition.width; requisition->height += child_requisition.height; } if (menu_item->submenu && menu_item->show_submenu_indicator) requisition->width += 21; accel_width = 0; gtk_container_foreach (GTK_CONTAINER (menu_item), gtk_menu_item_accel_width_foreach, &accel_width); menu_item->accelerator_width = accel_width;}static voidgtk_menu_item_size_allocate (GtkWidget *widget, GtkAllocation *allocation){ GtkMenuItem *menu_item; GtkBin *bin; GtkAllocation child_allocation; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU_ITEM (widget)); g_return_if_fail (allocation != NULL); menu_item = GTK_MENU_ITEM (widget); bin = GTK_BIN (widget); widget->allocation = *allocation; if (bin->child) { child_allocation.x = (GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness + BORDER_SPACING); child_allocation.y = (GTK_CONTAINER (widget)->border_width + widget->style->klass->ythickness); child_allocation.width = MAX (1, (gint)allocation->width - child_allocation.x * 2); child_allocation.height = MAX (1, (gint)allocation->height - child_allocation.y * 2); child_allocation.x += GTK_MENU_ITEM (widget)->toggle_size; child_allocation.width -= GTK_MENU_ITEM (widget)->toggle_size; if (menu_item->submenu && menu_item->show_submenu_indicator) child_allocation.width -= 21; gtk_widget_size_allocate (bin->child, &child_allocation); } if (GTK_WIDGET_REALIZED (widget)) gdk_window_move_resize (widget->window,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -