view src/indyvon/core.clj @ 1:a93cfcf60f27

Layers.
author Mikhail Kryshen <mikhail@kryshen.net>
date Mon, 07 Jun 2010 04:42:52 +0400
parents 43e3358ca4d9
children 0f2a98f71a9c
line wrap: on
line source

(ns indyvon.core
  (:import (java.awt Dimension Point Component Graphics2D)))

(def ^{:private true} *graphics*)
(def ^{:private true} *rx* 0)
(def ^{:private true} *ry* 0)

(def *width*)
(def *height*)

(def *lag*)

(def *update-fn*)

(defprotocol Layer
  (render! [this])
  (size [this])
  (anchor [this]))

;; (defmacro make-layer [& fns]
;;   (let [fn-map
;;         (apply hash-map
;;                (reduce #(conj %1 (first %2) (next %2)) []
;;                        fns))]
;;     ;; TODO
;;     fn-map))

(defn- translate [g x y w h clip]
  (if clip
    (.create g x y w h)
    (doto (.create g)
      (.translate x y))))

(defn render-layer!
  "Render layer in a new graphics context."
  ([layer]
     (render-layer! layer 0 0 *width* *height*))
  ([layer x y]
     (render-layer! layer x y true))
  ([layer x y clip]
     (let [s (size layer)]
       (render-layer! layer x y (.width s) (.height s) clip)))
  ([layer x y w h]
     (render-layer! layer x y w h true))
  ([layer x y w h clip]
     (binding [*graphics* (translate *graphics* x y w h clip)
               *rx* (+ *rx* x)
               *ry* (+ *ry* y)
               *width* w
               *height* h]
       (render! layer))))

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

;; (defn make-component [layer]
;;   (proxy [Component] []
;;     (update [g] (.paint this g))
;;     (paint [g]
;;            (let [insets (.getInsets this)
;;                  top (.top insets)
;;                  left (.left insets)
;;                  bottom (.bottom insets)
;;                  right (.right insets)
;;                  size (.getSize this)
;;                  width (- (.width size) left right)
;;                  height (- (.height size) top bottom)]
;;              (binding [*graphics* g
;;                        *update-fn* (make-update-fn this)]
;;                (render-layer! layer top left width height false))))
;;     (getPreferredSize []
;;                       (size layer))))

(defn make-component [layer]
  (proxy [Component] []
    (update [g] (.paint this g))
    (paint [g]
           (let [size (.getSize this)
                 width (.width size)
                 height (.height size)]
             (binding [*graphics* g
                       *update-fn* (make-update-fn this)]
               (render-layer! layer 0 0 width height false))))
    (getPreferredSize []
                      (let [s (size layer)]
                        (Dimension. (s 0) (s 1))))))

(comment
  (do 
    (def frame (java.awt.Frame. "Test"))
    (def layer
         (reify Layer
                (render! [this]
                         (.fillRect *graphics* 10 10 40 40))
                (size [this] [100 100])
                (anchor [this] [0 0])))
    (doto frame
      (.addWindowListener
       (proxy [java.awt.event.WindowAdapter] []
         (windowClosing [event] (.dispose frame))))
      (.add (make-component layer))
      (.pack)
      (.setVisible true))
    )
  )