---
layout: ../Site.layout.js
---
# com-popup : a notion of active interaction - adding a clim:command that pops up text and pictures in a new window

EDIT: NB I used the word `event` before, but I am just search replacing `event` to be `radio` instead.

<img src="../better-rock.png">

One solution as to where to put a-special-thing-happened text is to give it its own window. `clim:accepting-values` (as implemented by [McCLIM](https://mcclim.common-lisp.dev/)) does this (if you want it to).

## Usual [NicCLIM](https://lispy-gopher-show.itch.io/nicclim) setup

```
• (setq inferior-lisp-program "ecl")
• (setq eepitch-buffer-name "*slime-repl ECL*")
• (slime)
(ql:Quickload :McCLIM)
(compile-file "~/Downloads/nicclim.lisp" :load t)
(in-package :nic)
(string '~/game)
(ensure-directories-exist *)
(uiop:chdir (string '~/game/))
(uiop:chdir (string '~/game/)) ;; Twice, for some reason.
```

## Where will the data come from?

I guess I will have a `(com-popup my-symbol)` which will display strings and `:bitmap`ed symbols in a new frame, and read a radio selection box option back into the map's 2nd cursor `cur2` as a first pass. I will add the new `com-popup` to my NicCLIM.

## Adding a new command to the map editor at all

```
(define-map-editor-command (com-popup :name t)
    ((sym 'symbol))
  (accepting-values (t :own-window t)
    (print "yes or no!")
    (print 42)
    (accept 'boolean)))
```

trying it

```
(enclose-map 'grass-clearing.map)
```

<img src="../com-popup.png">

Well, that looks like I would expect it to look. Note that `print` prints a line *before* its output (imagine what you would hope a read-eval-print-loop would do).

## `com-popup` I will put in NicCLIM (now have put in NicCLIM)

The gist is to

```
popup example
```

meaning this included example:

<img src="../com-popup-working.png">

add images for `grass` and `solid` from before:

```
(when
    (probe-file #p"~/GAME/IMGS/GRASS.PNG")
  (setf (get 'grass :bitmap) 'imgs/grass.png
	(get 'solid :bitmap) 'imgs/solid.png))
```

this example requires that you have some `IMGS/GRASS.PNG` and `IMGS/GRASS.PNG` (if you follow the articles, `"~/GAME/IMGS/GRASS.PNG"`) to see images.

An example of a working radio (i.e. call for user interaction, not meaning a gesture):

```
(defparameter *radio-eg* 'example)
(setf (get *radio-eg* :radio-description)
      '("Lots of
text!"
       asdf grass solid
	(1 2 (3 4) 5))

      (get *radio-eg* :radio-lisp-hook)
      (list (lambda () 'nothing)
	    (lambda () 'nothing-else))

      (get *radio-eg* :radio-choices)
      '(member
	("choice the first" (etc 1))
	("choice the second" (etc 2))
	("choice the third" (etc 3))))
```

brings up a new window with words, pictures and a radio button select in it. The symbol names an interactive choice the player has to make.

This is going to be my LispGameJam's interaction-method. I guess you can see the CLIM spec's / McCLIM's radio buttons, `with-room-for-graphics` and `accepting-values `:own-window t` if those were your main interest:
       
```
(define-map-editor-command (com-popup :name t)
    ((sym 'symbol))
  "sets cur2 to the cadr of a radio box selection for some
(sym 'symbol)
Preamble -> (get sym 'radio-description) renders a symbol's :bitmap or presents
Lisp side side effects -> Attempts to mapc funcall (get sym :radio-lisp-hook)
Radio choices -> (get sym :radio-choices)
Sets map-editor's cur2 to the cadr of the choice.
"
  (accepting-values (t :own-window t)
    (let ((radio-description
	    (get sym :radio-description))
	  (radio-lisp-hook
	    (get sym :radio-lisp-hook))
	  (radio-choices
	    (get sym :radio-choices))
	  choice)

      (loop :for lambda :in radio-lisp-hook :do
	(funcall lambda))
      
      (loop :for thing :in radio-description
	    :if (and (symbolp thing) (get thing :bitmap)) :do
	      (with-room-for-graphics ()
		  (maybe-render-bitmap thing))
	      (present `(image of ,thing))
	    :else :do
	      (present thing)
	    :finally
	       (terpri))

      (setq choice
	    (accept
	     radio-choices
	     :prompt (format nil "Choices:~%")
	     :view '(radio-box-view
		     :orientation :vertical
		     :width 512)))
      
      (with-slots
	    (cur2)
	  *application-frame*
	(setf cur2 (cadr choice)))
    
    (values))))
```

# The example currently in NicCLIM

```
(enclose-map 'grass-clearing.map) ; (from before)
;; alt-shift-+
;; example <enter>
```
1. <img src="../com-popup-choose-symbol.png">
1. <img src="../com-popup-chosen-symbol.png">
1. <img src="../com-popup-done.png">

# Conclusions

Stumbling across how easy it is to say pop-me-up-this-text,-image-and-these-radio-selections like this seems oddly momentous.

This seems like a normal general thing to want or expect to have, but thinking about it, what can you do, write and serve a local web page?

Let us run through all of making another radio symbol to see if it really still looks easy (aside, choosing to use the word radio here is probably a mistake).

```
;; I want a picture.
(setf (get 'rock :bitmap) 'imgs/rock.png)
;; Admittedly this looks pretty lisp-code-y.
(setf (get 'rockradio :radio-description)
      '("Some rocks:"
	rock rock
	#\newline rock "rocks." grass))
(setf (get 'rockradio :radio-choices)
      '(member
	("rocks are great" ("obviously"))
	("rock" (rock))))
(enclose-map 'grass-clearing.map)
;; alt-+
;; rock-radio <enter>
```

<img src="../rock-radio.png">

oh right, I had it add image descriptions automatically. But I do not need that, as if someone runs it without setting rock to display as a bitmap, rock will display as `ROCK`. The textual form is the intrinsic default and changing the symbol to display as a bitmap is a positive action. So I can remove that.

<img src="../better-rock.png">

NicCLIM's `M-+ rock-radio` looks like the unix desktop environment `M-F2 rock-radio`, but instead of *run-a-program* it is *display-some-text,-graphics,-and-radio-choices*. It seems like a powerful idiom to me. Actually, it is most similar to VI's `:` *ex-mode* which is on theme with my NicCLIM being an homage to VI.

This is the second-last operational piece of my lispgamejam, being *a notion of active interaction*.

# Fin.

Talk [on the Mastodon](https://gamerplus.org/@screwlisp/115504909459721353) as always please! Several days left to do [the autumn lisp game jam](https://itch.io/jam/autumn-lisp-game-jam-2025/topic/5489995/who-is-doing-common-lisp-and-how)! See you at [the Sunday-morning-in-Europe peertube live](https://gamerplus.org/@screwlisp/115479029081407459).