Semi-automatic generation of FB program from glade 2 files

Linux specific questions.
lizard
Posts: 406
Joined: Oct 17, 2017 11:35
Location: Germany

Semi-automatic generation of FB program from glade 2 files

Postby lizard » Jul 20, 2018 22:07

Here i want to describe a procedure of semi-automatic generation of gtk-gui-forms from glade 2 to FB.

To keep things short:

1. Find and install glade 2 (not 3, because the code generation was stopped there) in Windows (10 or whatever).

2. Design your form in glade 2. In Options choose a folder on usb-stick. When ready click "build" to let glade generate the code on usb-stick.

3. Now boot Mint 18.3, find and install fbfrog from dkl.

4 In filemanager find the generated folder and its subfolder "src" on usb-stick. Copy this script there and make it executable:

Code: Select all

#!/bin/sh
# fbfrog_convert.sh

# written under mint 18.3, should work on most modern distros

# intended to convert all .c and .h files in current directory to
# FreeBasic .bas and .bi, with fbfrog (must be installed before),
# rename and sed (linux), mostly few "todo"s left for manual editing.
# it is meant as a base for own development

# **********************************************************************

echo
echo "Converting to FreeBASIC"
echo

# .c files first *******************************************************

# delete previous generated files (please check if it matches others)
# rm *.b*

CFILES=*.c
for f in $CFILES
do
  echo
  echo "Processing $f file"
  echo
  # take action on each file. $f stores current file name
  # '-target linux-x86 -target win64' also enables win32 and linux-x86_64
  # reducing passes from 23 to 4
  fbfrog -target linux-x86 -target win64 $f
done
# perl-rename (in case you have gnu-rename please modify)
rename 's/\.bi$/\.bac/' *.bi

echo

CFILES=*.bac
for f in $CFILES
do
  # cut extension
  e=$(basename $f .bac)

# convert generated .bac to new .bas file
# multiple commands, replace case insensitive, delete "extern C"
# and change end extern to end main(0,0)

sed '
s/#pragma once/\x27 '"$e"'.bas/I g
s/end extern/end main(0,0)/I g
/extern "C"/d' <$e.bac  >$e.bas
done

# then .h files ********************************************************

## replace in-place "FL_EXPORT" with "extern" in all .h files
## only in xforms needed
sed -i 's/FL_EXPORT/extern/g' *.h

HFILES=*.h
for f in $HFILES
do
  echo
  echo "Processing $f file"
  echo
  # take action on each file. $f stores current file name
  fbfrog -target linux-x86 -target win64 $f
done
 
# perl-rename - renames all .bi files to .bah
rename 's/\.bi$/\.bah/' *.bi

echo

HFILES=*.bah
for f in $HFILES
do
  # cut extension
  e=$(basename $f .bah)
  # add first comment line
  sed '1 i\\x27 '"$e"'.bi' <$e.bah >$e.bi
done

echo
echo "Conversion finished, mostly needs to be edited"
echo

# please be careful with sed, it is powerful, always make backups
# your lizard


5 After running this script you have interface.bas and main.bas in this folder. Insert main.bas at the end of interface.bas and comment out everything not needed.

6. And this could be the resulting FB-program:

Code: Select all

' inter.bas

#include once "gtk/gtk.bi"

