Mercurial > hg > indyvon
changeset 110:f3dedece38f3
Merged.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Mon, 10 Oct 2011 01:58:35 +0300 |
parents | 5bb50e6661af 491152048c89 |
children | 441fe457fc2b |
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, 110 insertions(+), 107 deletions(-) [+] |
line diff
1.1 --- a/src/net/kryshen/indyvon/async.clj Sat Oct 08 23:35:46 2011 +0300 1.2 +++ b/src/net/kryshen/indyvon/async.clj Mon Oct 10 01:58:35 2011 +0300 1.3 @@ -118,23 +118,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 @@ -172,6 +170,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 - (create-executor priority) 1.39 - (ref nil)))) 1.40 + ;; TODO: use operational event dispatcher. 1.41 + (->AsyncLayer (make-scene content) 1.42 + width 1.43 + height 1.44 + (create-executor priority) 1.45 + (ref nil))))
2.1 --- a/src/net/kryshen/indyvon/component.clj Sat Oct 08 23:35:46 2011 +0300 2.2 +++ b/src/net/kryshen/indyvon/component.clj Mon Oct 10 01:58:35 2011 +0300 2.3 @@ -29,29 +29,28 @@ 2.4 (defn font-context [^Component component] 2.5 (.getFontRenderContext (.getFontMetrics component (.getFont component)))) 2.6 2.7 -(defmacro with-component [component & body] 2.8 - `(let [c# ~component] 2.9 - (binding [*target* c# 2.10 - *font-context* (font-context c#)] 2.11 - ~@body))) 2.12 +(defn- paint-component [^Component c ^Graphics g scene] 2.13 + (let [size (.getSize c)] 2.14 + (.setColor g (:back-color *theme*)) 2.15 + (.fillRect g 0 0 (.width size) (.height size)) 2.16 + (draw-scene! scene g (.width size) (.height size)))) 2.17 + 2.18 +(defn- preferred-size [^Component c scene] 2.19 + (let [geom (scene-geometry scene (font-context c))] 2.20 + (Dimension. (width geom) (height geom)))) 2.21 2.22 (defn ^JPanel make-jpanel 2.23 ([layer] 2.24 (make-jpanel layer (root-event-dispatcher))) 2.25 ([layer event-dispatcher] 2.26 - (let [panel 2.27 - (proxy [JPanel] [] 2.28 - (paintComponent [^Graphics g] 2.29 - (let [size (.getSize ^Component this)] 2.30 - (.setColor g (:back-color *theme*)) 2.31 - (.fillRect g 0 0 (.width size) (.height size)) 2.32 - (draw-root! layer g (.width size) (.height size) 2.33 - event-dispatcher this))) 2.34 - (getPreferredSize [] 2.35 - (let [geom (root-geometry layer (font-context this) this)] 2.36 - (Dimension. (width geom) (height geom)))))] 2.37 + (let [panel (proxy [JPanel] []) 2.38 + scene (make-scene layer event-dispatcher panel)] 2.39 + (update-proxy 2.40 + panel 2.41 + {"paintComponent" #(paint-component %1 %2 scene) 2.42 + "getPreferredSize" #(preferred-size % scene)}) 2.43 (.setBackground panel (:back-color *theme*)) 2.44 - (add-observer panel layer (fn [w _] 2.45 + (add-observer panel scene (fn [w _] 2.46 ;; Use the first observer argument 2.47 ;; instead of closing over panel to 2.48 ;; allow the panel and associated 2.49 @@ -66,4 +65,4 @@ 2.50 (.pack))) 2.51 2.52 (defn message [m] 2.53 - (JOptionPane/showMessageDialog *target* m)) 2.54 + (JOptionPane/showMessageDialog (:component *scene*) m))
3.1 --- a/src/net/kryshen/indyvon/core.clj Sat Oct 08 23:35:46 2011 +0300 3.2 +++ b/src/net/kryshen/indyvon/core.clj Mon Oct 10 01:58:35 2011 +0300 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 @@ -40,11 +41,6 @@ 3.14 *font-context*) 3.15 3.16 (def ^{:dynamic true 3.17 - :tag Component 3.18 - :doc "Target AWT component, may be nil if drawing off-screen."} 3.19 - *target*) 3.20 - 3.21 -(def ^{:dynamic true 3.22 :doc "Width of the rendering area."} 3.23 *width*) 3.24 3.25 @@ -57,14 +53,14 @@ 3.26 *clip*) 3.27 3.28 (def ^{:dynamic true 3.29 - :doc "The root (background) layer of the scene."} 3.30 - *root*) 3.31 - 3.32 -(def ^{:dynamic true 3.33 :doc "Time in nanoseconds when the rendering of the current 3.34 frame starts."} 3.35 *time*) 3.36 3.37 +(def ^{:dynamic true 3.38 + :doc "Encloses state that should be retained between repaints."} 3.39 + *scene*) 3.40 + 3.41 (def ^{:dynamic true} 3.42 *event-dispatcher*) 3.43 3.44 @@ -260,22 +256,21 @@ 3.45 3.46 (defn add-context-observer 3.47 "Observer registered with this function will be automatically 3.48 - removed after the next frame rendering is complete." 3.49 + removed after the next repaint is complete." 3.50 [target f] 3.51 - (let [root *root*] 3.52 - (add-observer root target f))) 3.53 + (add-observer *scene* target f)) 3.54 3.55 (defn repaint-on-update 3.56 "Trigger repaint of the current scene when the target updates." 3.57 [target] 3.58 - (let [root *root*] 3.59 - (if (not= root target) 3.60 - (add-observer root target (fn [w _] (update w)))))) 3.61 + (let [scene *scene*] 3.62 + (if-not (identical? scene target) 3.63 + (add-observer scene target (fn [w _] (update w)))))) 3.64 3.65 (defn repaint 3.66 "Repaint the current scene." 3.67 [] 3.68 - (update *root*)) 3.69 + (update *scene*)) 3.70 3.71 ;; 3.72 ;; Rendering 3.73 @@ -478,56 +473,6 @@ 3.74 (- y (anchor-y geom v-align h)) 3.75 w h)))) 3.76 3.77 -(defn draw-root! 3.78 - "Draws the root layer." 3.79 - ([layer graphics width height event-dispatcher] 3.80 - (draw-root! layer graphics width height event-dispatcher nil)) 3.81 - ([layer ^Graphics2D graphics width height event-dispatcher target] 3.82 - ;; (.setRenderingHint graphics 3.83 - ;; RenderingHints/KEY_INTERPOLATION 3.84 - ;; RenderingHints/VALUE_INTERPOLATION_BILINEAR) 3.85 - ;; (.setRenderingHint graphics 3.86 - ;; RenderingHints/KEY_ALPHA_INTERPOLATION 3.87 - ;; RenderingHints/VALUE_ALPHA_INTERPOLATION_QUALITY) 3.88 - ;; (.setRenderingHint graphics 3.89 - ;; RenderingHints/KEY_ANTIALIASING 3.90 - ;; RenderingHints/VALUE_ANTIALIAS_ON) 3.91 - ;; (.setRenderingHint graphics 3.92 - ;; RenderingHints/KEY_TEXT_ANTIALIASING 3.93 - ;; RenderingHints/VALUE_TEXT_ANTIALIAS_ON) 3.94 - (binding [*root* layer 3.95 - *target* target 3.96 - *graphics* graphics 3.97 - *font-context* (.getFontRenderContext graphics) 3.98 - *initial-transform* (.getTransform graphics) 3.99 - *inverse-initial-transform* 3.100 - (-> graphics .getTransform .createInverse) 3.101 - *event-dispatcher* event-dispatcher 3.102 - *width* width 3.103 - *height* height 3.104 - *clip* (Rectangle2D$Double. 0 0 width height) 3.105 - *time* (System/nanoTime)] 3.106 - (apply-theme) 3.107 - (let [tmp-watcher (Object.)] 3.108 - ;; Keep current context observers until the rendering is 3.109 - ;; complete. Some observers may be invoked twice if they 3.110 - ;; appear in both groups until tmp-watcher is removed. 3.111 - (replace-observers-watcher layer tmp-watcher) 3.112 - (try 3.113 - (render! layer) 3.114 - (finally 3.115 - (remove-observers tmp-watcher) 3.116 - (commit event-dispatcher))))))) 3.117 - 3.118 -(defn root-geometry 3.119 - ([layer font-context] 3.120 - (root-geometry layer font-context nil)) 3.121 - ([layer font-context target] 3.122 - (binding [*root* layer 3.123 - *target* target 3.124 - *font-context* font-context] 3.125 - (geometry layer)))) 3.126 - 3.127 ;; 3.128 ;; Event handling. 3.129 ;; 3.130 @@ -572,13 +517,12 @@ 3.131 java.awt.event.MouseEvent/MOUSE_WHEEL :mouse-wheel}) 3.132 3.133 (def dummy-event-dispatcher 3.134 - (reify 3.135 - EventDispatcher 3.136 - (listen! [this component]) 3.137 - (create-dispatcher [this handle handlers] this) 3.138 - (commit [this]) 3.139 - (handle-picked? [this handle]) 3.140 - (handle-hovered? [this handle]))) 3.141 + (reify EventDispatcher 3.142 + (listen! [_ _]) 3.143 + (create-dispatcher [this _ _] this) 3.144 + (commit [_]) 3.145 + (handle-picked? [_ _]) 3.146 + (handle-hovered? [_ _]))) 3.147 3.148 (defrecord DispatcherNode [handle handlers parent 3.149 ^Shape clip ^AffineTransform transform 3.150 @@ -718,3 +662,64 @@ 3.151 (translate-and-dispatch @picked true event)) 3.152 (mouseMoved [this event] 3.153 (dispatch-mouse-motion hovered @tree this event))))) 3.154 + 3.155 +;; 3.156 +;; Scene 3.157 +;; 3.158 + 3.159 +(defrecord Scene [layer event-dispatcher component]) 3.160 + 3.161 +(defn make-scene 3.162 + ([layer] 3.163 + (make-scene layer dummy-event-dispatcher nil)) 3.164 + ([layer event-dispatcher] 3.165 + (make-scene layer event-dispatcher nil)) 3.166 + ([layer event-dispatcher component] 3.167 + (->Scene layer event-dispatcher component))) 3.168 + 3.169 +(defn draw-scene! 3.170 + [scene ^Graphics2D graphics width height] 3.171 + ;; (.setRenderingHint graphics 3.172 + ;; RenderingHints/KEY_INTERPOLATION 3.173 + ;; RenderingHints/VALUE_INTERPOLATION_BILINEAR) 3.174 + ;; (.setRenderingHint graphics 3.175 + ;; RenderingHints/KEY_ALPHA_INTERPOLATION 3.176 + ;; RenderingHints/VALUE_ALPHA_INTERPOLATION_QUALITY) 3.177 + ;; (.setRenderingHint graphics 3.178 + ;; RenderingHints/KEY_ANTIALIASING 3.179 + ;; RenderingHints/VALUE_ANTIALIAS_ON) 3.180 + ;; (.setRenderingHint graphics 3.181 + ;; RenderingHints/KEY_TEXT_ANTIALIASING 3.182 + ;; RenderingHints/VALUE_TEXT_ANTIALIAS_ON) 3.183 + (binding [*scene* scene 3.184 + *graphics* graphics 3.185 + *font-context* (.getFontRenderContext graphics) 3.186 + *initial-transform* (.getTransform graphics) 3.187 + *inverse-initial-transform* (-> graphics 3.188 + .getTransform 3.189 + .createInverse) 3.190 + *event-dispatcher* (:event-dispatcher scene) 3.191 + *width* width 3.192 + *height* height 3.193 + *clip* (Rectangle2D$Double. 0 0 width height) 3.194 + *time* (System/nanoTime)] 3.195 + (apply-theme) 3.196 + (let [tmp-watcher (Object.)] 3.197 + ;; Keep current context observers until the rendering is 3.198 + ;; complete. Some observers may be invoked twice if they 3.199 + ;; appear in both groups until tmp-watcher is removed. 3.200 + (replace-observers-watcher scene tmp-watcher) 3.201 + (try 3.202 + (render! (:layer scene)) 3.203 + (finally 3.204 + (remove-observers tmp-watcher) 3.205 + (commit (:event-dispatcher scene))))))) 3.206 + 3.207 +(defn scene-geometry [scene font-context] 3.208 + (binding [*scene* scene 3.209 + *font-context* font-context] 3.210 + (geometry (:layer scene)))) 3.211 + 3.212 +(defn set-cursor! [^Cursor cursor] 3.213 + (when-let [^Component component (:component *scene*)] 3.214 + (EventQueue/invokeLater #(.setCursor component cursor))))
4.1 --- a/src/net/kryshen/indyvon/layers.clj Sat Oct 08 23:35:46 2011 +0300 4.2 +++ b/src/net/kryshen/indyvon/layers.clj Mon Oct 10 01:58:35 2011 +0300 4.3 @@ -331,11 +331,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