How to Guides - McCLIM/McCLIM GitHub Wiki
This page contains how-to guides, AKA recipes for CLIM. To understand what content and style is suitable for this page, consult the Diataxis Framework.
Add (make-pane 'text-editor-pane) to :pane, :panes or :layouts in your define-application-frame expression. For example -
(clim:define-application-frame test () ()
(:layouts (default (clim:make-pane 'clim:text-editor-pane :height 200 :width 600))))In :pane or :panes, just specifying :text-editor suffices -
(clim:define-application-frame test () ()
(:pane :text-editor :height 200 :width 600))- If you use a REPL, you probably don’t want it to be blocked when you start your CLIM application. This can be achieved in one of the following ways -
(clim:find-application-frame 'my-frame) ;; or (bt:make-thread (lambda () (run-application-frame 'my-frame))
TODO - link to reference entries for find-application-frame and run-application-frame
- To update the application menu bar after evaluating a new command definition, use one of -
(setf (frame-command-table (find-application-frame 'my-frame)) (find-command-table 'my-table)) ;; or (McCLIM-specific) (let ((frame *application-frame*)) (climi::update-menu-bar (frame-menu-bar-pane frame) frame (frame-command-table frame))
Use (graft-height (find-graft)) and (graft-width (find-graft)) as values for :height and :width, e.g. -
(in-package :clim-user)
(define-application-frame test () ()
(:pane :application
:height (graft-height (find-graft))
:width (graft-width (find-graft))))
(run-frame-top-level (make-application-frame 'test))You can read more about grafts in the CLIM User Guide or the CLIM 2 Specification.
When accepting a type such as (integer 0 18), objects presented as integer are not sensitive even when the object falls in the mentioned range. This is because applicability is computed based on the presentation types first. To relax this constraint, we may use a translator. This has the benefit that it may be associated with a local command table, so it doesn’t affect other applications.
(defmacro define-multipass-translator
(ptype &optional (command-table 'global-command-table))
(let ((name (alexandria:symbolicate 'multipass- ptype)))
`(define-presentation-translator ,name
(,ptype nil ,command-table
:tester ((object context-type)
(presentation-typep object context-type)))
(object context-type)
(values object context-type))))
(define-multipass-translator integer my-command-table)Now, within my-command-table, objects that are typep to (integer 0 18) will be selectable.
Sometimes the drawing routine is complicated. In that case we don’t want to record all elements but rather redraw only the visible part of the screen, that is updated when scrolled. This snippet shows one possible way to do that.
(in-package #:clim-user)
(defclass my-fancy-record (climi::standard-displayed-output-record)
())
(defmethod replay-output-record ((record my-fancy-record) stream &optional region x y)
(declare (ignore x y))
(let ((ink (alexandria:random-elt (list +blue+ +red+ +yellow+ +green+ +cyan+ +grey+))))
(with-bounding-rectangle* (x1 y1 x2 y2) (pane-viewport-region stream)
(draw-rectangle* stream x1 y1 x2 y2 :ink +light-pink+)
(draw-rectangle* stream (+ x1 10) (+ y1 10 ) (- x2 10) (- y2 10) :ink ink))))
(defun fancy-display (frame stream)
(declare (ignore frame))
(stream-add-output-record stream
(make-instance 'my-fancy-record
:x1 0 :y1 0 :x2 800 :y2 600
:ink +black+
:clipping-region (make-rectangle* 0 0 800 600))))
(define-application-frame partialxr ()
()
(:pane :application :display-function 'fancy-display :display-time t))
(find-application-frame 'partialxr)- Print the object as a presentation, usually via
with-output-as-presentation. - Define a command for the action, usually via
define-<frame>-command. - Define a presentation-to-command-translator using
define-presentation-to-command-translator.
If you wish to perform an action when the pointer is not on any object, supply blank-area as the from-type argument.
See also the description of presentation-to-command translators, and the address book, puzzle, checkers, and German towns examples.