view src/indyvon/component.clj @ 14:0a2fafca72d8

Border layer decorator. Font render context. Manual identation for reify and proxy.
author Mikhail Kryshen <mikhail@kryshen.net>
date Tue, 15 Jun 2010 04:35:57 +0400
parents cd8a378414d1
children 87bd822aa815
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- font-context [component]
  (.getFontRenderContext (.getFontMetrics component (.getFont component))))

(defn make-component
  ([layer]
     (make-component layer (make-event-dispatcher)))
  ([layer event-dispatcher]
     (let [context (default-context)
           component
           (proxy [Component] []
             (update [g] (.paint this g))
             (paint [g]
                (let [size (.getSize this)
                      width (.width size)
                      height (.height size)
                      context (assoc context
                                :font-context (.getFontRenderContext g)
                                :dispatcher event-dispatcher
                                :update-fn (make-update-fn this))]
                  (draw! context layer g 0 0 width height false))
                (commit event-dispatcher))
             (getPreferredSize []
                (let [context (assoc context
                                :font-context (font-context this))
                      s (size layer context)]
                  (Dimension. (s 0) (s 1)))))]
       (listen! event-dispatcher component)
       (.setBackground component (-> context :theme :back-color))
       component)))

(comment
  (do 
    (def frame (java.awt.Frame. "Test"))
    (def layer1
         (reify-layer
          (render! [this context g]
             (register-context context)
             (.setColor g Color/RED)
             (.fillRect g 0 0 (:width context) (:height context)))
          (size [this context] [30 20])))
    (def layer1b (border-layer layer1 2 3))
    (def layer2
         (reify-layer
          (render! [this context g]
             (register-context context)
             (.setColor g Color/YELLOW)
             (.fillRect g 0 0 (:width context) (:height context))
             (draw! context layer1b g 10 5)
             (draw! context layer1 g 55 5))
          (size [this context] [70 65])))
    (def layer
         (reify-layer
          (render! [this context g]
             (.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"))
    )
  )