nodgui FAQ
Table of Contents
- FAQ
-
- Where is the documentation?
- Where can I found documentation about a widget?
- Where can i find documentation for non standard widget?
- How can I access the root window?
- How can i set the title and the class of the root window?
- I have a bunch of widgets placed in a grid and I want those to scale themselves when the window is resized, there is a way to accomplish this?
- I have two listbox placed on a window, when I select an entry of one of them the selected item in the others is automatically deselected, i want to keep all the selection: how can I do that?
- How can I specify layout for when creating a widget via
initialize-instance
? - How to quit a nodgui program?
- What are the differences between nodgui and LTK?
- Where can i find more code examples?
- Can I contribute to this project?
- Why is tcclib a dependency?
- Menu on Mac OS X shows a element, named
wish
, that I am not able to remove! Can I Fix this issue?
-
FAQ
Where is the documentation?
Nodgui shows a weak heritage from LTK, at this point the documentation for the original library can be confusing for the newcomer; i suggest, instead, these resources:
- a fellow lisper wrote an impressive set of examples for Nodgui.
- the demo code can be used both as teaching material or as boiler plate for your code.
- also check out the vindarel experiments
The rest of the documentation is this page and the rare docstrings at the moment.
If you want to help please open a pull request.
Where can I found documentation about a widget?
It is actually very simple: let's suppose you want to use a spinbox widget in your program and you have no idea how to do, the idea to solve this problem is like:
open the file
src/spinbox.lisp
an look at the top of this file:(defargs spinbox () cursor state style takefocus validate validatecommand xscrollcommand command format from increment to values wrap)
the symbols listed are all the options for the spinbox TK command (in TCL language everything is a command) or the configuration variable that you can pass as initarg for
(make instance 'spinbox ...)
and, sometimes, changed after object instancing viaconfigure
(see the general documentation)for the meaning of this symbols refers to the original TK documentation
As a general rule choose the link to the command with its name prefixed with "ttk::" (if exists).
In our example point to:
https://www.tcl.tk/man/tcl8.6/TkCmd/ttk_spinbox.htm
and not
https://www.tcl.tk/man/tcl8.6/TkCmd/spinbox.htm
You can easily understand what all the options above are for.
Where can i find documentation for non standard widget?
See: Widget pack
How can I access the root window?
The root window is returned by the function: nodgui:root-toplevel
.
How can i set the title and the class of the root window?
with-nodgui
accepts keywords :title
and :class
to change the name and the class of the window respectively.
I have a bunch of widgets placed in a grid and I want those to scale themselves when the window is resized, there is a way to accomplish this?
Sure! Use grid-(column|row)-configure
.
(grid-columnconfigure (root-toplevel) :all :weight 1) (grid-rowconfigure (root-toplevel) :all :weight 1)
You can replace :all
with a row or column indices to apply this behaviour only to a subset of the columns or rows.
I have two listbox placed on a window, when I select an entry of one of them the selected item in the others is automatically deselected, i want to keep all the selection: how can I do that?
Use nodgui:listbox-export-selection
(nodgui:with-nodgui () (let* ((listbox-1 (make-instance 'nodgui:listbox)) (listbox-2 (make-instance 'nodgui:listbox)) (entry (make-instance 'nodgui:entry))) (nodgui:grid listbox-1 0 0) (nodgui:grid listbox-2 0 1) (nodgui:grid entry 1 0 :columnspan 2 :pady 2 :sticky :ew) (setf (nodgui:text entry) "baz") ;; note the call to listbox-export-selection for each listbox (nodgui:listbox-export-selection listbox-1 nil) (nodgui:listbox-export-selection listbox-2 nil) (nodgui:listbox-insert listbox-1 0 "foo") (nodgui:listbox-insert listbox-2 0 "bar")))
If you try to run the same code without the two nodgui:listbox-export-selection
calls the selected text (even on
the entry) will remove all the other selections.
How can I specify layout for when creating a widget via initialize-instance
?
The method initialize-instance
specialized on widget
, a common ancestor of many GUI elements available (button
, frame
, etc) accepts the keyword argument: grid
, pack
and place
.
Pass a list of arguments, compatible with the corresponding layout function to this keyword argument to configure the layout for the widget you are creating, for example:
(make-instance 'nodgui:frame :grid '(0 ; first row 1 ; second column :sticky :news :padx 10))
see for reference: https://codeberg.org/cage/nodgui/issues/9#issuecomment-1549116
How to quit a nodgui program?
Use exit-nodgui
(with-nodgui () (let ((button (make-instance 'button :text "quit"))) (setf (command button) (lambda () (format t "quitting~%") (exit-nodgui))) (pack button)))
What are the differences between nodgui and LTK?
The two libraries diverged now, the API is no more compatible with LTK.
The major differences are:
A reader macro for events i.e.
#$<Alt-q>$
instead of"<Alt-q>"
(a string), the macro will parse and check for trivial errors in the event definition syntax at compile time.(named-readtables:in-readtable nodgui.syntax:nodgui-syntax) ; do not forget that! [...] (bind (root-toplevel) #$<Alt-q>$ (lambda (event) ...
Please note that a string is still accepted as event specifier.
A DSL for TCL code that allow to mix TCL code and lisp expression, check for example the following code to create a bitmap:
(named-readtables:in-readtable nodgui.syntax:nodgui-syntax) ; do not forget that! [...] (tclize `([list ,(loop for r from 0 below h collect (tclize `([list ,(loop ...
The
tclize
macro will transforms the backquoted forms in TCL code, the unquoted forms will be evaluated before the translation occurs;- The function
postscript
returns a postscript file as string instead of writing a file on disk; - Support for images in GIF, PNG, TGA, JPEG and raw RGB format, limited manipulation for the latest four formats is provided (scaling and rotation);
- Compatible only with TK 8.6;
- A general refactoring;
- Integrated with cl-colors library (can use X11 color names or RGB struct, see Colors Name);
- Many more widgets, some not even available with TK, included canvas with hardware accelerated rendering;
- Some bugs fixed (and more added of course :-) ).
Where can i find more code examples?
Check the file src/demo-tests.lisp
Can I contribute to this project?
Yes, of course! Please open an issue or a pull request on the web repository, if you do not feel comfortable with coding, documentation improvements are very welcome too! :)
Also i would appreciate testing if the library works on different environment than mine (Debian GNU/Linux with SBCL).
Why is tcclib a dependency?
I wrapped a few simple functions that can be used as a general utility.
match-path, comes for free as it is a standard TCL command
(defun match-path (text &key (root-directory nil) (join nil) (path nil) (type nil))) "Returns a list of filesystem paths that match template in `text' (see: glob(7) for template's syntax) starting from `start-directory' (default: the current directory)"
(defun csv-stream (stream &key (separator ",") (quote-char "\"")) "Needs tcllib. Returns a closure that, when invoked with no argument, returns a list corresponding to a row of the table represented by the CSV data (or nil after the last row has been parsed), the data are split using `separator' and each field cn be quoted using `quote-char'."
(defun make-zip-file (zip-filepath glob-paths) "Creates a zip file in `zip-filepaths' adding a list of paths contained in `glob-paths'. Each element of `glob-paths' uses globs e.g '(\"*.zip\" \"foo.*\")"
(defun zip-file-p (zip-filepath) "Returns non nil if the file pointed from `zip-file-path` is a zip file: note that the file must exists and readable). Each element of `glob-paths' uses globs e.g '(\"*.zip\" \"foo.*\")"
(defun zip-file-list-contents (zip-filepath) "Returns a list of strings, each item of the list is a file contained in zipfile pointed by `zip-filepath'"
(defun unzip-file (zip-filepath destination-path) "Decompress a zip file in `zip-filepaths' on `destination-path'."
(defun cpu-info () "Returns an alist of CPU information field (on GNU/Linux) are: - :memory - :vendor - :family - :model - :brand - :steppin - :speed - :features - :cpus"
(defun mac-addresses () "Returns a list of MAC addresses for this machines, the primary is listed first"
(defun ip-addresses () "Returns a list of IP addresses for this machines."
(defun convert-units (from to) "Convert quantity to differents measure units e.g.: (convert-units \"1 mm\" \"meter\") Please see: https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/units/units.md For more documentation"
(defun reduce-unit (unit-string) "Reduce `unit-string' to their atomic components e.g.: (reduce-units \"Joule\"); => \"1000.0 gram meter meter / second second\" Please see: https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/units/units.md For more documentation."
(defun new-unit (unit equivalent-to) " Create a nes unit equivalent to `equivalent-to' e.g. (with-nodgui () (new-unit \"furlong\" \"220 yards\") (convert-units \"10 furlong\" \"yards\")) ; => 2200.0 Please see: https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/units/units.md For more documentation."
(defun file-writable-p (path) "Return true if file in `path' is writable."
(defun replace-in-file (path start size data) "Remove `size' octets from file pointed by `path' starting at position: `start', replacing with `data', return `t' on success."
Menu on Mac OS X shows a element, named wish
, that I am not able to remove! Can I Fix this issue?
Menu on Mac OS X are a bit tricky but, fortunately, an user found a way to get an acceptable menu on this platform too, please see: this message.