📄 dw_embed_gtk.c
字号:
#include <gtk/gtk.h>#include "dw_embed_gtk.h"#include "dw_gtk_viewport.h"#include "debug.h"static void Dw_embed_gtk_init (DwEmbedGtk *embed_gtk);static void Dw_embed_gtk_class_init (DwEmbedGtkClass *klass);static void Dw_embed_gtk_destroy (GtkObject *object);static void Dw_embed_gtk_size_request (DwWidget *widget, DwRequisition *requisition);static gint Dw_embed_gtk_move_idle (void *data);static void Dw_embed_gtk_size_allocate (DwWidget *widget, DwAllocation *allocation);static void Dw_embed_gtk_draw (DwWidget *widget, DwRectangle *area, GdkEventExpose *event);static void Dw_embed_gtk_remove_gtk (DwEmbedGtk *embed_gtk);static GtkWidgetClass *parent_class;/* * Standard Gtk+ function */GtkType a_Dw_embed_gtk_get_type (void){ static GtkType type = 0; if (!type) { GtkTypeInfo info = { "DwEmbedGtk", sizeof (DwEmbedGtk), sizeof (DwEmbedGtkClass), (GtkClassInitFunc) Dw_embed_gtk_class_init, (GtkObjectInitFunc) Dw_embed_gtk_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL, (GtkClassInitFunc) NULL }; type = gtk_type_unique (DW_TYPE_WIDGET, &info); } return type;}/* * Standard Gtk+ function */DwWidget* a_Dw_embed_gtk_new (void){ GtkObject *object; object = gtk_object_new (DW_TYPE_EMBED_GTK, NULL); DBG_OBJ_CREATE (object, "DwEmbedGtk"); return DW_WIDGET (object);}/* * Standard Gtk+ function */static void Dw_embed_gtk_init (DwEmbedGtk *embed_gtk){ embed_gtk->child = NULL; embed_gtk->idle_id = 0; /*embed_gtk->child_size_request_lock = FALSE;*/}/* * Standard Gtk+ function */static void Dw_embed_gtk_class_init (DwEmbedGtkClass *klass){ GtkObjectClass *object_class; DwWidgetClass *widget_class; parent_class = gtk_type_class (DW_TYPE_WIDGET); object_class = GTK_OBJECT_CLASS (klass); object_class->destroy = Dw_embed_gtk_destroy; widget_class = (DwWidgetClass*) klass; widget_class->size_allocate = Dw_embed_gtk_size_allocate; widget_class->size_request = Dw_embed_gtk_size_request; widget_class->draw = Dw_embed_gtk_draw;}/* * Standard Gtk+ function */static void Dw_embed_gtk_destroy (GtkObject *object){ DwEmbedGtk *embed_gtk; embed_gtk = DW_EMBED_GTK (object); if (embed_gtk->child) gtk_object_destroy (GTK_OBJECT (embed_gtk->child)); if (embed_gtk->idle_id != 0) gtk_idle_remove (embed_gtk->idle_id); GTK_OBJECT_CLASS(parent_class)->destroy (object);}/* * Standard Gtk+ function */static void Dw_embed_gtk_size_request (DwWidget *widget, DwRequisition *requisition){ DwEmbedGtk *embed_gtk; GtkRequisition child_requisition; embed_gtk = DW_EMBED_GTK (widget); if (embed_gtk->child) { /*embed_gtk->child_size_request_lock = TRUE;*/ gtk_widget_size_request (embed_gtk->child, &child_requisition); /*embed_gtk->child_size_request_lock = FALSE;*/ requisition->width = child_requisition.width; requisition->ascent = child_requisition.height; requisition->descent = 0; } else { requisition->width = 0; requisition->ascent = 0; requisition->descent = 0; }}/* * Standard Gtk+ function */static gint Dw_embed_gtk_move_idle (void *data){ DwWidget *widget; DwEmbedGtk *embed_gtk; widget = DW_WIDGET (data); embed_gtk = DW_EMBED_GTK (data); if (embed_gtk->child) { if (embed_gtk->child->parent) gtk_layout_move (GTK_LAYOUT (widget->viewport), embed_gtk->child, widget->allocation.x, widget->allocation.y); else gtk_layout_put (GTK_LAYOUT (widget->viewport), embed_gtk->child, widget->allocation.x, widget->allocation.y); } embed_gtk->idle_id = 0; return FALSE;}/* * Standard Gtk+ function */static void Dw_embed_gtk_size_allocate (DwWidget *widget, DwAllocation *allocation){ DwEmbedGtk *embed_gtk; embed_gtk = DW_EMBED_GTK (widget); if (embed_gtk->child && widget->viewport) { if (allocation->width == 0 || allocation->ascent + allocation->descent == 0) gtk_widget_hide (embed_gtk->child); else { gtk_widget_show (embed_gtk->child); if (allocation->width != widget->allocation.width || allocation->ascent + allocation->descent != DW_WIDGET_HEIGHT(widget)) /* todo: try implementing it by gtk_widget_size_allocate */ gtk_widget_set_usize (embed_gtk->child, allocation->width, allocation->ascent + allocation->descent); if (allocation->x != widget->allocation.x || allocation->y != widget->allocation.y) { /* A simple call to gtk_layout_move does not seem to work, so this strange idle function. */ if (embed_gtk->idle_id == 0) embed_gtk->idle_id = gtk_idle_add (Dw_embed_gtk_move_idle, (void*) embed_gtk); } } }}static void Dw_embed_gtk_draw (DwWidget *widget, DwRectangle *area, GdkEventExpose *event){ /* This is the job of GtkDwViewport (resp. the base class GtkLayout). */}/* * This function is called when the embedded Gtk+ widget is destroyed. * Don't use this function directly! */static void Dw_embed_gtk_remove_gtk (DwEmbedGtk *embed_gtk){ embed_gtk->child = NULL; p_Dw_widget_queue_resize (DW_WIDGET (embed_gtk), 0, TRUE);}/* * This function is called when the embedded Gtk+ widget is focused and * will set the adjustments of the viewport. * Don't use this function directly! */static int Dw_embed_gtk_child_focus_in (DwEmbedGtk *embed_gtk){ DwWidget *widget; GtkLayout *layout; gint vx, vy, vw, vh, wx, wy, ww, wh; widget = DW_WIDGET (embed_gtk); layout = GTK_LAYOUT (widget->viewport); vx = layout->xoffset; vy = layout->yoffset; vw = GTK_WIDGET(layout)->allocation.width; vh = GTK_WIDGET(layout)->allocation.height; wx = widget->allocation.x; wy = widget->allocation.y; ww = widget->allocation.width; wh = DW_WIDGET_HEIGHT(widget); if (vx > wx) gtk_adjustment_set_value (layout->hadjustment, wx); else if (vx < wx + ww - vw) gtk_adjustment_set_value (layout->hadjustment, wx + ww - vw); if (vy > wy) gtk_adjustment_set_value (layout->vadjustment, wy); else if (vy < wy + wh - vh) gtk_adjustment_set_value (layout->vadjustment, wy + wh - vh); return FALSE;}#if 0/* * Called when the embedded Gtk widget emits a "size_request" signal, and used * to resise the embedding Dw widget. * * Currently not used. */static void Dw_embed_gtk_child_size_request (DwEmbedGtk *embed_gtk){ DwWidget *widget; GtkRequisition child_requisition; g_return_if_fail (embed_gtk->child); if (!embed_gtk->child_size_request_lock) { widget = DW_WIDGET (embed_gtk); embed_gtk->child_size_request_lock = TRUE; gtk_widget_size_request (embed_gtk->child, &child_requisition); embed_gtk->child_size_request_lock = FALSE; /* Check wether the size has changed at all. */ if (widget->requisition.width != child_requisition.width || widget->requisition.ascent != child_requisition.height) p_Dw_widget_queue_resize (widget, 0, TRUE); }}#endif/* * Add the Gtk+ widget to be embedded. * If there is already one, you have to destroy it before. */void a_Dw_embed_gtk_add_gtk (DwEmbedGtk *embed_gtk, GtkWidget *widget){ /* todo: problems with reparent's? */ g_return_if_fail (embed_gtk->child == NULL); embed_gtk->child = widget; if (DW_WIDGET(embed_gtk)->viewport) gtk_layout_put (GTK_LAYOUT (DW_WIDGET (embed_gtk)->viewport), widget, DW_WIDGET (embed_gtk)->allocation.x, DW_WIDGET (embed_gtk)->allocation.y); /* todo: We somehow must regognize size changes of the embedded Gtk+ * widget. Can this be done with size_request? Anyway, currently * deactivated, since it is not used in dillo. */#if 0 gtk_signal_connect_object (GTK_OBJECT (embed_gtk->child), "size_request", GTK_SIGNAL_FUNC(Dw_embed_gtk_child_size_request), GTK_OBJECT (embed_gtk));#endif /* for setting the adjustments */ gtk_signal_connect_object (GTK_OBJECT (embed_gtk->child), "focus_in_event", GTK_SIGNAL_FUNC (Dw_embed_gtk_child_focus_in), GTK_OBJECT (embed_gtk)); /* todo: An idea: use "remove" signal of DwGtkContainer instead. */ gtk_signal_connect_object (GTK_OBJECT (embed_gtk->child), "destroy", GTK_SIGNAL_FUNC (Dw_embed_gtk_remove_gtk), GTK_OBJECT (embed_gtk)); p_Dw_widget_queue_resize (DW_WIDGET (embed_gtk), 0, TRUE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -