Safe Haskell | None |
---|---|
Language | Haskell98 |
Extras.Widget
Description
A very simple Graphical User Interface (GUI) for user interaction with buttons, checkboxes, sliders and a few others.
Synopsis
- guiDrawingOf :: ([Widget], [Number] -> Picture) -> Program
- guiActivityOf :: ([Widget], [Number] -> state, ([Number], state, Event) -> state, ([Number], state) -> Picture) -> Program
- data Widget
- toggle :: (Text, Number, Number) -> Widget
- button :: (Text, Number, Number) -> Widget
- slider :: (Text, Number, Number) -> Widget
- randomBox :: (Text, Number, Number) -> Widget
- timer :: (Text, Number, Number) -> Widget
- counter :: (Text, Number, Number) -> Widget
- withConversion :: (Number -> Number, Widget) -> Widget
- setConversion :: (Number -> Number) -> Widget -> Widget
- widgetExample1 :: Program
- widgetExample2 :: Program
- widgetExample3 :: Program
- widgetExample4 :: Program
Documentation
Widget API
To use the extra features in this module, you must begin your code with this line:
import Extras.Widget
guiDrawingOf :: ([Widget], [Number] -> Picture) -> Program #
The function guiDrawingOf
is an entry point for drawing that allows
access to a simple GUI. It needs two arguments: a list of
Widgets and a function to create your drawing. This user-supplied drawing
function will have access to the list of the current values of the widgets,
which is passed as an argument.
Example of use:
program = guiDrawingOf(widgets,draw) where widgets = [ withConversion(\v -> 1 + 19 * v , slider("width" ,-7,-7)) , withConversion(\v -> 1 + 19 * v , slider("height" ,-7,-9)) , withConversion(flipflop , toggle("show circle" ,-7,-5)) , withConversion(flipflop , button("show in green",-7,-3)) , withConversion(\v -> 0.2 + 0.8 * v, randomBox("radius" ,-7,-1)) ] flipflop(v) = truncation(1 + 2 * v) draw(values) = blank & [blank, circle(r)]#s & colored(solidRectangle(w,h),[red,green]#c) where w = values#1 h = values#2 s = values#3 c = values#4 r = values#5
Note that the order in which the widgets are defined is important, because it determines how to access the correct value. Each widget fits in a box 4 units wide and 1 unit high.
guiActivityOf :: ([Widget], [Number] -> state, ([Number], state, Event) -> state, ([Number], state) -> Picture) -> Program #
The function guiActivityOf
is similar to activityOf
, but it also
takes in a list of widgets. The updating and drawing functions also
receive a list of the current values of the widgets.
Example of use:
program = guiActivityOf(widgets,init,update,draw) where widgets = [ withConversion(\v -> 20 * v, slider("width",-7,-7)) , withConversion(\v -> 2 + 3 * v, slider("height",-7,-9)) , withConversion (\v -> truncation(1 + 2*v), toggle("show circle",-7,-5)) , button("restart",-7,-3) , randomBox("new color",-7,-1) ] draw(values,(color@(RGB(r1,r2,r3)),angle,_)) = colored(base,color) & [blank, circle(5)]#s & translated(lettering(msg),0,9) where msg = joined(["(",printed(r1),",",printed(r2),",",printed(r3),")"]) base = rotated(solidRectangle(w,h),angle) w = values#1 h = values#2 s = values#3 init(rs) = (RGB(rs#1,rs#2,rs#3),0,0) update(values,(color@(RGB(r1,r2,r3)),angle,wait),TimePassing(_)) | values#4 > 0 , wait == 0 = (RGB(r2,r3,r),0,values#4) | otherwise = (color,angle+1,wait) where r = values#5 update(values,(color,angle,wait),PointerRelease(_)) = (color,angle,0) update(values,state,event) = state
Note that pre-defined actions on the widgets take precedence over anything that you define in your updating function, so you cannot alter the default behavior of the widgets.
Widgets
The internal structure of a Widget
is not exposed in the user interface. You
have access only to the current value of each widget.
toggle :: (Text, Number, Number) -> Widget #
A toggle (checkbox) with the given label at the given location. When the box is not set, the value produced is 0. When the box is set, the value produced is 0.5
button :: (Text, Number, Number) -> Widget #
A button placed at the given location. While the button is pressed, the value produced is 0.5, but when the button is released, the value reverts back to 0.
slider :: (Text, Number, Number) -> Widget #
A slider with the given label at the given location. The possible values will range from 0 to 1, and the initial value will be 0.
randomBox :: (Text, Number, Number) -> Widget #
A box that produces a random number between 0 and 1. Each time you click on it, the value will change. The value 1 is never produced, so the actual range of values is 0 to 0.99999...
timer :: (Text, Number, Number) -> Widget #
A toggle that counts time up when you set it. When you click on the left side of the widget, the current value is reset to 0. You can stop the timer and start it again, and the value will increase from where it was when you stopped it.
Example:
program = guiDrawingOf(widgets,draw) where widgets = [ withConversion(\v -> 1 + 9 * v , slider("length",-7,-7)) , withConversion(\v -> v * 30 , timer("angle" ,-7,-9)) ] draw([l,a]) = rotated(translated(colored(solidRectangle(l,0.25),red),l/2,0),a)
The timer operates in seconds, including decimals. However, the precision of the timer is not guaranteed beyond one or two decimals.
counter :: (Text, Number, Number) -> Widget #
A button that keeps incrementing the value each time you press it. The initial value is 1.
Convenience functions
withConversion :: (Number -> Number, Widget) -> Widget #
Make the widget use the provided function to convert values from the default range of a widget to a different range.
Example:
newSlider = withConversion(\v -> 20 * v - 10, oldSlider)
Assuming that the old slider did not have any conversion function applied to it, the example above will make the new slider produce values between -10 and 10, while the old slider will still produce values between 0 and 1
setConversion :: (Number -> Number) -> Widget -> Widget #
Same functionality as withConversion
, but using a different convention
for the arguments.
Examples
This is the example shown in the documentation for guiDrawingOf
This is the example shown in the documentation for guiActivityOf
This is the example shown in the documentation for timer
This example shows a tree created by a recursive function