?? sec-widgetindetail.html
字號:
g_return_if_fail (GTK_IS_BIN (container)); g_return_if_fail (child != NULL); g_return_if_fail (GTK_IS_WIDGET (child)); bin = GTK_BIN (container); g_return_if_fail (bin->child == child); widget_was_visible = GTK_WIDGET_VISIBLE (child); gtk_widget_unparent (child); bin->child = NULL; if (widget_was_visible) gtk_widget_queue_resize (GTK_WIDGET (container));} </pre> </td> </tr> </table> <p> A remove method is little more than a wrapper for <tt class="FUNCTION">gtk_widget_unparent</tt> that queues a resize if necessary. Most remove methods would check the container's <span class="STRUCTNAME"> GTK_VISIBLE</span> flag before queueing a resize, just as <tt class="FUNCTION">gtk_bin_add()</tt> does; <tt class="CLASSNAME">GtkBin</tt> does not because toplevel widgets like <tt class="CLASSNAME">GtkWindow</tt> derive from it, and those widgets always queue a resize, regardless of visibility. </p> </div> <div class="SECT3"> <h3 class="SECT3"> <a name="Z163">Iterating Over Children</a> </h3> <p> Containers have a <span class="STRUCTNAME"> forall</span> method for iterating over their children; <span class="STRUCTNAME">GtkContainer</span>'s default methods use <span class="STRUCTNAME">forall</span>, since they know nothing about the data members in subclasses' instance structs. The <span class= "STRUCTNAME">forall</span> method invokes a callback on each child, with the provided callback data as the second argument. Obviously it's going to be trivial for <tt class="CLASSNAME">GtkBin</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_bin_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data){ GtkBin *bin; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_BIN (container)); g_return_if_fail (callback != NULL); bin = GTK_BIN (container); if (bin->child) (* callback) (bin->child, callback_data);} </pre> </td> </tr> </table> <p> You may notice that <tt class="CLASSNAME">GtkBin</tt> ignores the <span class="STRUCTNAME"> include_internals</span> argument. Some containers have "incidental" child widgets in addition to the user-provided children they are primarily designed to hold. For example, <tt class="CLASSNAME"> GtkNotebook</tt> has a widget labelling each of its tabs; <tt class="CLASSNAME">GtkCList</tt> uses buttons to title each column in the list. These internal widgets must be included in the iteration in many cases; for example, when drawing each child in a container, or destroying each child in a container. However, some operations only operate on the "primary" children, such as the pages in <tt class="CLASSNAME"> GtkNotebook</tt>. The <span class="STRUCTNAME"> include_internals</span> flag indicates whether to invoke the callback on incidental widgets. </p> <p> Convenience functions are provided that invoke the <span class="STRUCTNAME">forall</span> method; these are used by application authors as well as <tt class= "CLASSNAME">GtkContainer</tt> internals. <tt class= "FUNCTION">gtk_container_foreach()</tt> iterates over only the primary children of a container, while <tt class="FUNCTION">gtk_container_forall()</tt> iterates over all the children. </p> </div> <div class="SECT3"> <h3 class="SECT3"> <a name="Z164">Child Type</a> </h3> <p> The <span class="STRUCTNAME">child_type</span> method returns the type of children a container can hold. For example, a <tt class="CLASSNAME">GtkMenuShell</tt> (parent class of <tt class="CLASSNAME">GtkMenu</tt> and <tt class="CLASSNAME">GtkMenuBar</tt>) can only hold children of type <span class="STRUCTNAME"> GTK_TYPE_MENU_ITEM</span>. The <span class= "STRUCTNAME">child_type</span> method allows GUI builders and scripting languages to determine at runtime what sort of children a container will accept. <span class="STRUCTNAME">GTK_TYPE_NONE</span> indicates that a container will not accept children at this time, for whatever reason. </p> <p> The <tt class="CLASSNAME">GtkBin</tt> implementation accepts <span class="STRUCTNAME">GTK_TYPE_WIDGET</span> if the bin is empty, and <span class="STRUCTNAME"> GTK_TYPE_NONE</span> if the bin already contains a child: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static GtkTypegtk_bin_child_type (GtkContainer *container){ if (!GTK_BIN (container)->child) return GTK_TYPE_WIDGET; else return GTK_TYPE_NONE;} </pre> </td> </tr> </table> </div> <div class="SECT3"> <h3 class="SECT3"> <a name="Z165">Other <tt class="CLASSNAME">GtkBin</tt> Functionality</a> </h3> <p> <tt class="CLASSNAME">GtkBin</tt> also provides default implementations of expose, map, unmap, and draw from <span class="STRUCTNAME">GtkWidgetClass</span>. Most <tt class="CLASSNAME">GtkBin</tt> subclasses will override these methods to handle the unique features of the subclass, but chain up to the <tt class= "CLASSNAME">GtkBin</tt> method to deal with their child widget. </p> <p> The <tt class="CLASSNAME">GtkBin</tt> map and unmap implementations are mostly the usual boilerplate (set <span class="STRUCTNAME">GTK_MAPPED</span>, show <span class="STRUCTNAME">widget->window</span>) but they add an important step unique to containers: mapping the child if it has been shown (remember that <span class= "STRUCTNAME">GTK_VISIBLE</span> signals a widget has been shown), and unmapping the child when the bin is unmapped. Here's the code: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_bin_map (GtkWidget *widget){ GtkBin *bin; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_BIN (widget)); GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); bin = GTK_BIN (widget); if (bin->child && GTK_WIDGET_VISIBLE (bin->child) && !GTK_WIDGET_MAPPED (bin->child)) gtk_widget_map (bin->child); if (!GTK_WIDGET_NO_WINDOW (widget)) gdk_window_show (widget->window);}static voidgtk_bin_unmap (GtkWidget *widget){ GtkBin *bin; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_BIN (widget)); GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); bin = GTK_BIN (widget); if (GTK_WIDGET_NO_WINDOW (widget)) gtk_widget_queue_clear (widget); else gdk_window_hide (widget->window); if (bin->child && GTK_WIDGET_MAPPED (bin->child)) gtk_widget_unmap (bin->child);} </pre> </td> </tr> </table> <p> <tt class="CLASSNAME">GtkBin</tt>'s draw and expose implementations simply redraw the child widget; most subclasses will need to override these methods in order to draw themselves, then chain up to draw the child. The code: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_bin_draw (GtkWidget *widget, GdkRectangle *area){ GtkBin *bin; GdkRectangle child_area; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_BIN (widget)); bin = GTK_BIN (widget); if (GTK_WIDGET_DRAWABLE (bin)) { if (bin->child && GTK_WIDGET_DRAWABLE (bin->child) && gtk_widget_intersect (bin->child, area, &child_area)) gtk_widget_draw (bin->child, &child_area); }}static gintgtk_bin_expose (GtkWidget *widget, GdkEventExpose *event){ GtkBin *bin; GdkEventExpose child_event; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_BIN (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (GTK_WIDGET_DRAWABLE (widget)) { bin = GTK_BIN (widget); child_event = *event; if (bin->child && GTK_WIDGET_DRAWABLE (bin->child) && GTK_WIDGET_NO_WINDOW (bin->child) && gtk_widget_intersect (bin->child, &event->area, &child_event.area)) gtk_widget_event (bin->child, (GdkEvent*) &child_event); } return FALSE;} </pre> </td> </tr> </table> <p> Notice that expose events are only generated for windowless widgets; widgets with windows will receive their own expose events. Containers are required to generate expose events for windowless children. </p> <p> You can probably guess that <tt class="FUNCTION"> gtk_widget_intersect()</tt> determines the intersection of a rectangle and a child widget. </p> </div> </div> </div> <div class="NAVFOOTER"> <br> <br> <table width="100%" border="0" bgcolor="#ffffff" cellpadding= "1" cellspacing="0"> <tr> <td width="25%" bgcolor="#ffffff" align="left"> <a href="z147.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="z166.html"><font color="#0000ff" size="2"><b> Next >>></b></font></a> </td> </tr> <tr> <td colspan="2" align="left"> <font color="#000000" size="2"><b>An Example: The <tt class="CLASSNAME">GtkEv</tt> Widget</b></font> </td> <td colspan="2" align="right"> <font color="#000000" size="2"><b><tt class= "CLASSNAME">GtkVBox</tt>: A Windowless Container</b></font> </td> </tr> </table> </div> </body></html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -