Hi,

I'm not really sure what *is_hint* is intended to provide, but anyway, what
you are trying to achieve is totally possible without its use (if I
understand you properly).

Going on the assumption I do understand what you are trying to achieve, I am
providing below some code to illustrate this.  Though actual code, it is not
runnable in its stand-alone form, you will need to tweak it a bit to make it
actually work.  However, it does contain all the hooks necessary to do the
following:

   1. Draw a solid line from point A to point B:
   point A = point at mouse-down
   point B = point at mouse-up
   2. Draw a dashed line from point A (same as in 1) to Drag Point B:
   Drag Point B = point at drag event callback

I have left out the configure and expose callbacks, I assume that these have
been called and produce a pixmap for display, this pixmap being held in the
global variable *DAcontents*.  (Again, this is to illustrate, not to
demonstrate proper coding, you probably shouldn't make a global variable for
this purpose.)

The mouse event callback:

   1. On mouse-down, save the starting point (point A)
   2. On mouse-up, draw a solid line from point A to the ending point
   (point B) and render to the screen.

The drag event callback:

   1. If mouse is not down, do nothing and return
   2. If mouse is down, create temporary pixmap and copy *DAcontents* to
   it
   3. draw a dashed line from point A to Drag Point B (event->x,
   event->y) on our temp pixmap
   4. Render temp pixmap to the screen
   5. unref temp pixmap
   6. call gdk_window_get_pointer() to tell the main loop we are done
   with the drag event and are ready to receive another call to the drag event
   callback

Not sure where the problem is in your implementation, but doing these sorts
of things with GTK+ is typically not problematic.

cheers,

richard

========= begin code ===================

GdkPixmap    *DAcontents;
GdkGC        *gcMain;

int main(int argc, char **argv)
{
    GtkWidget    *da;

    gtk_init(&argc, &argv);

    da = gtk_drawing_area_new();
    g_signal_connect (da, "button_press_event", G_CALLBACK (doMouse), NULL);
    g_signal_connect (da, "button_release_event", G_CALLBACK (doMouse),
NULL);
    g_signal_connect (da, "motion_notify_event", G_CALLBACK (doDrag), NULL);
    gtk_widget_set_events (da, gtk_widget_get_events (da)
                              | GDK_BUTTON_PRESS_MASK
                              | GDK_BUTTON_RELEASE_MASK
                              | GDK_POINTER_MOTION_MASK
                              | GDK_POINTER_MOTION_HINT_MASK);
    gtk_main();
}

int    startX, startY, endX, endY;
gboolean mouseDown;

gboolean doMouse(GtkWidget *da, GdkEventButton *event, gpointer nothing)
{
    if (!gcMain)
        gcMain = gdk_gc_new(da->window);

    switch(event->type)
    {
        case GDK_BUTTON_PRESS:
            startX = event->x;
            startY = event->y;
            mouseDown = TRUE;
        break;
        case GDK_BUTTON_RELEASE:
            endX = event->x;
            endY = event->y;
            gdk_draw_line(DAcontents, gcMain, startX, startY, endX, endY);
            gdk_draw_drawable(da->window,
da->style->fg_gc[GTK_STATE_NORMAL],
                                DAcontents, 0, 0, 0, 0, -1, -1);
            mouseDown = FALSE;
        break;
    }
    return TRUE;
}

gboolean doDrag (GtkWidget *da, GdkEventMotion *event, gpointer nothing)
{
    GdkModifierType     state;
    gint                x, y;
    GdkPixmap            *pixmap;
    static GdkGC        *gcDash=NULL;

    if (!gcDash)
    {    // first time call setup
        gcDash = gdk_gc_new(da->window);
        gdk_gc_set_line_attributes(gcDash, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
    }

    switch(mouseDown)
    {
        case FALSE:
        break;

        case TRUE:
            pixmap = gdk_pixmap_new(da->window, da->allocation.width, da->
allocation.height, -1);
            gdk_draw_drawable(pixmap, da->style->fg_gc[GTK_STATE_NORMAL],
DAcontents,
                        0, 0, 0, 0, -1, -1);
            gdk_draw_line(pixmap, gcDash, startX, startY, event->x,
event->y);
            gdk_draw_drawable(da->window,
da->style->fg_gc[GTK_STATE_NORMAL],
                                pixmap, 0, 0, 0, 0, -1, -1);
            g_object_unref(pixmap);
        break;
    }

    gdk_window_get_pointer(event->window, &x, &y, &state);
    return TRUE;
}

========= end code ===================


On Nov 27, 2007 3:27 AM, Stewart Weiss <[EMAIL PROTECTED]> wrote:

> I have been playing around with the motion_notify_event callback in the
> Scribble example from the tutorial, and I have discovered that none of
> what the documentation states is correct.  I modified the handler to
> generate
> output on the standard outout device as follows:
>
> gboolean motion_notify_event( GtkWidget      *widget,
>                              GdkEventMotion *event,
>                              gpointer       *mydata )
> {
>    int x, y;
>    GdkModifierType state;
>
>    if (event->is_hint) {
>        gdk_window_get_pointer (event->window, &x, &y, &state);
>        g_print ( "is hint at %d, %d\n", x, y );
>    }
>    else {
>        x = event->x;
>        y = event->y;
>        state = event->state;
>        g_print ( "is not hint at %d, %d\n", x, y );
>    }
>
> I have set events on the widget using all 8 possible combinations of the
> three
> masks:
>   GDK_POINTER_MOTION_MASK
>   GDK_BUTTON_MOTION_MASK
>   GDK_POINTER_MOTION_HINT_MASK
>
> What I have found is that the event->is_hint IS NEVER true, regardless of
> the
> masks I set on the widget.  What IS TRUE is that when the
> GDK_BUTTON_MOTION_MASK
> is set on the widget, with or without the GDK_POINTER_MOTION_HINT_MASK,
> the
> only
> signals emitted by the widget are when the mouse button is down while the
> pointer
> is in motion. This is contrary to what is written in the GDK Reference
> Manual.
>
> Because the "is hint at ..." is never displayed, it also implies that
> gdk_window_get_pointer() is never called.
>
> I was trying to implement a straight-line tool and I had hoped that I
> could
> detect
> the starting and ending points using the fact that the is_hint member
> would
> be true
> only when the window was entered, or a button press or release event (as
> it
> says in
> the tutorial.)   I figured I could get the point when the mouse button was
> first
> pressed and then wait until the mouse button was released to write the
> line
> into
> my pixmap.
>
> Does anyone know what the real semantics are, and when is_hint is true?
>
> Stewart
>
> _______________________________________________
> gtk-list mailing list
> gtk-list@gnome.org
> http://mail.gnome.org/mailman/listinfo/gtk-list
>
_______________________________________________
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list

Reply via email to