Mercurial > hg > indyvon
changeset 81:5d2153e8a28d
Code cleanup.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Thu, 02 Sep 2010 03:55:44 +0400 |
parents | 880ae8e03408 |
children | 9a69db231531 |
files | README src/net/kryshen/indyvon/async.clj src/net/kryshen/indyvon/component.clj src/net/kryshen/indyvon/core.clj src/net/kryshen/indyvon/demo.clj src/net/kryshen/indyvon/layers.clj |
diffstat | 6 files changed, 196 insertions(+), 229 deletions(-) [+] |
line wrap: on
line diff
--- a/README Wed Sep 01 22:25:55 2010 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -# indyvon - -FIXME: write description - -## Usage - -FIXME: write - -## Installation - -FIXME: write - -## License - -FIXME: write
--- a/src/net/kryshen/indyvon/async.clj Wed Sep 01 22:25:55 2010 +0400 +++ b/src/net/kryshen/indyvon/async.clj Thu Sep 02 03:55:44 2010 +0400 @@ -112,6 +112,7 @@ (.getGraphics ^Image (:image b)) (:width async-layer) (:height async-layer) + ;; TODO: use operational event dispatcher. dummy-event-dispatcher)) (update async-layer)) @@ -122,18 +123,18 @@ (defrecord AsyncLayer [content width height executor buffers] Layer (render! [layer] - (repaint-on-update layer) - (add-context-observer content (fn [_] (draw-offscreen-async layer))) - (when-not @buffers - ;; TODO: dynamic size, recreate buffers when size increases. - (let [new-buffers (repeatedly 2 (partial create-buffer layer))] - (dosync - (ref-set buffers new-buffers))) - (draw-offscreen-async layer)) - (with-buffer layer :front [b] - (.drawImage *graphics* ^Image (:image b) 0 0 nil))) + (repaint-on-update layer) + (add-context-observer content (fn [_] (draw-offscreen-async layer))) + (when-not @buffers + ;; TODO: dynamic size, recreate buffers when size increases. + (let [new-buffers (repeatedly 2 (partial create-buffer layer))] + (dosync + (ref-set buffers new-buffers))) + (draw-offscreen-async layer)) + (with-buffer layer :front [b] + (.drawImage *graphics* ^Image (:image b) 0 0 nil))) (layer-size [layer] - (Size. width height))) + (Size. width height))) (defn async-layer "Creates layer that draws the content asynchronously using
--- a/src/net/kryshen/indyvon/component.clj Wed Sep 01 22:25:55 2010 +0400 +++ b/src/net/kryshen/indyvon/component.clj Thu Sep 02 03:55:44 2010 +0400 @@ -37,12 +37,12 @@ (let [panel (proxy [JPanel] [] (paintComponent [g] - (let [size (.getSize ^Component this)] - (draw-root! layer g (.width size) (.height size) - event-dispatcher this))) + (let [size (.getSize ^Component this)] + (draw-root! layer g (.width size) (.height size) + event-dispatcher this))) (getPreferredSize [] - (let [s (root-size layer (font-context this) this)] - (Dimension. (:width s) (:height s)))))] + (let [s (root-size layer (font-context this) this)] + (Dimension. (:width s) (:height s)))))] (.setBackground panel (:back-color *theme*)) (add-observer panel layer (fn [_] (.repaint panel))) (listen! event-dispatcher panel)
--- a/src/net/kryshen/indyvon/core.clj Wed Sep 01 22:25:55 2010 +0400 +++ b/src/net/kryshen/indyvon/core.clj Thu Sep 02 03:55:44 2010 +0400 @@ -19,7 +19,7 @@ (ns net.kryshen.indyvon.core (:import - (java.awt Graphics2D RenderingHints Component Color Font AWTEvent Shape) + (java.awt Graphics2D RenderingHints Component Color Font Shape) (java.awt.geom AffineTransform Point2D$Double Rectangle2D$Double Area) (java.awt.event MouseListener MouseMotionListener) (java.awt.font FontRenderContext))) @@ -87,6 +87,8 @@ ;; TODO: modifiers (defrecord MouseEvent [id when x y x-on-screen y-on-screen button]) +;; TODO: KeyEvent + (defprotocol EventDispatcher (listen! [this ^Component component] "Listen for events on the specified AWT Component.") @@ -128,7 +130,7 @@ (extend-protocol Anchored net.kryshen.indyvon.core.Layer (anchor [this h-align v-align] - (default-anchor this h-align v-align))) + (default-anchor this h-align v-align))) (defn- assoc-cons [m key val] (->> (get m key) (cons val) (assoc m key))) @@ -371,9 +373,8 @@ (defn with-handlers* [handle handlers f & args] - (binding - [*event-dispatcher* (create-dispatcher - *event-dispatcher* handle handlers)] + (binding [*event-dispatcher* (create-dispatcher + *event-dispatcher* handle handlers)] (apply f args))) (defmacro with-handlers @@ -423,15 +424,15 @@ bindings] EventDispatcher (listen! [this component] - (listen! parent component)) + (listen! parent component)) (create-dispatcher [this handle handlers] - (create-dispatcher parent handle handlers)) + (create-dispatcher parent handle handlers)) (commit [this] - (commit parent)) + (commit parent)) (handle-picked? [this handle] - (handle-picked? parent handle)) + (handle-picked? parent handle)) (handle-hovered? [this handle] - (handle-hovered? parent handle))) + (handle-hovered? parent handle))) (defn- make-node [handle handlers] (DispatcherNode. handle handlers *event-dispatcher* *clip* @@ -518,58 +519,33 @@ (reify EventDispatcher (listen! [this component] - (doto component - (.addMouseListener this) - (.addMouseMotionListener this))) + (doto component + (.addMouseListener this) + (.addMouseMotionListener this))) (create-dispatcher [this handle handlers] - (let [node (make-node handle handlers)] - (dosync (alter tree-r add-node node)) - node)) + (let [node (make-node handle handlers)] + (dosync (alter tree-r add-node node)) + node)) (commit [this] - (dosync (ref-set tree @tree-r) - (ref-set tree-r {}))) + (dosync (ref-set tree @tree-r) + (ref-set tree-r {}))) (handle-picked? [this handle] - (some #(= handle (:handle %)) @picked)) + (some #(= handle (:handle %)) @picked)) (handle-hovered? [this handle] - (some #(= handle (:handle %)) @hovered)) + (some #(= handle (:handle %)) @hovered)) MouseListener (mouseEntered [this event] - (dispatch-mouse-motion hovered @tree this event)) + (dispatch-mouse-motion hovered @tree this event)) (mouseExited [this event] - (dispatch-mouse-motion hovered @tree this event)) + (dispatch-mouse-motion hovered @tree this event)) (mouseClicked [this event] - (dispatch-mouse-button picked hovered event)) + (dispatch-mouse-button picked hovered event)) (mousePressed [this event] - (dispatch-mouse-button picked hovered event)) + (dispatch-mouse-button picked hovered event)) (mouseReleased [this event] - (dispatch-mouse-button picked hovered event)) + (dispatch-mouse-button picked hovered event)) MouseMotionListener (mouseDragged [this event] - (translate-and-dispatch @picked true event)) + (translate-and-dispatch @picked true event)) (mouseMoved [this event] - (dispatch-mouse-motion hovered @tree this event))))) - -;; -;; ИДЕИ: -;; -;; Контекст: биндинги или запись? -;; -;; Установка обработчиков (в контексте слоя): -;; -;; (listen -;; (:mouse-entered e -;; ...) -;; (:mouse-exited e -;; ...)) -;; -;; Не надо IMGUI. -;; Построение сцены путем декорирования слоев: -;; -;; (listener -;; (:action e (println e)) -;; (:mouse-dragged e (println e)) -;; (theme :font "Helvetica-14" -;; (vbox -;; (button (text-layer "Button 1")) -;; (button (text-layer "Button 2"))))) -;; + (dispatch-mouse-motion hovered @tree this event)))))
--- a/src/net/kryshen/indyvon/demo.clj Wed Sep 01 22:25:55 2010 +0400 +++ b/src/net/kryshen/indyvon/demo.clj Thu Sep 02 03:55:44 2010 +0400 @@ -18,6 +18,7 @@ ;; (ns net.kryshen.indyvon.demo + "Indyvon demo and experiments." (:gen-class) (:use (net.kryshen.indyvon core layers component)) @@ -53,6 +54,8 @@ (:mouse-clicked _ (apply callback args)))) (defn combine-colors [^Color color1 ^Color color2 c] + "Returns color between color1 and color2. When c (0 <= c <= 1.0) is + closer to 0 the returned сolor is closer to color1." (case c 0.0 color1 1.0 color2 @@ -71,7 +74,6 @@ (= prev from) (if (pos? speed) :start :stop) (= prev to) (if (neg? speed) :start :stop) :default :continue)] - ;;(println prev from to speed state *interval*) (if (= state :stop) prev (let [interval (if (= state :start) 1 *interval*) @@ -80,7 +82,7 @@ (repaint) val)))) -(defn button +(defn animated-button "Create animated button layer." [content callback & args] (let [padding 4 @@ -120,80 +122,80 @@ (:mouse-released _ (repaint)) (:mouse-clicked _ (apply callback args)))) (layer-size [button] - (let [face-size (layer-size face)] - (Size. (+ (:width face-size) shadow-offset) - (+ (:height face-size) shadow-offset)))))))) + (let [face-size (layer-size face)] + (Size. (+ (:width face-size) shadow-offset) + (+ (:height face-size) shadow-offset)))))))) -(def button1 (button (label "Animated button 1") - println "Animated button 1 clicked")) +(def button1 (animated-button (label "Animated button 1") + println "Animated button 1 clicked")) -(def button2 (button (label "Animated button 2") - println "Animated button 2 clicked")) +(def button2 (animated-button (label "Animated button 2") + println "Animated button 2 clicked")) -(def layer1 +(def test-layer1 (reify Layer (render! [layer] - (with-handlers layer - (with-color (if (hovered? layer) Color/ORANGE Color/RED) - (.fillRect *graphics* 0 0 *width* *height*)) - (:mouse-entered e - (repaint) - (println e)) - (:mouse-exited e - (repaint) - (println e)) - (:mouse-moved e - (println e)))) + (with-handlers layer + (with-color (if (hovered? layer) Color/ORANGE Color/RED) + (.fillRect *graphics* 0 0 *width* *height*)) + (:mouse-entered e + (repaint) + (println e)) + (:mouse-exited e + (repaint) + (println e)) + (:mouse-moved e + (println e)))) (layer-size [layer] - (Size. 30 20)))) + (Size. 30 20)))) -(def layer1b (border layer1 2 3)) +(def test-layer1b (border test-layer1 2 3)) -(def layer2 +(def test-layer2 (reify Layer (render! [layer] - (doto *graphics* - (.setColor Color/YELLOW) - (.fillRect 0 0 *width* *height*)) - (with-rotate 0.5 0 0 - (draw! layer1b 30 25)) - (draw! layer1 55 5)) + (doto *graphics* + (.setColor Color/YELLOW) + (.fillRect 0 0 *width* *height*)) + (with-rotate 0.5 0 0 + (draw! test-layer1b 30 25)) + (draw! test-layer1 55 5)) (layer-size [layer] - (Size. 70 65)))) + (Size. 70 65)))) -(def layer2m (miniature layer2 30 30)) +(def test-layer2m (miniature test-layer2 30 30)) -(def layer3 (border (label "Sample\ntext" :right :center))) +(def test-layer3 (border (label "Sample\ntext" :right :bottom))) -(def layer +(def root (reify Layer (render! [layer] - ;;(repaint) - ;;(println (format "%.3f" (/ *interval* 1E9))) - (doto *graphics* - ;; Random color to see when repaint happens. - (.setColor (rand-nth [Color/BLACK Color/BLUE Color/RED])) - (.drawLine 0 0 *width* *height*) - (.drawLine *width* 0 0 *height*)) - (draw! layer2 15 20) - (draw! layer2m 120 50) - (draw! layer3 100 100 80 50) - (draw! button1 50 160) - (with-rotate (/ Math/PI 6) 250 200 - (draw! button1 200 160)) - (draw! button2 50 250) - (with-bounds 100 200 140 30 - (draw-button! :button - (label "Immediate button" :center :center) - #(println "Button clicked!")))) + ;;(repaint) + (doto *graphics* + (.drawLine 0 0 *width* *height*) + (.drawLine *width* 0 0 *height*) + ;; Random color to see when repaint happens. + (.setColor (rand-nth [Color/BLACK Color/BLUE Color/RED])) + (.fillOval 5 5 20 20)) + (draw! test-layer2 30 20) + (draw! test-layer2m 120 50) + (draw! test-layer3 100 100 80 50) + (draw! button1 50 160) + (with-rotate (/ Math/PI 6) 250 200 + (draw! button1 200 160)) + (draw! button2 50 250) + (with-bounds 100 200 140 30 + (draw-button! :button + (label "Immediate button" :center :center) + #(println "Button clicked!")))) (layer-size [layer] - (Size. 400 300)))) + (Size. 400 300)))) ;; Main viewport -(def vp (viewport layer)) +(def vp (viewport root)) ;; Miniature (rendered asynchronously) (def vp-miniature (border (viewport-miniature vp 100 75))) @@ -213,3 +215,6 @@ (defn -main [] (println "Try to drag the viewport.") (show-frame scene)) + +(comment + (show-frame (viewport-miniature vp 200 150)))
--- a/src/net/kryshen/indyvon/layers.clj Wed Sep 01 22:25:55 2010 +0400 +++ b/src/net/kryshen/indyvon/layers.clj Thu Sep 02 03:55:44 2010 +0400 @@ -80,12 +80,12 @@ ([content width gap] (let [layer (padding content (+ width gap))] (decorate-layer layer [_] - (with-color :border-color - (doseq [i (range 0 width)] - (.drawRect *graphics* i i - (- *width* 1 i i) - (- *height* 1 i i)))) - (render! layer))))) + (with-color :border-color + (doseq [i (range 0 width)] + (.drawRect *graphics* i i + (- *width* 1 i i) + (- *height* 1 i i)))) + (render! layer))))) (defn panel "Opaque layer using theme's alt-back-color." @@ -105,15 +105,15 @@ (reify Layer (render! [_] - ;; TODO: distribute space proportionally. - (let [w (/ *width* (count contents))] - (doseq [[i c] (map-indexed vector contents)] - (draw! c (* i w) 0 w *height*)))) + ;; TODO: distribute space proportionally. + (let [w (/ *width* (count contents))] + (doseq [[i c] (map-indexed vector contents)] + (draw! c (* i w) 0 w *height*)))) (layer-size [_] - (reduce #(Size. (+ (:width %1) (:width %2)) - (max (:height %1) (:height %2))) - (Size. 0 0) - (map layer-size contents))))) + (reduce #(Size. (+ (:width %1) (:width %2)) + (max (:height %1) (:height %2))) + (Size. 0 0) + (map layer-size contents))))) (defn- re-split [^java.util.regex.Pattern re s] (seq (.split re s))) @@ -155,32 +155,32 @@ (let [lines (re-split #"\r\n|\n|\r|\u0085|\u2028|\u2029" text)] (reify Layer (render! [layer] - (let [w *width* - h *height* - font (.getFont *graphics*) - layouts (layout-text lines font *font-context*) - y (align-y (text-height layouts) h v-align)] - (loop [layouts layouts, y y] - (when-first [^TextLayout layout layouts] - (let [ascent (.getAscent layout) - lh (+ ascent (.getDescent layout) (.getLeading layout)) - x (align-x (.getAdvance layout) w h-align)] - (.draw layout *graphics* x (+ y ascent)) - (recur (next layouts) (+ y lh))))))) + (let [w *width* + h *height* + font (.getFont *graphics*) + layouts (layout-text lines font *font-context*) + y (align-y (text-height layouts) h v-align)] + (loop [layouts layouts, y y] + (when-first [^TextLayout layout layouts] + (let [ascent (.getAscent layout) + lh (+ ascent (.getDescent layout) (.getLeading layout)) + x (align-x (.getAdvance layout) w h-align)] + (.draw layout *graphics* x (+ y ascent)) + (recur (next layouts) (+ y lh))))))) (layer-size [layer] - (let [layouts (layout-text lines (:font *theme*) *font-context*) - width (text-width layouts) - height (text-height layouts)] - (Size. width height))))))) + (let [layouts (layout-text lines (:font *theme*) *font-context*) + width (text-width layouts) + height (text-height layouts)] + (Size. width height))))))) (defn- ^ImageObserver image-observer [layer] (reify ImageObserver (imageUpdate [this img infoflags x y width height] - (update layer) - (zero? (bit-and infoflags - (bit-or ImageObserver/ALLBITS - ImageObserver/ABORT)))))) + (update layer) + (zero? (bit-and infoflags + (bit-or ImageObserver/ALLBITS + ImageObserver/ABORT)))))) (defn image-layer [image-or-uri] @@ -192,15 +192,15 @@ (reify Layer (render! [layer] - (repaint-on-update layer) - (.drawImage *graphics* image 0 0 (image-observer layer))) + (repaint-on-update layer) + (.drawImage *graphics* image 0 0 (image-observer layer))) (layer-size [layer] - (let [observer (image-observer layer) - width (.getWidth image observer) - height (.getHeight image observer) - width (if (pos? width) width 1) - height (if (pos? height) height 1)] - (Size. width height)))))) + (let [observer (image-observer layer) + width (.getWidth image observer) + height (.getHeight image observer) + width (if (pos? width) width 1) + height (if (pos? height) height 1)] + (Size. width height)))))) (defn miniature "Creates layer that asynchronously renders view of the content @@ -210,13 +210,13 @@ (reify Layer (render! [this] - (let [size (layer-size content) - sx (/ width (:width size)) - sy (/ height (:height size))] - (.scale *graphics* sx sy) - (draw! content 0 0 (:width size) (:height size)))) + (let [size (layer-size content) + sx (/ width (:width size)) + sy (/ height (:height size))] + (.scale *graphics* sx sy) + (draw! content 0 0 (:width size) (:height size)))) (layer-size [this] - (Size. width height))) + (Size. width height))) width height)) (defrecord Viewport [content h-align v-align @@ -224,34 +224,34 @@ x y fix-x fix-y last-width last-height] Layer (render! [layer] - (repaint-on-update layer) - (with-handlers layer - (let [anchor (anchor content h-align v-align)] - (dosync - (alter x + (align-x *width* @last-width h-align)) - (alter y + (align-y *height* @last-height v-align)) - (ref-set last-width *width*) - (ref-set last-height *height*)) - ;; TODO: notify observers when size changes. - (draw! content (- 0 @x (:x anchor)) (- 0 @y (:y anchor)))) - (:mouse-pressed e + (repaint-on-update layer) + (with-handlers layer + (let [anchor (anchor content h-align v-align)] (dosync - (ref-set fix-x (:x-on-screen e)) - (ref-set fix-y (:y-on-screen e))) - (when *target* - (->> Cursor/MOVE_CURSOR Cursor. (.setCursor *target*)))) - (:mouse-released e - (when *target* - (->> Cursor/DEFAULT_CURSOR Cursor. (.setCursor *target*)))) - (:mouse-dragged e - (dosync - (alter x + (- @fix-x (:x-on-screen e))) - (alter y + (- @fix-y (:y-on-screen e))) - (ref-set fix-x (:x-on-screen e)) - (ref-set fix-y (:y-on-screen e))) - (update layer)))) + (alter x + (align-x *width* @last-width h-align)) + (alter y + (align-y *height* @last-height v-align)) + (ref-set last-width *width*) + (ref-set last-height *height*)) + ;; TODO: notify observers when size changes. + (draw! content (- 0 @x (:x anchor)) (- 0 @y (:y anchor)))) + (:mouse-pressed e + (dosync + (ref-set fix-x (:x-on-screen e)) + (ref-set fix-y (:y-on-screen e))) + (when *target* + (->> Cursor/MOVE_CURSOR Cursor. (.setCursor *target*)))) + (:mouse-released e + (when *target* + (->> Cursor/DEFAULT_CURSOR Cursor. (.setCursor *target*)))) + (:mouse-dragged e + (dosync + (alter x + (- @fix-x (:x-on-screen e))) + (alter y + (- @fix-y (:y-on-screen e))) + (ref-set fix-x (:x-on-screen e)) + (ref-set fix-y (:y-on-screen e))) + (update layer)))) (layer-size [layer] - (layer-size content))) + (layer-size content))) (defn viewport "Creates scrollable viewport layer." @@ -273,15 +273,15 @@ [viewport width height] (miniature (decorate-layer (:content viewport) [_] - (repaint-on-update viewport) - (let [[x y w h] (viewport-visible-bounds viewport)] - (with-color :alt-back-color - (.fillRect *graphics* 0 0 *width* *height*)) - (with-color :back-color - (.fillRect *graphics* x y w h)) - (draw! (:content viewport)) - (with-color :border-color - (.drawRect *graphics* x y w h)))) + (repaint-on-update viewport) + (let [[x y w h] (viewport-visible-bounds viewport)] + (with-color :alt-back-color + (.fillRect *graphics* 0 0 *width* *height*)) + (with-color :back-color + (.fillRect *graphics* x y w h)) + (draw! (:content viewport)) + (with-color :border-color + (.drawRect *graphics* x y w h)))) width height)) ;; @@ -292,9 +292,9 @@ "Decorate layer to handle events." `(let [layer# ~layer] (decorate-layer layer# [t#] - (with-handlers t# - (render! layer#) - ~@handlers)))) + (with-handlers t# + (render! layer#) + ~@handlers)))) (defn theme [layer & map-or-keyvals] (let [theme (if (== (count map-or-keyvals) 1) @@ -303,15 +303,15 @@ (reify Layer (render! [t] - (with-theme theme - (render! layer))) + (with-theme theme + (render! layer))) (layer-size [t] - (with-theme theme - (layer-size layer))) + (with-theme theme + (layer-size layer))) Anchored (anchor [t xa ya] - (with-theme theme - (anchor layer xa ya)))))) + (with-theme theme + (anchor layer xa ya)))))) ;; ;; Measuring time