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