Click on TreeGadget image

Linux specific forum
wombats
Enthusiast
Enthusiast
Posts: 720
Joined: Thu Dec 29, 2011 5:03 pm

Click on TreeGadget image

Post by wombats »

Hi,

Is it possible to check for a click on the image of a TreeGadget?

I've been trying to adapt this code by freak, but I seem to always just get '0' for the column, no matter where the mouse is.
User avatar
Shardik
Addict
Addict
Posts: 2067
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Click on TreeGadget image

Post by Shardik »

After changing the -1 in line 77

Code: Select all

    AddGadgetColumn(#List, -1, "Col " + Str(i), 80)
of freak's code example to i (-1 seems to be not supported anymore in PB 5.22) and deleting CreateGadgetList(WindowID(0)), the example works like a charm on my Ubuntu 12.04 x64 with KDE. For your conveniance I have adapted freak's example for a tree gadget with icons:

Code: Select all

; needed to get correct TreeGadget index 
Structure tree_foreach_data 
  TreePath.l 
  ItemIndex.l 
EndStructure 

ProcedureC tree_foreach(*Model, *Path, *Iter, *user_data.tree_foreach_data) 
  If gtk_tree_path_compare_(*Path, *user_data\TreePath) = 0 
    ProcedureReturn #True 
  Else 
    *user_data\ItemIndex + 1 
    ProcedureReturn #False    
  EndIf 
EndProcedure 

Procedure GetMousePosition(Gadget, *ItemIndex.Integer) 
  Protected x, y, *TreePath, *TreeColumn
  Protected foreach_data.tree_foreach_data 

  gdk_window_get_pointer_(gtk_tree_view_get_bin_window_(GadgetID(Gadget)), @x, @y, 0) 
  
  If gtk_tree_view_get_path_at_pos_(GadgetID(Gadget), x, y, @*TreePath, @*TreeColumn, #Null, #Null) 
    If *ItemIndex 
      foreach_data\TreePath = *TreePath 
      gtk_tree_model_foreach_(gtk_tree_view_get_model_(GadgetID(Gadget)), @tree_foreach(), @foreach_data) 
      *ItemIndex\i = foreach_data\ItemIndex 
    EndIf 
    gtk_tree_path_free_(*TreePath) 
    
    ; *TreeColumn may not be freed!  
  Else 
    ; No item under the cursor, or cursor not inside the gadget 
    If *ItemIndex
      *ItemIndex\i = -1
    EndIf 
  EndIf 
EndProcedure 

ProcedureC MouseEvent(*Widget.GtkWidget, *Event.GdkEventMotion, user_data) 
  Protected ItemIndex, ColumnIndex 
  
  GetMousePosition(0, @ItemIndex) 
  SetGadgetText(1, "Cursor over item " + Str(ItemIndex)) 
EndProcedure 

UsePNGImageDecoder()

If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/world.png") = 0
  MessageRequester("Error", "Failed to load image world.png!")
  End
EndIf

OpenWindow(0, 100, 100, 230, 140, "Cursor detection")
TreeGadget(0, 10, 10, 210, 90)
TextGadget(1, 10, 110, 210, 20, "", #PB_Text_Border) 

AddGadgetItem(0, -1, "Parent item", ImageID(0), 0)
AddGadgetItem(0, -1, "Child item 1", ImageID(0), 1)
AddGadgetItem(0, -1, "Child item 2", ImageID(0), 1)

SetGadgetItemState(0, 0, #PB_Tree_Expanded)

g_signal_connect_data_(GadgetID(0), "motion-notify-event", @MouseEvent(), 0, #Null, #Null) 

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
But the above example displays the current cell below the hovering cursor. Your original intent was to detect a click onto an icon in a TreeGadget. Since the icon belongs to the whole line entry (it doesn't matter whether you click onto the icon or the text) - wouldn't it be much easier to detect a left click onto a single TreeGadget's line entry?

Code: Select all

UsePNGImageDecoder()

If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/world.png") = 0
  MessageRequester("Error", "Failed to load image world.png!")
  End
EndIf

OpenWindow(0, 100, 100, 230, 110, "Cursor detection")
TreeGadget(0, 10, 10, 210, 90)

AddGadgetItem(0, -1, "Parent item", ImageID(0), 0)
AddGadgetItem(0, -1, "Child item 1", ImageID(0), 1)
AddGadgetItem(0, -1, "Child item 2", ImageID(0), 1)

SetGadgetItemState(0, 0, #PB_Tree_Expanded)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0
        If EventType() = #PB_EventType_LeftClick
          Debug #DQUOTE$ + GetGadgetItemText(0, GetGadgetState(0)) + #DQUOTE$ +
            " was selected"
        EndIf
      EndIf
  EndSelect
ForEver
wombats
Enthusiast
Enthusiast
Posts: 720
Joined: Thu Dec 29, 2011 5:03 pm

Re: Click on TreeGadget image

Post by wombats »

Hi,

Thanks for the reply. For my purposes, I want to know only when the user clicks on the icon - it's for a layers control. The image is used to control locking the layer, and the checkbox to control visibility. It works flawlessly on Windows and almost flawlessly on OS X (it did, but then an update broke it slightly. I need to look into that next). On OS X, I was using the column to detect when the image was clicked, because the image was in a separate column on that OS. I think they're now part of the same column, so that'll be interesting.

On Windows, we can check for a click on "#TVHT_ONITEMICON". I was hoping there'd be something like that for Linux, but I've not yet found anything.
User avatar
Shardik
Addict
Addict
Posts: 2067
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Click on TreeGadget image

Post by Shardik »

wombats,

it would be nice if you could post a simple working and stripped down Windows example. Then I would be able to give it a try and find out whether it is possible to extend it into a crossplatform solution also supporting MacOS and Linux... :wink:
Post Reply