on 104faf1 help sign in
elk/libraries/Graphics/Element.elm
209 lines 6.9 kB history raw
2module Graphics.Element (widthOf, heightOf, sizeOf,
3 width, height, opacity, color, tag, link,
4 image, fittedImage, croppedImage,
5 flow, up, down, left, right, inward, outward,
6 above, below, beside, layers,
7 container, absolute, relative,
8 middle, topLeft, topRight, bottomLeft, bottomRight,
9 midLeft, midRight, midTop, midBottom, middleAt,
10 topLeftAt, topRightAt, bottomLeftAt, bottomRightAt,
11 midLeftAt, midRightAt, midTopAt, midBottomAt,
12 spacer, newElement
13 ) where
15import Native.Utils (guid, max, htmlHeight)
16import JavaScript as JS
17import List as List
18import Color
19import Maybe (Just, Nothing)
21type Properties = {
22 id : Int,
23 width : Int,
24 height : Int,
25 opacity : Float,
26 color : Maybe Color,
27 href : JSString,
28 tag : JSString
29 }
31type Element = { props : Properties, element : ElementPrim }
33widthOf : Element -> Int
34widthOf e = e.props.width
36heightOf : Element -> Int
37heightOf e = e.props.height
39sizeOf : Element -> Int
40sizeOf e = (e.props.width, e.props.height)
42width : Int -> Element -> Element
43width nw e = let p = e.props
44 props = case e.element of
45 Image _ w h _ -> {p| height <- h/w*nw }
46 RawHtml html -> {p| height <- let (w,h) = htmlHeight nw html in h}
47 _ -> p
48 in { element=e.element, props={props| width <- nw} }
50height : Int -> Element -> Element
51height nh e = let p = e.props
52 props = case e.element of
53 Image _ w h _ -> {p| width <- w/h*nh }
54 _ -> p
55 in { element=e.element, props={p| height <- nh} }
57opacity : Float -> Element -> Element
58opacity o e = let p = e.props in { element=e.element, props={p| opacity <- o} }
60color : Color -> Element -> Element
61color c e = let p = e.props in
62 { element=e.element, props={p| color <- Just c} }
64tag : String -> Element -> Element
65tag name e = let p = e.props in
66 { element=e.element, props={p| tag <- JS.fromString name} }
68link : String -> Element -> Element
69link href e = let p = e.props in
70 { element=e.element, props={p| href <- JS.fromString href} }
72emptyStr = JS.fromString ""
73newElement w h e =
74 { props = Properties (guid ()) w h 1 Nothing emptyStr emptyStr, element = e }
76data ElementPrim
77 = Image ImageStyle Int Int JSString
78 | Container Position Element
79 | Flow Direction [Element]
80 | Spacer
81 | RawHtml JSString
82 | Custom -- for custom Elements implemented in JS, see collage for example
84data ImageStyle = Plain | Fitted | Cropped (Int,Int)
86image : Int -> Int -> String -> Element
87image w h src = newElement w h (Image Plain w h (JS.fromString src))
89fittedImage : Int -> Int -> String -> Element
90fittedImage w h src = newElement w h (Image Fitted w h (JS.fromString src))
92croppedImage : Int -> Int -> (Int,Int) -> String -> Element
93croppedImage w h pos src =
94 newElement w h (Image (Cropped pos) w h (JS.fromString src))
96data Three = P | Z | N
97data Pos = Absolute Int | Relative Float
98type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }
100container : Int -> Int -> Position -> Element -> Element
101container w h pos e = newElement w h (Container pos e)
103spacer : Int -> Int -> Element
104spacer w h = newElement w h Spacer
106data Direction = DUp | DDown | DLeft | DRight | DIn | DOut
108flow : Direction -> [Element] -> Element
109flow dir es =
110 let ws = List.map widthOf es
111 hs = List.map heightOf es
112 newFlow w h = newElement w h (Flow dir es)
113 in
114 if es == [] then spacer 0 0 else
115 case dir of
116 DUp -> newFlow (List.maximum ws) (List.sum hs)
117 DDown -> newFlow (List.maximum ws) (List.sum hs)
118 DLeft -> newFlow (List.sum ws) (List.maximum hs)
119 DRight -> newFlow (List.sum ws) (List.maximum hs)
120 DIn -> newFlow (List.maximum ws) (List.maximum hs)
121 DOut -> newFlow (List.maximum ws) (List.maximum hs)
123above : Element -> Element -> Element
124above hi lo =
125 newElement (max (widthOf hi) (widthOf lo))
126 (heightOf hi + heightOf lo)
127 (Flow DDown [hi,lo])
129below : Element -> Element -> Element
130below lo hi =
131 newElement (max (widthOf hi) (widthOf lo))
132 (heightOf hi + heightOf lo)
133 (Flow DDown [hi,lo])
135beside : Element -> Element -> Element
136beside lft rht =
137 newElement (widthOf lft + widthOf rht)
138 (max (heightOf lft) (heightOf rht))
139 (Flow right [lft,rht])
141layers : [Element] -> Element
142layers es =
143 let ws = List.map widthOf es
144 hs = List.map heightOf es
145 in newElement (List.maximum ws) (List.maximum hs) (Flow DOut es)
148-- Repetitive things --
150absolute : Int -> Pos
151absolute = Absolute
152relative : Float -> Pos
153relative = Relative
155middle : Position
156middle = { horizontal=Z, vertical=Z, x=Relative 0.5, y=Relative 0.5 }
157topLeft : Position
158topLeft = { horizontal=N, vertical=P, x=Absolute 0, y=Absolute 0 }
159topRight : Position
160topRight = { topLeft | horizontal <- P }
161bottomLeft : Position
162bottomLeft = { topLeft | vertical <- N }
163bottomRight : Position
164bottomRight = { bottomLeft | horizontal <- P }
165midLeft : Position
166midLeft = { middle | horizontal <- N, x <- Absolute 0 }
167midRight : Position
168midRight = { midLeft | horizontal <- P }
169midTop : Position
170midTop = { middle | vertical <- P, y <- Absolute 0 }
171midBottom : Position
172midBottom = { midTop | vertical <- N }
174middleAt : Pos -> Pos -> Position
175middleAt x y = { horizontal = Z, vertical = Z, x = x, y = y }
176topLeftAt : Pos -> Pos -> Position
177topLeftAt x y = { horizontal = N, vertical = P, x = x, y = y }
178topRightAt : Pos -> Pos -> Position
179topRightAt x y = { horizontal = P, vertical = P, x = x, y = y }
180bottomLeftAt : Pos -> Pos -> Position
181bottomLeftAt x y = { horizontal = N, vertical = N, x = x, y = y }
182bottomRightAt : Pos -> Pos -> Position
183bottomRightAt x y = { horizontal = P, vertical = N, x = x, y = y }
184midLeftAt : Pos -> Pos -> Position
185midLeftAt x y = { horizontal = N, vertical = Z, x = x, y = y }
186midRightAt : Pos -> Pos -> Position
187midRightAt x y = { horizontal = P, vertical = Z, x = x, y = y }
188midTopAt : Pos -> Pos -> Position
189midTopAt x y = { horizontal = Z, vertical = P, x = x, y = y }
190midBottomAt : Pos -> Pos -> Position
191midBottomAt x y = { horizontal = Z, vertical = N, x = x, y = y }
193up : Direction
194up = DUp
196down : Direction
197down = DDown
199left : Direction
200left = DLeft
202right : Direction
203right = DRight
205inward : Direction
206inward = DIn
208outward : Direction
209outward = DOut