⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sec-creatingawidgetfromscratch.html

📁 gtk 开发手册和参考文档。 包括gtk glib gdk等
💻 HTML
📖 第 1 页 / 共 3 页
字号:
GtkWidget*     gtk_dial_new                    (GtkAdjustment *adjustment);guint          gtk_dial_get_type               (void);GtkAdjustment* gtk_dial_get_adjustment         (GtkDial      *dial);void           gtk_dial_set_update_policy      (GtkDial      *dial,						GtkUpdateType  policy);void           gtk_dial_set_adjustment         (GtkDial      *dial,						GtkAdjustment *adjustment);#ifdef __cplusplus}#endif /* __cplusplus */#endif /* __GTK_DIAL_H__ */</PRE></TD></TR></TABLE><P>Since there is quite a bit more going on in this widget than the lastone, we have more fields in the data structure, but otherwise thingsare pretty similar.</P><P>Next, after including header files and declaring a few constants,we have some functions to provide information about the widgetand initialize it:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">#include &#60;math.h&#62;#include &#60;stdio.h&#62;#include &#60;gtk/gtkmain.h&#62;#include &#60;gtk/gtksignal.h&#62;#include "gtkdial.h"#define SCROLL_DELAY_LENGTH  300#define DIAL_DEFAULT_SIZE 100/* Forward declarations */[ omitted to save space ]/* Local data */static GtkWidgetClass *parent_class = NULL;guintgtk_dial_get_type (){  static guint dial_type = 0;  if (!dial_type)    {      GtkTypeInfo dial_info =      {	"GtkDial",	sizeof (GtkDial),	sizeof (GtkDialClass),	(GtkClassInitFunc) gtk_dial_class_init,	(GtkObjectInitFunc) gtk_dial_init,	(GtkArgSetFunc) NULL,        (GtkArgGetFunc) NULL,      };      dial_type = gtk_type_unique (gtk_widget_get_type (), &#38;dial_info);    }  return dial_type;}static voidgtk_dial_class_init (GtkDialClass *class){  GtkObjectClass *object_class;  GtkWidgetClass *widget_class;  object_class = (GtkObjectClass*) class;  widget_class = (GtkWidgetClass*) class;  parent_class = gtk_type_class (gtk_widget_get_type ());  object_class-&#62;destroy = gtk_dial_destroy;  widget_class-&#62;realize = gtk_dial_realize;  widget_class-&#62;expose_event = gtk_dial_expose;  widget_class-&#62;size_request = gtk_dial_size_request;  widget_class-&#62;size_allocate = gtk_dial_size_allocate;  widget_class-&#62;button_press_event = gtk_dial_button_press;  widget_class-&#62;button_release_event = gtk_dial_button_release;  widget_class-&#62;motion_notify_event = gtk_dial_motion_notify;}static voidgtk_dial_init (GtkDial *dial){  dial-&#62;button = 0;  dial-&#62;policy = GTK_UPDATE_CONTINUOUS;  dial-&#62;timer = 0;  dial-&#62;radius = 0;  dial-&#62;pointer_width = 0;  dial-&#62;angle = 0.0;  dial-&#62;old_value = 0.0;  dial-&#62;old_lower = 0.0;  dial-&#62;old_upper = 0.0;  dial-&#62;adjustment = NULL;}GtkWidget*gtk_dial_new (GtkAdjustment *adjustment){  GtkDial *dial;  dial = gtk_type_new (gtk_dial_get_type ());  if (!adjustment)    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);  gtk_dial_set_adjustment (dial, adjustment);  return GTK_WIDGET (dial);}static voidgtk_dial_destroy (GtkObject *object){  GtkDial *dial;  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_DIAL (object));  dial = GTK_DIAL (object);  if (dial-&#62;adjustment)    gtk_object_unref (GTK_OBJECT (dial-&#62;adjustment));  if (GTK_OBJECT_CLASS (parent_class)-&#62;destroy)    (* GTK_OBJECT_CLASS (parent_class)-&#62;destroy) (object);}</PRE></TD></TR></TABLE><P>Note that this <TTCLASS="LITERAL">init()</TT> function does less than for the Tictactoewidget, since this is not a composite widget, and the <TTCLASS="LITERAL">new()</TT>function does more, since it now has an argument. Also, note that whenwe store a pointer to the Adjustment object, we increment itsreference count, (and correspondingly decrement it when we no longeruse it) so that GTK can keep track of when it can be safely destroyed.</P><P>Also, there are a few function to manipulate the widget's options:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GtkAdjustment*gtk_dial_get_adjustment (GtkDial *dial){  g_return_val_if_fail (dial != NULL, NULL);  g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);  return dial-&#62;adjustment;}voidgtk_dial_set_update_policy (GtkDial      *dial,			     GtkUpdateType  policy){  g_return_if_fail (dial != NULL);  g_return_if_fail (GTK_IS_DIAL (dial));  dial-&#62;policy = policy;}voidgtk_dial_set_adjustment (GtkDial      *dial,			  GtkAdjustment *adjustment){  g_return_if_fail (dial != NULL);  g_return_if_fail (GTK_IS_DIAL (dial));  if (dial-&#62;adjustment)    {      gtk_signal_disconnect_by_data (GTK_OBJECT (dial-&#62;adjustment), (gpointer) dial);      gtk_object_unref (GTK_OBJECT (dial-&#62;adjustment));    }  dial-&#62;adjustment = adjustment;  gtk_object_ref (GTK_OBJECT (dial-&#62;adjustment));  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",		      (GtkSignalFunc) gtk_dial_adjustment_changed,		      (gpointer) dial);  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",		      (GtkSignalFunc) gtk_dial_adjustment_value_changed,		      (gpointer) dial);  dial-&#62;old_value = adjustment-&#62;value;  dial-&#62;old_lower = adjustment-&#62;lower;  dial-&#62;old_upper = adjustment-&#62;upper;  gtk_dial_update (dial);}</PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2724">24.4.5. <TTCLASS="LITERAL">gtk_dial_realize()</TT></A></H2><P>Now we come to some new types of functions. First, we have a functionthat does the work of creating the X window. Notice that a mask ispassed to the function <TTCLASS="LITERAL">gdk_window_new()</TT> which specifies which fields ofthe GdkWindowAttr structure actually have data in them (the remainingfields will be given default values). Also worth noting is the way theevent mask of the widget is created. We call<TTCLASS="LITERAL">gtk_widget_get_events()</TT> to retrieve the event mask that the userhas specified for this widget (with <TTCLASS="LITERAL">gtk_widget_set_events()</TT>), andadd the events that we are interested in ourselves.</P><P>After creating the window, we set its style and background, and put apointer to the widget in the user data field of the GdkWindow. Thislast step allows GTK to dispatch events for this window to the correctwidget.</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">static voidgtk_dial_realize (GtkWidget *widget){  GtkDial *dial;  GdkWindowAttr attributes;  gint attributes_mask;  g_return_if_fail (widget != NULL);  g_return_if_fail (GTK_IS_DIAL (widget));  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);  dial = GTK_DIAL (widget);  attributes.x = widget-&#62;allocation.x;  attributes.y = widget-&#62;allocation.y;  attributes.width = widget-&#62;allocation.width;  attributes.height = widget-&#62;allocation.height;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.window_type = GDK_WINDOW_CHILD;  attributes.event_mask = gtk_widget_get_events (widget) |     GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |     GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |    GDK_POINTER_MOTION_HINT_MASK;  attributes.visual = gtk_widget_get_visual (widget);  attributes.colormap = gtk_widget_get_colormap (widget);  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;  widget-&#62;window = gdk_window_new (widget-&#62;parent-&#62;window, &#38;attributes, attributes_mask);  widget-&#62;style = gtk_style_attach (widget-&#62;style, widget-&#62;window);  gdk_window_set_user_data (widget-&#62;window, widget);  gtk_style_set_background (widget-&#62;style, widget-&#62;window, GTK_STATE_ACTIVE);}</PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2733">24.4.6. Size negotiation</A></H2><P>Before the first time that the window containing a widget isdisplayed, and whenever the layout of the window changes, GTK askseach child widget for its desired size. This request is handled by thefunction <TTCLASS="LITERAL">gtk_dial_size_request()</TT>. Since our widget isn't acontainer widget, and has no real constraints on its size, we justreturn a reasonable default value.</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">static void gtk_dial_size_request (GtkWidget      *widget,		       GtkRequisition *requisition){  requisition-&#62;width = DIAL_DEFAULT_SIZE;  requisition-&#62;height = DIAL_DEFAULT_SIZE;}</PRE></TD></TR></TABLE><P>After all the widgets have requested an ideal size, the layout of thewindow is computed and each child widget is notified of its actualsize. Usually, this will be at least as large as the requested size,but if for instance the user has resized the window, it mayoccasionally be smaller than the requested size. The size notificationis handled by the function <TTCLASS="LITERAL">gtk_dial_size_allocate()</TT>. Notice thatas well as computing the sizes of some component pieces for futureuse, this routine also does the grunt work of moving the widget's Xwindow into the new position and size.</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">static voidgtk_dial_size_allocate (GtkWidget     *widget,			GtkAllocation *allocation){  GtkDial *dial;  g_return_if_fail (widget != NULL);  g_return_if_fail (GTK_IS_DIAL (widget));  g_return_if_fail (allocation != NULL);  widget-&#62;allocation = *allocation;  if (GTK_WIDGET_REALIZED (widget))    {      dial = GTK_DIAL (widget);      gdk_window_move_resize (widget-&#62;window,			      allocation-&#62;x, allocation-&#62;y,			      allocation-&#62;width, allocation-&#62;height);      dial-&#62;radius = MAX(allocation-&#62;width,allocation-&#62;height) * 0.45;      dial-&#62;pointer_width = dial-&#62;radius / 5;    }}</PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2741">24.4.7. <TTCLASS="LITERAL">gtk_dial_expose()</TT></A></H2><P>As mentioned above, all the drawing of this widget is done in thehandler for expose events. There's not much to remark on here exceptthe use of the function <TTCLASS="LITERAL">gtk_draw_polygon</TT> to draw the pointer withthree dimensional shading according to the colors stored in thewidget's style.</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">static gintgtk_dial_expose (GtkWidget      *widget,		 GdkEventExpose *event){  GtkDial *dial;  GdkPoint points[3];  gdouble s,c;  gdouble theta;  gint xc, yc;  gint tick_length;  gint i;  g_return_val_if_fail (widget != NULL, FALSE);  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);  g_return_val_if_fail (event != NULL, FALSE);  if (event-&#62;count &#62; 0)    return FALSE;    dial = GTK_DIAL (widget);  gdk_window_clear_area (widget-&#62;window,			 0, 0,			 widget-&#62;allocation.width,			 widget-&#62;allocation.height);  xc = widget-&#62;allocation.width/2;  yc = widget-&#62;allocation.height/2;  /* Draw ticks */  for (i=0; i&#60;25; i++)    {      theta = (i*M_PI/18. - M_PI/6.);      s = sin(theta);      c = cos(theta);      tick_length = (i%6 == 0) ? dial-&#62;pointer_width : dial-&#62;pointer_width/2;            gdk_draw_line (widget-&#62;window,		     widget-&#62;style-&#62;fg_gc[widget-&#62;state],		     xc + c*(dial-&#62;radius - tick_length),		     yc - s*(dial-&#62;radius - tick_length),		     xc + c*dial-&#62;radius,		     yc - s*dial-&#62;radius);    }  /* Draw pointer */  s = sin(dial-&#62;angle);  c = cos(dial-&#62;angle);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -