Mercurial > hg > indyvon
changeset 104:491152048c89
Added Scene record to enclose state retained between repaints.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Thu, 19 May 2011 20:10:45 +0400 |
parents | 9b81174f0511 |
children | f3dedece38f3 |
files | src/net/kryshen/indyvon/async.clj src/net/kryshen/indyvon/component.clj src/net/kryshen/indyvon/core.clj src/net/kryshen/indyvon/layers.clj |
diffstat | 4 files changed, 102 insertions(+), 87 deletions(-) [+] |
line diff
1.1 --- a/src/net/kryshen/indyvon/async.clj Thu May 19 17:01:46 2011 +0400 1.2 +++ b/src/net/kryshen/indyvon/async.clj Thu May 19 20:10:45 2011 +0400 1.3 @@ -119,23 +119,21 @@ 1.4 (.setComposite g AlphaComposite/Clear) 1.5 (.fillRect g 0 0 (:width async-layer) (:height async-layer)) 1.6 (.setComposite g AlphaComposite/Src) 1.7 - (draw-root! (:content async-layer) 1.8 - g 1.9 - (:width async-layer) 1.10 - (:height async-layer) 1.11 - ;; TODO: use operational event dispatcher. 1.12 - dummy-event-dispatcher)) 1.13 + (draw-scene! (:scene async-layer) 1.14 + g 1.15 + (:width async-layer) 1.16 + (:height async-layer))) 1.17 (update async-layer))) 1.18 1.19 (defn- draw-offscreen-async [async-layer] 1.20 (.execute ^ThreadPoolExecutor (:executor async-layer) 1.21 #(draw-offscreen async-layer))) 1.22 1.23 -(defrecord AsyncLayer [content width height executor buffers] 1.24 +(defrecord AsyncLayer [scene width height executor buffers] 1.25 Layer 1.26 (render! [layer] 1.27 (repaint-on-update layer) 1.28 - (add-context-observer content (fn [_ _] (draw-offscreen-async layer))) 1.29 + (add-context-observer scene (fn [_ _] (draw-offscreen-async layer))) 1.30 (when-not @buffers 1.31 ;; TODO: dynamic size, recreate buffers when size increases. 1.32 (let [device-conf (.getDeviceConfiguration *graphics*) 1.33 @@ -173,6 +171,9 @@ 1.34 ([content width height] 1.35 (async-layer content width height nil)) 1.36 ([content width height priority] 1.37 - (AsyncLayer. content width height 1.38 + ;; TODO: use operational event dispatcher. 1.39 + (AsyncLayer. (make-scene content) 1.40 + width 1.41 + height 1.42 (create-executor priority) 1.43 (ref nil))))
2.1 --- a/src/net/kryshen/indyvon/component.clj Thu May 19 17:01:46 2011 +0400 2.2 +++ b/src/net/kryshen/indyvon/component.clj Thu May 19 20:10:45 2011 +0400 2.3 @@ -36,23 +36,28 @@ 2.4 *font-context* (font-context c#)] 2.5 ~@body))) 2.6 2.7 +(defn- paint-component [^Component c ^Graphics g scene] 2.8 + (let [size (.getSize c)] 2.9 + (.setColor g (:back-color *theme*)) 2.10 + (.fillRect g 0 0 (.width size) (.height size)) 2.11 + (draw-scene! scene g (.width size) (.height size)))) 2.12 + 2.13 +(defn- preferred-size [^Component c scene] 2.14 + (let [s (scene-size scene (font-context c))] 2.15 + (Dimension. (:width s) (:height s)))) 2.16 + 2.17 (defn ^JPanel make-jpanel 2.18 ([layer] 2.19 (make-jpanel layer (root-event-dispatcher))) 2.20 ([layer event-dispatcher] 2.21 - (let [panel 2.22 - (proxy [JPanel] [] 2.23 - (paintComponent [^Graphics g] 2.24 - (let [size (.getSize ^Component this)] 2.25 - (.setColor g (:back-color *theme*)) 2.26 - (.fillRect g 0 0 (.width size) (.height size)) 2.27 - (draw-root! layer g (.width size) (.height size) 2.28 - event-dispatcher this))) 2.29 - (getPreferredSize [] 2.30 - (let [s (root-size layer (font-context this) this)] 2.31 - (Dimension. (:width s) (:height s)))))] 2.32 + (let [panel (proxy [JPanel] []) 2.33 + scene (make-scene layer event-dispatcher panel)] 2.34 + (update-proxy 2.35 + panel 2.36 + {"paintComponent" #(paint-component %1 %2 scene) 2.37 + "getPreferredSize" #(preferred-size % scene)}) 2.38 (.setBackground panel (:back-color *theme*)) 2.39 - (add-observer panel layer (fn [w _] 2.40 + (add-observer panel scene (fn [w _] 2.41 ;; Use the first observer argument 2.42 ;; instead of closing over panel to 2.43 ;; allow the panel and associated
3.1 --- a/src/net/kryshen/indyvon/core.clj Thu May 19 17:01:46 2011 +0400 3.2 +++ b/src/net/kryshen/indyvon/core.clj Thu May 19 20:10:45 2011 +0400 3.3 @@ -19,7 +19,8 @@ 3.4 3.5 (ns net.kryshen.indyvon.core 3.6 (:import 3.7 - (java.awt Graphics2D RenderingHints Component Color Font Shape) 3.8 + (java.awt Graphics2D RenderingHints Component Color Font Shape 3.9 + Cursor EventQueue) 3.10 (java.awt.geom AffineTransform Point2D$Double Rectangle2D$Double Area) 3.11 (java.awt.event MouseListener MouseMotionListener 3.12 MouseWheelListener MouseWheelEvent) 3.13 @@ -57,14 +58,14 @@ 3.14 *clip*) 3.15 3.16 (def ^{:dynamic true 3.17 - :doc "The root (background) layer of the scene."} 3.18 - *root*) 3.19 - 3.20 -(def ^{:dynamic true 3.21 :doc "Time in nanoseconds when the rendering of the current 3.22 frame starts."} 3.23 *time*) 3.24 3.25 +(def ^{:dynamic true 3.26 + :doc "Encloses state that should be retained between repaints."} 3.27 + *scene*) 3.28 + 3.29 (def ^{:dynamic true} 3.30 *event-dispatcher*) 3.31 3.32 @@ -217,22 +218,21 @@ 3.33 3.34 (defn add-context-observer 3.35 "Observer registered with this function will be automatically 3.36 - removed after the next frame rendering is complete." 3.37 + removed after the next repaint is complete." 3.38 [target f] 3.39 - (let [root *root*] 3.40 - (add-observer root target f))) 3.41 + (add-observer *scene* target f)) 3.42 3.43 (defn repaint-on-update 3.44 "Trigger repaint of the current scene when the target updates." 3.45 [target] 3.46 - (let [root *root*] 3.47 - (if (not= root target) 3.48 - (add-observer root target (fn [w _] (update w)))))) 3.49 + (let [scene *scene*] 3.50 + (if-not (identical? scene target) 3.51 + (add-observer scene target (fn [w _] (update w)))))) 3.52 3.53 (defn repaint 3.54 "Repaint the current scene." 3.55 [] 3.56 - (update *root*)) 3.57 + (update *scene*)) 3.58 3.59 ;; 3.60 ;; Rendering 3.61 @@ -427,56 +427,6 @@ 3.62 (let [anchor (anchor layer h-align v-align)] 3.63 (draw! layer (- x (:x anchor)) (- y (:y anchor)) w h)))) 3.64 3.65 -(defn draw-root! 3.66 - "Draws the root layer." 3.67 - ([layer graphics width height event-dispatcher] 3.68 - (draw-root! layer graphics width height event-dispatcher nil)) 3.69 - ([layer ^Graphics2D graphics width height event-dispatcher target] 3.70 - ;; (.setRenderingHint graphics 3.71 - ;; RenderingHints/KEY_INTERPOLATION 3.72 - ;; RenderingHints/VALUE_INTERPOLATION_BILINEAR) 3.73 - ;; (.setRenderingHint graphics 3.74 - ;; RenderingHints/KEY_ALPHA_INTERPOLATION 3.75 - ;; RenderingHints/VALUE_ALPHA_INTERPOLATION_QUALITY) 3.76 - ;; (.setRenderingHint graphics 3.77 - ;; RenderingHints/KEY_ANTIALIASING 3.78 - ;; RenderingHints/VALUE_ANTIALIAS_ON) 3.79 - ;; (.setRenderingHint graphics 3.80 - ;; RenderingHints/KEY_TEXT_ANTIALIASING 3.81 - ;; RenderingHints/VALUE_TEXT_ANTIALIAS_ON) 3.82 - (binding [*root* layer 3.83 - *target* target 3.84 - *graphics* graphics 3.85 - *font-context* (.getFontRenderContext graphics) 3.86 - *initial-transform* (.getTransform graphics) 3.87 - *inverse-initial-transform* 3.88 - (-> graphics .getTransform .createInverse) 3.89 - *event-dispatcher* event-dispatcher 3.90 - *width* width 3.91 - *height* height 3.92 - *clip* (Rectangle2D$Double. 0 0 width height) 3.93 - *time* (System/nanoTime)] 3.94 - (apply-theme) 3.95 - (let [tmp-watcher (Object.)] 3.96 - ;; Keep current context observers until the rendering is 3.97 - ;; complete. Some observers may be invoked twice if they 3.98 - ;; appear in both groups until tmp-watcher is removed. 3.99 - (replace-observers-watcher layer tmp-watcher) 3.100 - (try 3.101 - (render! layer) 3.102 - (finally 3.103 - (remove-observers tmp-watcher) 3.104 - (commit event-dispatcher))))))) 3.105 - 3.106 -(defn root-size 3.107 - ([layer font-context] 3.108 - (root-size layer font-context nil)) 3.109 - ([layer font-context target] 3.110 - (binding [*root* layer 3.111 - *target* target 3.112 - *font-context* font-context] 3.113 - (layer-size layer)))) 3.114 - 3.115 ;; 3.116 ;; Event handling. 3.117 ;; 3.118 @@ -667,3 +617,64 @@ 3.119 (translate-and-dispatch @picked true event)) 3.120 (mouseMoved [this event] 3.121 (dispatch-mouse-motion hovered @tree this event))))) 3.122 + 3.123 +;; 3.124 +;; Scene 3.125 +;; 3.126 + 3.127 +(defrecord Scene [layer event-dispatcher component]) 3.128 + 3.129 +(defn make-scene 3.130 + ([layer] 3.131 + (make-scene layer dummy-event-dispatcher nil)) 3.132 + ([layer event-dispatcher] 3.133 + (make-scene layer event-dispatcher nil)) 3.134 + ([layer event-dispatcher component] 3.135 + (Scene. layer event-dispatcher component))) 3.136 + 3.137 +(defn draw-scene! 3.138 + [scene ^Graphics2D graphics width height] 3.139 + ;; (.setRenderingHint graphics 3.140 + ;; RenderingHints/KEY_INTERPOLATION 3.141 + ;; RenderingHints/VALUE_INTERPOLATION_BILINEAR) 3.142 + ;; (.setRenderingHint graphics 3.143 + ;; RenderingHints/KEY_ALPHA_INTERPOLATION 3.144 + ;; RenderingHints/VALUE_ALPHA_INTERPOLATION_QUALITY) 3.145 + ;; (.setRenderingHint graphics 3.146 + ;; RenderingHints/KEY_ANTIALIASING 3.147 + ;; RenderingHints/VALUE_ANTIALIAS_ON) 3.148 + ;; (.setRenderingHint graphics 3.149 + ;; RenderingHints/KEY_TEXT_ANTIALIASING 3.150 + ;; RenderingHints/VALUE_TEXT_ANTIALIAS_ON) 3.151 + (binding [*scene* scene 3.152 + *graphics* graphics 3.153 + *font-context* (.getFontRenderContext graphics) 3.154 + *initial-transform* (.getTransform graphics) 3.155 + *inverse-initial-transform* (-> graphics 3.156 + .getTransform 3.157 + .createInverse) 3.158 + *event-dispatcher* (:event-dispatcher scene) 3.159 + *width* width 3.160 + *height* height 3.161 + *clip* (Rectangle2D$Double. 0 0 width height) 3.162 + *time* (System/nanoTime)] 3.163 + (apply-theme) 3.164 + (let [tmp-watcher (Object.)] 3.165 + ;; Keep current context observers until the rendering is 3.166 + ;; complete. Some observers may be invoked twice if they 3.167 + ;; appear in both groups until tmp-watcher is removed. 3.168 + (replace-observers-watcher scene tmp-watcher) 3.169 + (try 3.170 + (render! (:layer scene)) 3.171 + (finally 3.172 + (remove-observers tmp-watcher) 3.173 + (commit (:event-dispatcher scene))))))) 3.174 + 3.175 +(defn scene-size [scene font-context] 3.176 + (binding [*scene* scene 3.177 + *font-context* font-context] 3.178 + (layer-size (:layer scene)))) 3.179 + 3.180 +(defn set-cursor! [^Cursor cursor] 3.181 + (when-let [^Component component (:component *scene*)] 3.182 + (EventQueue/invokeLater #(.setCursor component cursor))))
4.1 --- a/src/net/kryshen/indyvon/layers.clj Thu May 19 17:01:46 2011 +0400 4.2 +++ b/src/net/kryshen/indyvon/layers.clj Thu May 19 20:10:45 2011 +0400 4.3 @@ -333,11 +333,9 @@ 4.4 (dosync 4.5 (ref-set fix-x (:x-on-screen e)) 4.6 (ref-set fix-y (:y-on-screen e))) 4.7 - (when *target* 4.8 - (->> Cursor/MOVE_CURSOR Cursor. (.setCursor *target*)))) 4.9 + (set-cursor! (Cursor. Cursor/MOVE_CURSOR))) 4.10 (:mouse-released e 4.11 - (when *target* 4.12 - (->> Cursor/DEFAULT_CURSOR Cursor. (.setCursor *target*)))) 4.13 + (set-cursor! (Cursor. Cursor/DEFAULT_CURSOR))) 4.14 (:mouse-dragged e 4.15 (dosync 4.16 (alter transform pre-translate