screwlisp proposes kittens

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.

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) does this (if you want it to).

Usual 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 :bitmaped 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)

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:

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>

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>

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.

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 as always please! Several days left to do the autumn lisp game jam! See you at the Sunday-morning-in-Europe peertube live.

screwlisp proposes kittens