📄 gtklist.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 "gtklist.h"#include "gtklistitem.h"#include "gtkmain.h"#include "gtksignal.h"#include "gtklabel.h"enum { SELECTION_CHANGED, SELECT_CHILD, UNSELECT_CHILD, LAST_SIGNAL};enum { ARG_0, ARG_SELECTION_MODE};#define SCROLL_TIME 100/** GtkList Methods **/static void gtk_list_class_init (GtkListClass *klass);static void gtk_list_init (GtkList *list);static void gtk_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);/** GtkObject Methods **/static void gtk_list_shutdown (GtkObject *object);/** GtkWidget Methods **/static void gtk_list_size_request (GtkWidget *widget, GtkRequisition *requisition);static void gtk_list_size_allocate (GtkWidget *widget, GtkAllocation *allocation);static void gtk_list_realize (GtkWidget *widget);static void gtk_list_map (GtkWidget *widget);static void gtk_list_unmap (GtkWidget *widget);static void gtk_list_style_set (GtkWidget *widget, GtkStyle *previous_style);static void gtk_list_draw (GtkWidget *widget, GdkRectangle *area);static gint gtk_list_expose (GtkWidget *widget, GdkEventExpose *event);static gint gtk_list_motion_notify (GtkWidget *widget, GdkEventMotion *event);static gint gtk_list_button_press (GtkWidget *widget, GdkEventButton *event);static gint gtk_list_button_release (GtkWidget *widget, GdkEventButton *event);/** GtkContainer Methods **/static void gtk_list_add (GtkContainer *container, GtkWidget *widget);static void gtk_list_remove (GtkContainer *container, GtkWidget *widget);static void gtk_list_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);static GtkType gtk_list_child_type (GtkContainer *container);static void gtk_list_set_focus_child (GtkContainer *container, GtkWidget *widget);static gint gtk_list_focus (GtkContainer *container, GtkDirectionType direction);/** GtkList Private Functions **/static void gtk_list_move_focus_child (GtkList *list, GtkScrollType scroll_type, gfloat position);static gint gtk_list_horizontal_timeout (GtkWidget *list);static gint gtk_list_vertical_timeout (GtkWidget *list);static void gtk_list_remove_items_internal (GtkList *list, GList *items, gboolean no_unref);/** GtkList Selection Methods **/static void gtk_real_list_select_child (GtkList *list, GtkWidget *child);static void gtk_real_list_unselect_child (GtkList *list, GtkWidget *child);/** GtkList Selection Functions **/static void gtk_list_set_anchor (GtkList *list, gboolean add_mode, gint anchor, GtkWidget *undo_focus_child);static void gtk_list_fake_unselect_all (GtkList *list, GtkWidget *item);static void gtk_list_fake_toggle_row (GtkList *list, GtkWidget *item);static void gtk_list_update_extended_selection (GtkList *list, gint row);static void gtk_list_reset_extended_selection (GtkList *list);/** GtkListItem Signal Functions **/static void gtk_list_signal_drag_begin (GtkWidget *widget, GdkDragContext *context, GtkList *list);static void gtk_list_signal_toggle_focus_row (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_select_all (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_unselect_all (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_undo_selection (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_start_selection (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_end_selection (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_extend_selection (GtkListItem *list_item, GtkScrollType scroll_type, gfloat position, gboolean auto_start_selection, GtkList *list);static void gtk_list_signal_scroll_horizontal (GtkListItem *list_item, GtkScrollType scroll_type, gfloat position, GtkList *list);static void gtk_list_signal_scroll_vertical (GtkListItem *list_item, GtkScrollType scroll_type, gfloat position, GtkList *list);static void gtk_list_signal_toggle_add_mode (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_item_select (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_item_deselect (GtkListItem *list_item, GtkList *list);static void gtk_list_signal_item_toggle (GtkListItem *list_item, GtkList *list);static void gtk_list_drag_begin (GtkWidget *widget, GdkDragContext *context);static GtkContainerClass *parent_class = NULL;static guint list_signals[LAST_SIGNAL] = { 0 };static const gchar *vadjustment_key = "gtk-vadjustment";static guint vadjustment_key_id = 0;static const gchar *hadjustment_key = "gtk-hadjustment";static guint hadjustment_key_id = 0;GtkTypegtk_list_get_type (void){ static GtkType list_type = 0; if (!list_type) { static const GtkTypeInfo list_info = { "GtkList", sizeof (GtkList), sizeof (GtkListClass), (GtkClassInitFunc) gtk_list_class_init, (GtkObjectInitFunc) gtk_list_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; list_type = gtk_type_unique (GTK_TYPE_CONTAINER, &list_info); } return list_type;}static voidgtk_list_class_init (GtkListClass *class){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; container_class = (GtkContainerClass*) class; parent_class = gtk_type_class (GTK_TYPE_CONTAINER); vadjustment_key_id = g_quark_from_static_string (vadjustment_key); hadjustment_key_id = g_quark_from_static_string (hadjustment_key); list_signals[SELECTION_CHANGED] = gtk_signal_new ("selection_changed", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkListClass, selection_changed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); list_signals[SELECT_CHILD] = gtk_signal_new ("select_child", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkListClass, select_child), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); list_signals[UNSELECT_CHILD] = gtk_signal_new ("unselect_child", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkListClass, unselect_child), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); gtk_object_class_add_signals (object_class, list_signals, LAST_SIGNAL); object_class->shutdown = gtk_list_shutdown; object_class->set_arg = gtk_list_set_arg; object_class->get_arg = gtk_list_get_arg; widget_class->map = gtk_list_map; widget_class->unmap = gtk_list_unmap; widget_class->style_set = gtk_list_style_set; widget_class->realize = gtk_list_realize; widget_class->draw = gtk_list_draw; widget_class->expose_event = gtk_list_expose; widget_class->button_press_event = gtk_list_button_press; widget_class->button_release_event = gtk_list_button_release; widget_class->motion_notify_event = gtk_list_motion_notify; widget_class->size_request = gtk_list_size_request; widget_class->size_allocate = gtk_list_size_allocate; widget_class->drag_begin = gtk_list_drag_begin; container_class->add = gtk_list_add; container_class->remove = gtk_list_remove; container_class->forall = gtk_list_forall; container_class->child_type = gtk_list_child_type; container_class->set_focus_child = gtk_list_set_focus_child; container_class->focus = gtk_list_focus; class->selection_changed = NULL; class->select_child = gtk_real_list_select_child; class->unselect_child = gtk_real_list_unselect_child; gtk_object_add_arg_type ("GtkList::selection_mode", GTK_TYPE_SELECTION_MODE, GTK_ARG_READWRITE, ARG_SELECTION_MODE);}static voidgtk_list_init (GtkList *list){ list->children = NULL; list->selection = NULL; list->undo_selection = NULL; list->undo_unselection = NULL; list->last_focus_child = NULL; list->undo_focus_child = NULL; list->htimer = 0; list->vtimer = 0; list->anchor = -1; list->drag_pos = -1; list->anchor_state = GTK_STATE_SELECTED; list->selection_mode = GTK_SELECTION_SINGLE; list->drag_selection = FALSE; list->add_mode = FALSE;}static voidgtk_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkList *list = GTK_LIST (object); switch (arg_id) { case ARG_SELECTION_MODE: gtk_list_set_selection_mode (list, GTK_VALUE_ENUM (*arg)); break; }}static voidgtk_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkList *list = GTK_LIST (object); switch (arg_id) { case ARG_SELECTION_MODE: GTK_VALUE_ENUM (*arg) = list->selection_mode; break; default: arg->type = GTK_TYPE_INVALID; break; }}GtkWidget*gtk_list_new (void){ return GTK_WIDGET (gtk_type_new (GTK_TYPE_LIST));}/* Private GtkObject Methods : * * gtk_list_shutdown */static voidgtk_list_shutdown (GtkObject *object){ gtk_list_clear_items (GTK_LIST (object), 0, -1); GTK_OBJECT_CLASS (parent_class)->shutdown (object);}/* Private GtkWidget Methods : * * gtk_list_size_request * gtk_list_size_allocate * gtk_list_realize * gtk_list_map * gtk_list_unmap * gtk_list_motion_notify * gtk_list_button_press * gtk_list_button_release */static voidgtk_list_size_request (GtkWidget *widget, GtkRequisition *requisition){ GtkList *list; GtkWidget *child; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (widget)); g_return_if_fail (requisition != NULL); list = GTK_LIST (widget); requisition->width = 0; requisition->height = 0; children = list->children; while (children) { child = children->data; children = children->next; if (GTK_WIDGET_VISIBLE (child)) { GtkRequisition child_requisition; gtk_widget_size_request (child, &child_requisition); requisition->width = MAX (requisition->width, child_requisition.width); requisition->height += child_requisition.height; } } requisition->width += GTK_CONTAINER (list)->border_width * 2; requisition->height += GTK_CONTAINER (list)->border_width * 2; requisition->width = MAX (requisition->width, 1); requisition->height = MAX (requisition->height, 1);}static voidgtk_list_size_allocate (GtkWidget *widget, GtkAllocation *allocation){ GtkList *list; GtkWidget *child; GtkAllocation child_allocation; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (widget)); g_return_if_fail (allocation != NULL); list = GTK_LIST (widget); widget->allocation = *allocation; if (GTK_WIDGET_REALIZED (widget)) gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height); if (list->children) { child_allocation.x = GTK_CONTAINER (list)->border_width; child_allocation.y = GTK_CONTAINER (list)->border_width; child_allocation.width = MAX (1, (gint)allocation->width - child_allocation.x * 2); children = list->children; while (children) { child = children->data; children = children->next; if (GTK_WIDGET_VISIBLE (child)) { GtkRequisition child_requisition; gtk_widget_get_child_requisition (child, &child_requisition); child_allocation.height = child_requisition.height; gtk_widget_size_allocate (child, &child_allocation); child_allocation.y += child_allocation.height; } } }}static voidgtk_list_realize (GtkWidget *widget){ GdkWindowAttr attributes; gint attributes_mask; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (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) | GDK_EXPOSURE_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); gdk_window_set_background (widget->window, &widget->style->base[GTK_STATE_NORMAL]);}static voidgtk_list_map (GtkWidget *widget){ GtkList *list; GtkWidget *child; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (widget)); GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); list = GTK_LIST (widget); children = list->children; while (children) { child = children->data; children = children->next; if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child)) gtk_widget_map (child); } gdk_window_show (widget->window);}static voidgtk_list_unmap (GtkWidget *widget){ GtkList *list; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (widget)); if (!GTK_WIDGET_MAPPED (widget)) return; list = GTK_LIST (widget); GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -