Decouple headers from text-frame. In progress. More to do.

This commit is contained in:
Robert C. Martin 2022-02-21 11:54:29 -06:00
parent f0a43f96b8
commit 1e66acb7ed
5 changed files with 124 additions and 107 deletions

View File

@ -1,6 +1,7 @@
(ns more-speech.ui.header-frame-spec
(:require [speclj.core :refer :all]
[more-speech.ui.header-frame :refer :all]
[more-speech.ui.text-frame :refer :all]
[more-speech.ui.header-frame-functions :refer :all]
[more-speech.ui.widget :refer [widget setup-widget]]
[more-speech.ui.graphics :as g]
[more-speech.ui.config :as config]))
@ -23,8 +24,8 @@
(with frame {:x 0 :y 0 :w 500 :h 500})
(context "setup"
(it "determines number of article headers fit in the frame"
(let [frame (setup-header-frame @state @frame)]
(should= 10 (:n-headers frame)))
(let [frame (setup-text-frame @state @frame)]
(should= 10 (:n-elements frame)))
)
)

View File

@ -65,4 +65,14 @@
(satisfies? w/widget element))
(recur (rest elements)
(dissoc frame key))
(recur (rest elements) frame))))))
(recur (rest elements) frame))))))
(defn toggle-event-thread [button state]
(let [id (:id button)
frame-path (drop-last (:path button))
open-thread (get-in state [:application :open-thread])
open-thread (if (contains? open-thread id)
(disj open-thread id)
(conj open-thread id))
state (assoc-in state [:application :open-thread] open-thread)]
(update-widget state frame-path)))

View File

@ -18,7 +18,7 @@
draw-child-widgets
setup-child-widgets]]
[more-speech.ui.text-window :refer [map->text-window]]
[more-speech.ui.header-frame :refer [map->header-frame]]
[more-speech.ui.text-frame :refer [map->text-frame]]
[more-speech.ui.author-window :refer [map->author-window
draw-author-window]]
[more-speech.ui.graphics :as g]
@ -74,7 +74,7 @@
:y (:y 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))
:frame-constructor map->header-frame
:frame-constructor map->text-frame
})
:author-window (map->author-window
@ -83,3 +83,4 @@
)
))

View File

@ -1,46 +1,21 @@
(ns more-speech.ui.header-frame
(:require
[more-speech.ui.config :as config]
[more-speech.ui.cursor :as cursor]
[more-speech.content.article :as a]
[more-speech.ui.widget :refer [widget]]
[more-speech.ui.button :refer [map->button
up-arrow
down-arrow]]
[more-speech.ui.graphics :as g]
[more-speech.nostr.util :refer [num->hex-string]]
[more-speech.ui.app-util :as app]))
(ns more-speech.ui.header-frame-functions
(:require [more-speech.ui.config :as config]
[more-speech.ui.graphics :as g]
[more-speech.ui.cursor :as cursor]
[more-speech.nostr.util :refer [num->hex-string]]
[more-speech.content.article :as a]
[more-speech.ui.button :refer [map->button
up-arrow
down-arrow]]
[more-speech.ui.app-util :as app-util]))
(declare setup-header-frame
update-header-frame
draw-header-frame
mouse-wheel
scroll-frame
draw-headers)
(defrecord header-frame [x y w h display-position]
widget
(setup-widget [widget state]
(setup-header-frame state widget))
(update-widget [widget state]
(update-header-frame state widget))
(draw-widget [widget state]
(draw-header-frame state widget)
state)
)
(defn setup-header-frame [state frame]
(defn get-element-height [state]
(let [graphics (get-in state [:application :graphics])
line-height (g/line-height graphics)
header-height (+ config/header-bottom-margin
config/header-top-margin
(* config/header-lines line-height))
headers (quot (:h frame) header-height)
frame (assoc frame :n-headers headers
:header-height header-height
:mouse-wheel mouse-wheel
:scroll-frame scroll-frame)]
frame))
(* config/header-lines line-height))]
header-height))
(defn event->header [text-event nicknames]
(let [{:keys [id pubkey created-at content references indent]} text-event
@ -77,15 +52,6 @@
(g/line graphics [(quot w 2) 0 (quot w 2) h])
)))
(defn toggle-thread [button state]
(let [id (:id button)
frame-path (drop-last (:path button))
open-thread (get-in state [:application :open-thread])
open-thread (if (contains? open-thread id)
(disj open-thread id)
(conj open-thread id))
state (assoc-in state [:application :open-thread] open-thread)]
(app/update-widget state frame-path)))
(defrecord button-creator [state frame graphics])
@ -112,7 +78,7 @@
:h 10
:draw draw
:path (concat (:path frame) [id])
:left-down toggle-thread})))
:left-down app-util/toggle-event-thread})))
(defn create-thread-buttons [button-creator headers]
(let [state (:state button-creator)
@ -143,59 +109,6 @@
id (:id button)]
(recur (assoc frame id button) (rest buttons))))))
(defn- update-header-frame [state frame]
(if (app/update-widget? 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-headers 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/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)
state))
(defn draw-header-frame [state frame]
(let [{:keys [x y w h]} frame
application (:application state)
g (:graphics application)]
(g/with-translation
g [x y]
(fn [g]
(g/stroke g [0 0 0])
(g/stroke-weight g 2)
(g/no-fill g)
(g/rect g [0 0 w h])
(draw-headers state frame)))))
(defn scroll-frame [frame-path state delta]
(let [frame (get-in state frame-path)
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)
state (assoc-in state frame-path frame)
state (app/update-widget state frame)]
state))
(defn mouse-wheel [widget state clicks]
(scroll-frame (:path widget) state clicks))
(defn draw-header [frame cursor header index]
(let [g (:graphics cursor)
@ -208,6 +121,7 @@
(cursor/render cursor frame header))
)
(defn draw-headers [state frame]
(let [application (:application state)
g (:graphics application)

View File

@ -0,0 +1,91 @@
(ns more-speech.ui.text-frame
(:require
[more-speech.ui.widget :refer [widget]]
[more-speech.ui.graphics :as g]
[more-speech.content.article :as a]
[more-speech.ui.app-util :as app-util]
[more-speech.ui.header-frame-functions
:refer [get-element-height
draw-headers]
:as funcs]
))
(declare setup-text-frame
update-text-frame
draw-text-frame
mouse-wheel
scroll-frame)
(defrecord text-frame [x y w h display-position]
widget
(setup-widget [widget state]
(setup-text-frame state widget))
(update-widget [widget state]
(update-text-frame state widget))
(draw-widget [widget state]
(draw-text-frame state widget)
state)
)
(defn setup-text-frame [state frame]
(let [element-height (get-element-height state)
elements (quot (:h frame) element-height)
frame (assoc frame :n-elements elements
:mouse-wheel mouse-wheel
:scroll-frame scroll-frame)]
frame))
(defn- update-text-frame [state frame]
(if (app-util/update-widget? 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 (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))
(defn draw-text-frame [state frame]
(let [{:keys [x y w h]} frame
application (:application state)
g (:graphics application)]
(g/with-translation
g [x y]
(fn [g]
(g/stroke g [0 0 0])
(g/stroke-weight g 2)
(g/no-fill g)
(g/rect g [0 0 w h])
(draw-headers state frame)))))
(defn scroll-frame [frame-path state delta]
(let [frame (get-in state frame-path)
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)
state (assoc-in state frame-path frame)
state (app-util/update-widget state frame)]
state))
(defn mouse-wheel [widget state clicks]
(scroll-frame (:path widget) state clicks))