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

📄 z147.html

📁 gtk_text program sample&eg
💻 HTML
📖 第 1 页 / 共 4 页
字号:
          Once a widget's parent container decides how much space          is actually available, the widget receives a size          allocation. The size allocation method should do the          following:        </p>        <ul>          <li>            <p>              Assign the new allocation to <span class=              "STRUCTNAME">widget-&gt;allocation</span>; this does              <i class="EMPHASIS">not</i> happen automatically, as              it does for <span class="STRUCTNAME">              widget-&gt;requisition</span>.            </p>          </li>          <li>            <p>              Divide the allocation among any child widgets.            </p>          </li>          <li>            <p>              Resize any <span class="STRUCTNAME">              GdkWindow</span>s, if the widget is realized.            </p>          </li>          <li>            <p>              Perform any widget-specific tasks; for example, <tt              class="CLASSNAME">GtkEv</tt> updates the two <span              class="STRUCTNAME">GdkRectangle</span>s representing              its internal layout.            </p>          </li>        </ul>        <p>          Here is the <tt class="CLASSNAME">GtkEv</tt> size          allocation method; it should be self-explanatory:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static void gtk_ev_size_allocate  (GtkWidget        *widget,                       GtkAllocation    *allocation){  static const gint spacing = 10;   GtkEv* ev;  g_return_if_fail(widget != NULL);  g_return_if_fail(GTK_IS_EV(widget));    ev = GTK_EV(widget);  widget-&gt;allocation = *allocation;  ev-&gt;event_window_rect.width =     MAX(allocation-&gt;width - spacing*2, 0);  ev-&gt;event_window_rect.height =     MAX(allocation-&gt;height / 5 - spacing / 2, 0);  ev-&gt;event_window_rect.x =     (allocation-&gt;width - ev-&gt;event_window_rect.width)/2;  ev-&gt;event_window_rect.y =     MIN(spacing, allocation-&gt;height);  ev-&gt;description_rect.x = ev-&gt;event_window_rect.x;  ev-&gt;description_rect.y =     ev-&gt;event_window_rect.y + ev-&gt;event_window_rect.height + spacing;  ev-&gt;description_rect.width =     ev-&gt;event_window_rect.width;  ev-&gt;description_rect.height =     MAX((allocation-&gt;height - ev-&gt;event_window_rect.height - spacing*3), 0);  if (GTK_WIDGET_REALIZED (widget))    {      gdk_window_move_resize (widget-&gt;window,                              allocation-&gt;x,                               allocation-&gt;y,                              allocation-&gt;width,                               allocation-&gt;height);      gdk_window_move_resize (ev-&gt;event_window,                              ev-&gt;event_window_rect.x,                               ev-&gt;event_window_rect.y,                              ev-&gt;event_window_rect.width,                              ev-&gt;event_window_rect.height);          }}      </pre>            </td>          </tr>        </table>      </div>      <div class="SECT2">        <h2 class="SECT2">          <a name="SEC-GTKEVDRAWING">Drawing</a>        </h2>        <p>          There are three common situations that require a widget          to redraw all or part of itself:        </p>        <ol type="1">          <li>            <p>              Expose events signal that all or part of a widget's              <span class="STRUCTNAME">GdkWindow</span> has just              become visible on the screen and needs repainting              (see <a href="sec-gdkevent.html#SEC-EXPOSEEVENTS">the              section called <i>Expose Events</i> in the chapter              called <i>GDK Basics</i></a>). A widget's <span              class="STRUCTNAME">expose_event</span> method              performs these redraws.            </p>          </li>          <li>            <p>              GTK+ sometimes determines that a widget should be              redrawn. This might happen when a widget receives a              new size allocation different from its previous size              allocation, or when a new theme is loaded. A widget's              <span class="STRUCTNAME">draw</span> method, usually              invoked via <tt class="FUNCTION">              gtk_widget_queue_draw()</tt> or <tt class="FUNCTION">              gtk_widget_queue_clear()</tt>, handles this case.            </p>          </li>          <li>            <p>              Widgets sometimes decide to redraw themselves. For              example, if you change the text of a <tt class=               "CLASSNAME">GtkLabel</tt>, the label will redraw              itself to reflect the new text. Widget              implementations are free to handle this case however              they like, but most will use the <span class=               "STRUCTNAME">draw</span> method.            </p>          </li>        </ol>        <p>          There are two special cases of the second situation. The          first occurs when a widget receives or loses the keyboard          focus; the second occurs when the widget becomes (or          unbecomes) the "default" widget. Widgets should indicate          these states visually, but they can often do so without a          complete redraw. Thus, there are special <span class=           "STRUCTNAME">draw_focus</span> and <span class=          "STRUCTNAME">draw_default</span> signals to handle them.          These signals only have to be implemented if a widget can          meaningfully receive the focus or default.        </p>        <p>          Because there is typically little difference between a          widget's draw and expose methods, a common convention is          to write a static function to handle both of them. This          function is standardly called <tt class="FUNCTION">          gtk_whatever_paint()</tt>. It's also possible to avoid          implementing the draw method, because the default draw          method synthesizes an expose event covering the widget's          entire allocation and invokes the expose method.          (Remember that a synthetic expose event will have its          <span class="STRUCTNAME">send_event</span> flag set to          <span class="STRUCTNAME">TRUE</span>; you can use this to          distinguish synthetic events.)        </p>        <p>          The primary reason for distinguishing expose events from          other draws is that expose events are marked with the          window they occurred on; for widgets with multiple          windows such as <tt class="CLASSNAME">GtkEv</tt>, this          can increase efficiency. <tt class="CLASSNAME">GtkEv</tt>          implements two private functions, <tt class="CLASSNAME">          gtk_ev_paint()</tt> and <tt class="CLASSNAME">          gtk_ev_paint_event_window()</tt>, which it uses to          implement the expose and draw methods.        </p>        <p>          Here is the draw method:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static void gtk_ev_draw           (GtkWidget        *widget,                       GdkRectangle     *area){  GdkRectangle event_window_area;  GdkRectangle intersection;  GtkEv* ev;  g_return_if_fail(widget != NULL);  g_return_if_fail(GTK_IS_EV(widget));  ev = GTK_EV(widget);  gtk_ev_paint(ev, area);  event_window_area = *area;  if (gdk_rectangle_intersect(area, &amp;ev-&gt;event_window_rect, &amp;intersection))    {      /* Make the intersection relative to the event window */      intersection.x -= ev-&gt;event_window_rect.x;      intersection.y -= ev-&gt;event_window_rect.y;            gtk_ev_paint_event_window(ev, &amp;intersection);    }}      </pre>            </td>          </tr>        </table>        <p>          And the expose method:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static gint gtk_ev_expose         (GtkWidget        *widget,                       GdkEventExpose   *event){    if (event-&gt;window == widget-&gt;window)    gtk_ev_paint(GTK_EV(widget), &amp;event-&gt;area);  else if (event-&gt;window == GTK_EV(widget)-&gt;event_window)    gtk_ev_paint_event_window(GTK_EV(widget), &amp;event-&gt;area);  else    g_assert_not_reached();  return TRUE;}      </pre>            </td>          </tr>        </table>        <p>          Both the draw and expose methods should be          self-explanatory. All the work is done in the two paint          functions. Here is <tt class="FUNCTION">          gtk_ev_paint()</tt>, which renders the main widget          window:        </p>        <table border="0" bgcolor="#E0E0E0" width="100%">          <tr>            <td><pre class="PROGRAMLISTING">&#13;static void gtk_ev_paint          (GtkEv            *ev,                       GdkRectangle     *area){  GtkWidget* widget;  g_return_if_fail(ev != NULL);  g_return_if_fail(GTK_IS_EV(ev));  widget = GTK_WIDGET(ev);  if (!GTK_WIDGET_DRAWABLE (widget))    return;  gdk_window_clear_area (widget-&gt;window,                         area-&gt;x,                          area-&gt;y,                         area-&gt;width,                          area-&gt;height);  gdk_gc_set_clip_rectangle(widget-&gt;style-&gt;black_gc, area);  /* Draw a black rectangle around the event window */  gdk_draw_rectangle(widget-&gt;window,                     widget-&gt;style-&gt;black_gc,                     FALSE,                     ev-&gt;event_window_rect.x - 1,                      ev-&gt;event_window_rect.y - 1,                     ev-&gt;event_window_rect.width + 2,                     ev-&gt;event_window_rect.height + 2);  gdk_gc_set_clip_rectangle(widget-&gt;style-&gt;black_gc, NULL);  /* Draw text in the description area, if applicable */  if (ev-&gt;buffer)    {      GdkRectangle intersection;      if (gdk_rectangle_intersect(area,                                  &amp;ev-&gt;description_rect,                                  &amp;intersection))        {          static const gint space = 2;          gint line;          gint step;          gint first_baseline;                    GList* tmp;                step  = widget-&gt;style-&gt;font-&gt;ascent +             widget-&gt;style-&gt;font-&gt;descent + space;                first_baseline = ev-&gt;description_rect.y +             widget-&gt;style-&gt;font-&gt;ascent + space;                line = 0;                tmp = ev-&gt;buffer;                while (tmp != NULL)            {              gchar** this_event = tmp-&gt;data;              gint i = 0;              while (this_event[i])                {                  gtk_paint_string (widget-&gt;style,                                     widget-&gt;window,                                     widget-&gt;state,                                    &amp;intersection, widget, "ev",                                     ev-&gt;description_rect.x,                                    first_baseline + line*step,                                    this_event[i]);                  ++i;                  ++line;                }                        /* Bail out if we're off the bottom; the "- 2*step" is               *  needed because the next baseline may be outside the               *  redraw area but we are interested in the whole row of                *  text, not the baseline. The 2* is because line is one                *  larger than we've actually drawn.               */              if ((first_baseline + line*step - 2*step) &gt;                   (intersection.y + intersection.height))                break;                        tmp = g_list_next(tmp);            }        }    }

⌨️ 快捷键说明

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