on bbbd6ee help sign in
elk/libraries/Graphics/Element.elm
145 lines 5.4 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 Graphics.Color as 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 e = e.props.width
34heightOf e = e.props.height
35sizeOf e = (e.props.width, e.props.height)
37width nw e = let p = e.props
38 props = case e.element of
39 Image _ w h _ -> {p| height <- h/w*nw }
40 RawHtml html -> {p| height <- htmlHeight nw html }
41 _ -> p
42 in { element=e.element, props={props| width <- nw} }
43height nh e = let p = e.props
44 props = case e.element of
45 Image _ w h _ -> {p| width <- w/h*nh }
46 _ -> p
47 in { element=e.element, props={p| height <- nh} }
48opacity o e = let p = e.props in { element=e.element, props={p| opacity <- o} }
49color c e = let p = e.props in
50 { element=e.element, props={p| color <- Just c} }
51tag name e = let p = e.props in
52 { element=e.element, props={p| tag <- JS.fromString name} }
53link href e = let p = e.props in
54 { element=e.element, props={p| href <- JS.fromString href} }
56emptyStr = JS.fromString ""
57newElement w h e =
58 { props = Properties (guid ()) w h 1 Nothing emptyStr emptyStr, element = e }
60data ElementPrim
61 = Image ImageStyle Int Int JSString
62 | Container Position Element
63 | Flow Direction [Element]
64 | Spacer
65 | RawHtml JSString
66 | Custom -- for custom Elements implemented in JS, see collage for example
68data ImageStyle = Plain | Fitted | Cropped (Int,Int)
70image w h src = newElement w h (Image Plain w h (JS.fromString src))
71fittedImage w h src = newElement w h (Image Fitted w h (JS.fromString src))
72croppedImage w h pos src =
73 newElement w h (Image (Cropped pos) w h (JS.fromString src))
75data Three = P | Z | N
76data Pos = Absolute Int | Relative Float
77type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }
79container w h pos e = newElement w h (Container pos e)
80spacer w h = newElement w h Spacer
82data Direction = DUp | DDown | DLeft | DRight | DIn | DOut
84flow dir es =
85 let ws = List.map widthOf es
86 hs = List.map heightOf es
87 newFlow w h = newElement w h (Flow dir es)
88 in
89 case dir of
90 DUp -> newFlow (List.maximum ws) (List.sum hs)
91 DDown -> newFlow (List.maximum ws) (List.sum hs)
92 DLeft -> newFlow (List.sum ws) (List.maximum hs)
93 DRight -> newFlow (List.sum ws) (List.maximum hs)
94 DIn -> newFlow (List.maximum ws) (List.maximum hs)
95 DOut -> newFlow (List.maximum ws) (List.maximum hs)
97above hi lo =
98 newElement (max (widthOf hi) (widthOf lo))
99 (heightOf hi + heightOf lo)
100 (Flow DDown [hi,lo])
101below lo hi =
102 newElement (max (widthOf hi) (widthOf lo))
103 (heightOf hi + heightOf lo)
104 (Flow DDown [hi,lo])
105beside lft rht =
106 newElement (widthOf lft + widthOf rht)
107 (max (heightOf lft) (heightOf rht))
108 (Flow right [lft,rht])
110layers es =
111 let ws = List.map widthOf es
112 hs = List.map heightOf es
113 in newElement (List.maximum ws) (List.maximum hs) (Flow DOut es)
116-- Repetitive things --
118absolute = Absolute
119relative = Relative
121middle = { horizontal = Z, vertical = Z, x = Relative 0.5, y = Relative 0.5 }
122topLeft = { horizontal = N, vertical = P, x = Absolute 0, y = Absolute 0 }
123topRight = { topLeft | horizontal <- P }
124bottomLeft = { topLeft | vertical <- N }
125bottomRight = { bottomLeft | horizontal <- P }
126midLeft = { middle | horizontal <- N, x <- Absolute 0 }
127midRight = { midLeft | horizontal <- P }
128midTop = { middle | vertical <- P, y <- Absolute 0 }
129midBottom = { midTop | vertical <- N }
130middleAt x y = { horizontal = Z, vertical = Z, x = x, y = y }
131topLeftAt x y = { horizontal = N, vertical = P, x = x, y = y }
132topRightAt x y = { horizontal = P, vertical = P, x = x, y = y }
133bottomLeftAt x y = { horizontal = N, vertical = N, x = x, y = y }
134bottomRightAt x y = { horizontal = P, vertical = N, x = x, y = y }
135midLeftAt x y = { horizontal = N, vertical = Z, x = x, y = y }
136midRightAt x y = { horizontal = P, vertical = Z, x = x, y = y }
137midTopAt x y = { horizontal = Z, vertical = P, x = x, y = y }
138midBottomAt x y = { horizontal = Z, vertical = N, x = x, y = y }
140up = DUp
141down = DDown
142left = DLeft
143right = DRight
144inward = DIn
145outward = DOut