📄 dw_button.c
字号:
/* * File: dw_button.c * * Copyright (C) 2002 Sebastian Geerken <S.Geerken@ping.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *//* * This widget imitates the look and behavior of GtkButton. * * NOTE: Unlike in X, we do not get release events, if the pointer has * been moved out of the widget with mouse button down (implicit * pointer grab, will perhaps be added to Dw). For this reason, the * behavior of DwButton is a bit differernt from GtkButton: If the * user presses the mouse button within the button, then leaves it * (with mouse button pressed), and enters it again, a GtkButton will * still be in the state "pressed", while DwButton resets this state * when the user leaves the button. This is to avoid problems in the * situation when the user leaves the button with mouse button down, * and releases it outside of the button. * * BUG (reminder): If the user releases the button, it gets somehow a * "leave_notify" event. This bug is in the base code, not here, * somehow it is assumed that the mouse pointer is out of the viewport * (Dw_widget_mouse_event is called with widget == NULL). The effect * is that after releasing the mouse button, the DwButton switches * from "active" to "normal", not to "highlighted", as it should. * Should be fixed at the next opportunity. */#include "dw_button.h"#include "dw_gtk_viewport.h"#include "debug.h"#include <gtk/gtk.h>static void Dw_button_init (DwButton *button);static void Dw_button_class_init (DwButtonClass *klass);static void Dw_button_size_request (DwWidget *widget, DwRequisition *requisition);static void Dw_button_get_extremes (DwWidget *widget, DwExtremes *extremes);static void Dw_button_size_allocate (DwWidget *widget, DwAllocation *allocation);static void Dw_button_set_width (DwWidget *widget, gint32 width);static void Dw_button_set_ascent (DwWidget *widget, gint32 ascent);static void Dw_button_set_descent (DwWidget *widget, gint32 descent);static void Dw_button_draw (DwWidget *widget, DwRectangle *area, GdkEventExpose *event);static gboolean Dw_button_button_press (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event);static gboolean Dw_button_button_release (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event);static gboolean Dw_button_enter_notify (DwWidget *widget, DwWidget *last_widget, GdkEventMotion *event);static gboolean Dw_button_leave_notify (DwWidget *widget, DwWidget *next_widget, GdkEventMotion *event);static void Dw_button_add (DwContainer *container, DwWidget *widget);static void Dw_button_remove (DwContainer *container, DwWidget *widget);static void Dw_button_forall (DwContainer *container, DwCallback callback, gpointer callback_data);static DwIterator* Dw_button_iterator (DwWidget *widget, gint mask, gboolean at_end);static gboolean Dw_button_iterator_next (DwIterator *it);static gboolean Dw_button_iterator_prev (DwIterator *it);static gint Dw_button_iterator_compare (DwIterator *it1, DwIterator *it2);enum{ CLICKED, CLICKED_AT, LAST_SIGNAL};static DwContainerClass *parent_class;static guint button_signals[LAST_SIGNAL] = { 0 };/* * Return the type of DwButton */GtkType a_Dw_button_get_type (void){ static GtkType type = 0; if (!type) { GtkTypeInfo info = { "DwButton", sizeof (DwButton), sizeof (DwButtonClass), (GtkClassInitFunc) Dw_button_class_init, (GtkObjectInitFunc) Dw_button_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL, (GtkClassInitFunc) NULL }; type = gtk_type_unique (DW_TYPE_CONTAINER, &info); } return type;}/* * Standard Gtk+ function. * * - "flags" is a mask for the window flags, it should be the mask the * child uses (e.g. DW_USES_HINT for DwPage, 0 for DwImage). (Will * hopefully be removed soon.) * - When passing FALSE for "relief", the button will neither have a * border, nor paint a background. */DwWidget* a_Dw_button_new (gint flags, gboolean relief){ DwButton *button; button = DW_BUTTON (gtk_object_new (DW_TYPE_BUTTON, NULL)); DBG_OBJ_CREATE (button, "DwButton"); DW_WIDGET_SET_FLAGS (button, flags); button->relief = relief; return DW_WIDGET (button);}/* * Standard Gtk+ function. */static void Dw_button_init (DwButton *button){ button->child = NULL; button->in_button = FALSE; button->pressed = FALSE; button->sensitive = FALSE;}/* * Standard Gtk+ function. */static void Dw_button_class_init (DwButtonClass *klass){ GtkObjectClass *object_class; DwWidgetClass *widget_class; DwContainerClass *container_class; object_class = (GtkObjectClass*) klass; widget_class = (DwWidgetClass*) klass; container_class = (DwContainerClass*) klass; parent_class = gtk_type_class (DW_TYPE_CONTAINER); button_signals[CLICKED] = gtk_signal_new ("clicked", GTK_RUN_FIRST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (DwButtonClass, clicked), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); button_signals[CLICKED_AT] = gtk_signal_new ("clicked_at", GTK_RUN_FIRST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (DwButtonClass, clicked_at), gtk_marshal_NONE__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); gtk_object_class_add_signals (object_class, button_signals, LAST_SIGNAL); widget_class->size_request = Dw_button_size_request; widget_class->get_extremes = Dw_button_get_extremes; widget_class->size_allocate = Dw_button_size_allocate; widget_class->set_width = Dw_button_set_width; widget_class->set_ascent = Dw_button_set_ascent; widget_class->set_descent = Dw_button_set_descent; widget_class->draw = Dw_button_draw; widget_class->button_press_event = Dw_button_button_press; widget_class->button_release_event = Dw_button_button_release; widget_class->enter_notify_event = Dw_button_enter_notify; widget_class->leave_notify_event = Dw_button_leave_notify; widget_class->iterator = Dw_button_iterator; container_class->add = Dw_button_add; container_class->remove = Dw_button_remove; container_class->forall = Dw_button_forall; klass->clicked = NULL; klass->clicked_at = NULL;}/* * Standard Dw function. */static void Dw_button_size_request (DwWidget *widget, DwRequisition *requisition){ DwButton *button = DW_BUTTON (widget); DwRequisition child_requisition; GtkStyleClass *styleclass = widget->viewport->style->klass; if (button->child) { a_Dw_widget_size_request (button->child, &child_requisition); *requisition = child_requisition; } else { requisition->width = 0; requisition->ascent = 0; requisition->descent = 0; } if (button->relief) { requisition->width += 2 * styleclass->xthickness; requisition->ascent += styleclass->ythickness; requisition->descent += styleclass->ythickness; }}/* * Standard Dw function. */static void Dw_button_get_extremes (DwWidget *widget, DwExtremes *extremes){ DwButton *button = DW_BUTTON (widget); DwExtremes child_extremes; GtkStyleClass *styleclass = widget->viewport->style->klass; if (button->child) { a_Dw_widget_get_extremes (button->child, &child_extremes); *extremes = child_extremes; } else { extremes->min_width = 0; extremes->max_width = 0; } if (button->relief) { extremes->min_width += 2 * styleclass->xthickness; extremes->max_width += 2 * styleclass->xthickness; }}/* * Standard Dw function. */static void Dw_button_size_allocate (DwWidget *widget, DwAllocation *allocation){ DwButton *button = DW_BUTTON (widget); DwAllocation child_allocation; GtkStyleClass *styleclass = widget->viewport->style->klass; if (button->child) { child_allocation = *allocation; if (button->relief) { child_allocation. x += styleclass->xthickness; child_allocation. y += styleclass->ythickness; child_allocation.width -= 2 * styleclass->xthickness; child_allocation.ascent -= styleclass->ythickness; child_allocation.descent -= styleclass->ythickness; } a_Dw_widget_size_allocate (button->child, &child_allocation); }}/* * Standard Dw function. */static void Dw_button_set_width (DwWidget *widget, gint32 width){ DwButton *button = DW_BUTTON (widget); if (button->child) a_Dw_widget_set_width (button->child, width - (button->relief ? (2 * widget->viewport->style->klass->xthickness) : 0));}/* * Standard Dw function. */static void Dw_button_set_ascent (DwWidget *widget, gint32 ascent){ DwButton *button = DW_BUTTON (widget);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -