Re: Simple Gtk app.



On Wed, Oct 25, 2000 at 03:12:48PM +0100, Mark Hannah wrote:
Hi,
    I'm having problems writing a simple Gtk app.

What I want to do is open a window and place a pixmap
image in the window. I would then like to use the
keyboard arrow keys to move the image around the
window.

I can get as far as displaying thr pixmap in the
window, but I do not know how to capture and interpret
the keystrokes or move the pixmap position.

Can anyone help?

Many thanks,
Mark.

[snip]

I had the same problem when I was putting a GtkLabel into a
GtkEventBox and trying to receive key_press_events.
I asked on the list and Havoc Pennington wrote back:

"""
The problem is that you need the event box to have focus.

Set the GTK_CAN_FOCUS flag on the event box, and when you get a
focus_in event, set the GTK_HAS_FOCUS flag. On focus_out, unset
GTK_HAS_FOCUS. Also, you may want to gtk_grab_focus() when the user
clicks a mouse button on the widget.

If you don't want to fool with focus, handle key presses on the
toplevel GtkWindow instead of the event box.

Havoc
"""

example:

#include <gtk/gtk.h>

/*FIXME the values for GDK_(left|up|righ|down)arrow from gdkkeysyms.h
 * don't seem to match the values reported in the key press callback :(
 * I guess I'm doing something wrong here.
 * #include <gdk/gdkkeysyms.h>
 */
#define LEFT_KEY  (65361)
#define UP_KEY    (65362)
#define RIGHT_KEY (65363)
#define DOWN_KEY  (65364)

static gchar *xpm_data[] = {
  "16 16 3 1",
  "       c None",
  ".      c #000000000000",
  "X      c #FFFFFFFFFFFF",
  "                ",
  "   ......       ",
  "   .XXX.X.      ",
  "   .XXX.XX.     ",
  "   .XXX.XXX.    ",
  "   .XXX.....    ",
  "   .XXXXXXX.    ",
  "   .XXXXXXX.    ",
  "   .XXXXXXX.    ",
  "   .XXXXXXX.    ",
  "   .XXXXXXX.    ",
  "   .XXXXXXX.    ",
  "   .XXXXXXX.    ",
  "   .........    ",
  "                ",
  "                "};

gint fixed_focus_in_cb (GtkWidget     *fixed, 
                        GdkEventFocus *event, 
                        gpointer       data)
{
        GTK_WIDGET_SET_FLAGS (fixed, GTK_HAS_FOCUS);

        return FALSE;
}

gint fixed_focus_out_cb (GtkWidget     *fixed,
                         GdkEventFocus *event,
                         gpointer       data)
{
        GTK_WIDGET_UNSET_FLAGS (fixed, GTK_HAS_FOCUS);

        return FALSE;
}

gint fixed_key_press_cb (GtkWidget *fixed,
                         GdkEventKey *event,
                         gpointer data)
{
        GtkWidget *gtkpixmap;
        gint16 max_x, max_y;
        gint16 new_x, new_y;

        gtkpixmap = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (fixed), 
                                                     "gtkpixmap"));
        max_x = fixed->allocation.width - gtkpixmap->allocation.width;
        max_y = fixed->allocation.height - gtkpixmap->allocation.height;

        new_x = gtkpixmap->allocation.x;
        new_y = gtkpixmap->allocation.y;

        switch (event->keyval)
        {
                //case GDK_leftarrow:
                case LEFT_KEY:
                        g_print ("left\n");
                        new_x = MAX (0, gtkpixmap->allocation.x - 5);
                        break;
                //case GDK_uparrow:
                case UP_KEY:
                        g_print ("up\n");
                        new_y = MAX (0, gtkpixmap->allocation.y - 5);
                        break;
                //case GDK_rightarrow:
                case RIGHT_KEY:
                        g_print ("right\n");
                        new_x = MIN (max_x, gtkpixmap->allocation.x + 5);
                        break;
                //case GDK_downarrow:
                case DOWN_KEY:
                        g_print ("down\n");
                        new_y = MIN (max_y, gtkpixmap->allocation.y + 5);
                        break;
                default:
                        break;
        }

        gtk_fixed_move (GTK_FIXED (fixed), gtkpixmap, new_x, new_y);

        return FALSE;
}

gint fixed_button_press_cb (GtkWidget      *fixed,
                            GdkEventButton *event,
                            gpointer        data)
{
        gtk_widget_grab_focus (fixed);

        return FALSE;
}

int main (int argc, char *argv[])
{
        GtkWidget *window, *fixed, *gtkpixmap;
        GdkPixmap *gdkpixmap;
        GdkBitmap *mask;
        
        gtk_init (&argc, &argv);

        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_widget_set_usize (window, 300, 300);

        fixed = gtk_fixed_new ();
        gtk_widget_add_events (fixed, 
                               GDK_KEY_PRESS_MASK   |
                               GDK_BUTTON_PRESS_MASK);
        GTK_WIDGET_SET_FLAGS (fixed, GTK_CAN_FOCUS);
        gtk_signal_connect (GTK_OBJECT (fixed), 
                            "focus_in_event",
                            GTK_SIGNAL_FUNC (fixed_focus_in_cb),
                            NULL);
        gtk_signal_connect (GTK_OBJECT (fixed),
                            "focus_out_event",
                            GTK_SIGNAL_FUNC (fixed_focus_out_cb),
                            NULL);
        /* I "connect_after" so that the arrow keys don't change the focus */
        gtk_signal_connect_after (GTK_OBJECT (fixed),
                                  "key_press_event",
                                  GTK_SIGNAL_FUNC (fixed_key_press_cb),
                                  NULL);
        gtk_signal_connect (GTK_OBJECT (fixed),
                            "button_press_event",
                            GTK_SIGNAL_FUNC (fixed_button_press_cb),
                            NULL);
        gtk_container_add (GTK_CONTAINER (window), fixed);

        gtk_widget_realize (window);  /* in order to access window->window */
        gdkpixmap = gdk_pixmap_create_from_xpm_d (window->window,
                                                  &mask,
                                                  NULL,
                                                  xpm_data);
        gtkpixmap = gtk_pixmap_new (gdkpixmap, mask);
        gtk_fixed_put (GTK_FIXED (fixed), gtkpixmap, 0, 0);
        gtk_object_set_data (GTK_OBJECT (fixed), "gtkpixmap", gtkpixmap);

        gtk_widget_show_all (window);
        gtk_main ();
        return 0;
}






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]