Mercurial > hg > indyvon
view src/indyvon/core.clj @ 13:c6009a144727
Layer decorator macro.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Mon, 14 Jun 2010 06:26:07 +0400 |
parents | ea6fc44f19c8 |
children | 0a2fafca72d8 |
line wrap: on
line source
;; ;; Copyright (C) 2010 Mikhail Kryshen <mikhail@kryshen.net> ;; ;; This file is part of Indyvon. ;; (ns indyvon.core) (defprotocol Layer (render! [this context graphics]) (size [this context]) (anchor [this context])) (defrecord LayerContext [layer parent x y width height update-fn dispatcher]) (defn default-context [] (LayerContext. nil nil 0 0 0 0 nil nil)) (defn- spec-map ([specs] (spec-map {} specs)) ([mm specs] (if-let [form (first specs)] (recur (conj mm [(first form) (next form)]) (next specs)) mm))) (defn- merge-specs [s1 s2] (for [spec (spec-map (spec-map s1) s2)] (cons (first spec) (second spec)))) (defmacro reify-layer [& specs] `(reify Layer ~@(merge-specs '((size [_ _] [0 0]) (anchor [_ _] [0 0])) specs))) (defn- make-graphics [g x y w h clip] (if clip (.create g x y w h) (doto (.create g) (.translate x y)))) (defn draw! "Render layer in a new graphics context." ([context layer graphics] (draw! context layer graphics 0 0 (:width context) (:height context))) ([context layer graphics x y] (draw! context layer graphics x y true)) ([context layer graphics x y clip] (let [s (size layer context)] (draw! context layer graphics x y (s 0) (s 1) clip))) ([context layer graphics x y w h] (draw! context layer graphics x y w h true)) ([context layer graphics x y w h clip] (let [graphics (make-graphics graphics x y w h clip)] (try (render! layer (assoc context :layer layer :parent context :x (+ (:x context) x) :y (+ (:y context) y) :width w :height h) graphics) (finally (.dispose graphics)))))) (defmacro decorate-layer [layer & specs] `(let [layer# ~layer] (reify Layer ~@(merge-specs `((~'render! [l# c# g#] (draw! c# layer# g#)) (~'size [l# c#] (size layer# c#)) (~'anchor [l# c#] (anchor layer# c#))) specs))))