Mercurial > hg > indyvon
changeset 58:64b67aa224f4
Code cleanup, docstrings.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Fri, 20 Aug 2010 21:44:03 +0400 |
parents | c598c55c89e7 |
children | b68de6a43f29 |
files | src/net/kryshen/indyvon/component.clj src/net/kryshen/indyvon/core.clj |
diffstat | 2 files changed, 73 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/src/net/kryshen/indyvon/component.clj Fri Aug 20 03:19:37 2010 +0400 +++ b/src/net/kryshen/indyvon/component.clj Fri Aug 20 21:44:03 2010 +0400 @@ -23,6 +23,7 @@ width (.width size) height (.height size)] (.clearRect graphics 0 0 width height) + ;; Setup the root layer context (move to core?). (binding [*graphics* graphics *font-context* (.getFontRenderContext graphics) *initial-transform* (.getTransform graphics)
--- a/src/net/kryshen/indyvon/core.clj Fri Aug 20 03:19:37 2010 +0400 +++ b/src/net/kryshen/indyvon/core.clj Fri Aug 20 21:44:03 2010 +0400 @@ -11,20 +11,39 @@ (java.awt.event MouseListener MouseMotionListener) (java.awt.font FontRenderContext))) +;; +;; Layer context +;; + (def ^Graphics2D *graphics*) + (def ^FontRenderContext *font-context*) + (def ^Component *target*) + (def *width*) + (def *height*) + (def ^Shape *clip*) -(def *update*) + (def *event-dispatcher*) -(def ^AffineTransform *initial-transform*) -(def ^AffineTransform *inverse-initial-transform*) +(def ^{:doc "Fn to be called in a layer context to request redraw."} + *update*) + +(def ^{:tag AffineTransform + :doc "Initial transform associated with the graphics context"} + *initial-transform*) + +(def ^{:tag AffineTransform + :doc "Inversion of the initial transform associated with + the graphics context"} + *inverse-initial-transform*) (defrecord Theme [fore-color back-color alt-back-color border-color font]) +;; REMIND: use system colors, see java.awt.SystemColor. (defn default-theme [] (Theme. Color/BLACK Color/LIGHT_GRAY Color/WHITE Color/BLUE (Font. "Sans" Font/PLAIN 12))) @@ -35,6 +54,10 @@ (defrecord Size [width height]) (defrecord Bounds [x y width height]) +;; +;; Core protocols and types +;; + (defprotocol Layer "Basic UI element." (render! [this]) @@ -77,46 +100,26 @@ :center (/ (:height size) 2) :bottom (:height size))))))) -(defn- ^Graphics2D make-graphics [^Graphics2D graphics x y w h] - (.create graphics x y w h)) - -(defn- ^Graphics2D apply-theme [^Graphics2D graphics theme] - (doto graphics - (.setColor (:fore-color theme)) - (.setFont (:font theme)))) - -(defn intersect - "Compute intersection between a pair of rectangles (Bounds)." - ([b1 b2] - (let [x1 (:x b1) - y1 (:y b1) - x2 (:x b2) - y2 (:y b2)] - (intersect x1 y1 (+ x1 (:width b1)) (+ y1 (:height b1)) - x2 y2 (+ x2 (:width b2)) (+ y2 (:height b2))))) - ([x11 y11 x12 y12, x21 y21 x22 y22] - (let [x1 (max x11 x21) - y1 (max y11 y21) - x2 (min x12 x22) - y2 (min y12 y22)] - (Bounds. x1 y1 (- x2 x1) (- y2 y1))))) +;; +;; Rendering +;; (defn- relative-transform - "AffineTransform: layer -> absolute -> component." + "AffineTransform: layer context -> awt component." [] (let [tr (.getTransform *graphics*)] (.preConcatenate tr *inverse-initial-transform*) tr)) (defn- inverse-relative-transform - "AffineTransform: component (event) -> absolute -> layer." + "AffineTransform: awt component -> layer context." [] (let [tr (.getTransform *graphics*)] (.invert tr) ; absolute -> layer (.concatenate tr *initial-transform*) ; component -> absolute tr)) -(defn clip +(defn- clip "Intersect clipping area with the specified shape or bounds. Returns new clip (Shape or nil if empty)." ([x y w h] @@ -130,32 +133,43 @@ nil a1)))) -(defn ^Graphics2D create-graphics +(defn- ^Graphics2D apply-theme + "Set graphics' color and font to match theme. + Modifies and returns the first argument." + [^Graphics2D graphics theme] + (doto graphics + (.setColor (:fore-color theme)) + (.setFont (:font theme)))) + +(defn- ^Graphics2D create-graphics ([] (create-graphics 0 0 *width* *height*)) ([x y w h] (apply-theme (.create *graphics* x y w h) *theme*))) -(defmacro with-bounds [x y w h & body] - `(let [x# ~x, y# ~y - w# ~w, h# ~h - clip# (clip x# y# w# h#)] - (when clip# - (let [graphics# (create-graphics x# y# w# h#)] - (try - (binding [*width* w# - *height* h# - *clip* clip# - *graphics* graphics#] - ~@body) - (finally - (.dispose graphics#))))))) +(defn with-bounds* + [x y w h f & args] + (when-let [clip (clip x y w h)] + (let [graphics (create-graphics x y w h)] + (try + (binding [*width* w + *height* h + *clip* clip + *graphics* graphics] + (apply f args)) + (finally + (.dispose graphics)))))) -(defmacro with-handlers* [handle handlers & body] - `(binding - [*event-dispatcher* - (create-dispatcher *event-dispatcher* ~handle ~handlers)] - ~@body)) +(defmacro with-bounds + [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)* @@ -168,17 +182,15 @@ `(fn [~(second spec)] ~@(nnext spec)))) {} specs) - ~form)) + (fn [] ~form))) -(defn with-theme* [theme f & args] - (apply with-bindings* {#'*theme* (merge *theme* theme)} - f args)) - -(defmacro with-theme [theme & body] +(defmacro with-theme + [theme & body] `(binding [*theme* (merge *theme* ~theme)] ~@body)) -(defmacro with-color [color & body] +(defmacro with-color + [color & body] `(let [color# (.getColor *graphics*)] (try (.setColor *graphics* ~color) @@ -212,6 +224,7 @@ [(:x geometry) (:y geometry) (:width geometry) (:height geometry)])) (defn draw! + "Draws layer." ([layer] (let [graphics (create-graphics)] (try @@ -223,11 +236,11 @@ (let [size (layer-size layer)] (draw! layer x y (:width size) (:height size)))) ([layer x y width height] - (with-bounds x y width height - (render! layer)))) + (with-bounds* x y width height render! layer))) (defn draw-anchored! - "Draw with location relative to the anchor point." + "Draws layer. Location is relative to the layer's anchor point for + the specified alignment." ([layer h-align v-align x y] (let [anchor (anchor layer h-align v-align)] (draw! layer (- x (:x anchor)) (- y (:y anchor)))))