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