on bfa1bc2 help sign in
178 lines 5.6 kB history raw
1module Graphics.Input where
2{-| This module is for creating standard input widgets such as buttons and
3text fields. All functions in this library follow a general pattern in which
4you create an `Input` that many elements can report to:
6```haskell
7clicks : Input ()
8clicks = input ()
10clickableYogi : Element
11clickableYogi = clickable clicks.handle () (image 40 40 "/yogi.jpg")
12```
14Whenever the user clicks on the resulting `clickableYogi` element, it sends an
15update to the `clicks` input. You will see this pattern again and again in
16examples in this library, so just read on to get a better idea of how it works!
18# Creating Inputs
19@docs Input, input
21# Basic Input Elements
23To learn about text fields, see the
24[`Graphics.Input.Field`](Graphics-Input-Field) library.
26@docs button, customButton, checkbox, dropDown
28# Clicks and Hovers
29@docs clickable, hoverable
31-}
33import Signal (Signal)
34import Graphics.Element (Element)
35import Native.Graphics.Input
37{-| This is the key abstraction of this library. An `Input` is a record
38of two fields:
40 1. `signal` — all values coming to this input from “the world”
41 2. `handle` — a way to refer to this particular input and send it values
43This will make more sense as you see more examples.
44-}
45type Input a = { signal : Signal a, handle : Handle a }
47data Handle a = Handle
49{-| This creates a new `Input`. You provide a single argument that will serve
50as the initial value of the input’s `signal`. For example:
52 numbers : Input Int
53 numbers = input 42
55The initial value of `numbers.signal` is 42, and you will be able
56to pipe updates to the input using `numbers.handle`.
58Note: This is an inherently impure function. Specifically, `(input ())` and
59`(input ())` are actually two different inputs with different signals and handles.
60-}
61input : a -> Input a
62input = Native.Graphics.Input.input
64{-| Create a standard button. The following example begins making a basic
65calculator:
67 data Keys = Number Int | Plus | Minus | Clear
69 keys : Input Keys
70 keys = input Clear
72 calculator : Element
73 calculator =
74 flow right [ button keys.handle (Number 1) "1"
75 , button keys.handle (Number 2) "2"
76 , button keys.handle Plus "+"
77 ]
79If the user presses the "+" button, `keys.signal` will update to `Plus`. If the
80users presses "2", `keys.signal` will update to `(Number 2)`.
81-}
82button : Handle a -> a -> String -> Element
83button = Native.Graphics.Input.button
85{-| Same as `button` but lets you customize buttons to look however you want.
87 click : Input ()
88 click = input ()
90 prettyButton : Element
91 prettyButton =
92 customButton click.handle ()
93 (image 100 40 "/button_up.jpg")
94 (image 100 40 "/button_hover.jpg")
95 (image 100 40 "/button_down.jpg")
96-}
97customButton : Handle a -> a -> Element -> Element -> Element -> Element
98customButton = Native.Graphics.Input.customButton
100{-| Create a checkbox. The following example creates three synced checkboxes:
102 check : Input Bool
103 check = input False
105 boxes : Bool -> Element
106 boxes checked =
107 let box = container 40 40 middle (checkbox check.handle id checked)
108 in flow right [ box, box, box ]
110 main : Signal Element
111 main = boxes <~ check.signal
112-}
113checkbox : Handle a -> (Bool -> a) -> Bool -> Element
114checkbox = Native.Graphics.Input.checkbox
116{-| Create a drop-down menu. The following drop-down lets you choose your
117favorite British sport:
119 data Sport = Football | Cricket | Snooker
121 sport : Input (Maybe Sport)
122 sport = input Nothing
124 sportDropDown : Element
125 sportDropDown =
126 dropDown sport.handle
127 [ ("" , Nothing)
128 , ("Football", Just Football)
129 , ("Cricket" , Just Cricket)
130 , ("Snooker" , Just Snooker)
131 ]
133If the user selects "Football" from the drop down menue, `sport.signal`
134will update to `Just Football`.
135-}
136dropDown : Handle a -> [(String,a)] -> Element
137dropDown = Native.Graphics.Input.dropDown
139{-| Detect mouse hovers over a specific `Element`. In the following example,
140we will create a hoverable picture called `cat`.
142 hover : Input Bool
143 hover = input False
145 cat : Element
146 cat = image 30 30 "/cat.jpg"
147 |> hoverable hover.handle id
149When the mouse hovers above the `cat` element, `hover.signal` will become
150`True`. When the mouse leaves it, `hover.signal` will become `False`.
151-}
152hoverable : Handle a -> (Bool -> a) -> Element -> Element
153hoverable = Native.Graphics.Input.hoverable
155{-| Detect mouse clicks on a specific `Element`. In the following example,
156we will create a clickable picture called `cat`.
158 data Picture = Cat | Hat
160 picture : Input Picture
161 picture = input Cat
163 cat : Element
164 cat = image 30 30 "/cat.jpg"
165 |> clickable picture.handle Cat
167 hat : Element
168 hat = image 30 30 "/hat.jpg"
169 |> clickable picture.handle Hat
171When the user clicks on the `cat` element, `picture.signal` receives
172an update containing the value `Cat`. When the user clicks on the `hat` element,
173`picture.signal` receives an update containing the value `Hat`. This lets you
174distinguish which element was clicked. In a more complex example, they could be
175distinguished with IDs or more complex data structures.
176-}
177clickable : Handle a -> a -> Element -> Element
178clickable = Native.Graphics.Input.clickable