changeset 75:ddfde9cce39a

EventDispatcher can report hovered and picked states for handles.
author Mikhail Kryshen <mikhail@kryshen.net>
date Mon, 30 Aug 2010 20:44:23 +0400
parents a823dd0c2736
children dafd4ff9d313
files src/net/kryshen/indyvon/core.clj src/net/kryshen/indyvon/demo.clj
diffstat 2 files changed, 60 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/net/kryshen/indyvon/core.clj	Mon Aug 30 20:04:21 2010 +0400
+++ b/src/net/kryshen/indyvon/core.clj	Mon Aug 30 20:44:23 2010 +0400
@@ -90,7 +90,13 @@
       handlers (an event-id -> handler-fn map). Handle is used to
       match the contexts between commits.")
   (commit [this]
-     "Apply the registered handlers for event processing."))
+     "Apply the registered handlers for event processing.")
+  (handle-picked? [this handle]
+     "Returns true if the specified handle received the :mouse-pressed
+      event and have not yet received :moused-released.")
+  (handle-hovered? [this handle]
+     "Returns true if the specified handle received the :mouse-entered
+      event and have not yet received :mouse-exited."))
 
 (defprotocol Anchored
   "Provide anchor point for Layers. Used by viewport."
@@ -245,26 +251,6 @@
   [x y w h & body]
   `(with-bounds* ~x ~y ~w ~h (fn [] ~@body)))
 
-(defn with-handlers*
-  [handle handlers f & args]
-  (binding
-      [*event-dispatcher* (create-dispatcher
-                           *event-dispatcher* handle handlers)]
-    (apply f args)))
-
-(defmacro with-handlers
-  "specs => (:event-id name & handler-body)*
-
-  Execute form with the specified event handlers."
-  [handle form & specs]
-  `(with-handlers* ~handle
-     ~(reduce (fn [m spec]
-                (assoc m (first spec)
-                       `(fn [~(second spec)]
-                          ~@(nnext spec)))) {}
-                          specs)
-     (fn [] ~form)))
-
 (defmacro with-theme
   [theme & body]
   `(binding [*theme* (merge *theme* ~theme)]
@@ -374,6 +360,37 @@
        (layer-size layer))))
 
 ;;
+;; Event handling.
+;;
+
+(defn with-handlers*
+  [handle handlers f & args]
+  (binding
+      [*event-dispatcher* (create-dispatcher
+                           *event-dispatcher* handle handlers)]
+    (apply f args)))
+
+(defmacro with-handlers
+  "specs => (:event-id name & handler-body)*
+
+  Execute form with the specified event handlers."
+  [handle form & specs]
+  `(with-handlers* ~handle
+     ~(reduce (fn [m spec]
+                (assoc m (first spec)
+                       `(fn [~(second spec)]
+                          ~@(nnext spec)))) {}
+                          specs)
+     (fn [] ~form)))
+
+(defn picked? [handle]
+  (handle-picked? *event-dispatcher* handle))
+
+(defn hovered? [handle]
+  (handle-hovered? *event-dispatcher* handle))
+
+
+;;
 ;; EventDispatcher implementation
 ;;
 
@@ -391,7 +408,9 @@
       EventDispatcher
       (listen! [this component])
       (create-dispatcher [this handle handlers] this)
-      (commit [this])))
+      (commit [this])
+      (handle-picked? [this handle])
+      (handle-hovered? [this handle])))
 
 (defrecord DispatcherNode [handle handlers parent
                            ^Shape clip ^AffineTransform transform
@@ -402,7 +421,11 @@
   (create-dispatcher [this handle handlers]
      (create-dispatcher parent handle handlers))
   (commit [this]
-     (commit parent)))
+     (commit parent))
+  (handle-picked? [this handle]
+     (handle-picked? parent handle))
+  (handle-hovered? [this handle]
+     (handle-hovered? parent handle)))
 
 (defn- make-node [handle handlers]
   (DispatcherNode. handle handlers *event-dispatcher* *clip*
@@ -492,6 +515,10 @@
      (commit [this]
         (dosync (ref-set tree @tree-r)
                 (ref-set tree-r {})))
+     (handle-picked? [this handle]
+        (some #(= handle (:handle %)) @picked))
+     (handle-hovered? [this handle]
+        (some #(= handle (:handle %)) @hovered))
      MouseListener
      (mouseEntered [this event]
         (dispatch-mouse-motion hovered @tree this event))
--- a/src/net/kryshen/indyvon/demo.clj	Mon Aug 30 20:04:21 2010 +0400
+++ b/src/net/kryshen/indyvon/demo.clj	Mon Aug 30 20:44:23 2010 +0400
@@ -31,12 +31,16 @@
    Layer
    (render! [layer]
       (with-handlers layer
-        (doto *graphics*
-          (.setColor (rand-nth [Color/RED Color/ORANGE]))
-          (.fillRect 0 0 *width* *height*))
-        (:mouse-entered e (println e))
-        (:mouse-exited e (println e))
-        (:mouse-moved e (println e))))
+        (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))))