./GladeGUI.bin ./Part1.glade > Glade.pb
Code: Select all
; A console app that parses a glade XML file and generates
; a boiler plate PureBasic file that can be used to test
; the glade file.
;
; As an example, parse Part1.glade and create Glade.pb.
; ./GladeGUI.bin ./Part1.glade > Glade.pb
Global hXml = #Null
Global GladeFile$ = #Null$
Global Globals$ = #Null$
Global Imports$ = #Null$
Global Init$ = #Null$
Global Handlers$ = #Null$
; text of a simple Main() routine to launch gtk
#Main$ = ~"Procedure Main()\n" +
~" gtk_init_(#Null,#Null)\n" +
~" InitGuiFromBuilder(GladeFile$)\n" +
~" gtk_widget_show_all_(*window)\n" +
~" gtk_main_()\n" +
~" ProcedureReturn 0\n" +
~"EndProcedure\n\n" +
~"Main()\n\n"
; create an imports string, and
; later replace libdir$ With path To gtk
#imports$ = ~"ImportC \"libdir$\"\n" +
~" gtk_builder_new()\n" +
~" gtk_builder_add_from_file(builder,file.p-utf8,*error)\n" +
~" gtk_builder_new_from_file(file.p-utf8)\n" +
~" gtk_builder_get_object(builder,id.p-utf8)\n" +
~"EndImport\n"
; someone clicked the "X" close app?
#destroy$ = ~"Procedure gtk_main_quit()\n" +
~" Debug #PB_Compiler_Procedure\n" +
~" gtk_main_quit_()\n" +
~"EndProcedure\n"
; <requires lib="gtk+" version="3.0"/>
; spawn "find" to search for libgtk-3.so
Procedure$ FindLibGtk()
Protected hPgm = RunProgram("/bin/sh", ~"-c \"/bin/find /usr -name libgtk-3.so\"",
#Null$ , #PB_Program_Open | #PB_Program_Read),
libgtk$ = #Null$
If hPgm
While ProgramRunning(hPgm)
If AvailableProgramOutput(hPgm)
libgtk$ = ReadProgramString(hPgm)
EndIf
Wend
CloseProgram(hPgm)
EndIf
ProcedureReturn libgtk$
EndProcedure
; recurse through the xml
Procedure EnumerateObjects(hNode)
Static id$, object$, signal$, handler$
If hNode
Protected nodeName$ = GetXMLNodeName(hNode)
If nodeName$ = "object"
id$ = GetXMLAttribute(hNode,"id")
If id$
object$ = "*" + id$
Init$ = Init$ + " " + object$ +
~" = gtk_builder_get_object(*builder," +
~"\"" + id$ + ~"\")\n"
Globals$ = Globals$ + "Global " + object$ + ~" = #Null\n"
EndIf
ElseIf nodeName$ = "signal"
signal$ = GetXMLAttribute(hNode,"name")
handler$ = GetXMLAttribute(hNode,"handler")
If signal$ And handler$
Init$ = Init$ + Space(2) +
" g_signal_connect_(" + object$ +
~", \"" + signal$ + ~"\", @" +
handler$ + ~"(), #Null)\n"
Handlers$ = Handlers$ +
"Procedure " + handler$ + ~"(*widget,*data)\n" +
~" Debug #PB_Compiler_Procedure\n"
If signal$ = "destroy"
Handlers$ = Handlers$ + ~" gtk_main_quit_()\n"
EndIf
Handlers$ = Handlers$ + ~"EndProcedure\n\n"
EndIf
EndIf
EnumerateObjects(ChildXMLNode(hNode))
EnumerateObjects(NextXMLNode(hNode))
EndIf
EndProcedure
; a console app that parses a glade file and creates a rudimentary
; PB app to test it.
Procedure Main()
Protected hConsole = OpenConsole("Glade Parser",#PB_UTF8)
If hConsole
GladeFile$ = ProgramParameter()
PrintN(~"Global GladeFile$ = \"" + GladeFile$ + ~"\"")
PrintN("Global *builder = #Null")
; try to load the .glade file for parsing
hXml = LoadXML(#PB_Any,GladeFile$)
If hXml And XMLStatus(hXml) = #PB_XML_Success
; create a Procedure that will create the widgets and signal handlers
; found in the .glade file
Init$ = ~"Procedure InitGuiFromBuilder(GladeFile$)\n"
Init$ = Init$ + ~" *builder = gtk_builder_new_from_file(GladeFile$)\n"
Init$ = Init$ + ~" if *builder\n"
; recursively parse the .glade file looking for:
; "object"s which are widgets, and
; "signal"s which are handlers
EnumerateObjects(MainXMLNode(hXml))
FreeXML(hXml)
Init$ = Init$ + ~" g_signal_connect_(*window1, \"destroy\", @gtk_main_quit(), #Null)\n"
Init$ = Init$ + ~" EndIf\nEndProcedure\n"
; LoadXML or XMLStatus failed
Else
PrintN("LoadXML of " + GladeFile$ + "failed")
PrintN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
PrintN("XMLError = " + XMLError(hXml))
PrintN("XMLErrorLine = " + Str(XMLErrorLine(hXml)))
PrintN("XMLErrorPosition = " + Str(XMLErrorPosition(hXml)))
PrintN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
EndIf
PrintN(Globals$)
PrintN(ReplaceString(#imports$,"libdir$",FindLibGtk()))
PrintN(#destroy$)
PrintN(Handlers$)
PrintN(Init$)
PrintN(#Main$)
CloseConsole()
EndIf
EndProcedure
Main()
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkWindow" id="window1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="window-position">center</property>
<child>
<!-- n-columns=3 n-rows=3 -->
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">button1</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_button1_clicked" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">button2</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_button2_clicked" swapped="no"/>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="text" translatable="yes">Hello World!</property>
<signal name="changed" handler="on_entry1_changed" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button3">
<property name="label" translatable="yes">button3</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_button3_clicked" swapped="no"/>
<signal name="enter" handler="on_button3_enter" swapped="no"/>
<signal name="leave" handler="on_button3_leave" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
Code: Select all
Global GladeFile$ = "./Part1.glade"
Global *builder = #Null
Global *window1 = #Null
Global *grid1 = #Null
Global *button1 = #Null
Global *button2 = #Null
Global *entry1 = #Null
Global *button3 = #Null
ImportC "/usr/lib/x86_64-linux-gnu/libgtk-3.so"
gtk_builder_new()
gtk_builder_add_from_file(builder,file.p-utf8,*error)
gtk_builder_new_from_file(file.p-utf8)
gtk_builder_get_object(builder,id.p-utf8)
EndImport
Procedure gtk_main_quit()
Debug #PB_Compiler_Procedure
gtk_main_quit_()
EndProcedure
Procedure on_button1_clicked(*widget,*data)
Debug #PB_Compiler_Procedure
EndProcedure
Procedure on_button2_clicked(*widget,*data)
Debug #PB_Compiler_Procedure
EndProcedure
Procedure on_entry1_changed(*widget,*data)
Debug #PB_Compiler_Procedure
EndProcedure
Procedure on_button3_clicked(*widget,*data)
Debug #PB_Compiler_Procedure
EndProcedure
Procedure on_button3_enter(*widget,*data)
Debug #PB_Compiler_Procedure
EndProcedure
Procedure on_button3_leave(*widget,*data)
Debug #PB_Compiler_Procedure
EndProcedure
Procedure InitGuiFromBuilder(GladeFile$)
*builder = gtk_builder_new_from_file(GladeFile$)
If *builder
*window1 = gtk_builder_get_object(*builder,"window1")
*grid1 = gtk_builder_get_object(*builder,"grid1")
*button1 = gtk_builder_get_object(*builder,"button1")
g_signal_connect_(*button1, "clicked", @on_button1_clicked(), #Null)
*button2 = gtk_builder_get_object(*builder,"button2")
g_signal_connect_(*button2, "clicked", @on_button2_clicked(), #Null)
*entry1 = gtk_builder_get_object(*builder,"entry1")
g_signal_connect_(*entry1, "changed", @on_entry1_changed(), #Null)
*button3 = gtk_builder_get_object(*builder,"button3")
g_signal_connect_(*button3, "clicked", @on_button3_clicked(), #Null)
g_signal_connect_(*button3, "enter", @on_button3_enter(), #Null)
g_signal_connect_(*button3, "leave", @on_button3_leave(), #Null)
g_signal_connect_(*window1, "destroy", @gtk_main_quit(), #Null)
EndIf
EndProcedure
Procedure Main()
gtk_init_(#Null,#Null)
InitGuiFromBuilder(GladeFile$)
gtk_widget_show_all_(*window)
gtk_main_()
ProcedureReturn 0
EndProcedure
Main()