Mercurial > hg > indyvon
changeset 44:064b21604f74
Improved performance.
Added image layer.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Mon, 19 Jul 2010 15:36:08 +0400 |
parents | 7d67064f0880 |
children | 33d836041cef |
files | src/kryshen/indyvon/core.clj src/kryshen/indyvon/graph.clj src/kryshen/indyvon/layers.clj |
diffstat | 3 files changed, 99 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/src/kryshen/indyvon/core.clj Mon Jul 12 03:52:21 2010 +0400 +++ b/src/kryshen/indyvon/core.clj Mon Jul 19 15:36:08 2010 +0400 @@ -95,33 +95,32 @@ y2 (min y12 y22)] (Bounds. x1 y1 (- x2 x1) (- y2 y1))))) -(defn- ^Graphics2D create-graphics +(defn ^Graphics2D create-graphics ([] (create-graphics 0 0 (:width *bounds*) (:height *bounds*))) ([x y w h] (apply-theme (.create *graphics* x y w h) *theme*))) -(defn with-bounds* [x y w h f & args] - (let [graphics (create-graphics x y w h) - bounds (Bounds. (+ x (:x *bounds*)) - (+ y (:y *bounds*)) - w h)] - (try - (apply with-bindings* {#'*bounds* bounds - #'*clip* (intersect bounds *clip*) - #'*graphics* graphics} - f args) - (finally - (.dispose graphics))))) +(defmacro with-bounds [x y w h & body] + `(let [bounds# (Bounds. (+ ~x (:x *bounds*)) + (+ ~y (:y *bounds*)) + ~w ~h) + clip# (intersect bounds# *clip*)] + (when (and (pos? (:width clip#)) (pos? (:height clip#))) + (let [graphics# (create-graphics ~x ~y ~w ~h)] + (try + (binding [*bounds* bounds# + *clip* clip# + *graphics* graphics#] + ~@body) + (finally + (.dispose graphics#))))))) -(defmacro with-bounds [x y w h & body] - `(with-bounds* ~x ~y ~w ~h (fn [] ~@body))) - -(defn with-handlers* [handle handlers f & args] - (apply with-bindings* - {#'*event-dispatcher* - (create-dispatcher *event-dispatcher* handle handlers)} - f args)) +(defmacro with-handlers* [handle handlers & body] + `(binding + [*event-dispatcher* + (create-dispatcher *event-dispatcher* ~handle ~handlers)] + ~@body)) (defmacro with-handlers "specs => (:event-id name & handler-body)* @@ -134,14 +133,15 @@ `(fn [~(second spec)] ~@(nnext spec)))) {} specs) - (fn [] ~form))) + ~form)) (defn with-theme* [theme f & args] (apply with-bindings* {#'*theme* (merge *theme* theme)} f args)) (defmacro with-theme [theme & body] - `(with-theme* ~theme (fn [] ~@body))) + `(binding [*theme* (merge *theme* ~theme)] + ~@body)) (defmacro with-color [color & body] `(let [color# (.getColor *graphics*)] @@ -160,14 +160,16 @@ ([layer] (let [graphics (create-graphics)] (try - (with-bindings* {#'*graphics* graphics} render! layer) + (binding [*graphics* graphics] + (render! layer)) (finally (.dispose graphics))))) ([layer x y] (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." @@ -305,7 +307,8 @@ (mousePressed [this event] (dispatch-mouse-button picked hovered event)) (mouseReleased [this event] - (dispatch-mouse-button picked hovered event)) + (translate-and-dispatch @picked true event)) + ;;(dispatch-mouse-button picked hovered event)) MouseMotionListener (mouseDragged [this event] (translate-and-dispatch @picked true event))
--- a/src/kryshen/indyvon/graph.clj Mon Jul 12 03:52:21 2010 +0400 +++ b/src/kryshen/indyvon/graph.clj Mon Jul 19 15:36:08 2010 +0400 @@ -76,29 +76,29 @@ (.draw *graphics* path))) (.translate *graphics* (- x) (- y))) -(defrecord GraphLayer [graph-layout movable dragged fix-x fix-y] +(defrecord GraphLayer [layout movable dragged fix-x fix-y] Layer (render! [layer] - (let [bounds (.getBounds graph-layout) + (let [bounds (.getBounds layout) x (- (.getX bounds)) y (- (.getY bounds))] - (draw-edges! graph-layout x y) + (draw-edges! layout x y) (if movable - (draw-movable-vertices! graph-layout x y dragged fix-x fix-y) - (draw-vertices! graph-layout x y)))) + (draw-movable-vertices! layout x y dragged fix-x fix-y) + (draw-vertices! layout x y)))) (layer-size [layer] - (let [bounds (.getBounds graph-layout)] + (let [bounds (.getBounds layout)] (Size. (.getWidth bounds) (.getHeight bounds)))) Anchored (anchor [layer x-align y-align] - (let [bounds (.getBounds graph-layout)] + (let [bounds (.getBounds layout)] (Location. (- (.getX bounds)) (- (.getY bounds)))))) (defn graph-layer ([graph-layout] (graph-layer graph-layout false)) - ([^GraphGraph-Layout graph-layout movable] + ([^GraphLayout graph-layout movable] (GraphLayer. graph-layout movable (ref nil) (ref 0) (ref 0)))) (defn build-graph
--- a/src/kryshen/indyvon/layers.clj Mon Jul 12 03:52:21 2010 +0400 +++ b/src/kryshen/indyvon/layers.clj Mon Jul 19 15:36:08 2010 +0400 @@ -7,7 +7,9 @@ (ns kryshen.indyvon.layers (:use kryshen.indyvon.core) (:import (kryshen.indyvon.core Size Location) - (java.awt Font Cursor) + (java.lang.ref SoftReference) + (java.awt Font Cursor Image Toolkit) + (java.awt.image ImageObserver) (java.awt.font FontRenderContext TextLayout))) ;; Define as macro to avoid unnecessary calculation of inner and outer @@ -25,12 +27,13 @@ `(align-xy ~inner ~outer ~align :top :center :bottom)) (defmacro decorate-layer [layer & render-tail] - `(reify - Layer - (render! ~@render-tail) - (layer-size [t#] (layer-size ~layer)) - Anchored - (anchor [t# xa# ya#] (anchor ~layer xa# ya#)))) + `(let [layer# ~layer] + (reify + Layer + (render! ~@render-tail) + (layer-size [t#] (layer-size layer#)) + Anchored + (anchor [t# xa# ya#] (anchor layer# xa# ya#))))) (defn padding ([content pad] @@ -81,8 +84,24 @@ (defn- re-split [^java.util.regex.Pattern re s] (seq (.split re s))) -(defn- layout-text [lines ^Font font ^FontRenderContext font-context] - (map #(TextLayout. ^String % font font-context) lines)) +(def text-layout-cache (atom {})) + +(defn- get-text-layout + [^String line ^Font font ^FontRenderContext font-context] + (let [key [line font font-context]] + (or (if-let [softref (@text-layout-cache key)] + (.get softref) + (do (swap! text-layout-cache dissoc key) + false)) + (let [layout (TextLayout. line font font-context)] + (println "text-layout-cache miss" line) + (swap! text-layout-cache assoc key (SoftReference. layout)) + layout)))) + +(defn- layout-text + [lines ^Font font ^FontRenderContext font-context] + (map #(get-text-layout % font font-context) lines)) + ;;(map #(TextLayout. ^String % font font-context) lines)) (defn- text-width [layouts] (reduce (fn [w ^TextLayout tl] (max w (.getAdvance tl))) 0 layouts)) @@ -119,6 +138,34 @@ height (text-height layouts)] (Size. width height))))))) +(defn- image-observer [update-fn] + (reify + ImageObserver + (imageUpdate [this img infoflags x y width height] + (update-fn) + (zero? (bit-and infoflags + (bit-or ImageObserver/ALLBITS + ImageObserver/ABORT)))))) + +(defn image-layer + [image-or-uri] + (let [^Image image (if (isa? image-or-uri Image) + image-or-uri + (.createImage (Toolkit/getDefaultToolkit) + ^java.net.URL image-or-uri))] + (.prepareImage (Toolkit/getDefaultToolkit) image -1 -1 nil) + (reify + Layer + (render! [layer] + (.drawImage *graphics* image 0 0 (image-observer *update*))) + (layer-size [layer] + (let [observer (image-observer *update*) + width (.getWidth image observer) + height (.getHeight image observer) + width (if (pos? width) width 1) + height (if (pos? height) height 1)] + (Size. width height)))))) + (defn viewport "Creates scrollable viewport layer." ([content] (viewport content :left :top)) @@ -175,9 +222,12 @@ (reify Layer (render! [t] - (with-theme* theme render! layer)) + (with-theme theme + (render! layer))) (layer-size [t] - (with-theme* theme layer-size layer)) + (with-theme theme + (layer-size layer))) Anchored (anchor [t xa ya] - (with-theme* theme anchor layer xa ya))))) + (with-theme theme + (anchor layer xa ya))))))