📄 dw_widget.c
字号:
/* * File: dw_widget.c * * Copyright (C) 2001-2003 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. */#include <stdio.h>#include <string.h>#include <minigui/common.h>#include <minigui/minigui.h>#include <minigui/gdi.h>#include <minigui/window.h>#include "msg.h"#include "dw_widget.h"#include "dw_marshal.h"#include "dw_container.h"#include "dw_viewport.h"#define DEBUG_EVENT 10#define DEBUG_SIZE 0#define DEBUG_ALLOC 0#define DEBUG_LEVEL 1#include "debug.h"static void Dw_widget_init (DwWidget *widget);static void Dw_widget_class_init (DwWidgetClass *klass);static void Dw_widget_finalize (GObject *object);static void Dw_widget_real_destroy (DwWidget *widget);static void Dw_widget_real_size_request (DwWidget *widget, DwRequisition *requisition);static void Dw_widget_real_get_extremes (DwWidget *widget, DwExtremes *extremes);static void Dw_widget_update_cursor (DwWidget *widget);enum{ SIZE_REQUEST, FAST_SIZE_REQUEST, SIZE_ALLOCATE, SET_WIDTH, SET_ASCENT, SET_DESCENT, DRAW, REALIZE, UNREALIZE, DESTROY, BUTTON_PRESS_EVENT, BUTTON_RELEASE_EVENT, MOTION_NOTIFY_EVENT, ENTER_NOTIFY_EVENT, LEAVE_NOTIFY_EVENT, LAST_SIGNAL};static GObjectClass *parent_class;static guint widget_signals[LAST_SIGNAL] = { 0 };/* * Standard GObject function */GType a_Dw_widget_get_type (void){ static GType type = 0; if (!type) { static const GTypeInfo info = { sizeof (DwWidgetClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) Dw_widget_class_init, (GClassFinalizeFunc) NULL, (gconstpointer) NULL, sizeof (DwWidget), 0, (GInstanceInitFunc) Dw_widget_init }; type = g_type_register_static (G_TYPE_OBJECT, "DwWidget", &info, 0); } return type;}/* * Standard GObject function */static void Dw_widget_init (DwWidget *widget){ widget->flags = DW_NEEDS_RESIZE | DW_EXTREMES_CHANGED | DW_HAS_CONTENT; widget->parent = NULL; widget->viewport = NULL; widget->allocation.x = -1; widget->allocation.y = -1; widget->allocation.width = 1; widget->allocation.ascent = 1; widget->allocation.descent = 0; widget->cursor = 0; widget->style = NULL; widget->bg_color = NULL; widget->button_sensitive = TRUE; widget->button_sensitive_set = FALSE;}/* * Standard GObject function */static void Dw_widget_class_init (DwWidgetClass *klass){ GObjectClass *object_class; parent_class = g_type_class_peek_parent (klass); object_class = G_OBJECT_CLASS (klass); widget_signals[SIZE_REQUEST] = g_signal_new ("size_request", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, size_request), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); widget_signals[SIZE_ALLOCATE] = g_signal_new ("size_allocate", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, size_allocate), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); widget_signals[SET_WIDTH] = g_signal_new ("set_width", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, set_width), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_UINT); widget_signals[SET_ASCENT] = g_signal_new ("set_ascent", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, set_ascent), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_UINT); widget_signals[SET_DESCENT] = g_signal_new ("set_descent", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, set_descent), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_UINT); widget_signals[DRAW] = g_signal_new ("draw", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, draw), NULL, NULL, g_cclosure_marshal_VOID__UINT_POINTER, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER); widget_signals[REALIZE] = g_signal_new ("realize", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, realize), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); widget_signals[UNREALIZE] = g_signal_new ("unrealize", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (DwWidgetClass, unrealize), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); widget_signals[DESTROY] = g_signal_new ("destroy", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (DwWidgetClass, destroy), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); widget_signals[BUTTON_PRESS_EVENT] = g_signal_new ("button_press_event", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwWidgetClass, button_press_event), NULL, NULL, p_Dw_marshal_BOOL__INT_INT_UINT, G_TYPE_BOOLEAN, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_UINT); widget_signals[BUTTON_RELEASE_EVENT] = g_signal_new ("button_release_event", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwWidgetClass, button_release_event), NULL, NULL, p_Dw_marshal_BOOL__INT_INT_UINT, G_TYPE_BOOLEAN, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_UINT); widget_signals[MOTION_NOTIFY_EVENT] = g_signal_new ("motion_notify_event", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwWidgetClass, motion_notify_event), NULL, NULL, p_Dw_marshal_BOOL__INT_INT_UINT, G_TYPE_BOOLEAN, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_UINT); widget_signals[ENTER_NOTIFY_EVENT] = g_signal_new ("enter_notify_event", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwWidgetClass, enter_notify_event), NULL, NULL, p_Dw_marshal_BOOL__POINTER_POINTER, G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_POINTER); widget_signals[LEAVE_NOTIFY_EVENT] = g_signal_new ("leave_notify_event", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DwWidgetClass, leave_notify_event), NULL, NULL, p_Dw_marshal_BOOL__POINTER_POINTER, G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_POINTER); object_class->finalize = Dw_widget_finalize; klass->size_request = Dw_widget_real_size_request; klass->get_extremes = Dw_widget_real_get_extremes; klass->size_allocate = NULL; klass->mark_size_change = NULL; klass->mark_extremes_change = NULL; klass->set_width = NULL; klass->set_ascent = NULL; klass->set_descent = NULL; klass->draw = NULL; klass->realize = NULL; klass->unrealize = NULL; klass->destroy = Dw_widget_real_destroy; klass->button_press_event = NULL; klass->button_release_event = NULL; klass->motion_notify_event = NULL; klass->enter_notify_event = NULL; klass->leave_notify_event = NULL; klass->iterator = NULL;}/* * Standard GObject function */static void Dw_widget_finalize (GObject *object){ DwWidget *widget; widget = DW_WIDGET (object); if (DW_IS_CONTAINER (widget)) { a_Dw_container_forall (DW_CONTAINER (widget), (DwCallback) g_object_unref, NULL); } parent_class->finalize (object);}/* * Functions to end a DwWidget's life time */void a_Dw_widget_destroy (DwWidget *widget){ printf ("Enter a_Dw_widget_destroy\n"); g_return_if_fail (widget != NULL); g_return_if_fail (DW_IS_WIDGET (widget)); /* The widget the pointer is in? */ if (widget->viewport != NULL && widget == DW_VIEWPORT(widget->viewport)->last_entered) /* todo: perhaps call the leave_notify function? */ DW_VIEWPORT(widget->viewport)->last_entered = NULL; a_Dw_widget_unrealize (widget); if (widget->style) a_Dw_style_unref (widget->style); if (widget->parent) Dw_container_remove (DW_CONTAINER (widget->parent), widget); else Dw_viewport_remove_dw ((DwViewport *)widget->viewport); g_signal_emit (G_OBJECT (widget), widget_signals[DESTROY], 0);}static void Dw_widget_real_destroy (DwWidget *widget){ g_signal_handlers_destroy (G_OBJECT (widget)); g_object_unref (G_OBJECT (widget));}/* * Standard Dw function */static void Dw_widget_real_size_request (DwWidget *widget, DwRequisition *requisition){ g_warning ("DwWidget::size_request not implemented for `%s'", g_type_name (G_OBJECT_TYPE (widget))); /* return random size to prevent crashes*/ requisition->width = 50; requisition->ascent = 50; requisition->descent = 50;}/* * Standard Dw function */static void Dw_widget_real_get_extremes (DwWidget *widget, DwExtremes *extremes){ /* Simply return the requisition width */ DwRequisition requisition; a_Dw_widget_size_request (widget, &requisition); extremes->min_width = extremes->max_width = requisition.width;}/* * This function is a wrapper for DwWidget::size_request; it calls * this method only when needed. */void a_Dw_widget_size_request (DwWidget *widget, DwRequisition *requisition){ if (DW_WIDGET_NEEDS_RESIZE (widget)) { /* todo: check requisition == &(widget->requisition) and do what? */ g_signal_emit (G_OBJECT (widget), widget_signals[SIZE_REQUEST], 0, requisition); widget->requisition = *requisition; DW_WIDGET_UNSET_FLAGS (widget, DW_NEEDS_RESIZE); DBG_OBJ_SET_NUM (widget, "requisition.width", widget->requisition.width); DBG_OBJ_SET_NUM (widget, "requisition.ascent", widget->requisition.ascent); DBG_OBJ_SET_NUM (widget, "requisition.descent", widget->requisition.descent); } else *requisition = widget->requisition;}/* * Wrapper for DwWidget::get_extremes. */void a_Dw_widget_get_extremes (DwWidget *widget, DwExtremes *extremes){ DwWidgetClass *klass; if (DW_WIDGET_EXTREMES_CHANGED (widget)) { klass = DW_WIDGET_GET_CLASS (widget); (* (klass->get_extremes)) (widget, extremes); widget->extremes = *extremes; DW_WIDGET_UNSET_FLAGS (widget, DW_EXTREMES_CHANGED); DBG_OBJ_SET_NUM (widget, "extremes.min_width", widget->extremes.min_width); DBG_OBJ_SET_NUM (widget, "extremes.max_width", widget->extremes.max_width); } else *extremes = widget->extremes;}/* * Wrapper for DwWidget::size_allocate, only called when needed. */void a_Dw_widget_size_allocate (DwWidget *widget, DwAllocation *allocation){ if (DW_WIDGET_NEEDS_ALLOCATE (widget) || allocation->x != widget->allocation.x || allocation->y != widget->allocation.y || allocation->width != widget->allocation.width || allocation->ascent != widget->allocation.ascent || allocation->descent != widget->allocation.descent) { DEBUG_MSG (DEBUG_ALLOC, "a %stop-level %s with parent_ref = %d is newly allocated " "from %d, %d, %d x %d x %d ...\n", widget->parent ? "non-" : "", g_type_name (G_OBJECT_TYPE (widget)), widget->parent_ref, widget->allocation.x, widget->allocation.y, widget->allocation.width, widget->allocation.ascent, widget->allocation.descent); g_signal_emit (G_OBJECT (widget), widget_signals[SIZE_ALLOCATE], 0, allocation); DEBUG_MSG (DEBUG_ALLOC, "... to %d, %d, %d x %d x %d\n", widget->allocation.x, widget->allocation.y, widget->allocation.width, widget->allocation.ascent, widget->allocation.descent); widget->allocation = *allocation; DW_WIDGET_UNSET_FLAGS (widget, DW_NEEDS_ALLOCATE); DBG_OBJ_SET_NUM (widget, "allocation.x", widget->allocation.x); DBG_OBJ_SET_NUM (widget, "allocation.y", widget->allocation.y); DBG_OBJ_SET_NUM (widget, "allocation.width", widget->allocation.width); DBG_OBJ_SET_NUM (widget, "allocation.ascent", widget->allocation.ascent); DBG_OBJ_SET_NUM (widget, "allocation.descent", widget->allocation.descent); } /*DW_WIDGET_UNSET_FLAGS (widget, DW_NEEDS_RESIZE);*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -