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

📄 gnome-canvas-events.html

📁 linux下gnome编程
💻 HTML
📖 第 1 页 / 共 3 页
字号:
{  /* Process event for Shift-Ctrl combination, but ignore   * Shift-only and Ctrl-only combinations. */}        </PRE></TD></TR></TABLE><P>          For the most part you can ignore the remaining fields of          GdkEventButton.  They are used primarily for full-blooded          GTK+ event handling and don't really apply to Canvas item          events. Most of them exist to handle alternative pointer          hardware, like graphics tablets. The time field will come in          handy later, when we need to grab a Canvas item (see Section          11.5.6).        </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN1282">Mouse Motion</A></H2><P>          In addition to tracking mouse clicks, the Canvas keeps track          of mouse motion events, using the GdkEventMotion structure,          which is the motion field from Listing 11.8. As you can see          in Listing 11.11, the only difference between this event and          GdkEventButton is that the is_hint field replaces the button          field of GdkEventButton. The is_hint field describes the          volume of motion events that the X server is sending. If          is_hint is TRUE (which implies that GDK_POINTER_MOTION_MASK          is not enabled), the application knows that the X server is          sending only one unsolicited motion event at a time-only          hints of motion-and will send further motion events only if          the user clicks another button or key, or moves the cursor          to a different GdkWindow. Conversely, an is_hint value of          FALSE tells the application that the X server is sending a          constant stream of updates for every change in mouse          position: Each motion event is the real thing, not just a          hint. Hinting can be turned on and off separately for each          GdkWindow but is typically left on unless a window needs          detailed knowledge of the mouse position. As we'll see,          the Canvas requires the full, unthrottled flow of mouse          events and will thus set the GDK_POINTER_MOTION_MASK on its          GdkWindow. This means that the is_hint flag will always be          FALSE for Canvas item motion events.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 11.11 GdkEventMotion Structurestruct _GdkEventMotion{  GdkEventType type;  GdkWindow *window;  gint8 send_event;  guint32 time;  gdouble x;  gdouble y;  gdouble pressure;  gdouble xtilt;  gdouble ytilt;  guint state;  gint16 is_hint;  GdkInputSource source;  guint32 deviceid;  gdouble x_root, y_root;};        </PRE></TD></TR></TABLE><P>          Listing 11.12 shows an example of a diagnostic event handler          that prints out a potential flood of messages as you move          the cursor around inside a Canvas item. The handler also          prints out messages when you click mouse buttons and hold          down modifier keys:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 11.12 Sample Motion Event Handlergint handle_canvas_event(GnomeCanvasItem *item, GdkEvent *event,    gpointer data){  gchar keystate[30];  gboolean shift_pressed = event-&#62;button.state &#38; GDK_SHIFT_MASK;  gboolean ctrl_pressed = event-&#62;button.state &#38; GDK_CONTROL_MASK;  gboolean alt_pressed = event-&#62;button.state &#38; GDK_MOD1_MASK;  g_snprintf(keystate, sizeof(keystate), "%s%s%s",    shift_pressed ? "[Shift] " : "",    ctrl_pressed ? "[Ctrl] " : "",    alt_pressed ? "[Alt] " : "");  switch ((int)event-&#62;type)  {  case GDK_BUTTON_PRESS:    g_message("Button %d press (state = %d) %s",      event-&#62;button.button, event-&#62;button.state, keystate);    return TRUE;  case GDK_BUTTON_RELEASE:    g_message("Button %d release (state = %d) %s",      event-&#62;button.button, event-&#62;button.state, keystate);    return TRUE;  case GDK_MOTION_NOTIFY:    g_message("Mouse movement (state = %d) (%4.1f, %4.1f) %s",      event-&#62;button.state, event-&#62;motion.x, event-&#62;motion.y,      keystate);    return TRUE;  }  /* Event not handled; try parent item */  return FALSE;}        </PRE></TD></TR></TABLE><P>          The sample output will look something like this excerpt:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Message: Mouse movement (state = 0) (174.0, 41.0)Message: Mouse movement (state = 0) (174.0, 47.0)Message: Mouse movement (state = 0) (174.0, 50.0)Message: Mouse movement (state = 1) (174.0, 51.0) [Shift]Message: Mouse movement (state = 1) (174.0, 54.0) [Shift]Message: Mouse movement (state = 1) (174.0, 55.0) [Shift]Message: Button 1 press (state = 1) [Shift]Message: Mouse movement (state = 257) (174.0, 56.0) [Shift]Message: Mouse movement (state = 257) (174.0, 58.0) [Shift]Message: Mouse movement (state = 257) (174.0, 61.0) [Shift]Message: Mouse movement (state = 257) (173.0, 65.0) [Shift]Message: Mouse movement (state = 257) (173.0, 67.0) [Shift]Message: Button 1 release (state = 257) [Shift]Message: Mouse movement (state = 1) (173.0, 68.0) [Shift]Message: Mouse movement (state = 1) (173.0, 70.0) [Shift]Message: Mouse movement (state = 0) (172.0, 71.0)Message: Mouse movement (state = 0) (172.0, 73.0)Message: Mouse movement (state = 0) (172.0, 74.0)        </PRE></TD></TR></TABLE><P>          In this slightly unrealistic example, the user enters the          item from above and moves the mouse downward. During the          drag, the user presses the Shift button and then the left          mouse button, then releases the mouse button and the Shift          key, and then stops. Note that the motion events don't enjoy          a one-to-one correspondence to world coordinates. Also, the          faster the mouse is moving, the larger the jump is between          each consecutive point. This is a side effect of the          sampling rate of the mouse's movement by the X          server. Notice that the state value during the Shift-drag is          257, which is exactly equal to (GDK_SHIFT_MASK |          GDK_BUTTON1_MASK).        </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN1291">Rollovers</A></H2><P>          Now you can detect when and how the user clicks and moves          around inside a Canvas item. But how can you tell when the          cursor enters or leaves a specific item? Normally GDK sends          only GDK_ENTER_NOTIFY and GDK_LEAVE_NOTIFY events to          GdkWindow instances. GDK has no knowledge of the Canvas's          abstract notion of Canvas items, and it can't be expected to          know when the cursor rolls into a new item. As far as GDK is          concerned, you are still just moving around in the same          widget window, and it will continue to generate          GDK_MOTION_NOTIFY events until you completely leave the          Canvas window.        </P><P>          Only the Canvas can know when you enter and leave a Canvas          item, so it is up to the Canvas to handle these          notifications. To make things easier for the developer, the          Canvas watches the cursor position and internally          synthesizes enter and leave events from scratch. GTK+ is          oblivious to these synthetic events. The Canvas items are          aware of them only because the Canvas sends the fake events          to the same event handlers that it sends the other item          events. All of this is transparent to the Canvas-using          developer, though. You can set up entries in your          handler's switch( ) statement for enter and leave events          just as you would with any normal GTK+ event handler.        </P><P>          Thus rollover events are as simple as adding a          GDK_ENTER_NOTIFY case to your handler's switch( )          statement. If you need to clean up anything after the          rollover-perhaps you changed the color or shape of the item          and need to revert back to its original state-just add a          GDK_LEAVE_NOTIFY case as well.  Listing 11.13 shows a          modified version of the event handler template from Listing          11.7.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 11.13 GnomeCanvasItem Event Handler with Rollover Supportgint handle_canvas_event(GnomeCanvasItem *item, GdkEvent *event,    gpointer data){  switch (event-&#62;type)  {  case GDK_BUTTON_PRESS:    /* Handle mouse button press */    return TRUE;  case GDK_BUTTON_RELEASE:    /* Handle mouse button release */    return TRUE;  case GDK_MOTION_NOTIFY:    /* Handle mouse movement */    return TRUE;  case GDK_ENTER_NOTIFY:    /* Handle rollover */    return TRUE;  case GDK_LEAVE_NOTIFY:    /* Clean up after rollover */    return TRUE;  }  /* Event not handled; try parent item */  return FALSE;}        </PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN1297">Keyboard Events</A></H2><P>          Handling keyboard events is analogous to handling          button-press events. GTK+ generates GDK_KEY_PRESS and          GDK_KEY_RELEASE events (although the key-release event is          not always as predictable as the key-press event, depending          on your hardware, so be careful not to base too much on          receiving the release event) and passes the concurrent key          modifiers as bit flags in the state field of the GdkEventKey          structure (see Listing 11.14), which is just like the state          field in GdkEventButton.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 11.14 GdkEventKey Structurestruct _GdkEventKey{  GdkEventType type;  GdkWindow *window;  gint8 send_event;  guint32 time;  guint state;  guint keyval;  gint length;  gchar *string;};        </PRE></TD></TR></TABLE><P>          The only fields we haven't seen before are the last three,          which tell us which key the user just pressed. The keyval          field is the one you'll most often use in Canvas item          keyboard event handlers. It contains the GDK value of the          key, as defined in gtk+/gdk/gdkkeysyms.h. Each such key          value is prefixed by "GDK_" followed by a descriptive name          for the key-for example, GDK_t for the lowercase letter t,          GDK_Up for the up arrow, GDK_Shift_L for the left Shift key,          and GDK_F5 for the F5 function key. You can use the          gdk_keyval_*( ) functions to further process this value.        </P><P>          The length and string fields represent a printable version          of the key, if any, which you might use to render the user's          text input to a text display or entry widget. If you decide          to use the string field, you should make sure the value of          length is greater than 0 to avoid printing out potential          junk to your text buffer.        </P><P>          The key-press event sits in the item's event handler,          alongside the other events, like this:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">gint handle_canvas_event(GnomeCanvasItem *item, GdkEvent *event,    gpointer data){  switch (event-&#62;type)  {  ...  case GDK_KEY_PRESS:    /* Handle keyboard input */    return TRUE;  ...  }  /* Event not handled; try parent item */  return FALSE;}        </PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN1305">Grabbing Items</A></H2><P>          GTK+, or more specifically GDK, allows you to grab a window          and funnel some or all mouse events to that window. A window          grab does for the mouse what window focus does for the          keyboard. Just as the currently focused window receives          all keyboard input until it loses focus, a grabbed window          potentially receives all mouse events until it          relinquishes the grab. This feature is critical for          drag-and-drop operations, as we'll see in Section          11.5.7. The GDK function for this is gdk_pointer_grab( );          its companion function is gdk_pointer_ungrab( ). These          functions act on a GdkWindow instance as a whole.        </P><P>          The Canvas supplies its own function for grabbing, called          gnome_canvas_item_grab( ):        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"

⌨️ 快捷键说明

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