?? z147.html
字號:
if (GTK_WIDGET_HAS_FOCUS (widget)) { gtk_paint_focus (widget->style, widget->window, area, widget, "ev", widget->allocation.x, widget->allocation.y, widget->allocation.width-1, widget->allocation.height-1); }} </pre> </td> </tr> </table> <p> Most of <tt class="FUNCTION">gtk_ev_paint()</tt> is <tt class="CLASSNAME">GtkEv</tt>-specific; it simply draws the contents of the window. Notice that it checks <tt class="FUNCTION">GTK_WIDGET_DRAWABLE()</tt> at the beginning; this is required because the draw method may invoke the function. Unsynthesized expose events guarantee that a widget's X window is on-screen and thus this check is not really necessary when responding to expose events. </p> <p> <tt class="FUNCTION">gtk_ev_paint_event_window()</tt> paints the small subwindow; it's a very simple function: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static void gtk_ev_paint_event_window (GtkEv *ev, GdkRectangle *area){ GtkWidget* widget; gint width; gint x, y; const char* title; g_return_if_fail(ev != NULL); g_return_if_fail(GTK_IS_EV(ev)); widget = GTK_WIDGET(ev); if (!GTK_WIDGET_DRAWABLE (widget)) return; title = _("Event Window"); gdk_window_clear_area (ev->event_window, area->x, area->y, area->width, area->height); gdk_gc_set_clip_rectangle(widget->style->black_gc, area); /* Clearly it would be better to cache this */ width = gdk_string_width(widget->style->font, title); x = (ev->event_window_rect.width - width)/2; y = widget->style->font->ascent + 2; gdk_draw_string(ev->event_window, widget->style->font, widget->style->black_gc, x, y, title); gdk_gc_set_clip_rectangle(widget->style->black_gc, NULL);} </pre> </td> </tr> </table> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z153">Handling Focus</a> </h2> <p> <tt class="CLASSNAME">GtkEv</tt> wants to receive key press events so it can report information about them. As discussed in <a href="z57.html#SEC-FOCUSWIDGET">the section called <i>Focus</i> in the chapter called <i>GTK+ Basics</i></a> and <a href= "sec-gdkevent.html#SEC-GDKKEYFOCUS">the section called <i>Keyboard Focus</i> in the chapter called <i>GDK Basics</i></a>, only toplevel windows receive key events from GDK. <tt class="CLASSNAME">GtkWindow</tt> keeps track of a current <i class="FIRSTTERM">focus widget</i> and forwards key events to it. </p> <p> If a widget wants to receive key events, it must: </p> <ul> <li> <p> Set its <span class="STRUCTNAME">GTK_CAN_FOCUS</span> flag, so GTK+ will consider it as a possible focus widget. </p> </li> <li> <p> Respond to <span class="SYMBOL">"focus_in"</span> and <span class="SYMBOL">"focus_out"</span> signals by drawing and erasing a visual indication that it has the focus. </p> </li> </ul> <p> <tt class="CLASSNAME">GtkEv</tt> set the <span class= "STRUCTNAME">GTK_CAN_FOCUS</span> flag in <tt class= "FUNCTION">gtk_ev_init()</tt>; it implements focus in and focus out methods as follows: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static gint gtk_ev_focus_in (GtkWidget *widget, GdkEventFocus *event){ g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(GTK_IS_EV(widget), FALSE); GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); gtk_widget_draw_focus (widget); return FALSE;}static gint gtk_ev_focus_out (GtkWidget *widget, GdkEventFocus *event){ g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(GTK_IS_EV(widget), FALSE); GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); gtk_widget_draw_focus (widget); return FALSE;} </pre> </td> </tr> </table> <p> These implementations are the minimal ones; all focusable widgets must set or unset the <span class="STRUCTNAME"> GTK_HAS_FOCUS</span> flag when they gain or lose the focus, and they must emit the <span class="SYMBOL"> "draw_focus"</span> signal. </p> <p> <tt class="CLASSNAME">GtkEv</tt> has a lazy implementation of the <span class="SYMBOL"> "draw_focus"</span> signal; it just calls the same <tt class="FUNCTION">gtk_ev_paint()</tt> used to respond to expose events and redraw requests. Recall that <tt class= "FUNCTION">gtk_ev_paint()</tt> checks whether the <tt class="CLASSNAME">GtkEv</tt> has the focus and draws a focus frame if so. Here is the code: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static void gtk_ev_draw_focus (GtkWidget *widget){ GdkRectangle rect; GtkEv* ev; g_return_if_fail(widget != NULL); g_return_if_fail(GTK_IS_EV(widget)); ev = GTK_EV(widget); rect.x = 0; rect.y = 0; rect.width = widget->allocation.width; rect.height = widget->allocation.height; if (GTK_WIDGET_DRAWABLE (ev)) gtk_ev_paint(ev, &rect);} </pre> </td> </tr> </table> <p> Notice that widget implementations are responsible for emitting the <span class="SYMBOL">"draw_focus"</span> signal themselves; GTK+ does not emit it as the focus moves. Contrast this with the <span class="SYMBOL"> "draw_default"</span> signal, which GTK+ automatically emits whenever a widget gains or loses the default. <tt class="CLASSNAME">GtkEv</tt> cannot be the default widget, so it does not implement this signal. </p> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z154"><tt class="CLASSNAME">GtkEv</tt>'s Functionality</a> </h2> <p> All the code presented so far implements the <tt class= "CLASSNAME">GtkWidget</tt> and <span class="STRUCTNAME"> GtkObject</span> interfaces. <tt class="CLASSNAME"> GtkEv</tt> does have some unique functionality; namely, it responds to events on its event window by adding text describing the event to its buffer, and queueing a redraw. To do this, it overrides the default <span class= "SYMBOL">"event"</span> signal handler. </p> <p> Here is <tt class="CLASSNAME">GtkEv</tt>'s event method: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static gint gtk_ev_event (GtkWidget *widget, GdkEvent *event){ GtkEv* ev; g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(GTK_IS_EV(widget), FALSE); ev = GTK_EV(widget); if (event->any.window == widget->window) { if (GTK_WIDGET_CLASS(parent_class)->event) return (* GTK_WIDGET_CLASS(parent_class)->event) (widget, event); else return FALSE; } else { gchar* text; /* The event is either on ev->event_window, or it is a key event * passed down to us from the toplevel GtkWindow */ text = event_to_text(event); gtk_ev_push_text(ev, text); g_free(text); /* If it was a motion event, make sure we get more */ if (event->type == GDK_MOTION_NOTIFY) { gdk_window_get_pointer(ev->event_window, NULL, NULL, NULL); } /* We didn't "handle" the event, just listened in on it. */ return FALSE; }} </pre> </td> </tr> </table> <p> Notice that the <span class="STRUCTNAME">window</span> method of the event is used to distinguish events that occur on <span class="STRUCTNAME"> widget->window</span> from events that occur on the event subwindow. Some events will be received from a different window entirely; for example, key events actually occur on a toplevel window, and are passed to <tt class="CLASSNAME">GtkEv</tt> if <tt class= "CLASSNAME">GtkEv</tt> has the focus. </p> <p> <tt class="FUNCTION">event_to_text()</tt> is a lengthy but trivial function that creates a string describing the event; <tt class="FUNCTION">gtk_ev_push_text()</tt> pushes the text onto the front of the buffer and queues a redraw. The implementation of these functions is part of the complete <tt class="CLASSNAME">GtkEv</tt> code listing, in Appendix E. </p> </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="z144.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="sec-widgetindetail.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>The <tt class= "CLASSNAME">GtkWidget</tt> Base Class</b></font> </td> <td colspan="2" align="right"> <font color="#000000" size="2"><b><tt class= "CLASSNAME">GtkWidget</tt> In Detail</b></font> </td> </tr> </table> </div> </body></html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -