;;;; ;;;; Naledi ya Africa ("Star of Africa") is an ncurses-based survival game ;;;; set in Africa. ;;;; ;;;; This file holds extension functions for croatoan. ;;;; ;;;; (c) 2018 Daniel Vedder, MIT license ;;;; (in-package :naledi-ya-africa) (defun query-user (scr msg &key (cls NIL) (val-width 30) (default "")) "Display a popup asking the user to enter a value, then return that value" ;; I found croatoan's field/form too complicated to use (:form-default-keymap ;; doesn't seem to work), so I hacked up my own alternative ;; TODO display additional lines of text (when cls (croatoan:clear scr) (croatoan:refresh scr)) (let* ((x0 (- (halve (croatoan:.width scr)) (+ 5 (halve val-width)))) (y0 (- (halve (croatoan:.height scr)) 3)) (inputwin (make-instance 'croatoan:window :position (list y0 x0) :width (+ 10 val-width) :height 6))) (setf (croatoan:.visible inputwin) t) (croatoan:box inputwin) (croatoan:add-string inputwin msg :y 2 :x 4) (croatoan:add-string inputwin ">>> " :y 3 :x 4) (croatoan:add-string inputwin (to-string default) :y 3 :x 8 :color-pair '(:blue :black)) (croatoan:move inputwin 3 (+ 8 (length (to-string default)))) (croatoan:refresh inputwin) (croatoan:event-case (scr event) ((nil) nil) (:backspace (when (< 8 (croatoan:.cursor-position-x inputwin)) (croatoan:move inputwin 0 -1 :relative t) (croatoan:add-char inputwin #\space) (croatoan:move inputwin 0 -1 :relative t) (croatoan:refresh inputwin))) (#\newline (return-from croatoan:event-case (trim-whitespace (croatoan:extract-string inputwin :y 3 :x 8 :n val-width)))) (otherwise (when (and (characterp event) (> (+ 8 val-width) (croatoan:.cursor-position-x inputwin))) (croatoan:add-char inputwin event :color-pair '(:blue :black)) (croatoan:refresh inputwin)))))) (defun short-dialog (scr msg options &optional (cls NIL)) "Present the user with one line of text and a few options" (when cls (croatoan:clear scr) (croatoan:refresh scr)) (let ((dw (make-instance 'croatoan:dialog-window :center t :border t :width (max 20 (+ 4 (length msg))) :max-item-length (max 4 (halve (length msg))) :input-blocking t :layout (list 1 (length options)) :message-height 1 :message-text msg :items options))) (croatoan:draw-menu dw) (croatoan:event-case (scr event) ((nil) nil) ((:left :right) (croatoan:update-menu dw event) (croatoan:draw-menu dw)) (#\newline (return-from croatoan:event-case (croatoan:.current-item-number dw)))))) (defun user-confirm-p (scr msg &optional (cls NIL)) "Ask the user to confirm (Yes/No) a message." (zerop (short-dialog scr msg '(" Yes" " No") cls))) (defun inform-user (scr msg &optional (cls NIL)) "Display an informational message to the user" (short-dialog scr msg '(" OK ") cls))