├── README.md ├── demo1 ├── demo2 ├── demo3 ├── demo4 ├── demo5 ├── demo6 ├── demo7 ├── demo8 ├── demo9 ├── demos ├── demostuff ├── hotnews.md ├── makesans ├── menu └── sanssbcl /README.md: -------------------------------------------------------------------------------- 1 | # Gtk-Demos 2 | Brief demos of using Gtk user interface from a high level language without any C or makefiles. Installation of sbcl is no longer required. See the hotnews file. It has details and explanation/description of the demos, and notes about this version. 3 | 4 | To run the demos: 5 | 6 | chmod +x demos 7 | 8 | ./demos 9 | -------------------------------------------------------------------------------- /demo1: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo1 () 4 | (window demo1 demos "Four Button Demo" 300 150) 5 | (box h outerbox1 demo1) 6 | (box v mainbox1 outerbox1) 7 | (box h buttons1 mainbox1) 8 | (box h numbox1 mainbox1) 9 | (box v leftbuttons1 buttons1) 10 | (box v rightbuttons1 buttons1) 11 | (text num1 "Zero" numbox1) 12 | (button b1nw "1" leftbuttons1 (xtext num1 "One")) 13 | (button b1sw "2" leftbuttons1 (xtext num1 "Two")) 14 | (button b1ne "3" rightbuttons1 (xtext num1 "Three")) 15 | (button b1se "4" rightbuttons1 (xtext num1 "Four")) 16 | (gtk_widget_show_all demo1)) 17 | -------------------------------------------------------------------------------- /demo2: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo2 () 4 | (window demo2 demos "Numerals Demo" 250 250) 5 | (box h outerbox2 demo2) 6 | (box v mainbox2 outerbox2) 7 | (box h numbox2 mainbox2) 8 | (button b21 (bnt 1) mainbox2 (xnum (bn 1))) 9 | (button b22 (bnt 2) mainbox2 (xnum (bn 2))) 10 | (button b23 (bnt 3) mainbox2 (xnum (bn 3))) 11 | (button b24 (bnt 4) mainbox2 (xnum (bn 4))) 12 | (button b25 (bnt 5) mainbox2 (xnum (bn 5))) 13 | (button numeralbutton2 "Numerals" mainbox2 (togglenumar)) 14 | (text num2 "zero" numbox2) 15 | (gtk_widget_show_all demo2)) 16 | 17 | (defparameter numar 'a) ; 'r = I II II IV V. 'a = 1 2 3 4 5. 18 | 19 | ; Button number (bn) and button number text (bnt): 20 | (defun bn (n) (nth (1- n) '(11 22 33 44 55))) 21 | (defun bnt (n) (format nil (if (eq numar 'a) "~d" "~@R") (bn n))) 22 | 23 | (defun togglenumar () 24 | (setq numar (if (eq numar 'a) 'r 'a)) 25 | (loop as button in (list b21 b22 b23 b24 b25) 26 | as n from 1 to 5 27 | do (xlabel button (bnt n)))) 28 | 29 | (defun xnum (n) (xtext num2 (format nil "~R" n))) 30 | -------------------------------------------------------------------------------- /demo3: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo3 () 4 | (window demo3 demos "Dates Demo" 300 200) 5 | (box h outerbox3 demo3) 6 | (box v mainbox3 outerbox3) 7 | (button date1 "1066" mainbox3 (relabel date1 1066)) 8 | (button date2 "1415" mainbox3 (relabel date2 1415)) 9 | (button date3 "1492" mainbox3 (relabel date3 1492)) 10 | (button date4 "1620" mainbox3 (relabel date4 1620)) 11 | (button date5 "1776" mainbox3 (relabel date5 1776)) 12 | (gtk_widget_show_all demo3)) 13 | 14 | (defun relabel (button number) 15 | (let* ((old (gtk_button_get_label button)) 16 | (isdigits (<= 0 (- (char-int (aref old 0)) (char-int #\0)) 9)) 17 | (new (format nil (if isdigits "~@R" "~d") number))) 18 | (xlabel button new))) 19 | -------------------------------------------------------------------------------- /demo4: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo4 () 4 | (window demo4 demos "Gtk Version" 300 150) 5 | (box v deminimisbox4 demo4) 6 | (text deminimismsg4 (format nil "~&Gtk version ~a~%" (gver)) deminimisbox4) 7 | (gtk_widget_show_all demo4)) 8 | -------------------------------------------------------------------------------- /demo5: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo5 () 4 | (window demo5 demos "de minimis" 300 150) 5 | (box v deminimisbox5 demo5) 6 | (text deminimismsg5 "This demo is not yet defined." deminimisbox5) 7 | (gtk_widget_show_all demo5)) 8 | -------------------------------------------------------------------------------- /demo6: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo6 () 4 | (window demo6 demos "de minimis" 300 150) 5 | (box v deminimisbox6 demo6) 6 | (text deminimismsg6 "This demo is not yet defined." deminimisbox6) 7 | (gtk_widget_show_all demo6)) 8 | -------------------------------------------------------------------------------- /demo7: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo7 () 4 | (window demo7 demos "de minimis" 300 150) 5 | (box v deminimisbox7 demo7) 6 | (text deminimismsg7 "This demo is not yet defined." deminimisbox7) 7 | (gtk_widget_show_all demo7)) 8 | -------------------------------------------------------------------------------- /demo8: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo8 () 4 | (window demo8 demos "de minimis" 300 150) 5 | (box v deminimisbox8 demo8) 6 | (text deminimismsg8 "This demo is not yet defined." deminimisbox8) 7 | (gtk_widget_show_all demo8)) 8 | -------------------------------------------------------------------------------- /demo9: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun demo9 () 4 | (window demo9 demos "de minimis" 300 150) 5 | (box v deminimisbox9 demo9) 6 | (text deminimismsg9 "This demo is not yet defined." deminimisbox9) 7 | (gtk_widget_show_all demo9)) 8 | -------------------------------------------------------------------------------- /demos: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./sanssbcl 2> >(sed '/^Backtrace/,$d;/^; /d;/^$/d') 3 | 4 | # This script, demos, uses sanssbcl to run the demos, with or without 5 | # sbcl installed. 6 | # 7 | # sanssbcl has to be present with this script and the demo scripts. 8 | # To make the demos executable do this: chmod +x demos 9 | # To invoke the demos, do this: ./demos 10 | # 11 | # If you want to make sanssbcl, it can be made on a Linux PC that 12 | # has sbcl installed by using the makesans script. To make 13 | # sanssbcl there, do this: chmod +x makesans 14 | # ./makesans 15 | # Then you can copy sanssbcl to another Linux PC, whether it has 16 | # sbcl installed or not. 17 | -------------------------------------------------------------------------------- /demostuff: -------------------------------------------------------------------------------- 1 | #| 2 | This file of "demostuff", used by the demo scripts, loads Gtk 3 | and defines gapp, window, box, button, text, xtext, and xlabel. 4 | gapp Establishes a Gtk app. Its arguments are the app name 5 | and the code to be executed in the app. 6 | window Establishes a window. Its arguments are the name of 7 | the window object, the name of the app the window is 8 | used in, the window title, and the default width and 9 | height of the window. 10 | box Establishes a box to place Gtk objects in. Its three 11 | arguments are, first, h or v, for whether the contents 12 | of the box are to be organized horizontally or 13 | vertically, second, what box to establish, and third, 14 | what object the box is to be placed in. 15 | button Establishes a button. Its arguments are, what button 16 | to establish, the initial label text on the button, 17 | the object the button is to be placed in, and the code 18 | to be executed when the button is pressed. 19 | mbutton Is like button, except the button label text will be 20 | left-aligned instead of centered. It's for use in a 21 | column of buttons, such as a menu, where it might look 22 | neater to not center the button labels. 23 | text Establishes a text display object, which Gtk calls a 24 | label. Its arguments are the name of the text object, 25 | the initial text, and what object to place the text 26 | object in. 27 | xtext Is a function to display some text in a text object. 28 | Its arguments are what text object to display the text 29 | in, and what text to display. 30 | xlabel Is a function to update a button label. Its arguments 31 | are the button and the new text. 32 | |# 33 | 34 | (load-shared-object "libgtk-3.so.0") 35 | 36 | ; Gtk relies on being able to divide by zero. To prevent it from 37 | ; being an error, the following line changes the floating point 38 | ; errors to just overflow and invalid, and not division-by-zero. 39 | ; This isn't needed in most programming languages, because most 40 | ; of them default to having it not be an error. 41 | (sb-int:set-floating-point-modes :traps '(:overflow :invalid)) 42 | 43 | 44 | ; Gtk function prototypes: each has a code, such as xx or vxs. The 45 | ; first letter of the code is the return value type, and the rest are 46 | ; the argument types: 47 | ; v = void 48 | ; x = void* 49 | ; i = int 50 | ; l = long 51 | ; f = float 52 | ; d = double 53 | ; s = c-string 54 | ; y = vxx function 55 | (loop as (gfunc xx) in 56 | '((gtk_application_window_new xx) 57 | (gtk_get_major_version i) 58 | (gtk_get_minor_version i) 59 | (gtk_get_micro_version i) 60 | (gtk_window_set_title vxs) 61 | (gtk_window_set_default_size vxii) 62 | (gtk_button_box_new xi) 63 | (gtk_size_group_new xi) 64 | (gtk_bin_get_child xx) 65 | (gtk_widget_set_halign vxi) 66 | (gtk_container_add vxx) 67 | (gtk_label_new xs) 68 | (gtk_label_set_text vxs) 69 | (gtk_button_set_label vxs) 70 | (gtk_button_get_label sx) 71 | (gtk_button_new_with_label xs) 72 | (gtk_widget_destroy xx) 73 | (gtk_application_new xsi) 74 | (g_application_run ixix) 75 | (g_object_unref vx) 76 | (gtk_widget_show_all vx) 77 | (g_signal_connect_data lxsyxxi)) 78 | as types = (loop as x across (string xx) 79 | collect (ecase (char-downcase x) 80 | (#\v 'void) 81 | (#\x '(* t)) 82 | (#\i 'int) 83 | (#\l 'long) 84 | (#\f 'float) 85 | (#\d 'double) 86 | (#\s 'c-string) 87 | (#\y '(function void (* t) (* t))))) 88 | as rv = (car types) 89 | as args = (loop as argname in '(a b c d e f g h i j k l m) 90 | as argtype in (cdr types) 91 | collect (list argname argtype)) 92 | do (eval `(define-alien-routine ,gfunc ,rv ,@args))) 93 | 94 | 95 | ; callbackname makes a callback name from an object name. 96 | ; The eval-when makes it usable during macro expansions. 97 | (eval-when (:compile-toplevel :load-toplevel :execute) 98 | (defun callbackname (object) 99 | (intern (concatenate 'string (symbol-name object) "-CALLBACK")))) 100 | 101 | ; window establishes a Gtk window object. 102 | ; The arguments are, what window object to establish, what 103 | ; application the window is used in, the window title, and 104 | ; the width and height of the window. 105 | (defmacro window (awin app title wid ht) 106 | (eval `(defparameter ,awin nil)) 107 | `(progn 108 | (setf ,awin (gtk_application_window_new ,app)) 109 | (gtk_window_set_title ,awin ,title) 110 | (gtk_window_set_default_size ,awin ,wid ,ht))) 111 | 112 | ; box establishes a box object. The arguments are, whether the box 113 | ; contents are organized horizontally or vertically (h or v), what 114 | ; box is to be established, and what object to place the box in. 115 | (defmacro box (hv abox placement) 116 | (eval `(defparameter ,abox nil)) 117 | (let ((horizvert (case hv (h 0) (v 1) (t (error 118 | "The first argument to box should be h or v, not ~a" hv))))) 119 | `(progn 120 | (setf ,abox (gtk_button_box_new ,horizvert)) 121 | (gtk_container_add ,placement ,abox)))) 122 | 123 | ; button establishes a Gtk button object. The arguments are, 124 | ; the name of the button object, the text shown on the button, 125 | ; what object to place the button in, and the action of the 126 | ; button, which can be any sequence of code. 127 | (defmacro button (abutton buttonlabel placement &body body) 128 | (eval `(defparameter ,abutton nil)) 129 | (let ((cb (callbackname abutton))) 130 | (eval `(sb-alien::define-alien-callback 131 | ,cb void ((a (* t)) (b (* t))) 132 | (declare (ignore a b)) 133 | ,@body)) 134 | `(progn 135 | (setf ,abutton (gtk_button_new_with_label ,buttonlabel)) 136 | (g_signal_connect_data ,abutton "clicked" ,cb nil nil 0) 137 | (gtk_container_add ,placement ,abutton)))) 138 | 139 | ; mbutton is like button, except that the button label text will be 140 | ; left aligned instead of centered, to make it neater in a column of 141 | ; buttons, such as for a menu. 142 | (defmacro mbutton (abutton buttonlabel placement &body body) 143 | `(progn 144 | (button ,abutton ,buttonlabel ,placement ,@body) 145 | (let ((thelabel (gtk_bin_get_child ,abutton))) 146 | (gtk_widget_set_halign thelabel 1)))) 147 | 148 | ; text establishes a Gtk "label" object which is actually a text 149 | ; display object. The arguments are, what text object to 150 | ; establish, the initial text to display, and what object to 151 | ; place this text object in. 152 | (defmacro text (atext text0 placement) 153 | (eval `(defparameter ,atext nil)) 154 | `(progn 155 | (setf ,atext (gtk_label_new ,text0)) 156 | (gtk_container_add ,placement ,atext))) 157 | 158 | ; xtext changes the text in a text object. 159 | (defun xtext (textobject newtext) 160 | (gtk_label_set_text textobject newtext)) 161 | 162 | ; xlabel changes the text label on a button. 163 | (defun xlabel (button newtext) 164 | (gtk_button_set_label button newtext)) 165 | 166 | ; gver gets the Gtk version. 167 | (defun gver () 168 | (format nil "~d.~d.~d" 169 | (gtk_get_major_version) 170 | (gtk_get_minor_version) 171 | (gtk_get_micro_version))) 172 | 173 | ; gapp establishes a Gtk application. The arguments are, 174 | ; the name of the application object, and the code to be 175 | ; executed by the application. 176 | (defmacro gapp (theapp &body body) 177 | (eval `(defparameter ,theapp nil)) 178 | (let ((cb (callbackname theapp))) 179 | (eval `(sb-alien::define-alien-callback 180 | ,cb void ((a (* t)) (b (* t))) 181 | (declare (ignore a b)) 182 | ,@body)) 183 | `(progn 184 | (setf ,theapp (gtk_application_new nil 0)) 185 | (g_signal_connect_data ,theapp "activate" ,cb nil nil 0)))) 186 | 187 | ; End of the demostuff file, which gets loaded by each demo script. 188 | -------------------------------------------------------------------------------- /hotnews.md: -------------------------------------------------------------------------------- 1 | See "Introduction" below. 2 | 3 | The most recent version of Gtk-Demos is an update of the January 17 version. The following changes have been made since January 17: 4 | 5 | 1. It's no longer necessary to install sbcl to run the scripts. They're invoked by a new script named demos. A file named sanssbcl has to be with the scripts. See "Info about sanssbcl" below. 6 | 7 | 2. The demo scripts have minor changes whose purpose is for them to be invoked differently than before. To invoke them now, run the demos script, with the command: ./demos 8 | 9 | 3. Some of the object names in the demos have been changed to make them unique, because all the demos now get loaded into one name space. 10 | 11 | 4. The menu was demo4, but is now named menu. All the demos have been combined into one Gtk application, which is established by the gapp in menu. 12 | 13 | 5. Six de minimis demos have been added, so you can easily make your own demos by editing de minimis demos. The de minimis demos are demo4 through demo9. You should also edit the menu to give your demos appropriate names. The button name doesn't matter, and only has to be unique. The label text is what will show as the button label. Also change the window title in your demo, to no longer indicate it's a de minimis demo. 14 | 15 | 6. The syntax of the Gtk function prototypes has been changed again, to make them shorter and neater. If you need more Gtk functions than are presently in the list, simply add them to the list, using the same syntax. 16 | 17 | 18 | The demos are here: https://github.com/mifpasoti/Gtk-Demos 19 | 20 | 21 | Info about sanssbcl 22 | 23 | With the sanssbcl file, the demo scripts can be run with or without sbcl being installed. If sbcl is installed, you can make sanssbcl by running the makesans script. The makesans script is short and easy to understand. And sanssbcl is easy to understand, by understanding makesans. To make sanssbcl, replacing any existing sanssbcl, use the command: ./makesans 24 | 25 | 26 | The January 17 version of the demos had the following changes from the original version: 27 | 28 | 1. Added a menu of the other demos. It was demo4 in the January 17 version, but is now named menu. 29 | 30 | 2. The syntax for the list of Gtk function prototypes in demostuff was changed, but has been changed again. 31 | 32 | 3. Loading the Gtk shared object file by name only, without specifying the path, but using SBCL's built-in path logic, to be compatible with more Linux distros. 33 | 34 | 35 | Introduction 36 | 37 | To run the demos, use the command: ./demos 38 | 39 | To make changes to the demos, use any text editor, then run the demos again. 40 | 41 | These demos demonstrate using Gtk directly from a higher level language. None of the demos have any low level code in them. There is no need for any makefiles, C compilers, or any other low level stuff. There is probably no need to install Gtk, because it's probably already used by your Linux. 42 | 43 | You don't need to install sbcl if you have the sanssbcl file. But, if you want to install sbcl, you can usually install it via the Linux distro. In the rare circumstance that a particular Linux distro doesn't have sbcl, you could install, via sbcl.org, either a binary version, or the sources to compile. 44 | 45 | To use a different high level language for these demos, it is of course necessary to edit them to change the language. But they aren't very long and that might not take very long. It's strongly advised to run the present demos first, and make some minor changes to them, to see the differences, to make sure to understand how they work, before starting to change them to a different language. 46 | -------------------------------------------------------------------------------- /makesans: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/sbcl --script 2 | 3 | ; This script, makesans, uses sbcl to make sanssbcl, which can then 4 | ; be copied to a Linux PC that doesn't have sbcl. 5 | 6 | (defun load-and-go () 7 | (load "demostuff") 8 | (load "menu") 9 | (loop as n from 1 to 9 do (load (format nil "demo~d" n))) 10 | (menu)) 11 | 12 | (save-lisp-and-die "sanssbcl" :executable t :toplevel #'load-and-go) 13 | -------------------------------------------------------------------------------- /menu: -------------------------------------------------------------------------------- 1 | ; Refer to the demostuff file for definitions and descriptions. 2 | 3 | (defun menu () 4 | (gapp demos 5 | (window win demos "Demos Menu" 300 350) 6 | (box h outerbox win) 7 | (box v mainbox outerbox) 8 | (mbutton dodemo1 "Four Button Demo" mainbox (demo1)) 9 | (mbutton dodemo2 "Numerals Demo" mainbox (demo2)) 10 | (mbutton dodemo3 "Dates Demo" mainbox (demo3)) 11 | (mbutton dodemo4 "Gtk Version" mainbox (demo4)) 12 | (mbutton dodemo5 "de minimis" mainbox (demo5)) 13 | (mbutton dodemo6 "de minimis" mainbox (demo6)) 14 | (mbutton dodemo7 "de minimis" mainbox (demo7)) 15 | (mbutton dodemo8 "de minimis" mainbox (demo8)) 16 | (mbutton dodemo9 "de minimis" mainbox (demo9)) 17 | (gtk_widget_show_all win)) 18 | (g_application_run demos 0 nil) 19 | (g_object_unref demos)) 20 | -------------------------------------------------------------------------------- /sanssbcl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mifpasoti/Gtk-Demos/0642a421a1e15bc429ddbd5a5ba440d183a6e2d5/sanssbcl --------------------------------------------------------------------------------