Support for selection-animations and a menu-format

Now menu reselection/selection can be animated
easily! It'll look super-cool when I get input
working, I swearrr.
This commit is contained in:
Jaidyn Ann 2023-06-06 23:27:30 -05:00
parent ee8b68033d
commit e59c192888
2 changed files with 52 additions and 24 deletions

View File

@ -34,8 +34,8 @@
(defun main () (defun main ()
"A pathetic fascimile of a main loop. Look, I'm still tinkering!" "A pathetic fascimile of a main loop. Look, I'm still tinkering!"
(let ((matrix (make-screen-matrix)) (let ((matrix (make-screen-matrix))
(items '(("PLAY" ((selected . 30))) ("QUIT") ("ESCAPE") ("RUN AWAY")))) (items '(("PLAY" (SELECTION . 100) (SELECTED . T)) ("QUIT" (SELECTION . 100)) ("ESCAPE")
("RUN AWAY" (SELECTION . -100)))))
(cl-charms:with-curses () (cl-charms:with-curses ()
(cl-charms:enable-raw-input :interpret-control-characters 't) (cl-charms:enable-raw-input :interpret-control-characters 't)
(clear-screen) (clear-screen)

72
ui.lisp
View File

@ -19,7 +19,7 @@
(defpackage :flora-search-aurora.ui (defpackage :flora-search-aurora.ui
(:use :cl :flora-search-aurora.display) (:use :cl :flora-search-aurora.display)
(:export #:ui-loop #:render-menu-strip)) (:export #:ui-loop #:render-menu-strip :selection :selected))
(in-package :flora-search-aurora.ui) (in-package :flora-search-aurora.ui)
@ -33,7 +33,7 @@ with menus."
(let* ((matrix (make-screen-matrix)) (let* ((matrix (make-screen-matrix))
(new-menu (ui-update matrix menu-alist))) (new-menu (ui-update matrix menu-alist)))
(ui-draw matrix last-matrix) (ui-draw matrix last-matrix)
(sleep 1) (sleep .2)
(ui-loop matrix new-menu))) (ui-loop matrix new-menu)))
@ -46,8 +46,9 @@ with menus."
(defun ui-update (matrix menu-alist) (defun ui-update (matrix menu-alist)
"The update loop for menus. It processes all input, state, etc, and "The update loop for menus. It processes all input, state, etc, and
returns the new state of the menu." returns the new state of the menu."
(render-menu-strip matrix menu-alist 0 0) (let ((new-menu (progress-menu-items menu-alist)))
(cdr menu-alist)) (render-menu-strip matrix new-menu 0 0)
new-menu))
@ -67,7 +68,7 @@ returns the new state of the menu."
(defun render-menu-item (defun render-menu-item
(matrix text x y &key (width (+ (length text) 2)) (height 3) (selected 0)) (matrix text x y &key (width (+ (length text) 2)) (height 3) (selection 100))
"Render a menu-item that is, text surrounded by a box with an optional "Render a menu-item that is, text surrounded by a box with an optional
'selected' form. If selected is a non-zero number below 100, then that percent 'selected' form. If selected is a non-zero number below 100, then that percent
of the box will be displayed as selected/highlighted. This percent is from of the box will be displayed as selected/highlighted. This percent is from
@ -83,19 +84,19 @@ left-to-right, unless negative — in which case, right-to-left."
;; Render the weird “selected” top and bottom bars. A menu item might be ;; Render the weird “selected” top and bottom bars. A menu item might be
;; only partially-selected… ;; only partially-selected…
(if (and selected (if (and selection
(not (eq selected 0))) (not (eq selection 0)))
(let* ((bar-width (let* ((bar-width
(at-most width (ceiling (* width (* (abs selected) (at-most width (ceiling (* width (* (abs selection)
.01))))) .01)))))
(bar-start (if (> 0 selected) (- width bar-width) 0))) (bar-start (if (> 0 selection) (- width bar-width) 0)))
(dotimes (i bar-width) (dotimes (i bar-width)
(setf (aref matrix y (+ x bar-start i)) #\=) (setf (aref matrix y (+ x bar-start i)) #\=)
(setf (aref matrix (+ y (- height 1)) (+ x bar-start i)) #\=)))) (setf (aref matrix (+ y (- height 1)) (+ x bar-start i)) #\=))))
;; Render the horizontal “earmuffs” for helping the selected item stand out. ;; Render the horizontal “earmuffs” for helping the selected item stand out.
(when (and selected (when (and selection
(not (eq selected 0))) (not (eq selection 0)))
(dotimes (i (- height 2)) (dotimes (i (- height 2))
(setf (aref matrix (+ y i 1) x) #\|) (setf (aref matrix (+ y i 1) x) #\|)
(setf (aref matrix (+ y i 1) (+ x width -1)) #\|)) (setf (aref matrix (+ y i 1) (+ x width -1)) #\|))
@ -104,20 +105,21 @@ left-to-right, unless negative — in which case, right-to-left."
(defun render-menu-strip (matrix items x y &key (max-item-width 12) (height 3)) (defun render-menu-strip (matrix items x y &key (max-item-width 12) (height 3))
"Render several menu items to the matrix, starting at the given x/y coordinates, "Render several menu items to the matrix, starting at the given x/y coordinates,
maximum width for any given item, and the height of all items. If given a selected maximum width for any given item, and the height of all items.
item, than selected-% percent of it is displayed as highlighted/selected." The item list should be an alist of the following format:
((LABEL ((SELECTED . 'T)(SELECTION . 100))) (LABEL-2 (SELECTION . -20)) )"
(let ((x x)) (let ((x x))
(mapcar (mapcar
(lambda (item) (lambda (item)
(let* ((label (car item)) (let* ((label (car item))
(selected (or (assoc 'selected (cdr item)) (selection (or (cdr (assoc 'selection (cdr item)))
0)) 0))
(width (at-most max-item-width (width (at-most max-item-width
(+ (length label) 2)))) (+ (length label) 2))))
(render-menu-item matrix label x y (render-menu-item matrix label x y
:width width :width width
:height height :height height
:selected selected) :selection selection)
(setf x (+ x width 1)))) (setf x (+ x width 1))))
items)) items))
matrix) matrix)
@ -141,6 +143,26 @@ positional arguments nor the dimensions of the matrix."
matrix) matrix)
;;; ———————————————————————————————————
;;; Menu logic
;;; ———————————————————————————————————
(defun progress-menu-items (menu-alist)
"Given an associative list of menu-items, decrement or increment each
item's selected-percentage, so that they converge at the right percent.
That is, 0 for non-selected items and 100 for selected items."
(mapcar
(lambda (item)
(let ((selection (assoc 'selection (cdr item)))
(selectedp (assoc 'selected (cdr item))))
(if selection
(setf (cdr selection)
(gravitate-toward (if selectedp 100 0)
(cdr selection) 10)))))
menu-alist)
menu-alist)
;;; ——————————————————————————————————— ;;; ———————————————————————————————————
;;; Misc. utils ;;; Misc. utils
@ -173,13 +195,19 @@ maximum returns your more pitiful of moments."
num)) num))
(defun ± (num add) (defun gravitate-toward (goal num delta)
"Either add to a number, or subtract from it; whichever brings it closer to zero. "Either add to a number, or subtract from it; whichever brings it closer to zero.
In addition, the resultant value shall not pass zero." In addition, the resultant value shall not pass zero."
(cond (cond
((< num 0) ((< num goal)
(at-most 0 (+ num add))) (at-most goal (+ num delta)))
((> num 0) ((> num goal)
(at-minimum 0 (- num add))) (at-least goal (- num delta)))
('t ('t
num))) goal)))
;;"---{============= -------------------"
;; | Kill your mom | Give into despair
;; ---{============= -------------------