?? sec-widgetindetail.html
字號:
typedef struct _GtkContainerClass GtkContainerClass;struct _GtkContainerClass{ GtkWidgetClass parent_class; guint n_child_args; void (* add) (GtkContainer *container, GtkWidget *widget); void (* remove) (GtkContainer *container, GtkWidget *widget); void (* check_resize) (GtkContainer *container); void (* forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callbabck_data); gint (* focus) (GtkContainer *container, GtkDirectionType direction); void (* set_focus_child) (GtkContainer *container, GtkWidget *widget); GtkType (*child_type) (GtkContainer *container); void (*set_child_arg) (GtkContainer *container, GtkWidget *child, GtkArg *arg, guint arg_id); void (*get_child_arg) (GtkContainer *container, GtkWidget *child, GtkArg *arg, guint arg_id); gchar* (*composite_name) (GtkContainer *container, GtkWidget *child); /* Padding for future expansion */ GtkFunction pad1; GtkFunction pad2;}; </pre> </td> </tr> </table> <p> Many of these class functions do not have corresponding signals. <span class="STRUCTNAME">add</span>, <span class="STRUCTNAME">remove</span>, <span class= "STRUCTNAME">check_resize</span>, <span class= "STRUCTNAME">focus</span>, and <span class= "STRUCTNAME">set_focus_child</span> methods are default handlers for signals with the same name. The others are just methods. </p> <p> The <span class="STRUCTNAME">check_resize</span> method recalculates layout if necessary; it is invoked by the idle handler installed by <tt class="FUNCTION"> gtk_widget_queue_resize()</tt>. As the previous section mentioned, subclasses should not have to concern themselves with this process. </p> <p> The <span class="STRUCTNAME">focus</span> and <span class="STRUCTNAME">set_focus_child</span> methods handle moving focus around a <tt class="CLASSNAME"> GtkWindow</tt>. Users can move the focus with the arrow keys and the tab key. This results in emissions of the <span class="SYMBOL">"focus"</span> signal, with the <span class="STRUCTNAME">direction</span> argument indicating which way the focus should move. The possible directions are: <span class="STRUCTNAME"> GTK_DIR_TAB_FORWARD</span>, <span class="STRUCTNAME"> GTK_DIR_TAB_BACKWARD</span>, <span class="STRUCTNAME"> GTK_DIR_UP</span>, <span class="STRUCTNAME"> GTK_DIR_DOWN</span>, <span class="STRUCTNAME"> GTK_DIR_LEFT</span>, and <span class="STRUCTNAME"> GTK_DIR_RIGHT</span>. <tt class="CLASSNAME"> GtkContainer</tt> provides a default implementation based on the geometric location of child widgets; it works fine for most standard layout containers, such as <tt class="CLASSNAME">GtkBox</tt> and <tt class= "CLASSNAME">GtkTable</tt>. It should also work for <tt class="CLASSNAME">GtkBin</tt> subclasses. More elaborate or unusual containers, such as the tree and list widgets, or <tt class="CLASSNAME"> GtkNotebook</tt>, override this method. The <span class="STRUCTNAME">focus</span> method should return <span class="STRUCTNAME">TRUE</span> if an appropriate child was found and the focus was moved (using <tt class="FUNCTION">gtk_widget_grab_focus()</tt>). </p> <p> The <span class="STRUCTNAME">set_focus_child</span> method is used by <tt class="FUNCTION"> gtk_widget_grab_focus()</tt> to set the focus child of a container. <tt class="FUNCTION"> gtk_widget_grab_focus()</tt> can be invoked by the <span class="STRUCTNAME">focus</span> method of a container, or by a widget implementation (for example, <tt class="CLASSNAME">GtkEntry</tt> grabs the focus if the user clicks on it). The default implementation simply sets the <span class="STRUCTNAME"> focus_child</span> field of the container, and increments the child's reference count. </p> <p> <span class="STRUCTNAME">composite_name</span> returns a special name for a child when it's a part of a particular container. For example, the composite names of the two <tt class="CLASSNAME">GtkScrollbar</tt> widgets in a <tt class="CLASSNAME"> GtkScrolledWindow</tt> are "hscrollbar" and "vscrollbar." These names allow themes to specify widget attributes precisely. The default implementation of this method should always work fine; it returns the name set with <tt class="FUNCTION"> gtk_widget_set_composite_name()</tt>. </p> <p> <span class="STRUCTNAME">n_child_args</span>, <span class="STRUCTNAME">set_child_arg</span>, and <span class="STRUCTNAME">get_child_arg</span> are exactly analagous to the <span class="STRUCTNAME"> n_args</span>, <span class="STRUCTNAME">get_arg</span>, and <span class="STRUCTNAME">set_arg</span> fields of <span class="STRUCTNAME">GtkObjectClass</span>. <a href="hc-objectargs.html#SEC-GETSETARG">the section called <i>Using Object Arguments in Your Own <span class="STRUCTNAME">GtkObject</span> Subclass</i> in the chapter called <i>The GTK+ Object and Type System</i></a> mentions this briefly. Child arguments are used to get and set attributes of the container-child unit, such as the packing parameters for <tt class="CLASSNAME">GtkBox</tt> or the attachment parameters for <tt class="CLASSNAME">GtkTable</tt>. In contrast, normal object arguments set the characteristics of a single object in isolation. Though the implementation differs, child arguments work almost exactly like the object arguments described in <a href= "cha-objects.html">the chapter called <i>The GTK+ Object and Type System</i></a>. The only visible difference is that the get and set functions take a container and a widget as arguments, instead of a single object. </p> <p> The following section introduces the remaining functions in <tt class="CLASSNAME">GtkContainer</tt> by describing their implementation in <tt class= "CLASSNAME">GtkBin</tt>. </p> </div> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z161"><tt class="CLASSNAME">GtkBin</tt>: Containers With One Child</a> </h2> <p> <tt class="CLASSNAME">GtkBin</tt> doesn't introduce any new interfaces; it simply adds a data member to each container instance for storing a single child, and provides default implementations for the container methods that operate on this one child. <tt class= "CLASSNAME">GtkBin</tt> implements the <span class= "STRUCTNAME">add</span>, <span class="STRUCTNAME"> remove</span>, <span class="STRUCTNAME">forall</span>, and <span class="STRUCTNAME">child_type</span> methods from <tt class="CLASSNAME">GtkContainer</tt>; combined with <tt class="CLASSNAME">GtkContainer</tt>'s default implementations, simple subclasses of <tt class= "CLASSNAME">GtkBin</tt> (such as <tt class="CLASSNAME"> GtkEventBox</tt>, <tt class="CLASSNAME"> GtkAlignment</tt>, and <tt class="CLASSNAME"> GtkFrame</tt>) do not need to override any <tt class= "CLASSNAME">GtkContainer</tt> methods. Here's the instance struct: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td> typedef struct _GtkBin GtkBin;struct _GtkBin{ GtkContainer container; GtkWidget *child;}; </pre> </td> </tr> </table> <p> And the class struct: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> typedef struct _GtkBinClass GtkBinClass;struct _GtkBinClass{ GtkContainerClass parent_class;}; </pre> </td> </tr> </table> <p> No rocket science here. </p> <div class="SECT3"> <h3 class="SECT3"> <a name="Z162">Adding and Removing Children</a> </h3> <p> The <span class="STRUCTNAME">add</span> and <span class="STRUCTNAME">remove</span> functions do not have a default implementation (well, technically they do: the default implementation prints a warning that they aren't implemented). All containers should override these functions; their corresponding signals are emitted when library users call <tt class="FUNCTION"> gtk_container_add()</tt> and <tt class="FUNCTION"> gtk_container_remove()</tt>. For containers that normally require parameters when adding children (such as <tt class="CLASSNAME">GtkBox</tt> and <tt class= "CLASSNAME">GtkTable</tt>), the <span class= "STRUCTNAME">add</span> method should simply use reasonable defaults. </p> <p> <tt class="CLASSNAME">GtkBin</tt> implements an add method as follows: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_bin_add (GtkContainer *container, GtkWidget *child){ GtkBin *bin; g_return_if_fail (container != NULL); 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 == NULL); gtk_widget_set_parent (child, GTK_WIDGET (bin)); bin->child = child; if (GTK_WIDGET_VISIBLE (child->parent)) { if (GTK_WIDGET_REALIZED (child->parent) && !GTK_WIDGET_REALIZED (child)) gtk_widget_realize (child); if (GTK_WIDGET_MAPPED (child->parent) && !GTK_WIDGET_MAPPED (child)) gtk_widget_map (child); } if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (container)) gtk_widget_queue_resize (child);} </pre> </td> </tr> </table> <p> Notice the required parts of the add method: </p> <ul> <li> <p> <tt class="FUNCTION">gtk_widget_set_parent()</tt> is called to set the widget's parent; this fills in <span class="STRUCTNAME">widget->parent</span> and handles reference counting and some other internal details. </p> </li> <li> <p> The container saves a pointer to the child; this is easy for <tt class="CLASSNAME">GtkBin</tt>, since there is only one child and it goes in <span class= "STRUCTNAME">bin->child</span>. </p> </li> <li> <p> If the container has been shown (i.e., if its <span class="STRUCTNAME">GTK_VISIBLE</span> flag is set), parent and child's <span class="STRUCTNAME"> GTK_REALIZED</span> and <span class="STRUCTNAME"> GTK_MAPPED</span> states are synchronized. That is, the child is realized and mapped if the parent is realized and mapped. </p> </li> <li> <p> If both parent and child have been shown, a resize is queued. That is, layout will be recalculated in light of the new child. </p> </li> </ul> <p> The remove method reverses the process; here is its implementation: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_bin_remove (GtkContainer *container, GtkWidget *child){ GtkBin *bin; gboolean widget_was_visible; g_return_if_fail (container != NULL);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -