Home Directory / Gtk-Server

Return to the Gtk-Server-Wrapper home page

Gtk-Server Wrapper Examples Page


The Hello World Example

The first (real) Example - TextView and buttons

Second Example Textview, ScrolledWindow and Buttons

Example Three - Menu, MenuItems, MenuBar

Example Five - Custom Components



In this page I will comment some examples for the gtk-server wrapper package.

In the examples package you will find some other examples that I will not discuss here.

As you will see is really simple to create a GUI for your lisp application.



The Hello World Example



(defpackage :example-hello
  (:use :common-lisp :gtk-server)
  (:export :main))

(in-package :example-hello)

(defun main ()
  "The hello world example!!!"
  (with-gtk-server
      (with-components ((win (window 0))
                        (lb (label "Hello GTK-Server World!")))
        (gtk_container_add win lb)
        (gtk_window_set_title win "Hello World")
        (gtk_widget_show_all win)
        (with-event-loop my-event
          (win (return))))))
Hello World Example

Can we miss a hello world example? Here you see the "with-gtk-server" macro that starts the gtk-server. The "with-components" macro is in the form

(with-components (declarations*) forms*).

The declarations are in the form: (name (component-type parameters*))


The with-components form create for you the components (and the gtk api calls) and put in the scope the variables that represent the components.

There are many predefined components and you can also create yours. Please see "gui-generator.lisp".


Another important thing is the with-event-loop macro that wait for an event and check if that event was raised by then specified widget.

The syntax of with-event-loop is (with-event-loop event-var-name event-loop-case*) and the event-loop-case in the form:

(component-var forms*).

The forms are executed only if an event is raised by the component in component-var.



The first (real) Example - TextView and buttons


(defpackage :example-one
  (:use :common-lisp :gtk-server)
  (:export :main))

(in-package :example-one)

(defun main ()
  (with-gtk-server
      (with-components ((win (window 0))
                        (bt-ok (button "Ok"))
                        (bt-cancel (button "Cancel"))
                        (hbox (hbox 1 2))
                        (vbox (vbox 0 2))
                        (text (textview)))
        (gtk_window_set_title win "Window Title")
        (with-pack-in hbox
          ((:padding 0 :fill 1 :expand 1) bt-ok)
          ((:padding 0 :fill 1 :expand 1) bt-cancel))
        (with-pack-in vbox
          ((:padding 2 :fill 1 :expand 1) text)
          ((:padding 2 :fill 0 :expand 0) hbox))
        (gtk_text_view_set_text text "Hello from Me!")
        (gtk_container_add win vbox)
        (gtk_widget_show_all win)

        (with-event-loop my-event
          (win
           (return))
          (bt-ok
           (return))
          (bt-cancel
           (return))))))

Example One


Here you can see other component types and the (more important) with-pack-in macro whose syntax is

(with-pack-in container pack-forms*).


The pack-forms syntax is (:padding i-pad :fill i-fill :expand i-exp).

The pad represent how many pixel of padding should be taken.

The i-fill can be 0 or 1 for false or true.

The i-expand can be 0 or 1 for false or true.

Please see the gtk api for the meaning of these settings.



Second Example Textview, ScrolledWindow and Buttons


Return to Gtk-Server Wrapper Examples Page


(defpackage :example-two
  (:use :common-lisp :gtk-server)
  (:export :main))

(in-package :example-two)

(defun main ()
  (with-gtk-server
      (with-components ((win (window 0))
                        (bt-ok (button "Ok"))
                        (bt-cancel (button "Cancel"))
                        (bt-esci (button "Exit"))
                        (hbox (hbox 1 2))
                        (vboxt (vbox 1 2))
                        (vbox (vbox 0 2))
                        (scrollt1 (scrolledwindow))
                        (scrollt2 (scrolledwindow))
                        (text2 (textview))
                        (text (textview)))
        (gtk_container_add scrollt1 text)
        (gtk_container_add scrollt2 text2)
        (gtk_window_set_title win "Test window")
        (with-pack-in hbox
          ((:padding 0 :fill 1 :expand 1) bt-ok)
          ((:padding 0 :fill 1 :expand 1) bt-cancel)
          ((:padding 0 :fill 1 :expand 1) bt-esci))
        
        (with-pack-in vboxt
          ((:padding 2 :fill 1 :expand 1) scrollt1)
          ((:padding 2 :fill 1 :expand 1) scrollt2))

        (with-pack-in vbox
          ((:padding 2 :fill 1 :expand 1) vboxt)
          ((:padding 2 :fill 0 :expand 0) hbox))
        
        (gtk_text_view_set_text text "Hello from Me!")
        (gtk_text_view_set_text text2 "Another textview")
        (gtk_container_add win vbox)
        (gtk_widget_show_all win)

        (with-event-loop my-event
          (win
           (return))
          (bt-ok
           (format t "Ok button")
           (return))
          (bt-cancel
           (format t "Cancel button")
           (return))
          (bt-esci
           (format t "Exit button")
           (return))))))




