📄 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_viewport.h"#include "dw_marshal.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, HDC hdc, DwRectangle *area);static gboolean Dw_button_button_press (DwWidget *widget, gint32 x, gint32 y, DWORD flags);static gboolean Dw_button_button_release (DwWidget *widget, gint32 x, gint32 y, DWORD flags);static gboolean Dw_button_enter_notify (DwWidget *widget, DwWidget *last_widget, DWORD flags);static gboolean Dw_button_leave_notify (DwWidget *widget, DwWidget *next_widget, DWORD flags);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 */GType a_Dw_button_get_type (void){ static GType type = 0; if (!type) { static const GTypeInfo info = { sizeof (DwButtonClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) Dw_button_class_init, (GClassFinalizeFunc) NULL, (gconstpointer) NULL, sizeof (DwButton), 0, (GInstanceInitFunc) Dw_button_init }; type = g_type_register_static (DW_TYPE_WIDGET, "DwButton", &info, 0); } return type;}/* * Standard GObject 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 (g_object_new (DW_TYPE_BUTTON, NULL)); DW_WIDGET_SET_FLAGS (button, flags); button->relief = relief; return DW_WIDGET (button);}/* * Standard GObject function. */static void Dw_button_init (DwButton *button){ button->child = NULL; button->in_button = FALSE; button->pressed = FALSE; button->sensitive = FALSE;}/* * Standard GObject function. */static void Dw_button_class_init (DwButtonClass *klass){ GObjectClass *object_class; DwWidgetClass *widget_class; DwContainerClass *container_class; object_class = G_OBJECT_CLASS (klass); widget_class = (DwWidgetClass*) klass; container_class = (DwContainerClass*) klass; parent_class = g_type_class_peek_parent (klass); button_signals[CLICKED] = g_signal_new ("clicked", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (DwButtonClass, clicked), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); button_signals[CLICKED_AT] = g_signal_new ("clicked_at", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (DwButtonClass, clicked_at), NULL, NULL, p_Dw_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); 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; 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 * 2; requisition->ascent += 2; requisition->descent += 2; }}/* * Standard Dw function. */static void Dw_button_get_extremes (DwWidget *widget, DwExtremes *extremes){ DwButton *button = DW_BUTTON (widget); DwExtremes child_extremes; 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 * 2; extremes->max_width += 2 * 2; }}/* * Standard Dw function. */static void Dw_button_size_allocate (DwWidget *widget, DwAllocation *allocation){ DwButton *button = DW_BUTTON (widget); DwAllocation child_allocation; if (button->child) { child_allocation = *allocation; if (button->relief) { child_allocation. x += 2; child_allocation. y += 2; child_allocation.width -= 2 * 2; child_allocation.ascent -= 2; child_allocation.descent -= 2; } 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 * 2) : 0));}/* * Standard Dw function. */static void Dw_button_set_ascent (DwWidget *widget, gint32 ascent){ DwButton *button = DW_BUTTON (widget); if (button->child) a_Dw_widget_set_ascent (button->child, ascent - (button->relief ? 2 : 0));}/* * Standard Dw function. */static void Dw_button_set_descent (DwWidget *widget, gint32 descent){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -