rlm@10
|
1 ;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and
|
rlm@10
|
2 ;; distribution terms for this software are covered by the Eclipse Public
|
rlm@10
|
3 ;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can
|
rlm@10
|
4 ;; be found in the file epl-v10.html at the root of this distribution. By
|
rlm@10
|
5 ;; using this software in any fashion, you are agreeing to be bound by the
|
rlm@10
|
6 ;; terms of this license. You must not remove this notice, or any other,
|
rlm@10
|
7 ;; from this software.
|
rlm@10
|
8 ;;
|
rlm@10
|
9 ;; clojure.contrib.miglayout.internal
|
rlm@10
|
10 ;;
|
rlm@10
|
11 ;; Internal functions for 'clojure.contrib.miglayout
|
rlm@10
|
12 ;;
|
rlm@10
|
13 ;; scgilardi (gmail)
|
rlm@10
|
14 ;; Created 13 October 2008
|
rlm@10
|
15
|
rlm@10
|
16 (ns clojure.contrib.miglayout.internal
|
rlm@10
|
17 (:import (clojure.lang RT Reflector)
|
rlm@10
|
18 java.awt.Component
|
rlm@10
|
19 javax.swing.JComponent)
|
rlm@10
|
20 (:use (clojure.contrib
|
rlm@10
|
21 [core :only (new-by-name)]
|
rlm@10
|
22 [except :only (throwf)]
|
rlm@10
|
23 [fcase :only (fcase)]
|
rlm@10
|
24 [string :only (as-str)])))
|
rlm@10
|
25
|
rlm@10
|
26 (def MigLayout "net.miginfocom.swing.MigLayout")
|
rlm@10
|
27 (def LayoutCallback "net.miginfocom.layout.LayoutCallback")
|
rlm@10
|
28 (def ConstraintParser "net.miginfocom.layout.ConstraintParser")
|
rlm@10
|
29
|
rlm@10
|
30 (declare format-constraints)
|
rlm@10
|
31
|
rlm@10
|
32 (defn format-constraint
|
rlm@10
|
33 "Returns a vector of vectors representing one or more constraints
|
rlm@10
|
34 separated by commas. Constraints may be specified in Clojure using
|
rlm@10
|
35 strings, keywords, vectors, maps, and/or sets."
|
rlm@10
|
36 [c]
|
rlm@10
|
37 [[", "]
|
rlm@10
|
38 (fcase #(%1 %2) c
|
rlm@10
|
39 string? [c]
|
rlm@10
|
40 keyword? [c]
|
rlm@10
|
41 vector? (interpose " " c)
|
rlm@10
|
42 map? (apply concat (interpose [", "] (map #(interpose " " %) c)))
|
rlm@10
|
43 set? (apply concat (interpose [", "] (map format-constraints c)))
|
rlm@10
|
44 (throwf IllegalArgumentException
|
rlm@10
|
45 "unrecognized constraint: %s (%s)" c (class c)))])
|
rlm@10
|
46
|
rlm@10
|
47 (defn format-constraints
|
rlm@10
|
48 "Returns a string representing all the constraints for one keyword-item
|
rlm@10
|
49 or component formatted for miglayout."
|
rlm@10
|
50 [& constraints]
|
rlm@10
|
51 (let [formatted
|
rlm@10
|
52 (apply str
|
rlm@10
|
53 (map as-str
|
rlm@10
|
54 (rest (reduce concat []
|
rlm@10
|
55 (mapcat format-constraint constraints)))))]
|
rlm@10
|
56 ;; (prn formatted)
|
rlm@10
|
57 formatted))
|
rlm@10
|
58
|
rlm@10
|
59 (defn component?
|
rlm@10
|
60 "Returns true if x is a java.awt.Component"
|
rlm@10
|
61 [x]
|
rlm@10
|
62 (instance? Component x))
|
rlm@10
|
63
|
rlm@10
|
64 (defn constraint?
|
rlm@10
|
65 "Returns true if x is not a keyword-item or component"
|
rlm@10
|
66 [x]
|
rlm@10
|
67 (not
|
rlm@10
|
68 (or (component? x)
|
rlm@10
|
69 (#{:layout :column :row} x))))
|
rlm@10
|
70
|
rlm@10
|
71 (defn parse-item-constraints
|
rlm@10
|
72 "Iterates over args and builds a map containing values associated with
|
rlm@10
|
73 :keywords and :components. The value for :keywords is a map from keyword
|
rlm@10
|
74 items to constraints strings. The value for :components is a vector of
|
rlm@10
|
75 vectors each associating a component with its constraints string."
|
rlm@10
|
76 [& args]
|
rlm@10
|
77 (loop [[item & args] args
|
rlm@10
|
78 item-constraints {:keywords {} :components []}]
|
rlm@10
|
79 (if item
|
rlm@10
|
80 (let [[constraints args] (split-with constraint? args)]
|
rlm@10
|
81 (recur args
|
rlm@10
|
82 (update-in
|
rlm@10
|
83 item-constraints
|
rlm@10
|
84 [(if (component? item) :components :keywords)]
|
rlm@10
|
85 conj [item (apply format-constraints constraints)])))
|
rlm@10
|
86 item-constraints)))
|
rlm@10
|
87
|
rlm@10
|
88 (defn parse-component-constraint
|
rlm@10
|
89 "Parses a component constraint string returning a CC object"
|
rlm@10
|
90 [constraint]
|
rlm@10
|
91 (Reflector/invokeStaticMethod
|
rlm@10
|
92 ConstraintParser "parseComponentConstraint" (into-array [constraint])))
|
rlm@10
|
93
|
rlm@10
|
94 (defn add-components
|
rlm@10
|
95 "Adds components with constraints to a container"
|
rlm@10
|
96 [^JComponent container components]
|
rlm@10
|
97 (loop [[[^Component component constraint] & components] components
|
rlm@10
|
98 id-map nil]
|
rlm@10
|
99 (if component
|
rlm@10
|
100 (let [cc (parse-component-constraint constraint)]
|
rlm@10
|
101 (.add container component cc)
|
rlm@10
|
102 (recur
|
rlm@10
|
103 components
|
rlm@10
|
104 (if-let [id (.getId cc)]
|
rlm@10
|
105 (assoc id-map (keyword id) component)
|
rlm@10
|
106 id-map)))
|
rlm@10
|
107 (doto container (.putClientProperty ::components id-map)))))
|
rlm@10
|
108
|
rlm@10
|
109 (defn get-components
|
rlm@10
|
110 "Returns a map from id to component for all components with an id"
|
rlm@10
|
111 [^JComponent container]
|
rlm@10
|
112 (.getClientProperty container ::components))
|
rlm@10
|
113
|
rlm@10
|
114 (defn do-layout
|
rlm@10
|
115 "Attaches a MigLayout layout manager to container and adds components
|
rlm@10
|
116 with constraints"
|
rlm@10
|
117 [^JComponent container layout column row components]
|
rlm@10
|
118 (doto container
|
rlm@10
|
119 (.setLayout (new-by-name MigLayout layout column row))
|
rlm@10
|
120 (add-components components)))
|