;; Copyright (c) 2005 Jeremy Shute ;; Permission is hereby granted, free of charge, to any person obtaining a copy ;; of this software and associated documentation files (the "Software"), to ;; deal in the Software without restriction, including without limitation the ;; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or ;; sell copies of the Software, and to permit persons to whom the Software is ;; furnished to do so, subject to the following conditions: ;; The above copyright notice and this permission notice shall be included in ;; all copies or substantial portions of the Software. ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ;; IN THE SOFTWARE. (module test (include "gtk-server.sch") (main main)) (define (main args) ;; All programs using the GTK-Server binding should have all GTK-Server ;; calls within the (with-gtk-server ...) macro. This sets up the ;; connection to GTK-Server in a safe way and introduces all the functions ;; you see below. For a more complete overview, see: ;; http://www.gtk.org/api/2.6/gtk/index.html (with-gtk-server ;; Here, we use the (gtk-window-new ...) function to create the main ;; window of our program. Notice that we are using GTK enumerations by ;; their Scheme name. (let ((win (gtk-window-new *GTK-WINDOW-TOPLEVEL*))) ;; We set the title on the window object. I've made the design decision ;; to stick with the GTK naming of functions instead of, for instance, ;; calling this function (gtk-window-title-set! ...). This is so there ;; are less discrepencies between the GTK documentation and the programs ;; you write. (gtk-window-set-title win "Bigloo GTK-server demo with STDIN") ;; We set the default window size on the window. GTK is pretty ;; inconsistent in terms of rows/columns/width/height. Here, it's the ;; width first and height second. (Screen resolutions are reported that ;; way, for instance 640x480.) (gtk-window-set-default-size win 400 200) ;; We set the window to appear in the center of the screen. Notice that ;; we are using GTK enumerations by their Scheme name, once again. (gtk-window-set-position win *GTK-WIN-POS-CENTER*) ;; We create a table, with two rows and one column. (Matrices are ;; usually indexed this way, for instance in Fortran or Matlab.) (let ((tbl (gtk-table-new 2 1 #t))) ;; We add the table layout to the window. (gtk-container-add win tbl) ;; We create two widgets that will be added to our table. A one-line ;; text-entry box is created, and a button with a label. This is a ;; demonstration of how events are handled and how information is ;; read from widgets. (let ((entry (gtk-entry-new)) (but (gtk-button-new-with-label "Click to Quit"))) ;; We attach our entry and button to the table. The sequence here ;; is left, right, top, bottom. As we have one column and two ;; rows, this attachment places the text entry above the button. (gtk-table-attach-defaults tbl entry 0 1 0 1) (gtk-table-attach-defaults tbl but 0 1 1 2) ;; We are now ready to show off our handywork. Up until now, the ;; window has been in its default visibility (invisible), so that ;; the user doesn't have to watch as these painstaking operations ;; take place. (gtk-widget-show-all win) ;; We are now ready to watch for the button click. In order to do ;; so, we grab the predicate corresponding to the "clicked" event ;; of the button. We will use this predicate, below, to determine ;; whether the event we are looking at is, in fact, the button ;; being clicked (as all registered events are reported, not just ;; this one). (let ((clicked? (gtk-server-connect but 'clicked))) ;; We drop into the event-loop here. Note that Bigloo now ;; includes OS thread support, which means we can be servicing ;; the event-loop in this thread and watching for other types ;; of events (such as incoming information from the network) in ;; another. Here, we specify that we would like to wait until ;; the user interacts with the GTK interface. If the interface ;; needs to respond to data coming in from another thread, you ;; would want to call (gtk-server-callback #f), instead. (let loop ((event (gtk-server-callback #t))) ;; Now, we see if the event we've just caught is our button ;; being clicked. (if (clicked? event) ;; If so, we'll just print the text in our text entry ;; widget and return. As we will then leave the ;; (with-gtk-server ...) macro, our window will ;; automatically close and cleanup will automatically ;; take place. (pp (gtk-entry-get-text entry)) ;; If our event was not the button being clicked, we ;; wait politely for the next event. (loop (gtk-server-callback #t))))))))))