Tuesday, December 15, 2009

GUI with Gambit

There doesn't seem to be any real GUI libraries for Scheme. I spent
some time looking for a GUI framework that I can interface with
Gambit. WxWidgets was the first place I looked. I wasn't fully sure
that I could interface a C++ GUI framework with Gambit. The docs
mentioned it, but I didn't want to spent time exploring and debugging
C++ issues this time around.

Tk is a GUI library that is cross platform, works almost everywhere
without a hitch. I had spent a lot of time coding in Tcl/Tk a few
years back, and so getting back on the Tk bandwagon looked
appealing. The latest "Tile" updates to Tk also improves the
look-and-feel considerably. So, what options did I have for Scheme +
Tk?

On obvious way is to look at STKlos. The only reason, I didn't want to
do that, was because I wanted to stick to Gambit for the
moment. Gambit allows me to create a standalone application. Having a
standalone exe simplifies application delivery, esp. on Windows.

My first thought was to have a native interface to Tk. I thought about
a FFI interface to the Tk dll itself. Again no luck here. There was a
Snow package for Tk available but Snow itself seems to be dead with no
development happening on it.

I came across PS/Tk. PS/Tk uses Tcl as a bridge to Tk. You need to
have TCL installed though. We can get past this, if we use tclkit and
so, it looked like a good starting point.

The whole PS/Tk is just one file - pstk.scm that you download. Just
load the file and it should be good to go.

A-ha one Gotcha!

That doesn't work. What you need is to modify the file for specific
scheme support. There is example code written up for each scheme
implementation that PS/Tk supports and its just a question of
uncommenting the right one. For Gambit the code looks like so -


; GAMBIT
; (run-program
; (lambda (program)
; (let ((port
; (open-process
; (list path: "/bin/sh"
; arguments: (list "-c" (string-append "exec " program))
; stderr-redirection: #t))))
; (list port port))))
;
; (flush-output-port force-output)


Uncommenting this won't do as its Linux specific. Some small changes
and we should be able to use it on Windows. The changes are -


; GAMBIT / Windows
(run-program
(lambda (program)
(let ((port
(open-process
(list path: "c:/tcl/bin/tclsh85.exe"
stderr-redirection: #t))))
(list port port))))

(flush-output-port force-output)


Once that's done, we are good to go. We can create a simple frame with
a button like so -


(define f (tk 'create-widget 'frame))
(define b (f 'create-widget 'button))
(b 'configure 'text: "Hello World")
(tk/pack b)
(tk/pack f)


Next stop - change from a full fledged Tcl/Tk installation to Tclkit.

No comments: