Get a timer on the screen finally

This commit is contained in:
Logan Hunt 2022-05-29 21:31:48 -07:00
parent 088a03c2e7
commit edeab2d094
Signed by untrusted user who does not match committer: simponic
GPG Key ID: 52B3774857EB24B1
6 changed files with 77 additions and 52 deletions

View File

@ -15,5 +15,3 @@
(sxql:where (:= :category category)) (sxql:where (:= :category category))
;; Assumption that split categories are entered in the correct order by id ;; Assumption that split categories are entered in the correct order by id
(sxql:order-by :id))) (sxql:order-by :id)))
;; select *, sum(julianday(end_time)-julianday(start_time))*24*60*60 as total_time from run_split group by run_id order by total_time;

View File

@ -15,3 +15,9 @@
(mito:select-dao 'run-split (mito:select-dao 'run-split
(sxql:order-by :category_split_id) (sxql:order-by :category_split_id)
(sxql:where (:= :run run)))) (sxql:where (:= :run run))))
;; Returns stuff like PB, best of each split, etc.
(defun run-statistics (category)
`((asdf . 1)))
;; select *, sum(julianday(end_time)-julianday(start_time))*24*60*60 as total_time from run_split group by run_id order by total_time;

View File

@ -11,9 +11,10 @@
:arg-parser #'identity)) :arg-parser #'identity))
(defun main () (defun main ()
(let ((options (opts:get-opts))) (let ((options (opts:get-opts))
(category (car (mito:select-dao 'category))))
(when-option (options :import) (when-option (options :import)
(import-config (getf options :import)))) (import-config (getf options :import)))
(run-ui)) (run-ui category)))
(main) (main)

View File

@ -52,8 +52,8 @@
(speedrun-start-timestamp speedrun) (get-internal-real-time) (speedrun-start-timestamp speedrun) (get-internal-real-time)
(run-split-start-time (current-split speedrun)) (local-time:now))) (run-split-start-time (current-split speedrun)) (local-time:now)))
;; Set the state of the speedrun to be stopped if there are no more ;; Set the state of the speedrun to be stopped if there are no more splits.
;; splits, or set the current split to the next one ;; Or, set the current split to the next one in the list.
(defun next-split (speedrun) (defun next-split (speedrun)
(let ((now (local-time:now))) (let ((now (local-time:now)))
(setf (run-split-end-time (current-split speedrun)) now) (setf (run-split-end-time (current-split speedrun)) now)

95
ui.lisp
View File

@ -8,7 +8,7 @@
(defparameter *colors* (defparameter *colors*
'((main . (:green :black)) '((main . (:green :black))
(figlet . (:black :white)) (timer-box . (:red :black))
(selected-highlight . (:blue :black)) (selected-highlight . (:blue :black))
(unselected-highlight . (:white :black)))) (unselected-highlight . (:white :black))))
@ -18,6 +18,7 @@
(sh (croatoan:height screen))) (sh (croatoan:height screen)))
(list (round (- (/ sh 2) (/ height 2))) (round (- (/ sw 2) (/ width 2)))))) (list (round (- (/ sh 2) (/ height 2))) (round (- (/ sw 2) (/ width 2))))))
;; Write a list of horizontal slices to the screen scr at position pos
(defun write-horizontal-slice-list (scr pos slices) (defun write-horizontal-slice-list (scr pos slices)
(let ((yi (car pos))) (let ((yi (car pos)))
(mapcar (lambda (s) (mapcar (lambda (s)
@ -25,19 +26,20 @@
(inc yi)) (inc yi))
slices))) slices)))
;; Draws a list of strings horizontally in a window with padding and an optional border ;; Creates a window with the total time and statistics
(defun figlet-window (title-slices scr pos &key (padding 2) (border nil)) (defun timer-window (speedrun pos width height)
(let* ((width (+ (reduce (lambda (a x) (max a x)) (mapcar #'length title-slices)) (* 2 padding))) (let* ((timerglet (lispglet (format-time (make-time-alist (speedrun-elapsed speedrun)))))
(height (+ (length *lispruns-logo*) (* 2 padding))) (timer-box (make-instance 'croatoan:window
(title-box (make-instance 'croatoan:window :border t
:border border :position pos
:width width :width width
:height height :height height)))
:position pos))) (setf (croatoan:color-pair timer-box)
(setf (croatoan:background title-box) (make-instance 'croatoan:complex-char :color-pair (cdr (assoc 'figlet *colors*)))) (cdr (assoc 'timer-box *colors*)))
(write-horizontal-slice-list title-box `(,padding ,padding) title-slices) (write-horizontal-slice-list timer-box '(1 1) timerglet)
title-box)) timer-box))
;; Class to hold state for a list where one element is highlighted/selected
(defclass highlight-list () (defclass highlight-list ()
((scroll-i ((scroll-i
:initarg :scroll-i :initarg :scroll-i
@ -55,11 +57,12 @@
:initarg :width :initarg :width
:accessor highlight-list-width))) :accessor highlight-list-width)))
;; Create the actual window to render a highlight list hl at position pos
(defun highlight-list-window (hl pos) (defun highlight-list-window (hl pos)
(let* ((width (- (highlight-list-width hl) 2)) (let* ((width (- (highlight-list-width hl) 2)) ;; Magic number 2's are for the border on both sides
(height (- (highlight-list-height hl) 2)) (height (- (highlight-list-height hl) 2))
(elements (highlight-list-elements hl)) (elements (highlight-list-elements hl))
(current-element-index (highlight-list-current-element-index hl)) (current-element-index (mod (highlight-list-current-element-index hl) (length elements)))
(elements-to-draw-subseq (if (>= height (length elements)) (elements-to-draw-subseq (if (>= height (length elements))
(list 0 (length elements)) (list 0 (length elements))
(cond (cond
@ -71,7 +74,7 @@
(list (- current-element-index (floor dy)) (1+ (+ current-element-index (ceiling dy))))))))) (list (- current-element-index (floor dy)) (1+ (+ current-element-index (ceiling dy)))))))))
(highlight-menu (make-instance 'croatoan:window (highlight-menu (make-instance 'croatoan:window
:border t :border t
:width (+ 2 width) :width (+ 2 width) ;; Another magic 2
:height (+ 2 height) :height (+ 2 height)
:position pos))) :position pos)))
(let ((yi 0)) (let ((yi 0))
@ -87,32 +90,46 @@
(subseq elements (car elements-to-draw-subseq) (cadr elements-to-draw-subseq)))) (subseq elements (car elements-to-draw-subseq) (cadr elements-to-draw-subseq))))
highlight-menu)) highlight-menu))
(defun run-ui () (defun run-ui (category)
(croatoan:with-screen (scr :input-blocking nil :input-echoing nil :cursor-visible nil :enable-colors t :input-buffering nil :input-blocking nil) (croatoan:with-screen (scr :input-blocking nil :input-echoing nil :cursor-visible nil :enable-colors t :input-buffering nil :input-blocking nil)
(croatoan:clear scr)
(croatoan:refresh scr)
(setf (croatoan:background scr) (make-instance 'croatoan:complex-char :color-pair (cdr (assoc 'main *colors*)))) (setf (croatoan:background scr) (make-instance 'croatoan:complex-char :color-pair (cdr (assoc 'main *colors*))))
(croatoan:draw-border scr) (let* ((state 'TITLE)
(redraws '(title-instance))
(defvar windows '()) (speedrun (make-speedrun category)))
(defvar current-index 0)
(croatoan:event-case (scr event) (croatoan:event-case (scr event)
(#\b
(let ((hl (make-instance 'highlight-list
:scroll-i 0
:elements `(
(("HELLO" . ,(/ 1 2)) ("" . ,(/ 1 2)))
(("THIS IS A TEST" . ,(/ 1 2)) (" OF WRAPPING TRUNCATION" . ,(/ 1 2)))
)
:current-element-index current-index
:height 6
:width 20)))
(push (highlight-list-window hl '(10 20)) windows))
(push (figlet-window *lispruns-logo* scr '(2 2)) windows)
(inc current-index))
(#\q (return-from croatoan:event-case)) (#\q (return-from croatoan:event-case))
(#\c (croatoan:clear scr)) (#\space
(:resize nil) (case state
('TITLE
(start-speedrun speedrun)
(setf state 'RUNNING))
('RUNNING (next-split speedrun))))
(:resize (nil))
((nil) ((nil)
(mapcar #'croatoan:refresh (cons scr windows)) (case state
(sleep (/ 1 60)))))) ('TITLE
(if (member 'title-instance redraws)
(let* ((padding 3)
(width (+ (* 2 padding) (max-length *lispruns-logo*)))
(height (+ (* 2 padding) (length *lispruns-logo*)))
(logo-centered (center-box scr width height))
(logo-box (make-instance 'croatoan:window :border t :width width :height height :position logo-centered)))
(write-horizontal-slice-list logo-box `(,padding ,padding) *lispruns-logo*)
(croatoan:refresh logo-box))))
('RUNNING
(update-time speedrun)
(let ((timer-instance (timer-window speedrun '(10 10) 70 10)))
(croatoan:refresh timer-instance))))
(setf redraws '())
(sleep (/ 1 30)))))))
;; (setq hl (make-instance 'highlight-list
;; :scroll-i 0
;; :elements `(
;; (("HELLO" . ,(/ 1 2)) ("" . ,(/ 1 2)))
;; (("THIS IS A TEST" . ,(/ 1 2)) (" OF WRAPPING TRUNCATION" . ,(/ 1 2)))
;; )
;; :current-element-index current-index
;; :height 6
;; :width 20))

View File

@ -6,3 +6,6 @@
`(let ((it (getf ,options ,opt))) `(let ((it (getf ,options ,opt)))
(when it (when it
,@body))) ,@body)))
(defun max-length (lists)
(reduce (lambda (a x) (max a x)) (mapcar #'length lists)))