Nothing new here.

This example is only to show that you can create arbitrary complex gui interfaces with gtk-server and gtk-server wrapper.



Example Three - Menu, MenuItems, MenuBar



Return to Gtk-Server Wrapper Examples Page

(defpackage :example-three
  (:use :common-lisp :gtk-server)
  (:export :main))

(in-package :example-three)

(defun main ()
  "Simple example. Window with menu"
  (with-gtk-server
    (with-components ((win (window 0))
                      (text (textview))
                      (scroll (scrolledwindow))
                      (menubar (menubar))
                      (vbox (vbox 0 0))
                      ;; File Menu
                      (mnu-file (menu))
                      (itm-file (menuitem-l "File"))
                      (itm-open (menuitem-l "Open"))
                      (itm-save (menuitem-l "Save"))
                      (itm-exit (menuitem-l "Exit"))
                      ;; Edit menu
                      (mnu-edit (menu))
                      (itm-edit (menuitem-l "Edit"))
                      (itm-copy (menuitem-l "Copy"))
                      (itm-paste (menuitem-l "Paste"))
                      (itm-cut (menuitem-l "Cut")))

      ;; Create menu
      (append-in-menu mnu-file itm-open itm-save itm-exit)
      (gtk_menu_item_set_submenu itm-file mnu-file)
      (append-in-menu mnu-edit itm-copy itm-paste itm-cut)
      (gtk_menu_item_set_submenu itm-edit mnu-edit)
      (append-in-menu menubar itm-file itm-edit)

      ;; Insert widgets in window
      (gtk_container_add scroll text)
      (with-pack-in vbox
        ((:padding 0 :expand 0 :fill 1) menubar)
        ((:padding 2 :expand 1 :fill 1) scroll))
      (gtk_window_set_title win "Menu Test")
      (gtk_container_add win vbox)

      ;; Show All
      (gtk_widget_show_all win)

      ;; Event loop
      (with-event-loop my-event
        (win
         (return))
        (itm-exit
         (return))))))




He you can see an example of a window with a menubar.

You can create the menubar also using custom components that I fill discuss in the next paragraph.



Example Five - Custom Components



Return to Gtk-Server Wrapper Examples Page

 

(defpackage :example-five
  (:use :common-lisp :gtk-server)
  (:export :main))
(in-package :example-five)

(defclass input-entry (gui-component)
  ((text-entry)))

(defcomponent input-entry (label-desc)
  (let ((my-entry (make-instance 'input-entry)))
    (with-components
        ((box (hbox 0 2))
         (label (label label-desc))
         (entry (entry)))
      (with-pack-in box
        ((:padding 2 :fill 0 :expand 0) label)
        ((:padding 2 :fill 1 :expand 1) entry))
      (setf (slot-value my-entry 'text-entry) entry)
      (setf (widget my-entry) box)
      my-entry)))

(defgeneric get-text (self))
(defmethod get-text ((self input-entry))
  "Get text of an input entry"
  (gtk_entry_get_text (slot-value self 'text-entry)))

(defun main ()
  "Simple custom component example"
  (with-gtk-server
    (with-components
        ((win (window 0))
         (box (vbox 1 2))
         (ie-name (input-entry "Name:"))
         (ie-surname (input-entry "Surname:"))
         (bt-ok (button "Ok")))

      ;; Pack and show
      (with-pack-in box
        ((:padding 2 :fill 1 :expand 1) ie-surname)
        ((:padding 2 :fill 1 :expand 1) ie-name)
        ((:padding 2 :fill 0 :expand 0) bt-ok))
      (gtk_window_set_title win "Custom Component Example")
      (gtk_container_add win box)
      (gtk_widget_show_all win)

      ;; Events
      (with-event-loop my-event
        (win
         (return))
        (bt-ok
         (let ((nome (get-text ie-name))
               (cognome (get-text ie-surname)))
           (cond
             ((= 0 (length nome))
              (show-error-dialog win "Insert name!"))
             ((= 0 (length cognome))
              (show-error-dialog win "Insert surname!"))
             (t
              (show-info-dialog win (format nil "Welcome ~a ~a" nome cognome))
              (return)))))))))




Here you see an important feature of this wrapper: the ability of creating custom components.

The defcomponent macro has the syntax of the defun but register in the gtk-server wrapper a new component.

From this forms you must return an instance of the gtk-server:component class and fill the widget slot with the widget that represent the component.


If you respect this protocol you can create how many custom components you want and use them with the normal with-component macro.