mirror of
https://github.com/unclebob/more-speech.git
synced 2024-09-30 10:30:56 +00:00
Decoupling of headers from text-window and text-frame is complete. Now the text-window should be generic and usable for any window displaying text with scrollbars.
This commit is contained in:
parent
1e66acb7ed
commit
20ad98139c
@ -12,6 +12,11 @@
|
|||||||
20)
|
20)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(defrecord mock-controls []
|
||||||
|
text-window-controls
|
||||||
|
(get-element-height [_c _state]
|
||||||
|
2))
|
||||||
|
|
||||||
(defrecord mock-widget []
|
(defrecord mock-widget []
|
||||||
widget)
|
widget)
|
||||||
|
|
||||||
@ -21,11 +26,11 @@
|
|||||||
(describe "article frame"
|
(describe "article frame"
|
||||||
(with state {:application
|
(with state {:application
|
||||||
{:graphics (->mock-graphics)}})
|
{:graphics (->mock-graphics)}})
|
||||||
(with frame {:x 0 :y 0 :w 500 :h 500})
|
(with frame {:x 0 :y 0 :w 500 :h 500 :controls (->mock-controls)})
|
||||||
(context "setup"
|
(context "setup"
|
||||||
(it "determines number of article headers fit in the frame"
|
(it "determines number of article headers fit in the frame"
|
||||||
(let [frame (setup-text-frame @state @frame)]
|
(let [frame (setup-text-frame @state @frame)]
|
||||||
(should= 10 (:n-elements frame)))
|
(should= 250 (:n-elements frame)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,14 +53,14 @@
|
|||||||
(draw-widget application state)
|
(draw-widget application state)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defn mouse-wheel [state clicks]
|
(defn mouse-wheel [state delta]
|
||||||
(let [application (:application state)
|
(let [application (:application state)
|
||||||
x (q/mouse-x)
|
x (q/mouse-x)
|
||||||
y (q/mouse-y)
|
y (q/mouse-y)
|
||||||
widget (w/find-deepest-mouse-target application x y)
|
widget (w/find-deepest-mouse-target application x y)
|
||||||
wheel-f (get widget :mouse-wheel)]
|
wheel-f (get widget :mouse-wheel)]
|
||||||
(if (some? wheel-f)
|
(if (some? wheel-f)
|
||||||
(wheel-f widget state clicks)
|
(wheel-f widget state delta)
|
||||||
state))
|
state))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
setup-child-widgets]]
|
setup-child-widgets]]
|
||||||
[more-speech.ui.text-window :refer [map->text-window]]
|
[more-speech.ui.text-window :refer [map->text-window]]
|
||||||
[more-speech.ui.text-frame :refer [map->text-frame]]
|
[more-speech.ui.text-frame :refer [map->text-frame]]
|
||||||
|
[more-speech.ui.header-frame-functions :refer [->header-controls]]
|
||||||
[more-speech.ui.author-window :refer [map->author-window
|
[more-speech.ui.author-window :refer [map->author-window
|
||||||
draw-author-window]]
|
draw-author-window]]
|
||||||
[more-speech.ui.graphics :as g]
|
[more-speech.ui.graphics :as g]
|
||||||
@ -74,7 +75,7 @@
|
|||||||
:y (:y config/article-window-dimensions)
|
:y (:y config/article-window-dimensions)
|
||||||
:w (g/pos-width graphics (:char-width config/article-window-dimensions))
|
:w (g/pos-width graphics (:char-width config/article-window-dimensions))
|
||||||
:h (- (g/screen-height graphics) (:bottom-margin config/article-window-dimensions))
|
:h (- (g/screen-height graphics) (:bottom-margin config/article-window-dimensions))
|
||||||
:frame-constructor map->text-frame
|
:controls (->header-controls)
|
||||||
})
|
})
|
||||||
|
|
||||||
:author-window (map->author-window
|
:author-window (map->author-window
|
||||||
|
@ -7,9 +7,31 @@
|
|||||||
[more-speech.ui.button :refer [map->button
|
[more-speech.ui.button :refer [map->button
|
||||||
up-arrow
|
up-arrow
|
||||||
down-arrow]]
|
down-arrow]]
|
||||||
[more-speech.ui.app-util :as app-util]))
|
[more-speech.ui.app-util :as app-util]
|
||||||
|
[more-speech.ui.text-frame :refer [text-window-controls
|
||||||
|
get-element-height
|
||||||
|
draw-elements
|
||||||
|
update-elements
|
||||||
|
scroll-elements]]))
|
||||||
|
|
||||||
(defn get-element-height [state]
|
(declare get-header-height
|
||||||
|
draw-headers
|
||||||
|
update-headers
|
||||||
|
scroll-headers)
|
||||||
|
|
||||||
|
(defrecord header-controls []
|
||||||
|
text-window-controls
|
||||||
|
(get-element-height [_c state]
|
||||||
|
(get-header-height state))
|
||||||
|
(draw-elements [_c state frame]
|
||||||
|
(draw-headers state frame))
|
||||||
|
(update-elements [_c state frame]
|
||||||
|
(update-headers state frame))
|
||||||
|
(scroll-elements [_c state frame delta]
|
||||||
|
(scroll-headers state frame delta))
|
||||||
|
)
|
||||||
|
|
||||||
|
(defn get-header-height [state]
|
||||||
(let [graphics (get-in state [:application :graphics])
|
(let [graphics (get-in state [:application :graphics])
|
||||||
line-height (g/line-height graphics)
|
line-height (g/line-height graphics)
|
||||||
header-height (+ config/header-bottom-margin
|
header-height (+ config/header-bottom-margin
|
||||||
@ -109,6 +131,30 @@
|
|||||||
id (:id button)]
|
id (:id button)]
|
||||||
(recur (assoc frame id button) (rest buttons))))))
|
(recur (assoc frame id button) (rest buttons))))))
|
||||||
|
|
||||||
|
(defn update-headers [state frame]
|
||||||
|
(let [application (:application state)
|
||||||
|
event-map (:text-event-map application)
|
||||||
|
events (:chronological-text-events application)
|
||||||
|
open-thread (:open-thread application)
|
||||||
|
threaded-events (a/thread-events events event-map open-thread)
|
||||||
|
total-events (count threaded-events)
|
||||||
|
display-position (:display-position frame)
|
||||||
|
end-position (min (count threaded-events) (+ display-position (:n-elements frame)))
|
||||||
|
displayed-events (subvec threaded-events display-position end-position)
|
||||||
|
nicknames (:nicknames application)
|
||||||
|
headers (events->headers displayed-events nicknames)
|
||||||
|
bc (make-button-creator state frame)
|
||||||
|
frame-path (:path frame)
|
||||||
|
frame (get-in state frame-path)
|
||||||
|
frame (app-util/clear-widgets frame)
|
||||||
|
buttons (create-thread-buttons bc headers)
|
||||||
|
frame (add-thread-buttons frame buttons)
|
||||||
|
marked-up-headers (map a/markup-header headers)
|
||||||
|
frame (assoc frame :displayed-elements marked-up-headers
|
||||||
|
:total-elements total-events)
|
||||||
|
state (assoc-in state frame-path frame)]
|
||||||
|
state))
|
||||||
|
|
||||||
|
|
||||||
(defn draw-header [frame cursor header index]
|
(defn draw-header [frame cursor header index]
|
||||||
(let [g (:graphics cursor)
|
(let [g (:graphics cursor)
|
||||||
@ -136,3 +182,13 @@
|
|||||||
(recur cursor (rest headers) index)
|
(recur cursor (rest headers) index)
|
||||||
(recur (draw-header frame cursor header index)
|
(recur (draw-header frame cursor header index)
|
||||||
(rest headers) (inc index))))))))
|
(rest headers) (inc index))))))))
|
||||||
|
|
||||||
|
(defn scroll-headers [state frame delta]
|
||||||
|
(let [articles (get-in state [:application :chronological-text-events])
|
||||||
|
display-position (:display-position frame)
|
||||||
|
display-position (+ display-position delta)
|
||||||
|
display-position (min (count articles) display-position)
|
||||||
|
display-position (max 0 display-position)
|
||||||
|
frame (assoc frame :display-position display-position)]
|
||||||
|
frame))
|
||||||
|
|
||||||
|
@ -2,21 +2,27 @@
|
|||||||
(:require
|
(:require
|
||||||
[more-speech.ui.widget :refer [widget]]
|
[more-speech.ui.widget :refer [widget]]
|
||||||
[more-speech.ui.graphics :as g]
|
[more-speech.ui.graphics :as g]
|
||||||
[more-speech.content.article :as a]
|
|
||||||
[more-speech.ui.app-util :as app-util]
|
[more-speech.ui.app-util :as app-util]
|
||||||
[more-speech.ui.header-frame-functions
|
|
||||||
:refer [get-element-height
|
|
||||||
draw-headers]
|
|
||||||
:as funcs]
|
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(defprotocol text-window-controls
|
||||||
|
(get-element-height [controls state]
|
||||||
|
"returns the fixed height, in pixels, of the scrolled element.")
|
||||||
|
(draw-elements [controls state frame]
|
||||||
|
"draws :displayed-elements.")
|
||||||
|
(update-elements [controls state frame]
|
||||||
|
"Called only if the widget is in [:application :this-update]
|
||||||
|
sets :total-elements and :displayed-elements")
|
||||||
|
(scroll-elements [controls state frame delta]
|
||||||
|
"sets :display-position"))
|
||||||
|
|
||||||
(declare setup-text-frame
|
(declare setup-text-frame
|
||||||
update-text-frame
|
update-text-frame
|
||||||
draw-text-frame
|
draw-text-frame
|
||||||
mouse-wheel
|
mouse-wheel
|
||||||
scroll-frame)
|
scroll-frame)
|
||||||
|
|
||||||
(defrecord text-frame [x y w h display-position]
|
(defrecord text-frame [x y w h display-position controls]
|
||||||
widget
|
widget
|
||||||
(setup-widget [widget state]
|
(setup-widget [widget state]
|
||||||
(setup-text-frame state widget))
|
(setup-text-frame state widget))
|
||||||
@ -28,7 +34,8 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
(defn setup-text-frame [state frame]
|
(defn setup-text-frame [state frame]
|
||||||
(let [element-height (get-element-height state)
|
(let [controls (:controls frame)
|
||||||
|
element-height (get-element-height controls state)
|
||||||
elements (quot (:h frame) element-height)
|
elements (quot (:h frame) element-height)
|
||||||
frame (assoc frame :n-elements elements
|
frame (assoc frame :n-elements elements
|
||||||
:mouse-wheel mouse-wheel
|
:mouse-wheel mouse-wheel
|
||||||
@ -37,32 +44,11 @@
|
|||||||
|
|
||||||
(defn- update-text-frame [state frame]
|
(defn- update-text-frame [state frame]
|
||||||
(if (app-util/update-widget? state frame)
|
(if (app-util/update-widget? state frame)
|
||||||
(let [application (:application state)
|
(update-elements (:controls frame) state frame)
|
||||||
event-map (:text-event-map application)
|
|
||||||
events (:chronological-text-events application)
|
|
||||||
open-thread (:open-thread application)
|
|
||||||
threaded-events (a/thread-events events event-map open-thread)
|
|
||||||
total-events (count threaded-events)
|
|
||||||
display-position (:display-position frame)
|
|
||||||
end-position (min (count threaded-events) (+ display-position (:n-elements frame)))
|
|
||||||
displayed-events (subvec threaded-events display-position end-position)
|
|
||||||
nicknames (:nicknames application)
|
|
||||||
headers (funcs/events->headers displayed-events nicknames)
|
|
||||||
bc (funcs/make-button-creator state frame)
|
|
||||||
frame-path (:path frame)
|
|
||||||
frame (get-in state frame-path)
|
|
||||||
frame (app-util/clear-widgets frame)
|
|
||||||
buttons (funcs/create-thread-buttons bc headers)
|
|
||||||
frame (funcs/add-thread-buttons frame buttons)
|
|
||||||
marked-up-headers (map a/markup-header headers)
|
|
||||||
frame (assoc frame :displayed-elements marked-up-headers
|
|
||||||
:total-elements total-events)
|
|
||||||
state (assoc-in state frame-path frame)]
|
|
||||||
state)
|
|
||||||
state))
|
state))
|
||||||
|
|
||||||
(defn draw-text-frame [state frame]
|
(defn draw-text-frame [state frame]
|
||||||
(let [{:keys [x y w h]} frame
|
(let [{:keys [x y w h controls]} frame
|
||||||
application (:application state)
|
application (:application state)
|
||||||
g (:graphics application)]
|
g (:graphics application)]
|
||||||
(g/with-translation
|
(g/with-translation
|
||||||
@ -72,20 +58,15 @@
|
|||||||
(g/stroke-weight g 2)
|
(g/stroke-weight g 2)
|
||||||
(g/no-fill g)
|
(g/no-fill g)
|
||||||
(g/rect g [0 0 w h])
|
(g/rect g [0 0 w h])
|
||||||
(draw-headers state frame)))))
|
(draw-elements controls state frame)))))
|
||||||
|
|
||||||
(defn scroll-frame [frame-path state delta]
|
(defn scroll-frame [frame-path state delta]
|
||||||
(let [frame (get-in state frame-path)
|
(let [frame (get-in state frame-path)
|
||||||
articles (get-in state [:application :chronological-text-events])
|
controls (:controls frame)
|
||||||
display-position (:display-position frame)
|
state (assoc-in state frame-path (scroll-elements controls state frame delta))
|
||||||
display-position (+ display-position delta)
|
|
||||||
display-position (min (count articles) display-position)
|
|
||||||
display-position (max 0 display-position)
|
|
||||||
frame (assoc frame :display-position display-position)
|
|
||||||
state (assoc-in state frame-path frame)
|
|
||||||
state (app-util/update-widget state frame)]
|
state (app-util/update-widget state frame)]
|
||||||
state))
|
state))
|
||||||
|
|
||||||
(defn mouse-wheel [widget state clicks]
|
(defn mouse-wheel [frame state clicks]
|
||||||
(scroll-frame (:path widget) state clicks))
|
(scroll-frame (:path frame) state clicks))
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
(ns more-speech.ui.text-window
|
(ns more-speech.ui.text-window
|
||||||
(:require
|
(:require
|
||||||
[more-speech.ui.widget :refer [widget]]
|
[more-speech.ui.widget :refer [widget]]
|
||||||
|
[more-speech.ui.text-frame :refer [map->text-frame]]
|
||||||
[more-speech.ui.button :refer [map->button
|
[more-speech.ui.button :refer [map->button
|
||||||
up-arrow
|
up-arrow
|
||||||
down-arrow
|
down-arrow
|
||||||
@ -21,7 +22,7 @@
|
|||||||
scroll-up
|
scroll-up
|
||||||
scroll-down)
|
scroll-down)
|
||||||
|
|
||||||
(defrecord text-window [x y w h page-up page-down frame-constructor]
|
(defrecord text-window [x y w h page-up page-down controls]
|
||||||
widget
|
widget
|
||||||
(setup-widget [widget state]
|
(setup-widget [widget state]
|
||||||
(setup-text-window widget state))
|
(setup-text-window widget state))
|
||||||
@ -30,28 +31,29 @@
|
|||||||
(draw-widget [widget state]
|
(draw-widget [widget state]
|
||||||
(draw-text-window state widget)))
|
(draw-text-window state widget)))
|
||||||
|
|
||||||
(defn setup-text-window [widget _state]
|
(defn setup-text-window [window _state]
|
||||||
(let [{:keys [x y w h frame-constructor]} widget
|
(let [{:keys [x y w h controls]} window
|
||||||
frame-path (concat (:path widget) [:text-frame])
|
frame-path (concat (:path window) [:text-frame])
|
||||||
scroll-up (partial scroll-up frame-path)
|
scroll-up (partial scroll-up frame-path)
|
||||||
scroll-down (partial scroll-down frame-path)
|
scroll-down (partial scroll-down frame-path)
|
||||||
frame (frame-constructor {:x x
|
frame (map->text-frame {:x x
|
||||||
:y y
|
:y y
|
||||||
:w (- w config/scroll-bar-w)
|
:w (- w config/scroll-bar-w)
|
||||||
:h h
|
:h h
|
||||||
:display-position 0})
|
:controls controls
|
||||||
|
:display-position 0})
|
||||||
sb-button-offset (+ (/ config/scroll-bar-w 2)
|
sb-button-offset (+ (/ config/scroll-bar-w 2)
|
||||||
(/ config/scroll-bar-button-w 2))
|
(/ config/scroll-bar-button-w 2))
|
||||||
sb-button-x (+ x w (- sb-button-offset) 0.5)
|
sb-button-x (+ x w (- sb-button-offset) 0.5)
|
||||||
widget (assoc widget
|
widget (assoc window
|
||||||
:text-frame frame
|
:text-frame frame
|
||||||
:scroll-down (map->button {:x sb-button-x
|
:scroll-down (map->button {:x sb-button-x
|
||||||
:y (+ y config/scroll-bar-button-top-margin)
|
:y (+ y config/scroll-bar-button-top-margin)
|
||||||
:h config/scroll-bar-button-h
|
:h config/scroll-bar-button-h
|
||||||
:w config/scroll-bar-button-w
|
:w config/scroll-bar-button-w
|
||||||
:left-down scroll-down
|
:left-down scroll-down
|
||||||
:left-held scroll-down
|
:left-held scroll-down
|
||||||
:draw up-arrow})
|
:draw up-arrow})
|
||||||
:scroll-up (map->button {:x sb-button-x
|
:scroll-up (map->button {:x sb-button-x
|
||||||
:y (+ y h (- config/scroll-bar-button-bottom-margin))
|
:y (+ y h (- config/scroll-bar-button-bottom-margin))
|
||||||
:h config/scroll-bar-button-h
|
:h config/scroll-bar-button-h
|
||||||
|
Loading…
Reference in New Issue
Block a user