Get a timer on the screen finally
This commit is contained in:
parent
088a03c2e7
commit
edeab2d094
@ -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;
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
107
ui.lisp
107
ui.lisp
@ -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))
|
||||||
@ -86,33 +89,47 @@
|
|||||||
:position `(,yi 1)))
|
:position `(,yi 1)))
|
||||||
(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 ()
|
|
||||||
(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*))))
|
|
||||||
(croatoan:draw-border scr)
|
|
||||||
|
|
||||||
(defvar windows '())
|
(defun run-ui (category)
|
||||||
(defvar current-index 0)
|
(croatoan:with-screen (scr :input-blocking nil :input-echoing nil :cursor-visible nil :enable-colors t :input-buffering nil :input-blocking nil)
|
||||||
(croatoan:event-case (scr event)
|
(setf (croatoan:background scr) (make-instance 'croatoan:complex-char :color-pair (cdr (assoc 'main *colors*))))
|
||||||
(#\b
|
(let* ((state 'TITLE)
|
||||||
(let ((hl (make-instance 'highlight-list
|
(redraws '(title-instance))
|
||||||
:scroll-i 0
|
(speedrun (make-speedrun category)))
|
||||||
:elements `(
|
(croatoan:event-case (scr event)
|
||||||
(("HELLO" . ,(/ 1 2)) ("" . ,(/ 1 2)))
|
(#\q (return-from croatoan:event-case))
|
||||||
(("THIS IS A TEST" . ,(/ 1 2)) (" OF WRAPPING TRUNCATION" . ,(/ 1 2)))
|
(#\space
|
||||||
)
|
(case state
|
||||||
:current-element-index current-index
|
('TITLE
|
||||||
:height 6
|
(start-speedrun speedrun)
|
||||||
:width 20)))
|
(setf state 'RUNNING))
|
||||||
(push (highlight-list-window hl '(10 20)) windows))
|
('RUNNING (next-split speedrun))))
|
||||||
(push (figlet-window *lispruns-logo* scr '(2 2)) windows)
|
(:resize (nil))
|
||||||
(inc current-index))
|
((nil)
|
||||||
(#\q (return-from croatoan:event-case))
|
(case state
|
||||||
(#\c (croatoan:clear scr))
|
('TITLE
|
||||||
(:resize nil)
|
(if (member 'title-instance redraws)
|
||||||
((nil)
|
(let* ((padding 3)
|
||||||
(mapcar #'croatoan:refresh (cons scr windows))
|
(width (+ (* 2 padding) (max-length *lispruns-logo*)))
|
||||||
(sleep (/ 1 60))))))
|
(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))
|
||||||
|
Loading…
Reference in New Issue
Block a user