?? z166.html
字號(hào):
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html> <head> <title> GtkVBox: A Windowless Container </title> <meta name="GENERATOR" content= "Modular DocBook HTML Stylesheet Version 1.45"> <link rel="HOME" title="GTK+ / Gnome Application Development" href="ggad.html"> <link rel="UP" title="Writing a GtkWidget" href= "cha-widget.html"> <link rel="PREVIOUS" title="GtkWidget In Detail" href= "sec-widgetindetail.html"> <link rel="NEXT" title="GnomeAppBar: A Trivial Composite Widget" href="z170.html"> </head> <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink= "#840084" alink="#0000FF"> <div class="NAVHEADER"> <table width="100%" border="0" bgcolor="#ffffff" cellpadding= "1" cellspacing="0"> <tr> <th colspan="4" align="center"> <font color="#000000" size="2">GTK+ / Gnome Application Development</font> </th> </tr> <tr> <td width="25%" bgcolor="#ffffff" align="left"> <a href="sec-widgetindetail.html"><font color="#0000ff" size="2"><b><<< Previous</b></font></a> </td> <td width="25%" colspan="2" bgcolor="#ffffff" align= "center"> <font color="#0000ff" size="2"><b><a href="ggad.html"> <font color="#0000ff" size="2"><b> Home</b></font></a></b></font> </td> <td width="25%" bgcolor="#ffffff" align="right"> <a href="z170.html"><font color="#0000ff" size="2"><b> Next >>></b></font></a> </td> </tr> </table> </div> <div class="SECT1"> <h1 class="SECT1"> <a name="Z166"><tt class="CLASSNAME">GtkVBox</tt>: A Windowless Container</a> </h1> <p> This section describes some aspects of the <tt class= "CLASSNAME">GtkVBox</tt> widget, which differs substantially from the <tt class="CLASSNAME">GtkEv</tt> widget presented earlier in the chapter. To understand this section you must first understand how <tt class= "CLASSNAME">GtkBox</tt> works from a user's point of view; see <a href="sec-containers.html#SEC-GTKBOX">the section called <i><tt class="CLASSNAME">GtkBox</tt></i> in the chapter called <i>GTK+ Basics</i></a>. You might want to look through the files <tt class="FILENAME">gtkvbox.h</tt> and <tt class="FILENAME">gtkvbox.c</tt> from your GTK+ distribution as you read. </p> <p> Most of <tt class="CLASSNAME">GtkVBox</tt> is implemented in the <tt class="CLASSNAME">GtkBox</tt> base class; <tt class="CLASSNAME">GtkVBox</tt> itself implements only size request and allocation. The <tt class="CLASSNAME"> GtkBox</tt> instance struct looks like this: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> typedef struct _GtkBox GtkBox;struct _GtkBox{ GtkContainer container; GList *children; gint16 spacing; guint homogeneous : 1;}; </pre> </td> </tr> </table> <p> <tt class="CLASSNAME">GtkBoxClass</tt> adds nothing to <tt class="CLASSNAME">GtkContainerClass</tt>, and <tt class= "CLASSNAME">GtkVBox</tt> adds nothing to <tt class= "CLASSNAME">GtkBox</tt>. </p> <div class="SECT2"> <h2 class="SECT2"> <a name="Z167">Coding a <span class="STRUCTNAME"> GTK_NO_WINDOW</span> Widget</a> </h2> <p> The implementation of windowless widgets is slightly different from the implementation of "normal" widgets. </p> <p> Windowless widgets must set the <span class="STRUCTNAME"> GTK_NO_WINDOW</span> flag, so GTK+ can treat them appropriately. This should be done in the init function: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_box_init (GtkBox *box){ GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW); box->children = NULL; box->spacing = 0; box->homogeneous = FALSE;} </pre> </td> </tr> </table> <p> <tt class="CLASSNAME">GtkBox</tt> uses the default realize method described in <a href= "sec-widgetindetail.html#SEC-REALIZEMETHOD">the section called <i>Realization</i></a>; because no <span class= "STRUCTNAME">GdkWindow</span> needs to be created, a <span class="STRUCTNAME">GTK_NO_WINDOW</span> widget rarely needs a realize method. Recall that the default realize implementation sets the windowless widget's <span class="STRUCTNAME">window</span> field to the parent widget's <span class="STRUCTNAME">window</span> field. </p> <p> Because boxes are invisible layout containers, the <tt class="CLASSNAME">GtkBox</tt> draw and expose implementations simply pass the draw or expose request on to the box's children. This is identical to <tt class= "CLASSNAME">GtkBin</tt>'s draw and expose implementations, except that there's a list of children to iterate over. </p> <p> A <span class="STRUCTNAME">GTK_NO_WINDOW</span> widget that <i class="EMPHASIS">isn't</i> invisible, such as <tt class="CLASSNAME">GtkLabel</tt>, should be careful not to draw a background; the parent widget's background is used. </p> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z168">Size Negotiation</a> </h2> <p> <tt class="CLASSNAME">GtkVBox</tt>'s purpose in life is size negotiation; it passes size requests up from its children, and then divides a size allocation among them. This leads to the layout behavior described in <a href= "sec-containers.html#SEC-GTKBOX">the section called <i> <tt class="CLASSNAME">GtkBox</tt></i> in the chapter called <i>GTK+ Basics</i></a>. </p> <p> Here is the size request implementation: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_vbox_size_request (GtkWidget *widget, GtkRequisition *requisition){ GtkBox *box; GtkBoxChild *child; GtkRequisition child_requisition; GList *children; gint nvis_children; gint height; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_VBOX (widget)); g_return_if_fail (requisition != NULL); box = GTK_BOX (widget); requisition->width = 0; requisition->height = 0; nvis_children = 0; children = box->children; while (children) { child = children->data; children = children->next; if (GTK_WIDGET_VISIBLE (child->widget)) { gtk_widget_size_request (child->widget, &child_requisition); if (box->homogeneous) { height = child_requisition.height + child->padding * 2; requisition->height = MAX (requisition->height, height); } else { requisition->height += child_requisition.height + child->padding * 2; } requisition->width = MAX (requisition->width, child_requisition.width); nvis_children += 1; } } if (nvis_children > 0) { if (box->homogeneous) requisition->height *= nvis_children; requisition->height += (nvis_children - 1) * box->spacing; } requisition->width += GTK_CONTAINER (box)->border_width * 2; requisition->height += GTK_CONTAINER (box)->border_width * 2;} </pre> </td> </tr> </table> <p> If the box is homogenous, it multiplies the maximum child requisition times the number of children; otherwise, it sums the child requisitions. Then it adds padding, spacing, and border width, as appropriate. Recall that all containers must honor their border width, set with <tt class="FUNCTION"> gtk_container_set_border_width()</tt> and available as the <span class="STRUCTNAME">border_width</span> field in the <tt class="CLASSNAME">GtkContainer</tt> instance struct. </p> <p> When reading this code, it may help to know that <tt class="CLASSNAME">GtkBox</tt> stores a small struct for each child widget in its <span class="STRUCTNAME"> children</span> field. The struct looks like this: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> typedef struct _GtkBoxChild GtkBoxChild;struct _GtkBoxChild{ GtkWidget *widget; guint16 padding; guint expand : 1; guint fill : 1; guint pack : 1;}; </pre> </td> </tr> </table> <p> Size allocation is more complex; here, all the box-packing flags come into play. It will probably take you a while to fully understand this function, but there is no need to; the important thing is to see how layout takes place via size allocation. </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_vbox_size_allocate (GtkWidget *widget, GtkAllocation *allocation){ GtkBox *box; GtkBoxChild *child; GList *children; GtkAllocation child_allocation; gint nvis_children; gint nexpand_children; gint child_height; gint height; gint extra; gint y; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_VBOX (widget)); g_return_if_fail (allocation != NULL); box = GTK_BOX (widget); widget->allocation = *allocation;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -