@@ -1,5 +1,8 @@
2module Graphics.Element where
1module Graphics.Element where
2+{-| Graphical elements that snap together to build complex widgets and layouts.
3+Each Element is a rectangle with a known width and height, making them easy to
4import open Basics
7import open Basics
5import Native.Utils
8import Native.Utils
@@ -22,19 +25,19 @@ type Properties = {
23type Element = { props : Properties, element : ElementPrim }
26type Element = { props : Properties, element : ElementPrim }
25−-- Get the width of an Element
28+{-| Get the width of an Element -}
26widthOf : Element -> Int
29widthOf : Element -> Int
27widthOf e = e.props.width
30widthOf e = e.props.width
29−-- Get the height of an Element
32+{-| Get the height of an Element -}
30heightOf : Element -> Int
33heightOf : Element -> Int
31heightOf e = e.props.height
34heightOf e = e.props.height
33−-- Get the width and height of an Element
36+{-| Get the width and height of an Element -}
34sizeOf : Element -> (Int,Int)
37sizeOf : Element -> (Int,Int)
35sizeOf e = (e.props.width, e.props.height)
38sizeOf e = (e.props.width, e.props.height)
37−-- Create an `Element` with a given width.
40+{-| Create an `Element` with a given width. -}
38width : Int -> Element -> Element
41width : Int -> Element -> Element
39width nw e =
42width nw e =
40 let p = e.props
43 let p = e.props
@@ -44,7 +47,7 @@ width nw e =
45 in { element=e.element, props={ props | width <- nw } }
48 in { element=e.element, props={ props | width <- nw } }
47−-- Create an `Element` with a given height.
50+{-| Create an `Element` with a given height. -}
48height : Int -> Element -> Element
51height : Int -> Element -> Element
49height nh e =
52height nh e =
50 let p = e.props
53 let p = e.props
@@ -53,30 +56,32 @@ height nh e =
54 in { element=e.element, props={ p | height <- nh} }
57 in { element=e.element, props={ p | height <- nh} }
56−-- Create an `Element` with a new width and height.
59+{-| Create an `Element` with a new width and height. -}
57size : Int -> Int -> Element -> Element
60size : Int -> Int -> Element -> Element
58size w h e = height h (width w e)
61size w h e = height h (width w e)
60−-- Create an `Element` with a given opacity. Opacity is a number between 0 and 1
63+{-| Create an `Element` with a given opacity. Opacity is a number between 0 and 1
61−-- where 0 means totally clear.
64+where 0 means totally clear.
62opacity : Float -> Element -> Element
66opacity : Float -> Element -> Element
63opacity o e = let p = e.props in { element=e.element, props={p| opacity <- o} }
67opacity o e = let p = e.props in { element=e.element, props={p| opacity <- o} }
65−-- Create an `Element` with a given background color.
69+{-| Create an `Element` with a given background color. -}
66color : Color -> Element -> Element
70color : Color -> Element -> Element
67color c e = let p = e.props in
71color c e = let p = e.props in
68 { element = e.element
72 { element = e.element
69 , props = { p | color <- Just c}
73 , props = { p | color <- Just c}
72−-- Create an `Element` with a tag. This lets you link directly to it.
76+{-| Create an `Element` with a tag. This lets you link directly to it.
73−-- The element `(tag "all-about-badgers" thirdParagraph)` can be reached
77+The element `(tag "all-about-badgers" thirdParagraph)` can be reached
74−-- with a link lik this: `/facts-about-animals.elm#all-about-badgers`
78+with a link lik this: `/facts-about-animals.elm#all-about-badgers`
75tag : String -> Element -> Element
80tag : String -> Element -> Element
76tag name e = let p = e.props in
81tag name e = let p = e.props in
77 { element=e.element, props={p | tag <- JS.fromString name} }
82 { element=e.element, props={p | tag <- JS.fromString name} }
79−-- Create an `Element` that is a hyper-link.
84+{-| Create an `Element` that is a hyper-link. -}
80link : String -> Element -> Element
85link : String -> Element -> Element
81link href e = let p = e.props in
86link href e = let p = e.props in
82 { element=e.element, props={p | href <- JS.fromString href} }
87 { element=e.element, props={p | href <- JS.fromString href} }
@@ -95,20 +100,22 @@ data ElementPrim
96data ImageStyle = Plain | Fitted | Cropped (Int,Int) | Tiled
101data ImageStyle = Plain | Fitted | Cropped (Int,Int) | Tiled
98−-- Create an image given a width, height, and image source.
103+{-| Create an image given a width, height, and image source. -}
99image : Int -> Int -> String -> Element
104image : Int -> Int -> String -> Element
100image w h src = newElement w h (Image Plain w h (JS.fromString src))
105image w h src = newElement w h (Image Plain w h (JS.fromString src))
102−-- Create a fitted image given a width, height, and image source.
107+{-| Create a fitted image given a width, height, and image source.
103−-- This will crop the picture to best fill the given dimensions.
108+This will crop the picture to best fill the given dimensions.
104fittedImage : Int -> Int -> String -> Element
110fittedImage : Int -> Int -> String -> Element
105fittedImage w h src = newElement w h (Image Fitted w h (JS.fromString src))
111fittedImage w h src = newElement w h (Image Fitted w h (JS.fromString src))
107−-- Create a cropped image. Take a rectangle out of the picture starting
113+{-| Create a cropped image. Take a rectangle out of the picture starting
108−-- at the given top left coordinate. If you have a 140-by-140 image,
114+at the given top left coordinate. If you have a 140-by-140 image,
109−-- the following will cut a 100-by-100 square out of the middle of it.
115+the following will cut a 100-by-100 square out of the middle of it.
111−-- croppedImage (20,20) 100 100 "yogi.jpg"
117+ croppedImage (20,20) 100 100 "yogi.jpg"
112croppedImage : (Int,Int) -> Int -> Int -> String -> Element
119croppedImage : (Int,Int) -> Int -> Int -> String -> Element
113croppedImage pos w h src =
120croppedImage pos w h src =
114 newElement w h (Image (Cropped pos) w h (JS.fromString src))
121 newElement w h (Image (Cropped pos) w h (JS.fromString src))
@@ -121,31 +128,34 @@ data Three = P | Z | N
121data Pos = Absolute Int | Relative Float
128data Pos = Absolute Int | Relative Float
122type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }
129type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }
124−-- Put an element in a container. This lets you position the element really
131+{-| Put an element in a container. This lets you position the element really
125−-- easily, and there are tons of ways to set the `Position`.
132+easily, and there are tons of ways to set the `Position`.
126−-- To center `element` exactly in a 300-by-300 square you would say:
133+To center `element` exactly in a 300-by-300 square you would say:
128−-- container 300 300 middle element
135+ container 300 300 middle element
130−-- By setting the color of the container, you can create borders.
137+By setting the color of the container, you can create borders.
131container : Int -> Int -> Position -> Element -> Element
139container : Int -> Int -> Position -> Element -> Element
132container w h pos e = newElement w h (Container pos e)
140container w h pos e = newElement w h (Container pos e)
134−-- Create an empty box. This is useful for getting your spacing right and
142+{-| Create an empty box. This is useful for getting your spacing right and
135−-- for making borders.
143+for making borders.
136spacer : Int -> Int -> Element
145spacer : Int -> Int -> Element
137spacer w h = newElement w h Spacer
146spacer w h = newElement w h Spacer
139data Direction = DUp | DDown | DLeft | DRight | DIn | DOut
148data Direction = DUp | DDown | DLeft | DRight | DIn | DOut
141−-- Have a list of elements flow in a particular direction.
150+{-| Have a list of elements flow in a particular direction.
142−-- The `Direction` starts from the first element in the list.
151+The `Direction` starts from the first element in the list.
144−-- flow right [a,b,c]
153+ flow right [a,b,c]
146−-- +---+---+---+
155+ +---+---+---+
147−-- | a | b | c |
156+ | a | b | c |
148−-- +---+---+---+
157+ +---+---+---+
149flow : Direction -> [Element] -> Element
159flow : Direction -> [Element] -> Element
150flow dir es =
160flow dir es =
151 let ws = List.map widthOf es
161 let ws = List.map widthOf es
@@ -161,33 +171,37 @@ flow dir es =
161 DIn -> newFlow (List.maximum ws) (List.maximum hs)
171 DIn -> newFlow (List.maximum ws) (List.maximum hs)
162 DOut -> newFlow (List.maximum ws) (List.maximum hs)
172 DOut -> newFlow (List.maximum ws) (List.maximum hs)
164−-- Stack elements vertically. To put `a` above `b` you would say:
174+{-| Stack elements vertically. To put `a` above `b` you would say:
166−-- a `above` b
176+ a `above` b
167above : Element -> Element -> Element
178above : Element -> Element -> Element
168above hi lo =
179above hi lo =
169 newElement (max (widthOf hi) (widthOf lo))
180 newElement (max (widthOf hi) (widthOf lo))
170 (heightOf hi + heightOf lo)
181 (heightOf hi + heightOf lo)
171 (Flow DDown [hi,lo])
182 (Flow DDown [hi,lo])
173−-- Stack elements vertically. To put `a` below `b` you would say:
184+{-| Stack elements vertically. To put `a` below `b` you would say:
175−-- a `below` b
186+ a `below` b
176below : Element -> Element -> Element
188below : Element -> Element -> Element
177below lo hi =
189below lo hi =
178 newElement (max (widthOf hi) (widthOf lo))
190 newElement (max (widthOf hi) (widthOf lo))
179 (heightOf hi + heightOf lo)
191 (heightOf hi + heightOf lo)
180 (Flow DDown [hi,lo])
192 (Flow DDown [hi,lo])
182−-- Put elements beside each other horizontally.
194+{-| Put elements beside each other horizontally.
183beside : Element -> Element -> Element
196beside : Element -> Element -> Element
184beside lft rht =
197beside lft rht =
185 newElement (widthOf lft + widthOf rht)
198 newElement (widthOf lft + widthOf rht)
186 (max (heightOf lft) (heightOf rht))
199 (max (heightOf lft) (heightOf rht))
187 (Flow right [lft,rht])
200 (Flow right [lft,rht])
189−-- Layer elements on top of each other, starting from the bottom.
202+{-| Layer elements on top of each other, starting from the bottom.
190−-- `(layers == flow outward)`
203+`(layers == flow outward)`
191layers : [Element] -> Element
205layers : [Element] -> Element
192layers es =
206layers es =
193 let ws = List.map widthOf es
207 let ws = List.map widthOf es