Start using new Input type everywhere!
Whoo! :D
This commit is contained in:
parent
0c805d8c4f
commit
0018d32627
2 changed files with 68 additions and 59 deletions
|
@ -1,22 +1,22 @@
|
|||
module Graphics.Input where
|
||||
{-| This module is for creating standard input widgets such as buttons and
|
||||
text fields. All functions in this library follow this general pattern:
|
||||
text fields. All functions in this library follow a general pattern in which
|
||||
you create an `Input` that many elements can report to:
|
||||
|
||||
```haskell
|
||||
-- (Signal (), SignalID ())
|
||||
(clicks, clickID) = input ()
|
||||
clicks : Input ()
|
||||
clicks = input ()
|
||||
|
||||
clickableYogi : Element
|
||||
clickableYogi = clickable clickID () (image 40 40 "/yogi.jpg")
|
||||
clickableYogi = clickable clicks.handle () (image 40 40 "/yogi.jpg")
|
||||
```
|
||||
|
||||
Whenever the user clicks on the resulting `clickableYogi` element, it sends a
|
||||
`()` to the `clicks` signal. Typically, you would create all your input signals
|
||||
when setting up the signal graph, so then your graphics code can refer to them
|
||||
easily.
|
||||
Whenever the user clicks on the resulting `clickableYogi` element, it sends an
|
||||
update to the `clicks` input. You will see this pattern again and again in
|
||||
examples in this library, so just read on to get a better idea of how it works!
|
||||
|
||||
# Creating Inputs
|
||||
@docs input
|
||||
@docs Input, input
|
||||
|
||||
# Basic Input Elements
|
||||
Text fields come later.
|
||||
|
@ -33,46 +33,55 @@ import Signal (Signal)
|
|||
import Graphics.Element (Element)
|
||||
import Native.Graphics.Input
|
||||
|
||||
data SignalID a = SignalID
|
||||
data Handle a = Handle
|
||||
|
||||
{-| This function is the key to using this library. It creates a signal that
|
||||
input elements (buttens, checkboxes, etc.) can report to. It also create a
|
||||
unique `SignalID` that allows input elements to refer to this particular
|
||||
signal. It may be best to look at examples in the rest of the docs and return
|
||||
to this function.
|
||||
{-| This is the key abstraction of this library. An `Input` is a record
|
||||
of two fields:
|
||||
|
||||
Note: creating an input signal is an inherently imperative action, so this is
|
||||
one of very few impure functions in Elm. It is designed such that it can only
|
||||
be used as you build your signal graph at startup, keeping Elm pure at runtime.
|
||||
1. `signal` — all values coming to this input from “the world”
|
||||
2. `handle` — a way to refer to this particular input and send it values
|
||||
|
||||
This will make more sense as you see more examples.
|
||||
-}
|
||||
input : a -> (Signal a, SignalID a)
|
||||
type Input a = { signal : Signal a, handle : Handle a }
|
||||
|
||||
{-| Create a new `Input`. You just give the initial value for the
|
||||
input’s `signal`.
|
||||
|
||||
Note for Advanced Users: creating an `Input` is an inherently imperative
|
||||
action, so this is one of very few impure functions in Elm. That means
|
||||
`(input ())` and `(input ())` are actually two different inputs with different
|
||||
signals and handles. By design, Elm’s impure functions can only be useful
|
||||
as you build your signal graph at startup, so Elm is still pure at runtime.
|
||||
-}
|
||||
input : a -> Input a
|
||||
input = Native.Graphics.Input.input
|
||||
|
||||
{-| Create a standard button. The following example begins making a basic
|
||||
calculator:
|
||||
|
||||
data Input = Number Int | Plus | Minus | Clear
|
||||
data Keys = Number Int | Plus | Minus | Clear
|
||||
|
||||
-- (Signal Input, SignalID Input)
|
||||
(calcInput, pressID) = input Clear
|
||||
keys : Input Keys
|
||||
keys = input Clear
|
||||
|
||||
buttons : Element
|
||||
buttons =
|
||||
flow right [ button pressID (Number 1) "1"
|
||||
, button pressID (Number 2) "2"
|
||||
, button pressID Plus "+"
|
||||
calculator : Element
|
||||
calculator =
|
||||
flow right [ button keys.handle (Number 1) "1"
|
||||
, button keys.handle (Number 2) "2"
|
||||
, button keys.handle Plus "+"
|
||||
]
|
||||
|
||||
If the user presses the "plus" button, the `calcInput` signal will update to
|
||||
`Plus`. If the users presses "2", `calcInput` will update to `(Number 2)`.
|
||||
If the user presses the "+" button, `keys.signal` will update to `Plus`. If the
|
||||
users presses "2", `keys.signal` will update to `(Number 2)`.
|
||||
-}
|
||||
button : SignalID a -> a -> String -> Element
|
||||
button : Handle a -> a -> String -> Element
|
||||
button = Native.Graphics.Input.button
|
||||
|
||||
customButton : SignalID a -> a -> Element -> Element -> Element -> Element
|
||||
customButton : Handle a -> a -> Element -> Element -> Element -> Element
|
||||
customButton = Native.Graphics.Input.customButton
|
||||
|
||||
checkbox : SignalID a -> (Bool -> a) -> Bool -> Element
|
||||
checkbox : Handle a -> (Bool -> a) -> Bool -> Element
|
||||
checkbox = Native.Graphics.Input.checkbox
|
||||
|
||||
{-| Create a drop-down menu. The following drop-down lets you choose your
|
||||
|
@ -80,38 +89,38 @@ favorite British sport:
|
|||
|
||||
data Sport = Football | Cricket | Snooker
|
||||
|
||||
-- (Signal (Maybe Sport), SignalID (Maybe Sport))
|
||||
(dropStatus, dropID) = input Nothing
|
||||
sport : Input Sport
|
||||
sport = input Nothing
|
||||
|
||||
sportDropDown : Element
|
||||
sportDropDown =
|
||||
dropDown dropID
|
||||
dropDown sport.handle
|
||||
[ ("" , Nothing)
|
||||
, ("Football", Just Football)
|
||||
, ("Cricket" , Just Cricket)
|
||||
, ("Snooker" , Just Snooker)
|
||||
]
|
||||
|
||||
If the user selects "Football" from the drop down menue, the `dropStatus`
|
||||
signal will update to `Just Football`.
|
||||
If the user selects "Football" from the drop down menue, `sport.signal`
|
||||
will update to `Just Football`.
|
||||
-}
|
||||
dropDown : SignalID a -> [(String,a)] -> Element
|
||||
dropDown : Handle a -> [(String,a)] -> Element
|
||||
dropDown = Native.Graphics.Input.dropDown
|
||||
|
||||
{-| Detect mouse hovers over a specific `Element`. In the following example,
|
||||
we will create a hoverable picture called `cat`.
|
||||
|
||||
-- (Signal Bool, SignalID Bool)
|
||||
(hover, hoverID) = input False
|
||||
hover : Input Bool
|
||||
hover = input False
|
||||
|
||||
cat : Element
|
||||
cat = image 30 30 "/cat.jpg"
|
||||
|> hoverable hoverID (\hover -> hover)
|
||||
|> hoverable hover.handle id
|
||||
|
||||
When the mouse hovers above the `cat` element, the `hover` signal will become
|
||||
`True`. When the mouse leaves it, `hover` will become `False`.
|
||||
When the mouse hovers above the `cat` element, `hover.signal` will become
|
||||
`True`. When the mouse leaves it, `hover.signal` will become `False`.
|
||||
-}
|
||||
hoverable : SignalID a -> (Bool -> a) -> Element -> Element
|
||||
hoverable : Handle a -> (Bool -> a) -> Element -> Element
|
||||
hoverable = Native.Graphics.Input.hoverable
|
||||
|
||||
{-| Detect mouse clicks on a specific `Element`. In the following example,
|
||||
|
@ -119,24 +128,24 @@ we will create a clickable picture called `cat`.
|
|||
|
||||
data Picture = Cat | Hat
|
||||
|
||||
-- (Signal Picture, SignalID Picture)
|
||||
(click, clickID) = input Cat
|
||||
picture : Input Picture
|
||||
picture = input Cat
|
||||
|
||||
cat : Element
|
||||
cat = image 30 30 "/cat.jpg"
|
||||
|> clickable clickID Cat
|
||||
|> clickable picture.handle Cat
|
||||
|
||||
hat : Element
|
||||
hat = image 30 30 "/hat.jpg"
|
||||
|> clickable clickID Hat
|
||||
|> clickable picture.handle Hat
|
||||
|
||||
When the user clicks on the `cat` element, the `click` signal receives
|
||||
When the user clicks on the `cat` element, `picture.signal` receives
|
||||
an update containing the value `Cat`. When the user clicks on the `hat` element,
|
||||
the `click` signal receives an update containing the value `Hat`. This lets you
|
||||
`picture.signal` receives an update containing the value `Hat`. This lets you
|
||||
distinguish which element was clicked. In a more complex example, they could be
|
||||
distinguished with IDs or more complex data structures.
|
||||
-}
|
||||
clickable : SignalID a -> a -> Element -> Element
|
||||
clickable : Handle a -> a -> Element -> Element
|
||||
clickable = Native.Graphics.Input.clickable
|
||||
|
||||
{-| Represents the current content of a text field. For example:
|
||||
|
@ -170,25 +179,25 @@ noContent = FieldContent "" (Selection 0 0 Forward)
|
|||
called `nameField`. As the user types their name, the field will be updated
|
||||
to match what they have entered.
|
||||
|
||||
-- (Signal FieldContent, SignalID FieldContent)
|
||||
(nameContent,nameID) = input noContent
|
||||
name : Input FieldContent
|
||||
name = input noContent
|
||||
|
||||
nameField : Signal Element
|
||||
nameField = field nameID (\content -> content) "Name" <~ nameContent
|
||||
nameField = field name.handle (\content -> content) "Name" <~ nameContent
|
||||
-}
|
||||
field : SignalID a -> (FieldContent -> a) -> String -> FieldContent -> Element
|
||||
field : Handle a -> (FieldContent -> a) -> String -> FieldContent -> Element
|
||||
field = Native.Graphics.Input.field
|
||||
|
||||
{-| Same as `field` but the UI element blocks out each characters. -}
|
||||
password : SignalID a -> (FieldContent -> a) -> String -> FieldContent -> Element
|
||||
password : Handle a -> (FieldContent -> a) -> String -> FieldContent -> Element
|
||||
password = Native.Graphics.Input.password
|
||||
|
||||
{-| Same as `field` but it adds an annotation that this field is for email
|
||||
addresses. This is helpful for auto-complete and for mobile users who may
|
||||
get a custom keyboard with an `@` and `.com` button.
|
||||
-}
|
||||
email : SignalID a -> (FieldContent -> a) -> String -> FieldContent -> Element
|
||||
email : Handle a -> (FieldContent -> a) -> String -> FieldContent -> Element
|
||||
email = Native.Graphics.Input.email
|
||||
|
||||
-- area : SignalID a -> (FieldContent -> a) -> SignalID b -> ((Int,Int) -> b) -> (Int,Int) -> String -> FieldContent -> Element
|
||||
-- area : Handle a -> (FieldContent -> a) -> Handle b -> ((Int,Int) -> b) -> (Int,Int) -> String -> FieldContent -> Element
|
||||
-- area = Native.Graphics.Input.area
|
||||
|
|
|
@ -17,7 +17,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
|
|||
|
||||
function input(initialValue) {
|
||||
var sig = Signal.constant(initialValue);
|
||||
return Tuple2(sig, sig);
|
||||
return { _:{}, signal:sig, handle:sig };
|
||||
}
|
||||
|
||||
function renderDropDown(signal, values) {
|
||||
|
|
Loading…
Reference in a new issue