MaintainerThomas Hallgren
StabilityExperimental
Safe HaskellNone

ThreepennyFudgets

Contents

Description

Threepenny Fudgets is a prototype library for writing GUI applications in a functional style in Haskell, using a web browser for the user interface.

Threepenny Fudgets is based on Fudgets (a Graphical User Interface Libary for Haskell developed in the early 1990s) but has a completely separate implementation on top of threepenny-gui.

Synopsis

The Fudget type

data F hi ho #

F hi ho is the type of a fudget that consumes an high-level input stream of values of type hi and produces an high-level output stream of values of type ho. It can also generate a number of user interface elements, and can read input from and send output to those user interface elements.

Instances

Functor (F hi) # 

Methods

fmap :: (a -> b) -> F hi a -> F hi b

(<$) :: a -> F hi b -> F hi a

Applicative (F hi) # 

Methods

pure :: a -> F hi a

(<*>) :: F hi (a -> b) -> F hi a -> F hi b #

liftA2 :: (a -> b -> c) -> F hi a -> F hi b -> F hi c

(*>) :: F hi a -> F hi b -> F hi b #

(<*) :: F hi a -> F hi b -> F hi a #

Monoid (F hi ho) # 

Methods

mempty :: F hi ho

mappend :: F hi ho -> F hi ho -> F hi ho

mconcat :: [F hi ho] -> F hi ho

Other types

type (+) a b = Either a b #

We use the notation a+b for Either a b, the standard disjoint union type in Haskell.

fromLeft :: Either a b -> Maybe a #

fromRight :: Either b a -> Maybe a #

type URL = String #

Running a fudget

runF :: F hi ho -> IO () #

runF is typically used only once in the main function of a program. It runs the fudget and adds any user interface elements it generates to the documentBody of the web page.

runF' :: (Window -> UI a) -> F hi p -> IO () #

User interface elements

buttonF :: String -> F Click Click #

Creates a button, like <input type="button" value="label">. It outputs Click when pressed. (Click received on the input is propagated directly to the output, allowing button clicks to be simulated programmatically.)

data Click #

Constructors

Click 

Instances

Eq Click # 

Methods

(==) :: Click -> Click -> Bool

(/=) :: Click -> Click -> Bool

Read Click # 

Methods

readsPrec :: Int -> ReadS Click

readList :: ReadS [Click]

readPrec :: ReadPrec Click

readListPrec :: ReadPrec [Click]

Show Click # 

Methods

showsPrec :: Int -> Click -> ShowS

show :: Click -> String

showList :: [Click] -> ShowS

buttonGroupF :: F hi ho -> F (Click + hi) (Click + ho) #

Creates a button with another fudget inside (which should be something simple, e.g. an imgF or a stringDisplayF...), <button>...</button>.

toggleButtonF :: String -> F Bool Bool #

A checkboxF with a label

checkboxF :: F Bool Bool #

A checkbox, <input type=checkbox>.

radioGroupF :: Eq alt => Options alt -> F alt alt #

A group of checkboxes allowing you to select one of several alternatives

radioGroupF' :: Eq alt => Options alt -> F alt alt #

A radioGroupF without the built-in vertical layout

selectF :: Eq alt => Options alt -> F alt alt #

A menu of options, <select><option>...</option>...</select>

data Options alt #

Constructors

Options [(alt, String)] alt 

dynSelectF :: Eq alt => Options alt -> SelectF alt #

A menu of options that can be modified dynamically

type SelectF alt = F (ListRequest alt) alt #

data ListRequest alt #

Constructors

New (Options alt) 
Pick alt 

sliderF :: Enum a => (a, a) -> F a a #

A slider which lets you choose a value from an enumeration, <input type="range">

progressF :: (Num i, Ord i, Show i) => i -> F i o #

A progress meter <progress max=...></meter>

meterF :: (Num i, Ord i, Show i) => (i, i) -> F i o #

A meter for scalar value between given minimum and maximum. <meter min=... max=...></meter>

stringDisplayF :: F String ho #

An output-only element displaying text, <span>...</span>

htmlDisplayF :: F String ho #

An output-only element displaying HTML content

showF :: Show i => F i o #

stringF combined with show, marked read-only

numberF :: (Show a, Read a, Num a) => F a a #

readShowF restricted to numbers, <input type="number">

readShowF :: (Show a, Read a) => F a a #

stringF combined with show and read

stringF :: F String String #

A string input/output field, <input type="text">

passwordF :: F String String #

A string input/output field that shows **** instead of the actual input, <input type="password">

canvasF :: (Int, Int) -> F (Picture ()) (Int, Int) #

Creates a canvas of given width and height. Use the functions from Graphics.UI.Threepenny.Canvas to draw things. The canvas produces output on mouseup events (becase mouseup up seems to work for both the left and the right mouse button, while click only works for the left mouse button).

