Page 1 of 1

Map widgets of all windows

Posted: Wed Aug 22, 2012 10:17 am
by Shardik
In order to find the handle of a CalendarGadget which is dynamically generated and displayed as soon as the button beside a DateGadget is pressed, I wrote some sort of widget explorer which uses a TreeGadget to display all widgets and their hierarchy for all top windows currently displayed. To see the additional window with the GtkCalendar widget added to the TreeGadget, click onto the button beside the DateGadget and the TreeGadget will be updated.

Code: Select all

EnableExplicit

ImportC ""
  g_type_check_instance_is_a(*Instance.GTypeInstance, *Type.GTypeClass)
EndImport

Define *Button.GtkWidget
Define CalendarVisible.I
Define *HBox.GtkWidget
Define SubnodeLevel.I
Define *WindowList.GList

NewList FallbackSubnodeLevel.I()

Procedure.I GetChildren(*Widget.GtkWidget)
  Shared FallbackSubnodeLevel.I()
  Shared SubnodeLevel.I

  Protected *Child.GtkWidget
  Protected ChildrenCount.I
  Protected *ChildrenList.GList
  Protected i.I
  Protected *WidgetName
  
  If g_type_check_instance_is_a(*Widget\object\parent_instance\g_type_instance, gtk_container_get_type_()) = #False
    If ListSize(FallbackSubnodeLevel()) > 0
      LastElement(FallbackSubnodeLevel())
      SubnodeLevel = FallbackSubnodeLevel()
      DeleteElement(FallbackSubnodeLevel())
    EndIf
  Else
    *ChildrenList = gtk_container_get_children_(*Widget)
    ChildrenCount = g_list_length_(*ChildrenList)
    
    If ChildrenCount > 0
      If ChildrenCount > 1
        AddElement(FallbackSubnodeLevel())
        FallbackSubnodeLevel() = SubnodeLevel
      EndIf

      For i = 0 To ChildrenCount - 1
        *Child = g_list_nth_data_(*ChildrenList, i)
        *WidgetName = gtk_widget_get_name_(*Child)
        AddGadgetItem(1, -1, PeekS(*WidgetName), 0, SubnodeLevel)
        SubnodeLevel + 1
        GetChildren(*Child)
      Next i
    EndIf
  EndIf
EndProcedure

Procedure ExamineWindows()
  Shared FallbackSubnodeLevel.I()
  Shared SubnodeLevel.I

  Protected *Child.GtkWidget
  Protected i.I
  Protected *WidgetName
  Protected WindowCount.I
  Protected *Window.GtkWindow
  Protected *WindowList.GList

  ClearGadgetItems(1)

  *WindowList = gtk_window_list_toplevels_()
  WindowCount = g_list_length_(*WindowList)
  
  If WindowCount > 0
    For i = 0 To WindowCount - 1
      *Window = g_list_nth_data_(*WindowList, i)
      AddGadgetItem(1, -1, "GtkWindow", 0, 0)
      ClearList(FallbackSubnodeLevel())
      SubnodeLevel = 1
      GetChildren(*Window)
    Next i
  EndIf

  gtk_tree_view_expand_all_(GadgetID(1))
EndProcedure

ProcedureC Callback(*Widget.GtkWidget, *Event.GdkEventAny, *UserData)
  Shared CalendarVisible.I
  CalendarVisible = #True
EndProcedure

OpenWindow(0, 1400, 100, 460, 300, "Widget Explorer")
DateGadget(0, 10, 10, 180, 25, "Date: %mm/%dd/%yyyy")
TreeGadget(1, GadgetWidth(0) + 20, 10, WindowWidth(0) - GadgetWidth(0) - 30, WindowHeight(0) - 20)

ExamineWindows()

*HBox.GtkWidget = gtk_widget_get_parent_(GadgetID(0))
*Button.GtkWidget = g_list_nth_data_(gtk_container_get_children_(*HBox), 1)
g_signal_connect_(*Button, "button-release-event", @Callback(), 0)

Repeat
  If CalendarVisible
    ExamineWindows()
    CalendarVisible = #False
  EndIf
Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Map widgets of all windows

Posted: Wed Aug 22, 2012 8:36 pm
by idle
Thanks Shardik