view src/indyvon/component.clj @ 13:c6009a144727

Layer decorator macro.
author Mikhail Kryshen <mikhail@kryshen.net>
date Mon, 14 Jun 2010 06:26:07 +0400
parents cd8a378414d1
children 0a2fafca72d8
line wrap: on
line source

;;
;; Copyright (C) 2010 Mikhail Kryshen <mikhail@kryshen.net>
;;
;; This file is part of Indyvon.
;;

(ns indyvon.component
  (:use indyvon.core
        indyvon.event)
  (:import (java.awt Component Dimension Color)
           (java.awt.event MouseEvent)))

(defn- make-update-fn [component]
  (fn [] (.repaint component)))

(defn make-component
  ([layer]
     (make-component layer (make-event-dispatcher)))
  ([layer event-dispatcher]
     (let [component
           (proxy [Component] []
             (update [g] (.paint this g))
             (paint [g]
                    (let [size (.getSize this)
                          width (.width size)
                          height (.height size)
                          context (assoc (default-context)
                                    :dispatcher event-dispatcher
                                    :update-fn (make-update-fn this))]
                      (draw! context layer g 0 0 width height false))
                    (commit event-dispatcher))
             (getPreferredSize []
                               ;; TODO: supply context
                               (let [s (size layer nil)]
                                 (Dimension. (s 0) (s 1)))))]
       (listen! event-dispatcher component)
       component)))

(comment
  (do 
    (def frame (java.awt.Frame. "Test"))
    (def layer1
         (reify-layer
          (render! [this context g]
                   (register-context context)
                   (.setColor g Color/WHITE)
                   (.fillRect g 0 0 (:width context) (:height context)))
          (size [this context] [30 20])))
    (def layer2
         (reify-layer
          (render! [this context g]
                   (register-context context)
                   (.setColor g Color/BLUE)
                   (.fillRect g 0 0 (:width context) (:height context))
                   (draw! context layer1 g 10 5)
                   (draw! context layer1 g 50 5))
          (size [this context] [70 65])))
    (def layer
         (reify-layer
          (render! [this context g]
                   ;;(register-context context)
                   (.drawLine g 0 0 (:width context) (:height context))
                   (draw! context layer2 g 15 20))
          (size [this context] [100 100])))
    (doto frame
      (.addWindowListener
       (proxy [java.awt.event.WindowAdapter] []
         (windowClosing [event] (.dispose frame))))
      (.add (make-component layer))
      (.pack)
      (.setVisible true))

    (defmethod handle-layer-event [layer1 MouseEvent/MOUSE_ENTERED]
      [layer context event]
      (println "1 ENTERED"))
    (defmethod handle-layer-event [layer1 MouseEvent/MOUSE_EXITED]
      [layer context event]
      (println "1 EXITED"))
    (defmethod handle-layer-event [layer1 MouseEvent/MOUSE_MOVED]
      [layer context event]
      (println "1 MOVED"))
    (defmethod handle-layer-event [layer2 MouseEvent/MOUSE_ENTERED]
      [layer context event]
      (println "2 ENTERED"))
    (defmethod handle-layer-event [layer2 MouseEvent/MOUSE_EXITED]
      [layer context event]
      (println "2 EXITED"))
    (defmethod handle-layer-event [layer2 MouseEvent/MOUSE_MOVED]
      [layer context event]
      (println "2 MOVED"))
    (defmethod handle-layer-event [layer2 MouseEvent/MOUSE_DRAGGED]
      [layer context event]
      (println "2 DRAGGED"))
    )
  )