[RESOLVED] How to Trap a GTK Event?

Linux specific forum
StanDan
User
User
Posts: 57
Joined: Sun Feb 26, 2006 3:43 am
Location: Missouri, United States

callback something like?

Post by StanDan »

Button callback could be

Code: Select all

ProcedureCDLL EventCallback(*Widget, *Event.GdkEventCrossing, user_data)
  white.GdkColor
  blue.GdkColor
  gdk_color_parse_("white", @white)
  gdk_color_parse_("green", @blue)
  Select user_data
   Case 1
      Debug "container enter event"
      gtk_widget_modify_bg_(*Widget, #GTK_STATE_NORMAL, @blue)
   Case 2
      Debug "container leave event"
      gtk_widget_modify_bg_(*Widget, #GTK_STATE_NORMAL, @white)
   Case 3 : Debug "button enter event"
   Case 4 : Debug "button leave event"
  EndSelect
EndProcedure
Something like that, It's not setting the color for the leave event. Weird. It looks cool though. You could probably just use an ordinary ButtonGadget and pack directly into it. You'd have to remove the label widget. You could also set the colors for the border so it looks like the FF dialog.
StanDan
User
User
Posts: 57
Joined: Sun Feb 26, 2006 3:43 am
Location: Missouri, United States

Update?

Post by StanDan »

So how did it work out? Did you find an ideal solution? :)

I was working on a related project and thought I'd found a solution to this one. But it turns out that the underlying GTK container widget isn't emitting any signals at all at least on GTK 2.4.3. :cry:

Code: Select all

; From glib-2.0/gobject/gsignal.h:239
; #define g_signal_connect(instance, detailed_signal, c_handler, Data) \
;     g_signal_connect_data ((instance), (detailed_signal), (c_handler), (Data), NULL, (GConnectFlags) 0)
Procedure g_signal_connect(*object, name$, *func, *func_data)
  g_signal_connect_data_(*object, @name$, *func, *func_data, 0, 0)
EndProcedure
ProcedureCDLL BEventCallback(*Widget, *Event.GdkEventAny, user_data)
  Select user_data
   Case 3 : Debug "button enter event"
   Case 4 : Debug "button leave event"
  EndSelect
EndProcedure
ProcedureCDLL CEventCallback(*Widget, *Event.GdkEventAny, user_data)
  Debug Str(*Event\type) + " user_data: " + Str(user_data)
  Select *Event\type
    Case #GDK_DELETE
        Debug "Event: GDK_DELETE: 0"
    Case #GDK_DESTROY
        Debug "Event: GDK_DESTROY: 1"
    Case #GDK_EXPOSE
        Debug "Event: GDK_EXPOSE: 2"
    Case #GDK_MOTION_NOTIFY
        Debug "Event: GDK_MOTION_NOTIFY: 3"
    Case #GDK_BUTTON_PRESS
        Debug "Event: GDK_BUTTON_PRESS: 4"
    Case #GDK_2BUTTON_PRESS
        Debug "Event: GDK_2BUTTON_PRESS: 5"
    Case #GDK_3BUTTON_PRESS
        Debug "Event: GDK_3BUTTON_PRESS: 6"
    Case #GDK_BUTTON_RELEASE
        Debug "Event: GDK_BUTTON_RELEASE: 7"
    Case #GDK_KEY_PRESS
        Debug "Event: GDK_KEY_PRESS: 8"
    Case #GDK_KEY_RELEASE
        Debug "Event: GDK_KEY_RELEASE: 9"
    Case #GDK_ENTER_NOTIFY
        Debug "Event: GDK_ENTER_NOTIFY: 10"
    Case #GDK_LEAVE_NOTIFY
        Debug "Event: GDK_LEAVE_NOTIFY: 11"
    Case #GDK_FOCUS_CHANGE
        Debug "Event: GDK_FOCUS_CHANGE: 12"
    Case #GDK_CONFIGURE
        Debug "Event: GDK_CONFIGURE: 13"
    Case #GDK_MAP
        Debug "Event: GDK_MAP: 14"
    Case #GDK_UNMAP
        Debug "Event: GDK_UNMAP: 15"
    Case #GDK_PROPERTY_NOTIFY
        Debug "Event: GDK_PROPERTY_NOTIFY: 16"
    Case #GDK_SELECTION_CLEAR
        Debug "Event: GDK_SELECTION_CLEAR: 17"
    Case #GDK_SELECTION_REQUEST
        Debug "Event: GDK_SELECTION_REQUEST: 18"
    Case #GDK_SELECTION_NOTIFY
        Debug "Event: GDK_SELECTION_NOTIFY: 19"
    Case #GDK_PROXIMITY_IN
        Debug "Event: GDK_PROXIMITY_IN: 20"
    Case #GDK_PROXIMITY_OUT
        Debug "Event: GDK_PROXIMITY_OUT: 21"
    Case #GDK_DRAG_ENTER
        Debug "Event: GDK_DRAG_ENTER: 22"
    Case #GDK_DRAG_LEAVE
        Debug "Event: GDK_DRAG_LEAVE: 23"
    Case #GDK_DRAG_MOTION
        Debug "Event: GDK_DRAG_MOTION: 24"
    Case #GDK_DRAG_STATUS
        Debug "Event: GDK_DRAG_STATUS: 25"
    Case #GDK_DROP_START
        Debug "Event: GDK_DROP_START: 26"
    Case #GDK_DROP_FINISHED
        Debug "Event: GDK_DROP_FINISHED: 27"
    Case #GDK_CLIENT_EVENT
        Debug "Event: GDK_CLIENT_EVENT: 28"
    Case #GDK_VISIBILITY_NOTIFY
        Debug "Event: GDK_VISIBILITY_NOTIFY: 29"
    Case #GDK_NO_EXPOSE
        Debug "Event: GDK_NO_EXPOSE: 30"
    Case #GDK_SCROLL
        Debug "Event: GDK_SCROLL: 31"
    Case #GDK_WINDOW_STATE
        Debug "Event: GDK_WINDOW_STATE: 32"
  EndSelect
EndProcedure
#MyContainer = 10
#MyButton = 11
If OpenWindow(0,0,0,345,105,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Event Test") And CreateGadgetList(WindowID(0))
  ButtonGadget(#MyButton, 200, 10, 100, 30, "Test")
  ContainerGadget(#MyContainer, 10,10,100,83,#PB_Container_Raised)   
  ; connect the signals...
  g_signal_connect(*GadgetID(#MyContainer), "event", @CEventCallback(), 1)  
  g_signal_connect(*GadgetID(#MyButton), "enter-notify-event", @BEventCallback(), 3)
  g_signal_connect(*GadgetID(#MyButton), "leave-notify-event", @BEventCallback(), 4)
  Repeat
     EventID = WaitWindowEvent()         
     Select EventID     
       Case #PB_Event_Gadget
         Select EventGadgetID()
           Case #MyContainer : Debug "Container clicked!"
           Case #MyButton : Debug "Button clicked!"
         EndSelect     
     EndSelect
   Until EventID = #PB_Event_CloseWindow   
EndIf
The results of this look like:
4 user_data: 1
Event: GDK_BUTTON_PRESS: 4
2 user_data: 1
Event: GDK_EXPOSE: 2
4 user_data: 1
Event: GDK_BUTTON_PRESS: 4
31 user_data: 1
Event: GDK_SCROLL: 31
31 user_data: 1
Event: GDK_SCROLL: 31
button enter event
button leave event
4 user_data: 1
Event: GDK_BUTTON_PRESS: 4
StanDan
User
User
Posts: 57
Joined: Sun Feb 26, 2006 3:43 am
Location: Missouri, United States

Surely enough.

Post by StanDan »

So it looks there's only a handfull off widgets that define "methods" for these events (enter_notify_event and leave_notify_event): gtkbutton, gtkcalendar, gtkcolorsel, gtkcombo, gtkentrycompletion, gtkexpander, gtkitem, gtkmenu, gtkmenushell, gtknotebook, gtkpaned, gtkrange, gtkspinbutton, gtktreeview and gtkwindow.

GtkButton defines the methods in gtkbutton.c:113

Code: Select all

static gint gtk_button_enter_notify   (GtkWidget        *widget,
                       GdkEventCrossing *event);
static gint gtk_button_leave_notify   (GtkWidget        *widget,
                       GdkEventCrossing *event);
Then assigns them to the class in gtk_button_class_init():196

Code: Select all

widget_class->enter_notify_event = gtk_button_enter_notify;
widget_class->leave_notify_event = gtk_button_leave_notify;
So I started thinking how to add a method to the container widget. Then I realized I was an idiot :shock:

Code: Select all

gtk_widget_add_events_(*GadgetID(#MyContainer), #GDK_ENTER_NOTIFY_MASK|#GDK_LEAVE_NOTIFY_MASK)
So now it works, and all my widgets are responding like the obedient things they're supposed to. :D
Straker
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Apr 13, 2005 10:45 pm
Location: Idaho, USA

Post by Straker »

Thanks for all your help StanDan. I have been out of state for the last 4 days, but plan on testing this over the next few days. I will definitely post my results back here. I am going out of state on Thursday for 4 days so I may not be posting back until next week. Again, thanks for all your testing and for responding to my PM.

Regards.
Straker
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Apr 13, 2005 10:45 pm
Location: Idaho, USA

Post by Straker »

StanDan you da man!

I was able to test your code and I modified it to include ImageGadget within the Container gadget. I resized the Container gadget to the same size as the ImageGadget to give the illusion that its just an image. Then coded the image switcheroo when capturing the Container events.

Here is the revised code now with hover goodness:

Code: Select all

; From glib-2.0/gobject/gsignal.h:239
; #define g_signal_connect(instance, detailed_signal, c_handler, Data) \
;     g_signal_connect_data ((instance), (detailed_signal), (c_handler), (Data), NULL, (GConnectFlags) 0)

UsePNGImageDecoder()

#MyContainer = 10
#MyButton = 11
#MyImageGadget = 12

#MyImage = 21
#MyImage1 = 22
#MyImage2 = 23

Procedure g_signal_connect(*object, name$, *func, *func_data)
  g_signal_connect_data_(*object, @name$, *func, *func_data, 0, 0)
EndProcedure
ProcedureCDLL BEventCallback(*Widget, *Event.GdkEventAny, user_data)
  Select user_data
   Case 3 : Debug "button enter event"
   Case 4 : Debug "button leave event"
  EndSelect
EndProcedure
ProcedureCDLL CEventCallback(*Widget, *Event.GdkEventAny, user_data)
  Debug Str(*Event\type) + " user_data: " + Str(user_data)
  Select *Event\type
    Case #GDK_DELETE
        Debug "Event: GDK_DELETE: 0"
    Case #GDK_DESTROY
        Debug "Event: GDK_DESTROY: 1"
    Case #GDK_EXPOSE
        Debug "Event: GDK_EXPOSE: 2"
    Case #GDK_MOTION_NOTIFY
        Debug "Event: GDK_MOTION_NOTIFY: 3"
    Case #GDK_BUTTON_PRESS
        Debug "Event: GDK_BUTTON_PRESS: 4"
    Case #GDK_2BUTTON_PRESS
        Debug "Event: GDK_2BUTTON_PRESS: 5"
    Case #GDK_3BUTTON_PRESS
        Debug "Event: GDK_3BUTTON_PRESS: 6"
    Case #GDK_BUTTON_RELEASE
        Debug "Event: GDK_BUTTON_RELEASE: 7"
    Case #GDK_KEY_PRESS
        Debug "Event: GDK_KEY_PRESS: 8"
    Case #GDK_KEY_RELEASE
        Debug "Event: GDK_KEY_RELEASE: 9"
    Case #GDK_ENTER_NOTIFY
        Debug "Event: GDK_ENTER_NOTIFY: 10"
        SetGadgetState(#MyImageGadget,UseImage(#MyImage2))
    Case #GDK_LEAVE_NOTIFY
        Debug "Event: GDK_LEAVE_NOTIFY: 11"
        SetGadgetState(#MyImageGadget,UseImage(#MyImage))
    Case #GDK_FOCUS_CHANGE
        Debug "Event: GDK_FOCUS_CHANGE: 12"
    Case #GDK_CONFIGURE
        Debug "Event: GDK_CONFIGURE: 13"
    Case #GDK_MAP
        Debug "Event: GDK_MAP: 14"
    Case #GDK_UNMAP
        Debug "Event: GDK_UNMAP: 15"
    Case #GDK_PROPERTY_NOTIFY
        Debug "Event: GDK_PROPERTY_NOTIFY: 16"
    Case #GDK_SELECTION_CLEAR
        Debug "Event: GDK_SELECTION_CLEAR: 17"
    Case #GDK_SELECTION_REQUEST
        Debug "Event: GDK_SELECTION_REQUEST: 18"
    Case #GDK_SELECTION_NOTIFY
        Debug "Event: GDK_SELECTION_NOTIFY: 19"
    Case #GDK_PROXIMITY_IN
        Debug "Event: GDK_PROXIMITY_IN: 20"
    Case #GDK_PROXIMITY_OUT
        Debug "Event: GDK_PROXIMITY_OUT: 21"
    Case #GDK_DRAG_ENTER
        Debug "Event: GDK_DRAG_ENTER: 22"
    Case #GDK_DRAG_LEAVE
        Debug "Event: GDK_DRAG_LEAVE: 23"
    Case #GDK_DRAG_MOTION
        Debug "Event: GDK_DRAG_MOTION: 24"
    Case #GDK_DRAG_STATUS
        Debug "Event: GDK_DRAG_STATUS: 25"
    Case #GDK_DROP_START
        Debug "Event: GDK_DROP_START: 26"
    Case #GDK_DROP_FINISHED
        Debug "Event: GDK_DROP_FINISHED: 27"
    Case #GDK_CLIENT_EVENT
        Debug "Event: GDK_CLIENT_EVENT: 28"
    Case #GDK_VISIBILITY_NOTIFY
        Debug "Event: GDK_VISIBILITY_NOTIFY: 29"
    Case #GDK_NO_EXPOSE
        Debug "Event: GDK_NO_EXPOSE: 30"
    Case #GDK_SCROLL
        Debug "Event: GDK_SCROLL: 31"
    Case #GDK_WINDOW_STATE
        Debug "Event: GDK_WINDOW_STATE: 32"
  EndSelect
EndProcedure

If OpenWindow(0,0,0,345,105,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Event Test") And CreateGadgetList(WindowID(0))
  ;ButtonGadget(#MyButton, 200, 10, 100, 30, "Test")
  ContainerGadget(#MyContainer, 10,10,91,55,#PB_Container_BorderLess)   
  ; connect the signals...
  
  LoadImage(#MyImage,"/home/ubuntu/normal.png")
  LoadImage(#MyImage2,"/home/ubuntu/highlight.png")

  ImageGadget(#MyImageGadget, 0, 0, 87, 51, UseImage(#MyImage)) 
  
  gtk_widget_add_events_(*GadgetID(#MyContainer), #GDK_ENTER_NOTIFY_MASK|#GDK_LEAVE_NOTIFY_MASK)
  
  g_signal_connect(*GadgetID(#MyContainer), "event", @CEventCallback(), 1) 
  ;g_signal_connect(*GadgetID(#MyButton), "enter-notify-event", @BEventCallback(), 3)
  ;g_signal_connect(*GadgetID(#MyButton), "leave-notify-event", @BEventCallback(), 4)
  Repeat
     EventID = WaitWindowEvent()         
     Select EventID     
       Case #PB_Event_Gadget
         Select EventGadgetID()
           Case #MyContainer : Debug "Container clicked!"
           ;Case #MyButton : Debug "Button clicked!"
         EndSelect     
     EndSelect
   Until EventID = #PB_Event_CloseWindow   
EndIf 
Here are the images:
Normal:
Image

Highlight:
Image

BTW, I noticed that the container gadget needs to be 4 pixels wider and 4 pixels higher than the image gadget, not a big deal.

Thanks again.
Post Reply