2012-10-05 02:01:20 +00:00
|
|
|
|
2013-03-12 07:48:11 +00:00
|
|
|
module Graphics.Element (widthOf, heightOf, sizeOf,
|
|
|
|
width, height, opacity, color, tag, link,
|
|
|
|
image, fittedImage, croppedImage,
|
|
|
|
flow, up, down, left, right, inward, outward,
|
|
|
|
above, below, beside, layers,
|
|
|
|
container, absolute, relative,
|
|
|
|
middle, topLeft, topRight, bottomLeft, bottomRight,
|
|
|
|
midLeft, midRight, midTop, midBottom, middleAt,
|
|
|
|
topLeftAt, topRightAt, bottomLeftAt, bottomRightAt,
|
|
|
|
midLeftAt, midRightAt, midTopAt, midBottomAt,
|
2013-03-12 08:51:54 +00:00
|
|
|
spacer, newElement
|
2013-03-12 07:48:11 +00:00
|
|
|
) where
|
2013-03-02 22:07:45 +00:00
|
|
|
|
2013-03-13 05:59:15 +00:00
|
|
|
import Native.Utils (guid, max, htmlHeight)
|
2013-03-02 22:07:45 +00:00
|
|
|
import JavaScript as JS
|
|
|
|
import List as List
|
2013-03-12 07:48:11 +00:00
|
|
|
import Graphics.Color as Color
|
|
|
|
import Maybe (Just, Nothing)
|
2013-03-02 22:07:45 +00:00
|
|
|
|
|
|
|
type Properties = {
|
|
|
|
id : Int,
|
|
|
|
width : Int,
|
|
|
|
height : Int,
|
|
|
|
opacity : Float,
|
2013-03-07 19:06:48 +00:00
|
|
|
color : Maybe Color,
|
2013-03-02 22:07:45 +00:00
|
|
|
href : JSString,
|
|
|
|
tag : JSString
|
|
|
|
}
|
|
|
|
|
2013-03-07 19:06:48 +00:00
|
|
|
type Element = { props : Properties, element : ElementPrim }
|
2013-03-02 22:07:45 +00:00
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
widthOf : Element -> Int
|
2013-03-07 19:06:48 +00:00
|
|
|
widthOf e = e.props.width
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
heightOf : Element -> Int
|
2013-03-07 19:06:48 +00:00
|
|
|
heightOf e = e.props.height
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
sizeOf : Element -> Int
|
2013-03-07 19:06:48 +00:00
|
|
|
sizeOf e = (e.props.width, e.props.height)
|
2013-03-02 22:07:45 +00:00
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
width : Int -> Element -> Element
|
2013-03-13 05:59:15 +00:00
|
|
|
width nw e = let p = e.props
|
|
|
|
props = case e.element of
|
|
|
|
Image _ w h _ -> {p| height <- h/w*nw }
|
|
|
|
RawHtml html -> {p| height <- htmlHeight nw html }
|
|
|
|
_ -> p
|
|
|
|
in { element=e.element, props={props| width <- nw} }
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
height : Int -> Element -> Element
|
2013-03-13 05:59:15 +00:00
|
|
|
height nh e = let p = e.props
|
|
|
|
props = case e.element of
|
|
|
|
Image _ w h _ -> {p| width <- w/h*nh }
|
|
|
|
_ -> p
|
|
|
|
in { element=e.element, props={p| height <- nh} }
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
opacity : Float -> Element -> Element
|
2013-03-07 19:06:48 +00:00
|
|
|
opacity o e = let p = e.props in { element=e.element, props={p| opacity <- o} }
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
color : Color -> Element -> Element
|
2013-03-12 07:48:11 +00:00
|
|
|
color c e = let p = e.props in
|
|
|
|
{ element=e.element, props={p| color <- Just c} }
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
tag : String -> Element -> Element
|
2013-03-07 19:06:48 +00:00
|
|
|
tag name e = let p = e.props in
|
2013-03-12 07:48:11 +00:00
|
|
|
{ element=e.element, props={p| tag <- JS.fromString name} }
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
link : String -> Element -> Element
|
2013-03-07 19:06:48 +00:00
|
|
|
link href e = let p = e.props in
|
2013-03-12 07:48:11 +00:00
|
|
|
{ element=e.element, props={p| href <- JS.fromString href} }
|
2012-10-05 02:01:20 +00:00
|
|
|
|
2013-03-02 22:07:45 +00:00
|
|
|
emptyStr = JS.fromString ""
|
|
|
|
newElement w h e =
|
2013-03-12 07:48:11 +00:00
|
|
|
{ props = Properties (guid ()) w h 1 Nothing emptyStr emptyStr, element = e }
|
2012-10-05 02:01:20 +00:00
|
|
|
|
2013-03-02 22:07:45 +00:00
|
|
|
data ElementPrim
|
2013-03-07 19:06:48 +00:00
|
|
|
= Image ImageStyle Int Int JSString
|
2013-03-02 22:07:45 +00:00
|
|
|
| Container Position Element
|
|
|
|
| Flow Direction [Element]
|
|
|
|
| Spacer
|
|
|
|
| RawHtml JSString
|
2013-03-21 09:29:23 +00:00
|
|
|
| Custom -- for custom Elements implemented in JS, see collage for example
|
2012-10-05 02:01:20 +00:00
|
|
|
|
2013-03-07 19:06:48 +00:00
|
|
|
data ImageStyle = Plain | Fitted | Cropped (Int,Int)
|
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
image : Int -> Int -> String -> Element
|
2013-03-07 19:06:48 +00:00
|
|
|
image w h src = newElement w h (Image Plain w h (JS.fromString src))
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
fittedImage : Int -> Int -> String -> Element
|
2013-03-07 19:06:48 +00:00
|
|
|
fittedImage w h src = newElement w h (Image Fitted w h (JS.fromString src))
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
croppedImage : Int -> Int -> (Int,Int) -> String -> Element
|
2013-03-07 19:06:48 +00:00
|
|
|
croppedImage w h pos src =
|
|
|
|
newElement w h (Image (Cropped pos) w h (JS.fromString src))
|
2012-10-05 02:01:20 +00:00
|
|
|
|
2013-03-07 19:06:48 +00:00
|
|
|
data Three = P | Z | N
|
|
|
|
data Pos = Absolute Int | Relative Float
|
|
|
|
type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }
|
2012-10-05 02:01:20 +00:00
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
container : Int -> Int -> Position -> Element -> Element
|
2013-03-02 22:07:45 +00:00
|
|
|
container w h pos e = newElement w h (Container pos e)
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
spacer : Int -> Int -> Element
|
2013-03-02 22:07:45 +00:00
|
|
|
spacer w h = newElement w h Spacer
|
2012-10-05 02:01:20 +00:00
|
|
|
|
2013-03-07 19:06:48 +00:00
|
|
|
data Direction = DUp | DDown | DLeft | DRight | DIn | DOut
|
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
flow : Direction -> [Element] -> Element
|
2013-03-02 22:07:45 +00:00
|
|
|
flow dir es =
|
2013-03-12 08:51:54 +00:00
|
|
|
let ws = List.map widthOf es
|
|
|
|
hs = List.map heightOf es
|
2013-03-02 22:07:45 +00:00
|
|
|
newFlow w h = newElement w h (Flow dir es)
|
|
|
|
in
|
2013-03-26 07:12:31 +00:00
|
|
|
if es == [] then spacer 0 0 else
|
2013-03-02 22:07:45 +00:00
|
|
|
case dir of
|
|
|
|
DUp -> newFlow (List.maximum ws) (List.sum hs)
|
|
|
|
DDown -> newFlow (List.maximum ws) (List.sum hs)
|
|
|
|
DLeft -> newFlow (List.sum ws) (List.maximum hs)
|
|
|
|
DRight -> newFlow (List.sum ws) (List.maximum hs)
|
|
|
|
DIn -> newFlow (List.maximum ws) (List.maximum hs)
|
|
|
|
DOut -> newFlow (List.maximum ws) (List.maximum hs)
|
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
above : Element -> Element -> Element
|
2013-03-21 09:29:23 +00:00
|
|
|
above hi lo =
|
|
|
|
newElement (max (widthOf hi) (widthOf lo))
|
|
|
|
(heightOf hi + heightOf lo)
|
|
|
|
(Flow DDown [hi,lo])
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
below : Element -> Element -> Element
|
2013-03-21 09:29:23 +00:00
|
|
|
below lo hi =
|
|
|
|
newElement (max (widthOf hi) (widthOf lo))
|
|
|
|
(heightOf hi + heightOf lo)
|
|
|
|
(Flow DDown [hi,lo])
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
beside : Element -> Element -> Element
|
2013-03-21 09:29:23 +00:00
|
|
|
beside lft rht =
|
|
|
|
newElement (widthOf lft + widthOf rht)
|
|
|
|
(max (heightOf lft) (heightOf rht))
|
|
|
|
(Flow right [lft,rht])
|
2013-03-07 19:06:48 +00:00
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
layers : [Element] -> Element
|
2013-03-07 19:06:48 +00:00
|
|
|
layers es =
|
2013-03-12 08:51:54 +00:00
|
|
|
let ws = List.map widthOf es
|
|
|
|
hs = List.map heightOf es
|
2013-03-13 17:31:37 +00:00
|
|
|
in newElement (List.maximum ws) (List.maximum hs) (Flow DOut es)
|
2013-03-07 19:06:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
-- Repetitive things --
|
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
absolute : Pos
|
2013-03-07 19:06:48 +00:00
|
|
|
absolute = Absolute
|
2013-04-08 08:49:44 +00:00
|
|
|
relative : Pos
|
2013-03-07 19:06:48 +00:00
|
|
|
relative = Relative
|
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
middle : Position
|
|
|
|
middle = { horizontal=Z, vertical=Z, x=Relative 0.5, y=Relative 0.5 }
|
|
|
|
topLeft : Position
|
|
|
|
topLeft = { horizontal=N, vertical=P, x=Absolute 0, y=Absolute 0 }
|
|
|
|
topRight : Position
|
2013-03-07 19:06:48 +00:00
|
|
|
topRight = { topLeft | horizontal <- P }
|
2013-04-08 08:49:44 +00:00
|
|
|
bottomLeft : Position
|
2013-03-07 19:06:48 +00:00
|
|
|
bottomLeft = { topLeft | vertical <- N }
|
2013-04-08 08:49:44 +00:00
|
|
|
bottomRight : Position
|
2013-03-07 19:06:48 +00:00
|
|
|
bottomRight = { bottomLeft | horizontal <- P }
|
2013-04-08 08:49:44 +00:00
|
|
|
midLeft : Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midLeft = { middle | horizontal <- N, x <- Absolute 0 }
|
2013-04-08 08:49:44 +00:00
|
|
|
midRight : Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midRight = { midLeft | horizontal <- P }
|
2013-04-08 08:49:44 +00:00
|
|
|
midTop : Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midTop = { middle | vertical <- P, y <- Absolute 0 }
|
2013-04-08 08:49:44 +00:00
|
|
|
midBottom : Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midBottom = { midTop | vertical <- N }
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
middleAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
middleAt x y = { horizontal = Z, vertical = Z, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
topLeftAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
topLeftAt x y = { horizontal = N, vertical = P, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
topRightAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
topRightAt x y = { horizontal = P, vertical = P, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
bottomLeftAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
bottomLeftAt x y = { horizontal = N, vertical = N, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
bottomRightAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
bottomRightAt x y = { horizontal = P, vertical = N, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
midLeftAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midLeftAt x y = { horizontal = N, vertical = Z, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
midRightAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midRightAt x y = { horizontal = P, vertical = Z, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
midTopAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midTopAt x y = { horizontal = Z, vertical = P, x = x, y = y }
|
2013-04-08 08:49:44 +00:00
|
|
|
midBottomAt : Pos -> Pos -> Position
|
2013-03-07 19:06:48 +00:00
|
|
|
midBottomAt x y = { horizontal = Z, vertical = N, x = x, y = y }
|
|
|
|
|
2013-04-08 08:49:44 +00:00
|
|
|
up : Direction
|
2013-03-07 19:06:48 +00:00
|
|
|
up = DUp
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
down : Direction
|
2013-03-07 19:06:48 +00:00
|
|
|
down = DDown
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
left : Direction
|
2013-03-07 19:06:48 +00:00
|
|
|
left = DLeft
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
right : Direction
|
2013-03-07 19:06:48 +00:00
|
|
|
right = DRight
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
inward : Direction
|
2013-03-07 19:06:48 +00:00
|
|
|
inward = DIn
|
2013-04-08 08:49:44 +00:00
|
|
|
|
|
|
|
outward : Direction
|
2013-03-07 19:06:48 +00:00
|
|
|
outward = DOut
|