logo My first GTK application

Page updated: April 16, 2011
Page updated August 19, 2022

The Author, Barry kauler, wrote this page in 2011. The 2022 update is just some minor link corrections. This page continues written in the first-person...

I have got to say, this has been an incredible experience. I sat in front of my computer almost the entire day (Nov. 15, 2010), writing my first serious application in BaCon.
What I must emphasize here is that I had only messed around very casually a couple of days beforehand, looking around in the BaCon documentation and examples.
Early in the morning (Nov. 15) I was discussing on my blog the need for a GUI to setup handling of a proxy server for Internet access in Puppy ....then I thought, well, this will be a very good exercise to learn BaCon coding at the same time.

Come evening, it is done, and I am already an accomplished BaCon programmer. Most extraordinary is the ease with which I developed the GUI window and the interface with my code. I used HUG (Highlevel Universal GUI) which, it turns out, is a delight to use.

For you to have the same pleasant experience, I recommend having the online documentation open (with popup keyword menu):

https://www.basic-converter.org/documentation.html

Oh yes, the HUG documentation is an essential read:

https://www.basic-converter.org/hugdoc.html

You do need to have BaCon installed. In EasyOS, click on the "sfs" icon at top of the desktop to load the "devx" SFS -- that will give you a complete compiling environment, including gcc and bacon.

You will also find it best to have a text-editor that supports BaCon colour syntax highlighting. EasyOS has the Geany text editor -- Geany also has a HTML plugin, so you can export files in HTML format, with syntax highlighting, which is very nice for documentation.

Then off you go...

My first window

The very first thing that I did was create a little empty window. Here is the complete program:
REM setup proxy server for wget
REM Barry Kauler, my first BaCon GTK program

INCLUDE "/usr/share/BaCon/hug.bac"
INIT

mainwin = WINDOW("Proxy server setup", 400, 300)

REM endless gtk loop...
DISPLAY
Well, no need for a snapshot, it is just an empty window. Here is the code if you want to try it for yourself: proxy_setup1.bac. To compile is easy:
# bacon proxy_setup1.bac

Widgets and more widgets

Then I populated it with the various widgets that I wanted:
REM setup proxy server for wget
REM Barry Kauler, my first BaCon GTK program

INCLUDE "/usr/share/BaCon/hug.bac"
INIT

mainwin = WINDOW("Proxy server setup", 400, 285)

image1=IMAGE("/usr/local/lib/X11/pixmaps/www48.png",48,48)
ATTACH(mainwin,image1,10,10)

label_hdr1=MARK("If you connect to the Internet through a proxy",350,15)
ATTACH(mainwin,label_hdr1,58,10)
label_hdr2=MARK("server, tick the checkbox and fill in the fields",350,15)
ATTACH(mainwin,label_hdr2,58,25)
label_hdr3=MARK("(leave Username/Password blank if not needed)",350,15)
ATTACH(mainwin,label_hdr3,58,40)

check1 = CHECK("Enable Internet connection through proxy server",350,20)
ATTACH(mainwin,check1,20,70)

label_http = MARK("HTTP:",50,20)
ATTACH(mainwin, label_http, 10, 100)
httpproxy = ENTRY("foo.org:8080",280,20)
ATTACH(mainwin, httpproxy, 100, 100)

label_ftp = MARK("FTP:",50,20)
ATTACH(mainwin, label_ftp, 10, 130)
ftpproxy = ENTRY("foo.org:8080",280,20)
ATTACH(mainwin, ftpproxy, 100, 130)

label_user=MARK("Username:",80,20)
ATTACH(mainwin,label_user,10,160)
username = ENTRY("",280,20)
ATTACH(mainwin, username, 100, 160)

label_pass=MARK("Password:",80,20)
ATTACH(mainwin,label_pass,10,190)
password1=PASSWORD(150,20)
ATTACH(mainwin,password1,100,190)

label_pass=MARK("Enter password again:",170,20)
ATTACH(mainwin,label_pass,10,220)
password1=PASSWORD(150,20)
ATTACH(mainwin,password1,180,220)

ok_btn = BUTTON("OKAY", 65, 25)
ATTACH(mainwin, ok_btn, 240, 250)
cancel_btn = BUTTON("Cancel", 65, 25)
ATTACH(mainwin, cancel_btn, 320, 250)

REM Define the callbacks
CALLBACK(ok_btn, QUIT)
CALLBACK(cancel_btn, QUIT)

REM endless gtk loop...
DISPLAY
That is highly readable, and as a raw beginner I had no hesitation at all creating it. Here is the file: proxy-setup2.bac

Callbacks

Then I got stuck into the backend code to make it do something useful. This mainly involves defining callbacks, that respond to actions in the GUI window, and vice-versa, values that can be posted from the code to the window.