private function create_window2() as GtkWidget ptr
   dim as GtkWidget ptr window2
   dim as GtkWidget ptr vbox4
   dim as GtkWidget ptr hbox2
   dim as GtkWidget ptr combobox1
   dim as GtkWidget ptr colorbutton1
   dim as GtkWidget ptr filechooserbutton1
   dim as GtkWidget ptr fontbutton1
   dim as GtkWidget ptr hbox1
   dim as GtkWidget ptr scrolledwindow2
   dim as GtkWidget ptr treeview1
   dim as GtkWidget ptr scrolledwindow1
   dim as GtkWidget ptr textview1
   dim as GtkWidget ptr hbuttonbox1
   dim as GtkWidget ptr button16
   dim as GtkWidget ptr button17
   dim as GtkWidget ptr button18
   dim as GtkWidget ptr button19
   dim as GtkWidget ptr button20
   dim as GtkWidget ptr button21
   dim as GtkWidget ptr button22
   dim as GtkWidget ptr button23
   window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL)
   gtk_window_set_title(GTK_WINDOW(window2), "window2")
   vbox4 = gtk_vbox_new(FALSE, 0)
   gtk_widget_show(vbox4)
   gtk_container_add(GTK_CONTAINER(window2), vbox4)
   hbox2 = gtk_hbox_new(FALSE, 0)
   gtk_widget_show(hbox2)
   gtk_box_pack_start(GTK_BOX(vbox4), hbox2, TRUE, TRUE, 0)
   combobox1 = gtk_combo_box_new_text()
   gtk_widget_show(combobox1)
   gtk_box_pack_start(GTK_BOX(hbox2), combobox1, TRUE, TRUE, 0)
   colorbutton1 = gtk_color_button_new()
   gtk_widget_show(colorbutton1)
   gtk_box_pack_start(GTK_BOX(hbox2), colorbutton1, FALSE, FALSE, 0)
   filechooserbutton1 = gtk_file_chooser_button_new(!"Datei ausw\195\164hlen", GTK_FILE_CHOOSER_ACTION_OPEN)
   gtk_widget_show(filechooserbutton1)
   gtk_box_pack_end(GTK_BOX(hbox2), filechooserbutton1, FALSE, FALSE, 0)
   fontbutton1 = gtk_font_button_new()
   gtk_widget_show(fontbutton1)
   gtk_box_pack_start(GTK_BOX(hbox2), fontbutton1, TRUE, FALSE, 3)
   hbox1 = gtk_hbox_new(FALSE, 0)
   gtk_widget_show(hbox1)
   gtk_box_pack_start(GTK_BOX(vbox4), hbox1, TRUE, TRUE, 0)
   scrolledwindow2 = gtk_scrolled_window_new(NULL, NULL)
   gtk_widget_show(scrolledwindow2)
   gtk_box_pack_start(GTK_BOX(hbox1), scrolledwindow2, TRUE, TRUE, 0)
   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow2), GTK_SHADOW_IN)
   treeview1 = gtk_tree_view_new()
   gtk_widget_show(treeview1)
   gtk_container_add(GTK_CONTAINER(scrolledwindow2), treeview1)
   scrolledwindow1 = gtk_scrolled_window_new(NULL, NULL)
   gtk_widget_show(scrolledwindow1)
   gtk_box_pack_start(GTK_BOX(hbox1), scrolledwindow1, TRUE, TRUE, 0)
   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_SHADOW_IN)
   textview1 = gtk_text_view_new()
   gtk_widget_show(textview1)
   gtk_container_add(GTK_CONTAINER(scrolledwindow1), textview1)
   gtk_widget_set_size_request(textview1, 20, 600)
   hbuttonbox1 = gtk_hbutton_box_new()
   gtk_widget_show(hbuttonbox1)
   gtk_box_pack_start(GTK_BOX(vbox4), hbuttonbox1, FALSE, TRUE, 0)
   gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox1), 5)
   button16 = gtk_button_new_with_mnemonic("button16")
   gtk_widget_show(button16)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button16)
   GTK_WIDGET_SET_FLAGS(button16, GTK_CAN_DEFAULT)
   button17 = gtk_button_new_with_mnemonic("button17")
   gtk_widget_show(button17)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button17)
   GTK_WIDGET_SET_FLAGS(button17, GTK_CAN_DEFAULT)
   button18 = gtk_button_new_with_mnemonic("button18")
   gtk_widget_show(button18)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button18)
   GTK_WIDGET_SET_FLAGS(button18, GTK_CAN_DEFAULT)
   button19 = gtk_button_new_with_mnemonic("button19")
   gtk_widget_show(button19)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button19)
   GTK_WIDGET_SET_FLAGS(button19, GTK_CAN_DEFAULT)
   button20 = gtk_button_new_with_mnemonic("button20")
   gtk_widget_show(button20)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button20)
   GTK_WIDGET_SET_FLAGS(button20, GTK_CAN_DEFAULT)
   button21 = gtk_button_new_with_mnemonic("button21")
   gtk_widget_show(button21)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button21)
   GTK_WIDGET_SET_FLAGS(button21, GTK_CAN_DEFAULT)
   button22 = gtk_button_new_with_mnemonic("button22")
   gtk_widget_show(button22)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button22)
   GTK_WIDGET_SET_FLAGS(button22, GTK_CAN_DEFAULT)
   button23 = gtk_button_new_with_mnemonic("button23")
   gtk_widget_show(button23)
   gtk_container_add(GTK_CONTAINER(hbuttonbox1), button23)
   GTK_WIDGET_SET_FLAGS(button23, GTK_CAN_DEFAULT)
   g_object_set_data(G_OBJECT(window2), "window2", window2)
      return window2
