changeset 16:0fda22fc53d2

Remove anchor from Layer protocol. More function text layout calculation.
author Mikhail Kryshen <mikhail@kryshen.net>
date Thu, 17 Jun 2010 05:20:37 +0400
parents 87bd822aa815
children 31382464ef27
files src/indyvon/component.clj src/indyvon/core.clj
diffstat 2 files changed, 31 insertions(+), 65 deletions(-) [+]
line diff
     1.1 --- a/src/indyvon/component.clj	Tue Jun 15 06:31:11 2010 +0400
     1.2 +++ b/src/indyvon/component.clj	Thu Jun 17 05:20:37 2010 +0400
     1.3 @@ -47,7 +47,7 @@
     1.4    (do 
     1.5      (def frame (java.awt.Frame. "Test"))
     1.6      (def layer1
     1.7 -         (reify-layer
     1.8 +         (reify Layer
     1.9            (render! [this context g]
    1.10               (register-context context)
    1.11               (.setColor g Color/RED)
    1.12 @@ -55,7 +55,7 @@
    1.13            (size [this context] [30 20])))
    1.14      (def layer1b (border-layer layer1 2 3))
    1.15      (def layer2
    1.16 -         (reify-layer
    1.17 +         (reify Layer
    1.18            (render! [this context g]
    1.19               (register-context context)
    1.20               (.setColor g Color/YELLOW)
    1.21 @@ -66,7 +66,7 @@
    1.22      (def layer3
    1.23           (border-layer (text-layer "Sample\ntext" :right :bottom)))
    1.24      (def layer
    1.25 -         (reify-layer
    1.26 +         (reify Layer
    1.27            (render! [this context g]
    1.28               (.drawLine g 0 0 (:width context) (:height context))
    1.29               (draw! context layer2 g 15 20)
     2.1 --- a/src/indyvon/core.clj	Tue Jun 15 06:31:11 2010 +0400
     2.2 +++ b/src/indyvon/core.clj	Thu Jun 17 05:20:37 2010 +0400
     2.3 @@ -10,8 +10,7 @@
     2.4  
     2.5  (defprotocol Layer
     2.6    (render! [this context graphics])
     2.7 -  (size [this context])
     2.8 -  (anchor [this context]))
     2.9 +  (size [this context]))
    2.10  
    2.11  (defrecord Theme [fore-color back-color border-color font])
    2.12  
    2.13 @@ -24,25 +23,6 @@
    2.14  (defn default-context []
    2.15    (LayerContext. nil nil 0 0 0 0 nil nil nil (default-theme)))
    2.16  
    2.17 -(defn- spec-map
    2.18 -  ([specs]
    2.19 -     (spec-map {} specs))
    2.20 -  ([mm specs]
    2.21 -     (if-let [form (first specs)]
    2.22 -       (recur (conj mm [(first form) (next form)])
    2.23 -              (next specs))
    2.24 -       mm)))
    2.25 -
    2.26 -(defn- merge-specs [s1 s2]
    2.27 -  (for [spec (spec-map (spec-map s1) s2)]
    2.28 -    (cons (first spec) (second spec))))
    2.29 -     
    2.30 -(defmacro reify-layer [& specs]
    2.31 -  `(reify Layer ~@(merge-specs
    2.32 -                   '((size [_ _] [0 0])
    2.33 -                     (anchor [_ _] [0 0]))
    2.34 -                   specs)))
    2.35 -
    2.36  (defn- make-graphics [graphics x y w h clip]
    2.37    (if clip
    2.38      (.create graphics x y w h)
    2.39 @@ -64,10 +44,10 @@
    2.40    ([context layer graphics x y clip]
    2.41       (let [s (size layer context)]
    2.42         (draw! context layer graphics
    2.43 -                      x y (s 0) (s 1) clip)))
    2.44 +              x y (s 0) (s 1) clip)))
    2.45    ([context layer graphics x y w h]
    2.46       (draw! context layer graphics
    2.47 -                    x y w h true))
    2.48 +            x y w h true))
    2.49    ([context layer graphics x y w h clip]
    2.50       (let [graphics (make-graphics graphics x y w h clip)
    2.51             graphics (apply-theme graphics (:theme context))]
    2.52 @@ -84,14 +64,6 @@
    2.53           (finally
    2.54            (.dispose graphics))))))
    2.55  
    2.56 -(defmacro decorate-layer [layer & specs]
    2.57 -  `(let [layer# ~layer]
    2.58 -     (reify Layer ~@(merge-specs
    2.59 -                     `((~'render! [l# c# g#] (draw! c# layer# g#))
    2.60 -                       (~'size [l# c#] (size layer# c#))
    2.61 -                       (~'anchor [l# c#] (anchor layer# c#)))
    2.62 -                     specs))))
    2.63 -
    2.64  ;;
    2.65  ;; Layer implementations.
    2.66  ;;
    2.67 @@ -104,7 +76,7 @@
    2.68       (border-layer content width 0))
    2.69    ([content width gap]
    2.70       (let [offset (+ width gap)]
    2.71 -       (reify-layer
    2.72 +       (reify Layer
    2.73          (render! [l c g]
    2.74             (let [w (:width c)
    2.75                   h (:height c)]
    2.76 @@ -116,28 +88,20 @@
    2.77          (size [l c]
    2.78             (let [s (size content c)]
    2.79               [(+ (s 0) offset offset)
    2.80 -              (+ (s 1) offset offset)]))
    2.81 -        (anchor [l c]
    2.82 -           (let [a (anchor content c)]
    2.83 -             [(+ (a 0) offset)
    2.84 -              (+ (a 1) offset)]))))))
    2.85 +              (+ (s 1) offset offset)]))))))
    2.86  
    2.87  (defn- re-split [re s]
    2.88    (seq (.split re s)))
    2.89  
    2.90 -(defn- text-size [lines font font-context]
    2.91 -  (loop [lines lines
    2.92 -         width 0
    2.93 -         height 0]
    2.94 -    (if-let [line (first lines)]
    2.95 -      (let [layout (TextLayout. line font font-context)]
    2.96 -        (recur (next lines)
    2.97 -               (max width (.getAdvance layout))
    2.98 -               (+ height
    2.99 -                  (.getAscent layout)
   2.100 -                  (.getDescent layout)
   2.101 -                  (.getLeading layout))))
   2.102 -      [width height])))
   2.103 +(defn- layout-text [lines font font-context]
   2.104 +  (map #(TextLayout. % font font-context) lines))
   2.105 +
   2.106 +(defn- text-width [layouts]
   2.107 +  (reduce #(max %1 (.getAdvance %2)) 0 layouts))
   2.108 +
   2.109 +(defn- text-height [layouts]
   2.110 +  (reduce #(+ %1 (.getAscent %2) (.getDescent %2) (.getLeading %2))
   2.111 +          0 layouts))
   2.112  
   2.113  (defn text-layer
   2.114    "Creates a layer to display multiline text."
   2.115 @@ -145,29 +109,31 @@
   2.116       (text-layer text :left :top))
   2.117    ([text h-align v-align]
   2.118       (let [lines (re-split #"\r\n|\n|\r|\u0085|\u2028|\u2029" text)]
   2.119 -       (reify-layer
   2.120 +       (reify Layer
   2.121          (render! [l c g]
   2.122             (let [w (:width c)
   2.123                   h (:height c)
   2.124                   font (.getFont g)
   2.125                   font-context (:font-context c)
   2.126 +                 layouts (layout-text lines font font-context)
   2.127                   y (case v-align
   2.128                       :top 0
   2.129 -                     :center (/ (- h ((text-size
   2.130 -                                       lines font font-context) 1))
   2.131 -                                2)
   2.132 -                     :bottom (- h ((text-size
   2.133 -                                    lines font font-context) 1)))]
   2.134 -             (loop [lines lines, y y]
   2.135 -               (when-first [line lines]
   2.136 -                 (let [layout (TextLayout. line font font-context)
   2.137 -                       ascent (.getAscent layout)
   2.138 +                     :center (/ (- h (text-height layouts)) 2)
   2.139 +                     :bottom (- h (text-height layouts)))]
   2.140 +             (loop [layouts layouts, y y]
   2.141 +               (when-first [layout layouts]
   2.142 +                 (let [ascent (.getAscent layout)
   2.143                         lh (+ ascent (.getDescent layout) (.getLeading layout))
   2.144                         x (case h-align
   2.145                             :left 0
   2.146                             :center (/ (- w (.getAdvance layout)) 2)
   2.147                             :right (- w (.getAdvance layout)))]
   2.148                     (.draw layout g x (+ y ascent))
   2.149 -                   (recur (next lines) (+ y lh)))))))
   2.150 +                   (recur (next layouts) (+ y lh)))))))
   2.151          (size [l c]
   2.152 -           (text-size lines (-> c :theme :font) (:font-context c)))))))
   2.153 +           (let [layouts (layout-text lines
   2.154 +                                      (-> c :theme :font)
   2.155 +                                      (:font-context c))
   2.156 +                 width (text-width layouts)
   2.157 +                 height (text-height layouts)]
   2.158 +             [width height]))))))