Here are my first steps:
REM setup proxy server for wget
REM Barry Kauler, my first BaCon GTK program using HUG

INCLUDE "/usr/share/BaCon/hug.bac"
INIT

http_proxy$=GETENVIRON$("http_proxy")
ftp_proxy$=GETENVIRON$("ftp_proxy")

proxy_flag=0
IF http_proxy$ != "" THEN proxy_flag=1
IF ftp_proxy$ != "" THEN proxy_flag=1

SUB check1_callback
 LOCAL status
 status=GET(check1)
 IF status = 1 THEN
  ENABLE(httpproxy)
  ENABLE(ftpproxy)
  ENABLE(username)
  ENABLE(password1)
  ENABLE(password2)
 ELSE
  DISABLE(httpproxy)
  DISABLE(ftpproxy)
  DISABLE(username)
  DISABLE(password1)
  DISABLE(password2)
 ENDIF
ENDSUB

mainwin = WINDOW("Proxy server setup", 400, 285)

image1=IMAGE("/usr/local/lib/X11/pixmaps/www48.png",48,48)
ATTACH(mainwin,image1,10,10)

label_hdr1=MARK("If you connect to the Internet through a proxy",350,15)
ATTACH(mainwin,label_hdr1,58,10)
label_hdr2=MARK("server, tick the checkbox and fill in the fields",350,15)
ATTACH(mainwin,label_hdr2,58,25)
label_hdr3=MARK("(leave Username/Password blank if not needed)",350,15)
ATTACH(mainwin,label_hdr3,58,40)

check1 = CHECK("Enable Internet connection through proxy server",350,20)
ATTACH(mainwin,check1,20,70)

label_http = MARK("HTTP:",50,20)
ATTACH(mainwin, label_http, 10, 100)
httpproxy = ENTRY("foo.org:8080",280,20)
ATTACH(mainwin, httpproxy, 100, 100)

label_ftp = MARK("FTP:",50,20)
ATTACH(mainwin, label_ftp, 10, 130)
ftpproxy = ENTRY("foo.org:8080",280,20)
ATTACH(mainwin, ftpproxy, 100, 130)

label_user=MARK("Username:",80,20)
ATTACH(mainwin,label_user,10,160)
username = ENTRY("",280,20)
ATTACH(mainwin, username, 100, 160)

label_pass=MARK("Password:",80,20)
ATTACH(mainwin,label_pass,10,190)
password1=PASSWORD(150,20)
ATTACH(mainwin,password1,100,190)

label_pass=MARK("Enter password again:",170,20)
ATTACH(mainwin,label_pass,10,220)
password2=PASSWORD(150,20)
ATTACH(mainwin,password2,180,220)

ok_btn = BUTTON("OKAY", 65, 25)
ATTACH(mainwin, ok_btn, 240, 250)
cancel_btn = BUTTON("Cancel", 65, 25)
ATTACH(mainwin, cancel_btn, 320, 250)

REM Define the callbacks
CALLBACK(ok_btn, QUIT)
CALLBACK(cancel_btn, QUIT)
CALLBACK(check1,check1_callback)

REM tick or untick the checkbox...
SET(check1,1)
SET(check1,proxy_flag)

REM endless gtk loop...
DISPLAY
The code is here: proxy-setup3.bac

The complete application

Well, it was really just more of the same. I got stuck into the logical steps required to manage the proxy settings.

Then there it was, a working program:

window

Here is the source code: proxy-setup.bac

Or, as a HTML page: proxy-setup.bac.html

...well, although this was my first BaCon GTK application, I did revisit this code and tidy it up a bit and add some extra stuff such as international language support, improved layout and shared hug.so, see notes below.

I compiled it like this:
# bacon -x proxy-setup.bac
The -x option is for international language support, see my Internationalization page.

I also put some code in to ensure that layout always renders properly, such as no truncated text, for all theme/font settings and screen resolution/dpi settings -- see my layout page.

Note, an alternative is to have /usr/lib/libhug.so, which is hug.bac compiled as a shared library. This reduces the size of individual applications. The code replaces this:
INCLUDE "/usr/share/BaCon/hug.bac"
With this, to use the shared libhug.so library:
INCLUDE "/usr/share/BaCon/hug_imports.bac"
The stripped executable is 50KB, not too bad (with hug.bac included it is about 90KB). The source file is 7.2KB.

Further information

More HUG documentation, written by BaCon Forum member bigbass:

https://www.basic-converter.org/hug-tutorial/BaCon_widget_Examples_Documentation.html


Copyright Barry Kauler 2010 bkhome.org All rights reserved
See FAQ for legal statement.