canvasF' :: (Int, Int) -> F (Bool, Picture ()) (Int, Int) #

canvasF with an option to render on top of or replace the current picture

imgF :: URL -> F URL o #

An image, <img src="url" alt=""> You can change the image dynamically by sending in the URL of another image.

imgF' :: Attribute -> URL -> F URL o #

An image with extra attributes, <img src="url" ...>. You can change the image dynamically by sending in the URL of another image.

Interaction control

focusF :: F hi ho -> F (Bool + hi) (Bool + ho) #

Allows you to observe and control the focus of a fudget. (Focus determines where keyboard input goes.)

disableF :: F hi ho -> F (Bool + hi) ho #

Disable and enable buttons and other input elements.

eventF :: [Element -> Event b] -> ((Element -> Event b, b) -> ho) -> F hi ho -> F hi ho #

Add event handlers to the elements generated by a fudget. Event types can be imported from Graphics.UI.Threepenny.Events.

Static content

textF :: String -> F hi ho #

Plain text

htmlF :: String -> F hi ho #

Text with HTML markup

ahrefF :: URL -> F i o -> F i o #

A hyperlink <a href="url">...</a>

Web page layout

h1F :: F hi ho -> F hi ho #

Level 1 header <h1>...</h1>

h2F :: F hi ho -> F hi ho #

Level 2 header <h2>...</h2>

h3F :: F hi ho -> F hi ho #

Level 3 header <h3>...</h3>

h4F :: F hi ho -> F hi ho #

Level 4 header <h4>...</h4>

pF :: F hi ho -> F hi ho #

Paragraph <p>...</p>

tableF :: Int -> F hi ho -> F hi ho #

A table with n columns. The elements generated by the argument fudget are placed in separate table cells.

divF :: F hi ho -> F hi ho #

A div element <div>...</div>

boxF :: F hi ho -> F hi ho #

A div element with a black border and some padding

ulF :: F hi ho -> F hi ho #

Unordered list <ul>...</ul>

olF :: F hi ho -> F hi ho #

Ordered list <ol>...</ol>

liF :: F hi ho -> F hi ho #

List item <li>...</li>

preF :: F hi ho -> F hi ho #

A pre element <pre>...</pre>

permuteF :: ([Element] -> [Element]) -> F hi ho -> F hi ho #

Rearrange the elements generated by a fudget. Note that Elements can not be duplicated.

Traditional Fudgets compatibility

shellF :: String -> F hi ho -> F hi ho #

With traditional Fudgets, shellF creates top-level application windows. With WebFudgets, using shellF is entierly optional. It just puts a title above another fudget and adds a couple of <div> elements that can be styled to look like a traditional application window with a title bar, if you wish. <div class="shellF"><h4>title</h4><div>...</div></div>

vBoxF :: F hi ho -> F hi ho #

Place elements vertically

hBoxF :: F hi ho -> F hi ho #

Place elements horizontally

Changing style and other properties

classF :: F hi ho -> String -> F hi ho #

Set the class attribute of the elements generated by a fudget

withF :: F hi ho -> [Attribute] -> F hi ho #

Apply attributes to the elements generated by a fudget

dynWithF :: F hi ho -> F ([Attribute] + hi) ho #

Dynamically change element attributes

dynF :: F i o -> F (F i o + i) o #

A fudget that can be replaced dynamically

Fudget plumbing

Parallel composition

(>+<) :: F i1 o1 -> F i2 o2 -> F (i1 + i2) (o1 + o2) infixl 5 #

Tagged parallel composition. Messages to/from the left fudget are tagged Left. Messages to/from the right fudget are tagged Right.

(>+) :: F hi1 ho -> F hi2 p -> F hi1 ho infixl 5 #

Parallel composition where only the left fudget is connected. The right fudget is typically static content.

(+<) :: F hi1 p -> F hi2 ho -> F hi2 ho infixl 5 #

Parallel composition where only the right fudget is connected. The left fudget is typically static content.

listF :: Eq a => [(a, F hi b)] -> F (a, hi) (a, b) #

Tagged parallel composition of a list of fudgets

Serial composition

(=<=) :: F hi1 ho -> F hi2 hi1 -> F hi2 ho infixr 3 #

Right-to-left serial composition. The output stream of the right fudget is connected to the input stream of the left fudget. This was originally called >==< in Fudgets.

(=>=) :: F hi1 hi2 -> F hi2 ho -> F hi1 ho infixr 3 #

Left-to-right serial composition. The output stream of the left fudget is connected to the input stream of the right fudget. (This was not included in the original implementation of Fudgets. Using both =>= and =<= in the same expression might lead to confusion...)

Loops

loopLeftF :: F (loop + hi) (loop + ho) -> F hi ho #

