📄 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. */#include "dw_button.h"#include "dw_gtk_viewport.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 gint Dw_button_button_press (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event);static gint Dw_button_button_release (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event);static gint Dw_button_enter_notify (DwWidget *widget, DwWidget *last_widget, GdkEventMotion *event);static gint 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);enum{ CLICKED, 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. */DwWidget* a_Dw_button_new (void){ GtkObject *object; object = gtk_object_new (DW_TYPE_BUTTON, NULL); return DW_WIDGET (object);}/* * Standard Gtk+ function. */static void Dw_button_init (DwButton *button){ DW_WIDGET_SET_FLAGS (button, DW_USES_HINTS); 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); 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; container_class->add = Dw_button_add; container_class->remove = Dw_button_remove; container_class->forall = Dw_button_forall; klass->clicked = 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); else { child_requisition.width = 0; child_requisition.ascent = 0; child_requisition.descent = 0; } requisition->width = child_requisition.width + 2 * styleclass->xthickness; requisition->ascent = child_requisition.ascent + styleclass->ythickness; requisition->descent = child_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); else { child_extremes.min_width = 0; child_extremes.max_width = 0; } extremes->min_width = child_extremes.min_width + 2 * styleclass->xthickness; extremes->max_width = child_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. x = allocation->x + styleclass->xthickness; child_allocation. y = allocation->y + styleclass->ythickness; child_allocation.width = allocation->width - 2 * styleclass->xthickness; child_allocation.ascent = allocation->ascent - styleclass->ythickness; child_allocation.descent = 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 - 2 * widget->viewport->style->klass->xthickness);}/* * 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 - widget->viewport->style->klass->ythickness);}/* * Standard Dw function. */static void Dw_button_set_descent (DwWidget *widget, gint32 descent){ DwButton *button = DW_BUTTON (widget); if (button->child) a_Dw_widget_set_descent (button->child, descent - widget->viewport->style->klass->ythickness);}/* * Standard Dw function. */static void Dw_button_draw (DwWidget *widget, DwRectangle *area, GdkEventExpose *event){ DwButton *button = DW_BUTTON (widget); GtkStateType state; GtkShadowType shadow; GdkRectangle gdk_area; DwRectangle child_area; if (button->sensitive) { if (button->in_button) { if (button->pressed) { state = GTK_STATE_ACTIVE; shadow = GTK_SHADOW_IN; } else { state = GTK_STATE_PRELIGHT; shadow = GTK_SHADOW_OUT; } } else { state = GTK_STATE_NORMAL; shadow = GTK_SHADOW_OUT; } } else { state = GTK_STATE_INSENSITIVE; shadow = GTK_SHADOW_OUT; } gdk_area.x = p_Dw_widget_x_world_to_viewport (widget, area->x + widget->allocation.x); gdk_area.y = p_Dw_widget_y_world_to_viewport (widget, area->y + widget->allocation.y); gdk_area.width = area->width; gdk_area.height = area->height; gtk_paint_box (widget->viewport->style, DW_WIDGET_WINDOW (widget), state, shadow, &gdk_area, widget->viewport, "buttondefault", p_Dw_widget_x_world_to_viewport (widget, widget->allocation.x), p_Dw_widget_y_world_to_viewport (widget, widget->allocation.y), widget->allocation.width, widget->allocation.ascent + widget->allocation.descent); if (button->child && p_Dw_widget_intersect (button->child, area, &child_area)) a_Dw_widget_draw (button->child, &child_area, event);}/* * Standard Dw function. */static gint Dw_button_button_press (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event){ DwButton *button = DW_BUTTON (widget); button->pressed = TRUE; p_Dw_widget_queue_draw (widget); return TRUE;}/* * Standard Dw function. */static gint Dw_button_button_release (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event){ /* * BUG: Unlike in X, we do not get release events, if the pointer * has been moved out of the widget (will perhaps be fixed in * Dw). This results in a different behavior. */ DwButton *button = DW_BUTTON (widget); button->pressed = FALSE; p_Dw_widget_queue_draw (widget); if (button->in_button && button->sensitive) gtk_signal_emit (GTK_OBJECT (widget), button_signals[CLICKED]); return TRUE;}/* * Standard Dw function. */static gint Dw_button_enter_notify (DwWidget *widget, DwWidget *last_widget, GdkEventMotion *event){ DwButton *button = DW_BUTTON (widget); button->in_button = TRUE; p_Dw_widget_queue_draw (widget); return TRUE;}/* * Standard Dw function. */static gint Dw_button_leave_notify (DwWidget *widget, DwWidget *next_widget, GdkEventMotion *event){ DwButton *button = DW_BUTTON (widget); if(button->child == NULL || next_widget != button->child) { button->in_button = FALSE; p_Dw_widget_queue_draw (widget); } return TRUE;}/* * Standard Dw function. */static void Dw_button_add (DwContainer *container, DwWidget *widget){ DwButton *button = DW_BUTTON(container); g_return_if_fail (button->child == NULL); button->child = widget; p_Dw_widget_set_parent (widget, DW_WIDGET (container));}/* * Standard Dw function. */static void Dw_button_remove (DwContainer *container, DwWidget *widget){ DwButton *button = DW_BUTTON(container); g_return_if_fail (button->child != NULL); g_return_if_fail (widget == button->child); button->child = NULL;}/* * Standard Dw function. */static void Dw_button_forall (DwContainer *container, DwCallback callback, gpointer callback_data){ DwButton *button = DW_BUTTON(container); if (button->child) callback (button->child, callback_data);}/* * An insensitive button does not respond on user interaction. Used * in HTML forms. */void a_Dw_button_set_sensitive (DwButton *button, gboolean sensitive){ button->sensitive = sensitive; p_Dw_widget_queue_draw (DW_WIDGET (button));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -