2module Graphics.Element (widthOf, heightOf, sizeOf,
3 width, height, size, opacity, color, tag, link,
4 image, fittedImage, croppedImage, tiledImage,
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,
15import Native.Utils (guid, max, htmlHeight)
16import JavaScript as JS
19import Maybe (Just, Nothing)
32type Element = { props : Properties, element : ElementPrim }
34-- Get the width of an Element
35widthOf : Element -> Int
36widthOf e = e.props.width
38-- Get the height of an Element
39heightOf : Element -> Int
40heightOf e = e.props.height
42-- Get the width and height of an Element
43sizeOf : Element -> (Int,Int)
44sizeOf e = (e.props.width, e.props.height)
46-- Create an `Element` with a given width.
47width : Int -> Element -> Element
48width nw e = let p = e.props
49 props = case e.element of
50 Image _ w h _ -> {p| height <- h/w*nw }
51 RawHtml html -> {p| height <- let (w,h) = htmlHeight nw html in h}
53 in { element=e.element, props={props| width <- nw} }
55-- Create an `Element` with a given height.
56height : Int -> Element -> Element
57height nh e = let p = e.props
58 props = case e.element of
59 Image _ w h _ -> {p| width <- w/h*nh }
61 in { element=e.element, props={p| height <- nh} }
63-- Create an `Element` with a new width and height.
64size : Int -> Int -> Element -> Element
65size w h e = height h (width w e)
67-- Create an `Element` with a given opacity. Opacity is a number between 0 and 1
68-- where 0 means totally clear.
69opacity : Float -> Element -> Element
70opacity o e = let p = e.props in { element=e.element, props={p| opacity <- o} }
72-- Create an `Element` with a given background color.
73color : Color -> Element -> Element
74color c e = let p = e.props in
75 { element=e.element, props={p| color <- Just c} }
77-- Create an `Element` with a tag. This lets you link directly to it.
78-- The element `(tag "all-about-badgers" thirdParagraph)` can be reached
79-- with a link lik this: `/facts-about-animals.elm#all-about-badgers`
80tag : String -> Element -> Element
81tag name e = let p = e.props in
82 { element=e.element, props={p| tag <- JS.fromString name} }
84-- Create an `Element` that is a hyper-link.
85link : String -> Element -> Element
86link href e = let p = e.props in
87 { element=e.element, props={p| href <- JS.fromString href} }
89emptyStr = JS.fromString ""
91 { props = Properties (guid ()) w h 1 Nothing emptyStr emptyStr (), element = e }
94 = Image ImageStyle Int Int JSString
95 | Container Position Element
96 | Flow Direction [Element]
99 | Custom -- for custom Elements implemented in JS, see collage for example
101data ImageStyle = Plain | Fitted | Cropped (Int,Int) | Tiled
103-- Create an image given a width, height, and image source.
104image : Int -> Int -> String -> Element
105image w h src = newElement w h (Image Plain w h (JS.fromString src))
107-- Create a fitted image given a width, height, and image source.
108-- This will crop the picture to best fill the given dimensions.
109fittedImage : Int -> Int -> String -> Element
110fittedImage w h src = newElement w h (Image Fitted w h (JS.fromString src))
112-- Create a cropped image. Take a rectangle out of the picture starting
113-- at the given top left coordinate. If you have a 140-by-140 image,
114-- the following will cut a 100-by-100 square out of the middle of it.
116-- croppedImage (20,20) 100 100 "yogi.jpg"
117croppedImage : (Int,Int) -> Int -> Int -> String -> Element
118croppedImage pos w h src =
119 newElement w h (Image (Cropped pos) w h (JS.fromString src))
121tiledImage : Int -> Int -> String -> Element
123 newElement w h (Image Tiled w h (JS.fromString src))
125data Three = P | Z | N
126data Pos = Absolute Int | Relative Float
127type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }
129-- Put an element in a container. This lets you position the element really
130-- easily, and there are tons of ways to set the `Position`.
131-- To center `element` exactly in a 300-by-300 square you would say:
133-- container 300 300 middle element
135-- By setting the color of the container, you can create borders.
136container : Int -> Int -> Position -> Element -> Element
137container w h pos e = newElement w h (Container pos e)
139-- Create an empty box. This is useful for getting your spacing right and
140-- for making borders.
141spacer : Int -> Int -> Element
142spacer w h = newElement w h Spacer
144data Direction = DUp | DDown | DLeft | DRight | DIn | DOut
146-- Have a list of elements flow in a particular direction.
147-- The `Direction` starts from the first element in the list.
154flow : Direction -> [Element] -> Element
156 let ws = List.map widthOf es
157 hs = List.map heightOf es
158 newFlow w h = newElement w h (Flow dir es)
160 if es == [] then spacer 0 0 else
162 DUp -> newFlow (List.maximum ws) (List.sum hs)
163 DDown -> newFlow (List.maximum ws) (List.sum hs)
164 DLeft -> newFlow (List.sum ws) (List.maximum hs)
165 DRight -> newFlow (List.sum ws) (List.maximum hs)
166 DIn -> newFlow (List.maximum ws) (List.maximum hs)
167 DOut -> newFlow (List.maximum ws) (List.maximum hs)
169-- Stack elements vertically. To put `a` above `b` you would say:
172above : Element -> Element -> Element
174 newElement (max (widthOf hi) (widthOf lo))
175 (heightOf hi + heightOf lo)
178-- Stack elements vertically. To put `a` below `b` you would say:
181below : Element -> Element -> Element
183 newElement (max (widthOf hi) (widthOf lo))
184 (heightOf hi + heightOf lo)
187-- Put elements beside each other horizontally.
188beside : Element -> Element -> Element
190 newElement (widthOf lft + widthOf rht)
191 (max (heightOf lft) (heightOf rht))
192 (Flow right [lft,rht])
194-- Layer elements on top of each other, starting from the bottom.
195-- `(layers == flow outward)`
196layers : [Element] -> Element
198 let ws = List.map widthOf es
199 hs = List.map heightOf es
200 in newElement (List.maximum ws) (List.maximum hs) (Flow DOut es)
203-- Repetitive things --
207relative : Float -> Pos
211middle = { horizontal=Z, vertical=Z, x=Relative 0.5, y=Relative 0.5 }
213topLeft = { horizontal=N, vertical=P, x=Absolute 0, y=Absolute 0 }
215topRight = { topLeft | horizontal <- P }
217bottomLeft = { topLeft | vertical <- N }
218bottomRight : Position
219bottomRight = { bottomLeft | horizontal <- P }
221midLeft = { middle | horizontal <- N, x <- Absolute 0 }
223midRight = { midLeft | horizontal <- P }
225midTop = { middle | vertical <- P, y <- Absolute 0 }
227midBottom = { midTop | vertical <- N }
229middleAt : Pos -> Pos -> Position
230middleAt x y = { horizontal = Z, vertical = Z, x = x, y = y }
231topLeftAt : Pos -> Pos -> Position
232topLeftAt x y = { horizontal = N, vertical = P, x = x, y = y }
233topRightAt : Pos -> Pos -> Position
234topRightAt x y = { horizontal = P, vertical = P, x = x, y = y }
235bottomLeftAt : Pos -> Pos -> Position
236bottomLeftAt x y = { horizontal = N, vertical = N, x = x, y = y }
237bottomRightAt : Pos -> Pos -> Position
238bottomRightAt x y = { horizontal = P, vertical = N, x = x, y = y }
239midLeftAt : Pos -> Pos -> Position
240midLeftAt x y = { horizontal = N, vertical = Z, x = x, y = y }
241midRightAt : Pos -> Pos -> Position
242midRightAt x y = { horizontal = P, vertical = Z, x = x, y = y }
243midTopAt : Pos -> Pos -> Position
244midTopAt x y = { horizontal = Z, vertical = P, x = x, y = y }
245midBottomAt : Pos -> Pos -> Position
246midBottomAt x y = { horizontal = Z, vertical = N, x = x, y = y }
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list