📄 dw_embed_gtk.c
字号:
#include <gtk/gtk.h>#include "dw_embed_gtk.h"#include "dw_gtk_viewport.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, }; 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); return DW_WIDGET(object);}/* * Standard Gtk+ function */static void Dw_embed_gtk_init(DwEmbedGtk * embed_gtk){ embed_gtk->child = NULL; embed_gtk->idle_id = -1;}/* * 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 != -1) 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) { gtk_widget_size_request(embed_gtk->child, &child_requisition); 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 = -1; 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 != widget->allocation.ascent + widget->allocation.descent) /* 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 == -1) 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; Dw_widget_queue_resize(DW_WIDGET(embed_gtk));}/* * 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 = widget->allocation.ascent + widget->allocation.descent; 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;}/* * 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);#if 0 /* This is to recognize size changes of the embedded Gtk+ widget, but this simple implementation causes too much page rewraps, so it is currently deactivated */ gtk_signal_connect_object(GTK_OBJECT(embed_gtk->child), "size_request", GTK_SIGNAL_FUNC(Dw_widget_queue_resize), 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)); Dw_widget_queue_resize(DW_WIDGET(embed_gtk));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -