Mercurial > hg > indyvon
changeset 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 | c6009a144727 |
children | 87bd822aa815 |
files | src/indyvon/component.clj src/indyvon/core.clj src/indyvon/event.clj |
diffstat | 3 files changed, 100 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/src/indyvon/component.clj Mon Jun 14 06:26:07 2010 +0400 +++ b/src/indyvon/component.clj Tue Jun 15 04:35:57 2010 +0400 @@ -13,27 +13,34 @@ (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 [component + (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 (default-context) - :dispatcher event-dispatcher - :update-fn (make-update-fn this))] - (draw! context layer g 0 0 width height false)) - (commit event-dispatcher)) + (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 [] - ;; TODO: supply context - (let [s (size layer nil)] - (Dimension. (s 0) (s 1)))))] + (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 @@ -42,25 +49,25 @@ (def layer1 (reify-layer (render! [this context g] - (register-context context) - (.setColor g Color/WHITE) - (.fillRect g 0 0 (:width context) (:height context))) + (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/BLUE) - (.fillRect g 0 0 (:width context) (:height context)) - (draw! context layer1 g 10 5) - (draw! context layer1 g 50 5)) + (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] - ;;(register-context context) - (.drawLine g 0 0 (:width context) (:height context)) - (draw! context layer2 g 15 20)) + (.drawLine g 0 0 (:width context) (:height context)) + (draw! context layer2 g 15 20)) (size [this context] [100 100]))) (doto frame (.addWindowListener
--- a/src/indyvon/core.clj Mon Jun 14 06:26:07 2010 +0400 +++ b/src/indyvon/core.clj Tue Jun 15 04:35:57 2010 +0400 @@ -4,17 +4,24 @@ ;; This file is part of Indyvon. ;; -(ns indyvon.core) +(ns indyvon.core + (:import (java.awt Color Font))) (defprotocol Layer (render! [this context graphics]) (size [this context]) (anchor [this context])) -(defrecord LayerContext [layer parent x y width height update-fn dispatcher]) +(defrecord Theme [fore-color back-color border-color font]) + +(defn default-theme [] + (Theme. Color/BLACK Color/WHITE Color/BLUE (Font. "Sans" Font/PLAIN 12))) + +(defrecord LayerContext + [layer parent x y width height update-fn dispatcher font-context theme]) (defn default-context [] - (LayerContext. nil nil 0 0 0 0 nil nil)) + (LayerContext. nil nil 0 0 0 0 nil nil nil (default-theme))) (defn- spec-map ([specs] @@ -35,12 +42,17 @@ (anchor [_ _] [0 0])) specs))) -(defn- make-graphics [g x y w h clip] +(defn- make-graphics [graphics x y w h clip] (if clip - (.create g x y w h) - (doto (.create g) + (.create graphics x y w h) + (doto (.create graphics) (.translate x y)))) +(defn- apply-theme [graphics theme] + (doto graphics + (.setColor (:fore-color theme)) + (.setFont (:font theme)))) + (defn draw! "Render layer in a new graphics context." ([context layer graphics] @@ -77,3 +89,40 @@ (~'size [l# c#] (size layer# c#)) (~'anchor [l# c#] (anchor layer# c#))) specs)))) + +;; +;; Layer implementations. +;; + +(defn border-layer + "Decorate layer with a border." + ([content] + (border-layer content 1)) + ([content width] + (border-layer content width 0)) + ([content width gap] + (let [offset (+ width gap)] + (reify-layer + (render! [l c g] + (let [w (:width c) + h (:height c)] + (.setColor g (-> c :theme :border-color)) + (doseq [i (range 0 width)] + (.drawRect g i i (- w 1 i i) (- h 1 i i))) + (draw! c content g offset offset (- w offset offset) + (- h offset offset)))) + (size [l c] + (let [s (size content c)] + [(+ (s 0) offset offset) + (+ (s 1) offset offset)])) + (anchor [l c] + (let [a (anchor content c)] + [(+ (a 0) offset) + (+ (a 1) offset)])))))) + +;; (defn text-layer +;; ([text] +;; (text :left :top)) +;; ([text h-align v-align] +;; (let [newline #"\\r\\n|\\n|\\r|\\u0085|\\u2028|\\u2029"] +;; (reify-layer)))) \ No newline at end of file
--- a/src/indyvon/event.clj Mon Jun 14 06:26:07 2010 +0400 +++ b/src/indyvon/event.clj Tue Jun 15 04:35:57 2010 +0400 @@ -71,10 +71,8 @@ (- (.getY event) y) (.getClickCount event) (.isPopupTrigger event)] - (getXOnScreen [] - (.getXOnScreen event)) - (getYOnScreen [] - (.getYOnScreen event)))) + (getXOnScreen [] (.getXOnScreen event)) + (getYOnScreen [] (.getYOnScreen event)))) (defn- translate-and-dispatch ([contexts event] @@ -130,30 +128,30 @@ (reify EventDispatcher (listen! [this component] - (doto component - (.addMouseListener this) - (.addMouseMotionListener this))) + (doto component + (.addMouseListener this) + (.addMouseMotionListener this))) (register [this context] - (dosync (alter context-tree-r add-context context))) + (dosync (alter context-tree-r add-context context))) (commit [this] - (dosync (ref-set context-tree @context-tree-r) - (ref-set context-tree-r {}))) + (dosync (ref-set context-tree @context-tree-r) + (ref-set context-tree-r {}))) (picked? [this layer] false) (hovered? [this layer] false) MouseListener (mouseEntered [this event] - (dispatch-mouse-motion hovered context-tree event)) + (dispatch-mouse-motion hovered context-tree event)) (mouseExited [this event] - (dispatch-mouse-motion hovered context-tree event)) + (dispatch-mouse-motion hovered context-tree event)) (mouseClicked [this event] - (dispatch-mouse-button picked hovered context-tree event)) + (dispatch-mouse-button picked hovered context-tree event)) (mousePressed [this event] - (dispatch-mouse-button picked hovered context-tree event)) + (dispatch-mouse-button picked hovered context-tree event)) (mouseReleased [this event] - (dispatch-mouse-button picked hovered context-tree event)) + (dispatch-mouse-button picked hovered context-tree event)) MouseMotionListener (mouseDragged [this event] - (translate-and-dispatch @picked event)) + (translate-and-dispatch @picked event)) (mouseMoved [this event] - (dispatch-mouse-motion hovered context-tree event))))) + (dispatch-mouse-motion hovered context-tree event)))))