end function

private function main(byval argc as long, byval argv as zstring ptr ptr) as long
   dim as GtkWidget ptr window2
   gtk_init(@argc, @argv)
   window2 = create_window2()
   gtk_widget_show(window2)
   gtk_main()
   return 0
end function

end main(0,0)


This is meant only as a raw-recipe to generate such FB programs. You can change all parts in many ways to match your needs.

Have fun!
lizard
Posts: 406
Joined: Oct 17, 2017 11:35
Location: Germany

Re: Semi-automatic generation of FB program from glade 2 files

Postby lizard » Jul 22, 2018 10:57

On Win (or Linux) even a complete manual conversion from glade 2 C files to FB is not quite difficult. Much can be done with search/replace. In case of the above example its mainly 4 steps:

Including header in c

Code: Select all

#include <gtk/gtk.h>


becomes in FB

Code: Select all

#include once "gtk/gtk.bi"


Alll other "#include" can be commented out


Function in C

Code: Select all

GtkWidget* create_window2 (void)


becomes in FB

Code: Select all

private function create_window2() as GtkWidget ptr



Variable declaration in C

Code: Select all

GtkWidget *window2;


becomes

Code: Select all

dim as GtkWidget ptr window2


in FB. Thats almost all. Its that easy. Then delete all ";" at the end of lines and comment out everything not needed.

Naturally for the cracks here i am not telling anything new.



At the end the tricky part begins. That is filling the empty form with life. Connecting the buttons with callbacks, loading text files in textwindow and such, to finish the final useable program. This is demonstrated in the examples that come with fbc. Or can be found with google.
TJF
Posts: 3355
Joined: Dec 06, 2009 22:27
Location: N47°, E15°

Re: Semi-automatic generation of FB program from glade 2 files

Postby TJF » Jul 31, 2018 10:37

Hi lizard.

Do you know GladeToBac? It's a cross-platform solution to auto-generate all the stuff you mentioned (including the FB main code), for deprecated Glade2 (libglade) input as well as for up-to-date Glade3 (GtkBuilder) input. Additionally it auto-generates templates for the callback procedures for signal handling.

Regards
lizard
Posts: 406
Joined: Oct 17, 2017 11:35
Location: Germany

Re: Semi-automatic generation of FB program from glade 2 files

Postby lizard » Aug 01, 2018 18:51

Hi TJF,

i have seen your name many times in threads about gtk. You seem to be one with deeper understanding of gtk together with FB. Yes, i have researched some time about gtk and tried your GladeToBac. But afaik only few of base elements like clist, vbox and hbox are deprecated, so you cant say whole Glade 2 or the procedure i have shown here is deprecated. Only need to replace the deprecated elements.

Regards
TJF
Posts: 3355
Joined: Dec 06, 2009 22:27
Location: N47°, E15°

Re: Semi-automatic generation of FB program from glade 2 files

Postby TJF » Aug 02, 2018 9:00

Yes, I made some GTK applications in FB over the time.

lizard wrote:... and tried your GladeToBac.

Obviously you didn't understand it, yet. Otherwise you would have titled "Full-automatic generation of FB program from glade 2 or 3 files". And you wont have spend so much time in this solution.

  • C code generation in Glade2 was the first approach for widget handling in the custom application.
  • Then libglade was developed by a third party, in order to reduce the pitfalls coming up by differences between GTK development and Glade code generation.
  • libglade was very successful, so that GTK developers intergrated it in the main line, with enhanced features. That's the current GtkBuilder.
Your approach is not going one step, instead it's going two major steps backwards.

lizard wrote:... afaik only few of base elements like clist, vbox and hbox are deprecated ...

Not only the deprecated elements, but in first place the missing support for all new and modern widgets should make you (or at least your readers) think about this solution.

Do whatever you want, but note: based on my GTK experience, I cannot find any advantage in your "solution".

Good luck!

Return to “Linux”

Who is online

Users browsing this forum: No registered users and 1 guest