"**NOTE**: Only the `Int` widgets are shown in this notebook. The `Float` widgets are the same as their `Int` counterparts, but hold `Float`s instead of `Int`s."
"----------------------\n",
"\n",
"First of all, we have to import the Widgets library. Sometimes we need some Haskell language extensions. We need `OverloadedStrings` because some widget methods receive a `Text` as an argument, instead of a `[Char]`."
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"metadata": {
"metadata": {},
"collapsed": true
},
"outputs": [],
"outputs": [],
"source": [
"source": [
"{-# LANGUAGE OverloadedStrings #-}\n",
"{-# LANGUAGE OverloadedStrings #-}\n",
...
@@ -41,131 +41,315 @@
...
@@ -41,131 +41,315 @@
"cell_type": "markdown",
"cell_type": "markdown",
"metadata": {},
"metadata": {},
"source": [
"source": [
"#### `IntText` and `BoundedIntText`"
"#### `IntText` and `FloatText`\n",
"We are going to see how the `Text` family works. They create a \"Stepper\", which lets us click to increment a certain amount. We can also input the number as if it were text."
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"metadata": {
"metadata": {},
"collapsed": false
},
"outputs": [],
"outputs": [],
"source": [
"source": [
"int <- mkIntText\n",
"intt <- mkIntText\n",
"int"
"floatt <- mkFloatText\n",
"intt\n",
"floatt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For any numeric widget, we can use `getField w IntValue` and `getField w FloatValue` to obtain the value stored in the widget. Try changing the numbers in the widgets and then executing the cell bellow!"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"metadata": {
"metadata": {},
"collapsed": false
},
"outputs": [],
"outputs": [],
"source": [
"source": [
"bit <- mkBoundedIntText\n",
"getField intt IntValue\n",
"bit"
"getField floatt FloatValue"
]
]
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"metadata": {},
"metadata": {},
"source": [
"source": [
"Both the widgets are similar, but the second one possesses some additional properties."
"We can also use these results for any computation. For example, let us add them together:"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"metadata": {
"metadata": {},
"collapsed": false
},
"outputs": [],
"outputs": [],
"source": [
"source": [
"setField bit MaxInt 20\n",
"x <- getField intt IntValue\n",
"setField bit MinInt 10\n",
"y <- getField floatt FloatValue\n",
"setField bit ChangeHandler (getField bit IntValue >>= print)"
"\n",
"(fromIntegral x) + y"
]
]
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"metadata": {},
"metadata": {},
"source": [
"source": [
"Now, the first widget will accept arbitrary input whereas the second one wil accept input in the the 10-20 range. For example, try entering large values and hitting return/enter in the second widget."
"But incrementing and decrementing one by one is a bit boring... We can change the number incremented each step if we set the `StepInt` and `StepFloat` fields."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"setField intt StepInt 5\n",
"setField floatt StepFloat 0.5"
]
]
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"metadata": {},
"metadata": {},
"source": [
"source": [
"#### `IntSlider` and `IntRangeSlider`"
"Try clicking on the buttons of the text field now.\n",
"\n",
"By the way, does this mean that we can change other fields with `setField`? Yes! For example, let us change the `IntValue`/`FloatValue`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"setField intt IntValue 42\n",
"setField floatt FloatValue 3.14"
]
]
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"metadata": {},
"metadata": {},
"source": [
"source": [
"Both these widgets are sliders (duh!). `IntSlider` represents a single value, whereas `IntRangeSlider` represents a pair (range) of values."
"One special field is the `ChangeHandler`. This field is an IO function that is executed everytime the value is changed. We are going to \"sync\" the two widgets using two `ChangeHandler` functions. Each time the value changes in one widget, it is changed on the other widget too."
"-- Let's display the widgets again so we don't have to scroll up and down\n",
"intt\n",
"floatt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `BoundedIntText` and `BoundedFloatText`\n",
"\n",
"So, what's the difference between the Bounded family and the other two? `Bounded` widgets have the `Max` and `Min` attributes, which let you set an upper and lower bound. Let's try it"
"If you try clicking on the buttons or editing the text, you can't but anything that is not between the `Min` and `Max`! That's pretty neat, but, if you want to do something with bounds, maybe it's better to use an slider"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### `IntSlider`, `FloatSlider`, `FloatLogSlider`, `IntRangeSlider` and `FloatRangeSlider`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All these widgets are sliders (duh!). `IntSlider`, `FloatSlider` and `FloatLogSlider` represent a single value, whereas `IntRangeSlider` and `FloatRangeSlider` represent a pair (range) of values. `FloatLogSlider` uses a logarithmic scale, which means that every step will multiply (instead of increment) the value!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"ins <- mkIntSlider\n",
"ins <- mkIntSlider\n",
"irs <- mkIntRangeSlider"
"irs <- mkIntRangeSlider\n",
"fns <- mkFloatSlider\n",
"fls <- mkFloatLogSlider\n",
"frs <- mkFloatRangeSlider\n",
"setField fns StepFloat 0.25\n",
"-- We can set the base of the logslider\n",
"setField fls BaseFloat 2\n",
"setField fls StepFloat 1"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"metadata": {
"metadata": {},
"collapsed": false
},
"outputs": [],
"outputs": [],
"source": [
"source": [
"ins\n",
"ins\n",
"irs"
"irs\n",
"fns\n",
"fls\n",
"frs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"They work the same as the previous widgets plus, they are a lot more confortable if you have bounds. The only difference is with the pair ones, we have to get the `IntPairValue` and `FloatPairValue` fields"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"getField irs IntPairValue\n",
"getField frs FloatPairValue"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"-- We can also set the field!\n",
"setField irs IntPairValue (32,42)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's create a small program using widgets that gives us the greatest common divisor of two numbers! It displays the result on a `IntText` widget"
"Finally, we have these two widgets, that we can use as progress bars."
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"metadata": {
"metadata": {},
"collapsed": false
},
"outputs": [],
"outputs": [],
"source": [
"source": [
"getField irs IntPairValue"
"fnp <- mkFloatProgress\n",
"fnp"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"setField fnp FloatValue 42.5\n",
"getField fnp FloatValue"
]
]
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"metadata": {},
"metadata": {},
"source": [
"source": [
"#### `IntProgress`"
"We can also display them Vertically.\n",
"\n",
"*(Did you know you can also display the Sliders vertically?)*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"setField fnp Orientation VerticalOrientation"
]
]
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"metadata": {},
"metadata": {},
"source": [
"source": [
"This widget is meant to be used as a progress bar."
"Now we are going to create a REAL progress bar! For example, let's create a thread that does some incredible complex calculations (sleeping) and then reports the progress to the widget"