on 1c832af help sign in
193 lines 6.7 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 this general pattern:
5```haskell
6-- (Signal (), SignalID ())
7(clicks, clickID) = input ()
9clickableYogi : Element
10clickableYogi = clickable clickID () (image 40 40 "/yogi.jpg")
11```
13Whenever the user clicks on the resulting `clickableYogi` element, it sends a
14`()` to the `clicks` signal. Typically, you would create all your input signals
15when setting up the signal graph, so then your graphics code can refer to them
16easily.
18# Creating Inputs
19@docs input
21# Basic Input Elements
22Text fields come later.
23@docs button, customButton, checkbox, dropDown
25# Clicks and Hovers
26@docs clickable, hoverable
28# Text Fields
29@docs field, password, email, noContent, FieldContent, Selection, Direction
30-}
32import Signal (Signal)
33import Graphics.Element (Element)
35data SignalID a = SignalID
37{-| This function is the key to using this library. It creates a signal that
38input elements (buttens, checkboxes, etc.) can report to. It also create a
39unique `SignalID` that allows input elements to refer to this particular
40signal. It may be best to look at examples in the rest of the docs and return
41to this function.
43Note: creating an input signal is an inherently imperative action, so this is
44one of very few impure functions in Elm. It is designed such that it can only
45be used as you build your signal graph at startup, keeping Elm pure at runtime.
46-}
47input : a -> (Signal a, SignalID a)
48input = Native.Graphics.Input.input
50{-| Create a standard button. The following example begins making a basic
51calculator:
53 data Input = Number Int | Plus | Minus | Clear
55 -- (Signal Input, SignalID Input)
56 (calcInput, pressID) = input Clear
58 buttons : Element
59 buttons =
60 flow right [ button pressID (Number 1) "1"
61 , button pressID (Number 2) "2"
62 , button pressID Plus "+"
63 ]
65If the user presses the "plus" button, the `calcInput` signal will update to
66`Plus`. If the users presses "2", `calcInput` will update to `(Number 2)`.
67-}
68button : SignalID a -> a -> String -> Element
69button = Native.Graphics.Input.button
71customButton : SignalID a -> a -> Element -> Element -> Element -> Element
72customButton = Native.Graphics.Input.customButton
74checkbox : SignalID a -> (Bool -> a) -> Bool -> Element
75checkbox = Native.Graphics.Input.checkboxes
77{-| Create a drop-down menu. The following drop-down lets you choose your
78favorite British sport:
80 data Sport = Football | Cricket | Snooker
82 -- (Signal (Maybe Sport), SignalID (Maybe Sport))
83 (dropStatus, dropID) = input Nothing
85 sportDropDown : Element
86 sportDropDown =
87 dropDown dropID
88 [ ("" , Nothing)
89 , ("Football", Just Football)
90 , ("Cricket" , Just Cricket)
91 , ("Snooker" , Just Snooker)
92 ]
94If the user selects "Football" from the drop down menue, the `dropStatus`
95signal will update to `Just Football`.
96-}
97dropDown : SignalID a -> [(String,a)] -> Element
98dropDown = Native.Graphics.Input.dropDown
100{-| Detect mouse hovers over a specific `Element`. In the following example,
101we will create a hoverable picture called `cat`.
103 -- (Signal Bool, SignalID Bool)
104 (hover, hoverID) = input False
106 cat : Element
107 cat = image 30 30 "/cat.jpg"
108 |> hoverable hoverID (\hover -> hover)
110When the mouse hovers above the `cat` element, the `hover` signal will become
111`True`. When the mouse leaves it, `hover` will become `False`.
112-}
113hoverable : SignalID a -> (Bool -> a) -> Element -> Element
114hoverable = Native.Graphics.Input.hoverable
116{-| Detect mouse clicks on a specific `Element`. In the following example,
117we will create a clickable picture called `cat`.
119 data Picture = Cat | Hat
121 -- (Signal Picture, SignalID Picture)
122 (click, clickID) = input Cat
124 cat : Element
125 cat = image 30 30 "/cat.jpg"
126 |> clickable clickID Cat
128 hat : Element
129 hat = image 30 30 "/hat.jpg"
130 |> clickable clickID Hat
132When the user clicks on the `cat` element, the `click` signal receives
133an update containing the value `Cat`. When the user clicks on the `hat` element,
134the `click` signal receives an update containing the value `Hat`. This lets you
135distinguish which element was clicked. In a more complex example, they could be
136distinguished with IDs or more complex data structures.
137-}
138clickable : SignalID a -> a -> Element -> Element
139clickable = Native.Graphics.Input.clickable
141{-| Represents the current content of a text field. For example:
143 FieldContent "She sells sea shells" (Selection 0 3 Backward)
145This means the user highlighted the substring `"She"` backwards.
146-}
147type FieldContent = { string:String, selection:Selection }
149{-| The selection within a text field. `start` is never greater than `end`:
151 Selection 0 0 Forward -- cursor precedes all characters
153 Selection 5 9 Backward -- highlighting characters starting after
154 -- the 5th and ending after the 9th
155-}
156type Selection = { start:Int, end:Int, direction:Direction }
158{-| The direction of selection.-}
159data Direction = Forward | Backward
161{-| A field with no content:
163 FieldContent "" (Selection 0 0 Forward)
164-}
165noContent : FieldContent
166noContent = FieldContent "" (Selection 0 0 Forward)
168{-| Create a text field. The following example creates a time-varying element
169called `nameField`. As the user types their name, the field will be updated
170to match what they have entered.
172 -- (Signal FieldContent, SignalID FieldContent)
173 (nameContent,nameID) = input noContent
175 nameField : Signal Element
176 nameField = field nameID (\content -> content) "Name" <~ nameContent
177-}
178field : SignalID a -> (FieldContent -> a) -> String -> FieldContent -> Element
179field = Native.Graphics.Input.field
181{-| Same as `field` but the UI element blocks out each characters. -}
182password : SignalID a -> (FieldContent -> a) -> String -> FieldContent -> Element
183password = Native.Graphics.Input.password
185{-| Same as `field` but it adds an annotation that this field is for email
186addresses. This is helpful for auto-complete and for mobile users who may
187get a custom keyboard with an `@` and `.com` button.
188-}
189email : SignalID a -> (FieldContent -> a) -> String -> FieldContent -> Element
190email = Native.Graphics.Input.email
192-- area : SignalID a -> (FieldContent -> a) -> SignalID b -> ((Int,Int) -> b) -> (Int,Int) -> String -> FieldContent -> Element
193-- area = Native.Graphics.Input.area