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

📄 z147.html

📁 gtk_text program sample&eg
💻 HTML
📖 第 1 页 / 共 4 页
字号:
        <p>          If you aren't familiar with the concept of <i class=           "FIRSTTERM">realizing</i> and <i class="FIRSTTERM">          mapping</i> a widget, go back and read <a href=           "z57.html#SEC-REALIZINGSHOWING">the section called <i>          Realizing, Mapping, and Showing</i> in the chapter called          <i>GTK+ Basics</i></a> before reading this section.        </p>        <p>          <tt class="CLASSNAME">GtkEv</tt> does not override the          map or unmap method; the default <tt class="CLASSNAME">          GtkWidget</tt> methods suffice. The defaults set and          unset the <span class="STRUCTNAME">          GTK_WIDGET_MAPPED</span> flag, and show or hide <span          class="STRUCTNAME">widget-&gt;window</span>.        </p>        <p>          Any widget with a <span class="STRUCTNAME">          GdkWindow</span> that has <tt class="CLASSNAME">          GtkWidget</tt> as its immediate parent will need to          override the realize method; the default is only suitable          for windowless widgets. <tt class="CLASSNAME">GtkEv</tt>          is no exception. <tt class="CLASSNAME">GtkEv</tt> also          overrides the unrealize method, in order to destroy the          event window.        </p>        <p>          Here is <tt class="CLASSNAME">GtkEv</tt>'s realize          method:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static void gtk_ev_realize        (GtkWidget        *widget){  GdkWindowAttr attributes;  gint attributes_mask;  GtkEv* ev;  GdkCursor* cursor;  g_return_if_fail(widget != NULL);  g_return_if_fail(GTK_IS_EV(widget));  ev = GTK_EV(widget);  /* Set realized flag */  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);  /* Main widget window */  attributes.window_type = GDK_WINDOW_CHILD;  attributes.x = widget-&gt;allocation.x;  attributes.y = widget-&gt;allocation.y;  attributes.width = widget-&gt;allocation.width;  attributes.height = widget-&gt;allocation.height;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.visual = gtk_widget_get_visual (widget);  attributes.colormap = gtk_widget_get_colormap (widget);  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;  widget-&gt;window = gdk_window_new (gtk_widget_get_parent_window (widget),                                   &amp;attributes, attributes_mask);  gdk_window_set_user_data (widget-&gt;window, widget);  /* Event window */  cursor = gdk_cursor_new(GDK_CROSSHAIR);  attributes.window_type = GDK_WINDOW_CHILD;  attributes.x = ev-&gt;event_window_rect.x;  attributes.y = ev-&gt;event_window_rect.y;  attributes.width = ev-&gt;event_window_rect.width;  attributes.height = ev-&gt;event_window_rect.height;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.visual = gtk_widget_get_visual (widget);  attributes.colormap = gtk_widget_get_colormap (widget);  attributes.event_mask = GDK_ALL_EVENTS_MASK;  attributes.cursor = cursor;  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL |     GDK_WA_COLORMAP | GDK_WA_CURSOR;  ev-&gt;event_window = gdk_window_new (widget-&gt;window,                                     &amp;attributes, attributes_mask);  gdk_window_set_user_data (ev-&gt;event_window, widget);  gdk_window_show(ev-&gt;event_window);  gdk_cursor_destroy(cursor);  /* Style */  widget-&gt;style = gtk_style_attach (widget-&gt;style, widget-&gt;window);  gtk_style_set_background (widget-&gt;style, widget-&gt;window, GTK_STATE_NORMAL);  gdk_window_set_background (ev-&gt;event_window,                              &amp;widget-&gt;style-&gt;base[GTK_STATE_NORMAL]);}      </pre>            </td>          </tr>        </table>        <p>          The first step in any realize method is to set the <span          class="STRUCTNAME">GTK_REALIZED</span> flag; this is a          small but important detail. After that, most of the          realize method is concerned with creating the two <span          class="STRUCTNAME">GdkWindow</span>s, as described in <a          href="sec-gdkwindow.html">the section called <i><span          class="STRUCTNAME">GdkWindow</span></i> in the chapter          called <i>GDK Basics</i></a>. <span class="STRUCTNAME">          widget-&gt;window</span> should be created as a subwindow          of the widget's parent's <span class="STRUCTNAME">          GdkWindow</span>; the parent window is obtained with <tt          class="FUNCTION">gtk_widget_get_parent_window()</tt>.        </p>        <p>          Notice that <i class="EMPHASIS">all</i> events are          requested on the event window, for obvious reasons. Also,          the event window has a special cursor, to give the user          visual feedback when the pointer moves into it. The          client-side cursor handle is destroyed immediately after          attaching the cursor to the window; the X server will          keep it around as long as it's in use.        </p>        <p>          After creating each <span class="STRUCTNAME">          GdkWindow</span>, a pointer to the <tt class="CLASSNAME">          GtkEv</tt> is stored in the <span class="STRUCTNAME">          GdkWindow</span>'s "user data" field. GTK+ uses the          contents of this field to determine which widget should          receive events that occur on the window. Recall that GTK+          receives a stream of events from GDK, and that each <span          class="STRUCTNAME">GdkEvent</span> has a <span class=           "STRUCTNAME">window</span> field indicating the <span          class="STRUCTNAME">GdkWindow</span> that received it.          GTK+ forwards each event to the widget owning the event's          <span class="STRUCTNAME">GdkWindow</span>. (<a href=           "sec-gdkevent.html">the section called <i>Events</i> in          the chapter called <i>GDK Basics</i></a> details this          process if you don't remember.)        </p>        <p>          The code calls <tt class="FUNCTION">          gdk_window_show()</tt> on the event window but not <span          class="STRUCTNAME">widget-&gt;window</span>; <span class=           "STRUCTNAME">widget-&gt;window</span> should not be shown          until the widget is mapped. Because the event window is a          child of <span class="STRUCTNAME">          widget-&gt;window</span>, it will remain offscreen until          its parent is shown. Alternatively, <tt class=          "CLASSNAME">GtkEv</tt> could implement a map method to          show the child, but this way seems simpler.        </p>        <p>          All widgets must take create their associated <span          class="STRUCTNAME">GtkStyle</span> in their realize          method, because a style contains X resources. (See <a          href="sec-style.html">the section called <i><span class=           "STRUCTNAME">GtkStyle</span> and Themes</i> in the          chapter called <i>GDK Basics</i></a> for more information          about <span class="STRUCTNAME">GtkStyle</span>.) Recall          from <a href="z57.html#SEC-REALIZINGSHOWING">the section          called <i>Realizing, Mapping, and Showing</i> in the          chapter called <i>GTK+ Basics</i></a> that widgets          allocate all X resources in their realize method. GTK+          provides a simple function to create a widget's style:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;  widget-&gt;style = gtk_style_attach (widget-&gt;style, widget-&gt;window);      </pre>            </td>          </tr>        </table>        <p>          <i class="EMPHASIS">After</i> filling in <span class=           "STRUCTNAME">widget-&gt;style</span>, <tt class=          "CLASSNAME">GtkEv</tt> uses colors from the style to set          window backgrounds. It sets the main window's background          using <tt class="FUNCTION">          gtk_style_set_background()</tt>, which could do almost          anything (it might invoke a routine from a dynamically          loaded theme module). If the default theme is running, it          simply sets the window's background to an appropriate          color or pixmap tile. There is no special style function          to set the background of the event window, so we set it          to the "base" color (the base color is white by default;          it's the background color for lists and text entries).          Selecting a color from the style means that users will be          able to customize the widget's color. It's also          convenient to avoid allocating and deallocating a custom          color.        </p>        <p>          Notice that the realize method does not chain up to the          default realize method, because the default isn't          appropriate for <tt class="CLASSNAME">GtkEv</tt>.        </p>        <p>          Unrealizing <tt class="CLASSNAME">GtkEv</tt> is          relatively simple:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static void gtk_ev_unrealize (GtkWidget        *widget){  GtkEv* ev;  g_return_if_fail(widget != NULL);  g_return_if_fail(GTK_IS_EV(widget));  ev = GTK_EV(widget);  /* Hide all windows */  if (GTK_WIDGET_MAPPED (widget))    gtk_widget_unmap (widget);    GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);  /* Destroy our child window */  if (ev-&gt;event_window)    {      gdk_window_set_user_data(ev-&gt;event_window, NULL);      gdk_window_destroy(ev-&gt;event_window);      ev-&gt;event_window = NULL;    }  /* This destroys widget-&gt;window and unsets the realized flag   */  if (GTK_WIDGET_CLASS(parent_class)-&gt;unrealize)    (* GTK_WIDGET_CLASS(parent_class)-&gt;unrealize) (widget);}      </pre>            </td>          </tr>        </table>        <p>          First, the unrealize method ensures that the widget is          unmapped. This is essential: GTK+ maintains the invariant          that mapped widgets are also realized. Next, the          unrealize method destroys the event window. It sets the          window's user data to <span class="STRUCTNAME">          NULL</span> before destroying it; otherwise <tt class=           "CLASSNAME">GtkEv</tt> would receive a useless destroy          event. Finally, <tt class="CLASSNAME">GtkEv</tt> chains          up to the default unrealize method, which unsets the          <span class="STRUCTNAME">GTK_WIDGET_REALIZED</span> flag          and destroys <span class="STRUCTNAME">          widget-&gt;window</span>. Unrealize implemenations are <i          class="EMPHASIS">required</i> to chain up to their base          class's implementation.        </p>        <p>          When writing your realize and unrealize methods, keep in          mind that they can be called multiple times, but they are          always paired. That is, a widget can be unrealized and          re-realized over and over, but it will never be realized          twice without an intervening unrealize. The pairing is          guaranteed; that is, if a widget is realized it will          definitely be unrealized sooner or later, unless the          program exits.        </p>      </div>      <div class="SECT2">        <h2 class="SECT2">          <a name="SEC-GTKEVSIZENEG">Size Negotiation</a>        </h2>        <p>          <a href="sec-containers.html#SEC-SIZENEGOTIATION">the          section called <i>Size Allocation</i> in the chapter          called <i>GTK+ Basics</i></a> describes the size          negotiation process; be sure you're familiar with it          before reading this section.        </p>        <p>          There's no obvious "right" size for <span class=           "STRUCTNAME">GtkEv</span>, so the size request method          requests an arbitrary size that looks nice:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static void gtk_ev_size_request   (GtkWidget        *widget,                       GtkRequisition   *requisition){  g_return_if_fail(widget != NULL);  g_return_if_fail(GTK_IS_EV(widget));  /*    * GtkEv always wants to be the same fixed size.   */    requisition-&gt;width  = 450;  requisition-&gt;height = 300;}      </pre>            </td>          </tr>        </table>        <p>          GTK+ takes care of storing a widget's last size request          in <span class="STRUCTNAME">          widget-&gt;requisition</span>.        </p>        <p>          If <tt class="CLASSNAME">GtkEv</tt> were a real-life          widget rather than an illustrative example, it would be          unnecessary to implement a size request method. The          default <tt class="CLASSNAME">GtkWidget</tt> method          simply returns the current value of <span class=           "STRUCTNAME">widget-&gt;requisition</span>, so <tt class=           "CLASSNAME">GtkEv</tt> could initialize <span class=           "STRUCTNAME">widget-&gt;requisition</span> in <tt class=           "FUNCTION">gtk_ev_init()</tt> and use the default method.        </p>        <p>          Alternatively, the size request method could be          implemented more elaborately; <tt class="CLASSNAME">          GtkEv</tt> could attempt to predict the maximum width of          the text to be displayed, for example.        </p>        <p>

⌨️ 快捷键说明

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