Creates a feedback loop. loopLeftF fud behaves as follows: output from fud tagged Left will be sent back to the input of fud. Output from fud tagged Right will be sent to the output of loopLeftF fud. Input to loopLeftF fud will be tagged Right and delivered to fud.

loopF :: F ho ho -> F ho ho #

Copy output back to the input. The fudget needs to send on average strictly less than one output message per input message, otherwise it will become busy reacting to its own messages.

loopThroughRightF :: F (Either a hi) (Either b ho) -> F b a -> F hi ho #

loopThroughRightF master slave is similar to loopLeftF master, but the loop goes through the slave fudget. (A better name might be encapsulateF since all communication with the slave has to go via the master, so the slave is encapsulated in this sense.) loopThroughRightF :: F (ro+hi) (ri+ho) -> F ri ro -> F hi ho

Adding application specific functionality

Stateless

mapF :: (a -> ho) -> F a ho #

Like map for lists. mapF f outputs f x for every x in the input stream

filterF :: (ho -> Bool) -> F ho ho #

Like filter for lists. Propagates values from the input stream to the output stream if they pass a test.

mapMaybeF :: (a -> Maybe ho) -> F a ho #

Like mapMaybe for lists. A combination of mapF and filterF.

concatMapF :: (i -> [o]) -> F i o #

Like concatMap for lists. A combination of concatF and mapF.

Stateful

stateF :: (s -> hi -> (s, [ho])) -> s -> F hi ho #

stateF is used to maintain an internal state. Given a state transition function f and an initial state s, stateF f s responds to input by applying f to it to update the internal state and generate zero or more output messages.

persistentStateF :: (Read s, Show s) => String -> (s -> i -> (s, [o])) -> s -> F i o #

Like stateF, but also uses LocalStorage to retain the state between activations of the web application. The first argument is a key that should be unique among all web applications on the same server.

localStorageF :: (Read a, Show a) => String -> a -> F a a #

Outputs one message read from LocalStorage on startup. Writes any input to LocalStorage.

Stream manipulation

putF :: ho -> F hi ho -> F hi ho #

putF x fud outputs x, then behaves like fud

putsF :: [ho] -> F hi ho -> F hi ho #

putF xs fud outputs xs, then behaves like fud

nullF :: F p ho #

Ignores all input. Doesn't produce any output.

idF :: F hi hi #

mapF id, propagates all input directly to the output

concatF :: F [i] i #

Like concat for lists, flattens a stream of lists.

toBothF :: F a (a + a) #

throughF :: F ho ho -> F ho ho #

splitF :: F (a, b) (a + b) #

gatherF :: F (a + b) (a, b) #

After the first Left a and Right b has arrived on the input, gatherF output pairs (a,b) with the most recent a and b values received.

gatherF' :: (a, b) -> F (a + b) (a, b) #

gatherF with initial values.

Timing

timerF :: F (Maybe Int) Tick #

timerF outputs Tick at regular intervals. The timer starts when it receives Just interval on its input. The timer stops when it receives Nothing in its input.

data Tick #

Constructors

Tick 

Instances

Eq Tick # 

Methods

(==) :: Tick -> Tick -> Bool

(/=) :: Tick -> Tick -> Bool

Show Tick # 

Methods

showsPrec :: Int -> Tick -> ShowS

show :: Tick -> String

showList :: [Tick] -> ShowS

Debugging

writeLogF :: (hi -> String) -> F hi hi #

Like idF but also writes messages to stdout

Internal

These definitions reveals implementation details that might change.

initF :: UI a -> (a -> F hi ho) -> F hi ho #

ioF :: (hi -> IO ho) -> F hi ho #

elemDisplayF :: Maybe (UI Element -> UI a) -> F (UI Element -> UI b) o #

modifyF :: (H ho -> [Element] -> UI [Element]) -> F hi ho -> F hi ho #

type H a = a -> UI () #

The type of an event handler

Threepenny extras

Attributes

type Attribute = UI Element -> UI Element #

An attribute is a function that modifies a user interface element. See also Graphics.UI.Threepenny.Attributes.

(=:) :: ReadWriteAttr Element i o -> i -> Attribute #

a=:v is the same as v # set a

attr :: String -> WriteAttr Element String #

style :: WriteAttr Element [(String, String)] #

Drawing on a canvas

type Picture a = Canvas -> UI a #

type Point = (Double, Double) #

circle :: Point -> Double -> Canvas -> UI () #

line :: Point -> Point -> Picture () #

Draw a straight line between to points

strokePath :: String -> [Point] -> Picture () #

fillPath :: FillStyle -> [Point] -> Picture () #

Other utilities

chop :: Int -> [a] -> [[a]] #

readM :: Read a => String -> Maybe a #