Lately I have been hacking to find another way of embedding GTK functions into newLISP. Normally, I send a GTK-function as a string to a macro, which, in it's turn, sends everything to the GTK-server:
(define-macro (GTK)
(set 'str (append (first (args)) " "))
(dolist (x (rest (args)))(set 'str (append str (string (eval x)) " ")))
(get-string (gtk str))
)
(GTK "gtk_init" "NULL" "NULL" )
(setq win (GTK "gtk_window_new" 0 ))
(GTK "gtk_window_set_title" win ""A different time"" )
(GTK "gtk_widget_set_usize" win 200 32 )
(GTK "gtk_window_set_resizable" win 0)
(GTK "gtk_window_set_position" win 1 )
...etc...
But actually, it would be a lot nicer if we can embed GTK functions directly into our newLISP program, as follows:
(gtk_server_logging 1)
(gtk_init NULL NULL)
(setq win (gtk_window_new 0))
(gtk_window_set_title win {"A different time"})
(gtk_widget_set_usize win 200 32)
(gtk_window_set_resizable win 0)
(gtk_window_set_position win 1)
...etc...
Looks much cleaner, and more professional also. Well, good news, as I figured a nice construction to achieve this goal. Below the way it looks with the TIME program of Norman.
Also add the GTK-server internal commands to the configfile, otherwise it does not work. See also here: http://www.gtk-server.org/gtk-server.cfg
#-----------------------------------------
(if (= (last (sys-info)) 6)
(import "gtk-server.dll" "gtk")
(import "libgtk-server.so" "gtk"))
# (set 'cfgfile (open "C:\GTK-server\gtk-server.cfg" "read"))
(set 'cfgfile (open "/etc/gtk-server.cfg" "read"))
(while (read-line cfgfile)
(if (starts-with (current-line) "GTK_LIB_FUNCTION")
(begin
(set 'func (chop ((parse (current-line) " ") 2)))
(set 'lb (append "(lambda ()(setq s "" func "")(dolist (x (args))(setq s (append s " " (string x))))(get-string (gtk s)))"))
(constant (global (sym func)) (eval-string lb))
)
)
)
(close cfgfile)
#-----------------------------------------
(gtk_server_logging 1)
(gtk_init NULL NULL)
(setq win (gtk_window_new 0))
(gtk_window_set_title win {"A different time"})
(gtk_widget_set_usize win 200 32)
(gtk_window_set_resizable win 0)
(gtk_window_set_position win 1)
;; Use async functionality
(gtk_server_connect win "show" "win")
(gtk_server_timeout 1000 win "show")
(setq tbl (gtk_table_new 100 100 1))
(gtk_container_add win tbl)
(setq pb1 (gtk_progress_bar_new))
(gtk_table_attach_defaults tbl pb1 1 100 1 10)
(setq pb2 (gtk_progress_bar_new))
(gtk_table_attach_defaults tbl pb2 1 100 11 20)
(setq pb3 (gtk_progress_bar_new))
(gtk_table_attach_defaults tbl pb3 1 100 21 30)
(gtk_widget_show_all win)
(setq event 0)
(while (!= event win)
(gtk_progress_bar_set_fraction pb3 (div (float (slice (replace ":" (slice (date (apply date-value (now))) 11 8) "") 4 2)) 60) )
(gtk_progress_bar_set_fraction pb2 (div (float (slice (replace ":" (slice (date (apply date-value (now))) 11 8) "") 2 2)) 60) )
(gtk_progress_bar_set_fraction pb1 (div (float (slice (replace ":" (slice (date (apply date-value (now))) 11 8) "") 0 2)) 24) )
(setq event (gtk_server_callback "wait")))
(exit)
Nice, or what! This way we can start programming GTK directly into the newLISP sourcecode. And the nice thing is: if you make a mistake with a GTK function, newLISP will complain it doesn't understand. So the syntax-checking is also taken care of.
Much better this way, I'ld say :-)
Peter
Even smaller:
(while (read-line cfgfile)
(if (starts-with (current-line) "GTK_LIB_FUNCTION")
(begin
(set 'func (chop ((parse (current-line) " ") 2)))
(set 'lb (append {(lambda()(setq s "} func {")(dolist (x (args))(setq s (string s " " x)))(get-string (gtk s)))}))
(constant (global (sym func)) (eval-string lb))
)
)
)
Some real-world program examples:
http://www.turtle.dds.nl/newlisp/mouse.lsp
http://www.turtle.dds.nl/newlisp/rss.lsp
http://www.turtle.dds.nl/newlisp/cdplayer.lsp
:-)
Peter
With the following line in the VIM syntax file, embedded GTK commands can be highlighted in VIM:
Quote
syn match newlispAtom "[Gg][TtDd][Kk][_][_a-zA-Z0-9]+"
Now the highlighting is the same as a quoted symbolname.
Peter