diff --git a/examples/Interactive Widgets/Widget Styling.ipynb b/examples/Interactive Widgets/Widget Styling.ipynb
index 136ae87..c9fce87 100644
--- a/examples/Interactive Widgets/Widget Styling.ipynb
+++ b/examples/Interactive Widgets/Widget Styling.ipynb
@@ -7,7 +7,7 @@
]
],
"name": "",
- "signature": "sha256:cd7d3d42126bdbf20c087014460779dfbdb0a63dcb8f489ba7ebfc230a685edd"
+ "signature": "sha256:55ee4a4661f0939c40550752218a4c127b985536811190a2b7e581d7fe25cec7"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -18,243 +18,865 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "from IPython.html import widgets # Widget definitions\n",
- "from IPython.display import display # Used to display widgets in the notebook"
+ "%%html\n",
+ ""
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "html": [
+ ""
+ ],
+ "metadata": {},
+ "output_type": "display_data",
+ "text": [
+ ""
+ ]
+ }
+ ],
+ "prompt_number": 145
+ },
+ {
+ "cell_type": "heading",
+ "level": 1,
+ "metadata": {},
+ "source": [
+ "CSS"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Since the representation of the widget you see is a browser element, Cascading Style Sheets (CSS) are used for styling. Widgets have a `set_css` method that allows you to add and remove CSS properties from your elements. The following example shows had `set_css` can be used to set the background color of a `TextWidget`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "from IPython.html import widgets\n",
+ "text = widgets.TextWidget()\n",
+ "text.set_css('background', 'lime')\n",
+ "text "
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 146
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In the example above, the color `lime` is specified by name. CSS also supports specifying colors by a 3 byte hexadecimal string. The first byte is red, second green, and third blue. The following example sets the `TextWidget`'s background to blue."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "text.set_css('background', '#0000FF')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 147
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Font color is just `color`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "text.set_css('color', '#FFFFFF')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 148
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To remove the styling, you can call `set_css` again, but use an empty string instead of a color value."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "text.set_css('background', '')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 149
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "CSS is also used to set the height and width of controls. The `set_css` method also can accept a single dictionary with multiple CSS properties (as seen below)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "btn = widgets.ButtonWidget()\n",
+ "btn.set_css({\n",
+ " 'width': '100px',\n",
+ " 'height': '100px',\n",
+ "})\n",
+ "btn"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 150
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "For more information about what can be done with CSS, please refer to the [Mozilla Developer Network's series on it](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started).\n"
+ ]
+ },
+ {
+ "cell_type": "heading",
+ "level": 1,
+ "metadata": {},
+ "source": [
+ "Parent/Child Relationships"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To display widget A inside widget B, widget A must be a child of widget B. Only one instance of any particular widget can be child of another. In other words, *widget A* cannot have *widget B* listed twice in it's list of children.\n",
+ "\n",
+ "Widgets that can contain other widgets have a `children` attribute. This attribute can be set via a kwarg in the widget's constructor or after construction. Calling display on an object with children automatically displays those children, too."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "\n",
+ "from IPython.display import display\n",
+ "\n",
+ "float_range = widgets.FloatSliderWidget()\n",
+ "string = widgets.TextWidget(value='hi')\n",
+ "container = widgets.ContainerWidget(children=[float_range, string])\n",
+ "\n",
+ "container.set_css('border', '3px dotted red')\n",
+ "display(container) # Displays the `container` and all of it's children."
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 151
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Children can also be added to parents after the parent has been displayed. The parent is responsible for rendering its children."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "container = widgets.ContainerWidget()\n",
+ "container.set_css('border', '3px dotted red')\n",
+ "display(container)\n",
+ "\n",
+ "int_range = widgets.IntSliderWidget()\n",
+ "container.children=[int_range]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 152
+ },
+ {
+ "cell_type": "heading",
+ "level": 2,
+ "metadata": {},
+ "source": [
+ "Fancy containers"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "If you need to display a more complicated set of widgets, there are specialized containers that you can use. To display multiple sets of widgets, you can use an `AccordionWidget` or a `TabWidget` in combination with one `ContainerWidget` per set of widgets (as seen below). The \"pages\" of these widgets are their children. To set the titles of the pages, one must call `set_title` after the widget has been displayed."
+ ]
+ },
+ {
+ "cell_type": "heading",
+ "level": 3,
+ "metadata": {},
+ "source": [
+ "AccordionWidget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "name1 = widgets.TextWidget(description='Location:')\n",
+ "zip1 = widgets.BoundedIntTextWidget(description='Zip:', min=0, max=99999)\n",
+ "page1 = widgets.ContainerWidget(children=[name1, zip1])\n",
+ "\n",
+ "name2 = widgets.TextWidget(description='Location:')\n",
+ "zip2 = widgets.BoundedIntTextWidget(description='Zip:', min=0, max=99999)\n",
+ "page2 = widgets.ContainerWidget(children=[name2, zip2])\n",
+ "\n",
+ "accord = widgets.AccordionWidget(children=[page1, page2])\n",
+ "display(accord)\n",
+ "\n",
+ "accord.set_title(0, 'From')\n",
+ "accord.set_title(1, 'To')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 153
+ },
+ {
+ "cell_type": "heading",
+ "level": 3,
+ "metadata": {},
+ "source": [
+ "TabWidget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "name = widgets.TextWidget(description='Name:')\n",
+ "color = widgets.DropdownWidget(description='Color:', values=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'])\n",
+ "page1 = widgets.ContainerWidget(children=[name, color])\n",
+ "\n",
+ "age = widgets.IntSliderWidget(description='Age:', min=0, max=120, value=50)\n",
+ "gender = widgets.RadioButtonsWidget(description='Gender:', values=['male', 'female'])\n",
+ "page2 = widgets.ContainerWidget(children=[age, gender])\n",
+ "\n",
+ "tabs = widgets.TabWidget(children=[page1, page2])\n",
+ "display(tabs)\n",
+ "\n",
+ "tabs.set_title(0, 'Name')\n",
+ "tabs.set_title(1, 'Details')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 154
+ },
+ {
+ "cell_type": "heading",
+ "level": 3,
+ "metadata": {},
+ "source": [
+ "PopupWidget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Unlike the other two special containers, the `PopupWidget` is only designed to display one set of widgets. The `PopupWidget` can be used to display widgets outside of the widget area. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "counter = widgets.IntTextWidget(description='Counter:')\n",
+ "popup = widgets.PopupWidget(children=[counter], description='Popup Demo', button_text='Popup Button')\n",
+ "display(popup)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 155
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "counter.value += 1"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "counter.value += 1"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 157
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "popup.close()"
],
"language": "python",
"metadata": {},
"outputs": [],
- "prompt_number": 1
+ "prompt_number": 158
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
- "CSS"
+ "Alignment"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "When trying to design an attractive widget GUI, styling becomes important.\n",
- "Most widget views are DOM (document object model) elements that can be controlled with CSS.\n",
- "There are two helper methods that allow the manipulation of the widget's CSS.\n",
- "The first is the `Widget.set_css` method.\n",
- "This method allows one or more CSS attributes to be set at once. "
+ "Most widgets have a `description` attribute, which allows a label for the widget to be defined.\n",
+ "The label of the widget has a fixed minimum width.\n",
+ "The text of the label is always right aligned and the widget is left aligned:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "print(widgets.DOMWidget.set_css.__doc__)"
+ "display(widgets.TextWidget(description=\"a:\"))\n",
+ "display(widgets.TextWidget(description=\"aa:\"))\n",
+ "display(widgets.TextWidget(description=\"aaa:\"))"
],
"language": "python",
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Set one or more CSS properties of the widget.\n",
- "\n",
- " This function has two signatures:\n",
- " - set_css(css_dict, selector='')\n",
- " - set_css(key, value, selector='')\n",
- "\n",
- " Parameters\n",
- " ----------\n",
- " css_dict : dict\n",
- " CSS key/value pairs to apply\n",
- " key: unicode\n",
- " CSS key\n",
- " value:\n",
- " CSS value\n",
- " selector: unicode (optional, kwarg only)\n",
- " JQuery selector to use to apply the CSS key/value. If no selector \n",
- " is provided, an empty selector is used. An empty selector makes the \n",
- " front-end try to apply the css to a default element. The default\n",
- " element is an attribute unique to each view, which is a DOM element\n",
- " of the view that should be styled with common CSS (see \n",
- " `$el_to_style` in the Javascript code).\n",
- " \n"
- ]
- }
- ],
- "prompt_number": 2
+ "outputs": [],
+ "prompt_number": 159
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "The second is `get_css` which allows CSS attributesto be read.\n",
- "Note that this method will only read CSS attributes that have been set using the `set_css` method."
+ "If a label is longer than the minimum width, the widget is shifted to the right:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "print(widgets.DOMWidget.get_css.__doc__)"
+ "display(widgets.TextWidget(description=\"a:\"))\n",
+ "display(widgets.TextWidget(description=\"aa:\"))\n",
+ "display(widgets.TextWidget(description=\"aaa:\"))\n",
+ "display(widgets.TextWidget(description=\"aaaaaaaaaaaaaaaaaa:\"))"
],
"language": "python",
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Get a CSS property of the widget.\n",
- "\n",
- " Note: This function does not actually request the CSS from the \n",
- " front-end; Only properties that have been set with set_css can be read.\n",
- "\n",
- " Parameters\n",
- " ----------\n",
- " key: unicode\n",
- " CSS key\n",
- " selector: unicode (optional)\n",
- " JQuery selector used when the CSS key/value was set.\n",
- " \n"
- ]
- }
- ],
- "prompt_number": 3
+ "outputs": [],
+ "prompt_number": 160
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Below is an example that applies CSS attributes to a container to emphasize text."
+ "If a `description` is not set for the widget, the label is not displayed:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "label = widgets.LatexWidget()\n",
- "label.value = \"$\\\\textbf{ALERT:} Hello World!$\"\n",
- "container = widgets.ContainerWidget(children=[label])\n",
- "\n",
- "# set_css used to set a single CSS attribute.\n",
- "container.set_css('border', '3px solid black') # Border the container\n",
- "\n",
- "# set_css used to set multiple CSS attributes.\n",
- "container.set_css({'padding': '6px', # Add padding to the container\n",
- " 'background': 'yellow'}) # Fill the container yellow\n",
- "\n",
- "display(container)"
+ "display(widgets.TextWidget(description=\"a:\"))\n",
+ "display(widgets.TextWidget(description=\"aa:\"))\n",
+ "display(widgets.TextWidget(description=\"aaa:\"))\n",
+ "display(widgets.TextWidget())"
],
"language": "python",
"metadata": {},
"outputs": [],
- "prompt_number": 4
+ "prompt_number": 161
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
- "CSS Classes"
+ "DOM Classes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "IPython defines a large number of DOM (document object model) classes that you can apply to your widgets. Applying a DOM class causes all of the CSS associated with that class to be applied to the element. Classes can be applied and removed using the `add_class` and `remove_class` methods after a widget has been displayed. The majority of DOM classes defined by IPython are actually Bootstrap classes. For more information on Bootstrap classes and CSS, please refer to [Bootstrap's website](http://getbootstrap.com/2.3.2/)."
+ ]
+ },
+ {
+ "cell_type": "heading",
+ "level": 2,
+ "metadata": {},
+ "source": [
+ "Path dependent"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "In some cases, it is necessary to apply CSS classes to your widgets.\n",
- "CSS classes allow DOM elements to be indentified in Javascript and CSS.\n",
- "The notebook defines its own set of classes to stylize its elements.\n",
- "The `add_class` widget method allows you to add CSS classes to your widget."
+ "Both `add_class` and `remove_class` allow you to use CSS selectors to pick which sub elements of your widget get styled. Because of this, the `add_class` and `remove_class` methods are path dependent (order specific). The following example shows the same three calls made in three different orders and the resulting output. All three differ."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "print(widgets.DOMWidget.add_class.__doc__)"
+ "%%html\n",
+ ""
],
"language": "python",
"metadata": {},
"outputs": [
{
- "output_type": "stream",
- "stream": "stdout",
+ "html": [
+ ""
+ ],
+ "metadata": {},
+ "output_type": "display_data",
"text": [
- "Add class[es] to a DOM element.\n",
- "\n",
- " Parameters\n",
- " ----------\n",
- " class_names: unicode or list\n",
- " Class name(s) to add to the DOM element(s).\n",
- " selector: unicode (optional)\n",
- " JQuery selector to select the DOM element(s) that the class(es) will\n",
- " be added to.\n",
- " \n"
+ ""
]
}
],
- "prompt_number": 5
+ "prompt_number": 162
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "from IPython.html import widgets\n",
+ "from IPython.display import display\n",
+ "html = '
'.join([''.join(['x
' for i in range(8)]) for j in range(8)])\n",
+ "widget = [widgets.HTMLWidget(value=html) for i in range(3)]\n",
+ "\n",
+ "display(widget[0])\n",
+ "widget[0].add_class('red', 'div.cube:nth-child(even)')\n",
+ "widget[0].remove_class('red', 'div.red:nth-child(7n+1)')\n",
+ "widget[0].add_class('blue', 'div.red:nth-child(3n+1)')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 163
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "display(widget[1])\n",
+ "widget[1].remove_class('red', 'div.red:nth-child(7n+1)')\n",
+ "widget[1].add_class('blue', 'div.red:nth-child(3n+1)')\n",
+ "widget[1].add_class('red', 'div.cube:nth-child(even)')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 164
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "display(widget[2])\n",
+ "widget[2].add_class('red', 'div.cube:nth-child(even)')\n",
+ "widget[2].add_class('blue', 'div.red:nth-child(3n+1)')\n",
+ "widget[2].remove_class('red', 'div.red:nth-child(7n+1)')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 165
+ },
+ {
+ "cell_type": "heading",
+ "level": 2,
+ "metadata": {},
+ "source": [
+ "Alignment classes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Widgets can be aligned using IPython specific alignment classes. These classes should work with most widgets, but were designed to be applied to `ContainerWidget`s. Examples of these classes follow:\n",
+ "\n",
+ "### Orientation classes\n",
+ "#### \"vbox\"\n",
+ "Widget containers default to this orientation.\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "#### \"hbox\"\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "### Packing classes\n",
+ "These examples use the hbox layout to show packing. Packing is the alignment of the widgets along the the axis that they are displayed on.\n",
+ "#### \"start\"\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "#### \"center\"\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "#### \"end\"\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "### Aligning classes\n",
+ "These examples use the hbox layout to show alignment. Packing is the alignment of the widgets along the the axis perpindicular to the one that they are displayed on.\n",
+ "#### \"align-start\"\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "#### \"align-center\"\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "#### \"align-end\"\n",
+ "\n",
+ "
A
\n",
+ "
B
\n",
+ "
C
\n",
+ "
\n",
+ "\n",
+ "### Flex classes\n",
+ "To specify how \"greedy\" a container is when filling in the remaining space of its parent, the `box-flexN` properties are used (where N is 0, 1, or 2). The higher the value of N, the more greedy the child is. `box-flex0` is the default behavior, which is to not fill the parent.\n",
+ "\n",
+ "#### Example 1\n",
+ "\n",
+ "
box-flex0
\n",
+ "
box-flex0
\n",
+ "
box-flex0
\n",
+ "
\n",
+ "\n",
+ "#### Example 2\n",
+ "\n",
+ "
box-flex0
\n",
+ "
box-flex1
\n",
+ "
box-flex0
\n",
+ "
\n",
+ "\n",
+ "#### Example 3\n",
+ "\n",
+ "
box-flex0
\n",
+ "
box-flex1
\n",
+ "
box-flex1
\n",
+ "
\n",
+ "\n",
+ "#### Example 4\n",
+ "\n",
+ "
box-flex1
\n",
+ "
box-flex1
\n",
+ "
box-flex1
\n",
+ "
\n",
+ "\n",
+ "#### Example 5\n",
+ "\n",
+ "
box-flex2
\n",
+ "
box-flex1
\n",
+ "
box-flex1
\n",
+ "
\n",
+ "\n",
+ "#### Example 6\n",
+ "\n",
+ "
box-flex0
\n",
+ "
box-flex1
\n",
+ "
box-flex2
\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "heading",
+ "level": 3,
+ "metadata": {},
+ "source": [
+ "Application to widgets"
+ ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Since `add_class` is a DOM operation, **it will only affect widgets that have already been displayed**.\n",
- "`add_class` must be called after the widget has been displayed.\n",
- "Extending the example above, the corners of the container can be rounded by adding the `corner-all` CSS class to the container."
+ "Widget containers default as vertical boxes."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "container = widgets.ContainerWidget()\n",
- "container.set_css({'border': '3px solid black',\n",
- " 'padding': '6px', \n",
- " 'background': 'yellow'}) \n",
+ "buttons = [widgets.ButtonWidget(description=str(i)) for i in range(3)]\n",
"\n",
- "label = widgets.LatexWidget()\n",
- "label.value = \"$\\\\textbf{ALERT:} Hello World!$\"\n",
- "container.children = [label]\n",
+ "container = widgets.ContainerWidget(children=buttons)\n",
+ "display(container)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 166
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To make a widget container display its widgets horizontally, you need to remove the `vbox` class from the container and add the `hbox` class in its place."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "container = widgets.ContainerWidget(children=buttons)\n",
"display(container)\n",
- "container.add_class('corner-all') # Must be called AFTER display"
+ "container.remove_class('vbox')\n",
+ "container.add_class('hbox')"
],
"language": "python",
"metadata": {},
"outputs": [],
- "prompt_number": 6
+ "prompt_number": 167
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "The IPython notebook uses [bootstrap](http://getbootstrap.com/\u200e) for styling.\n",
- "The example above can be simplified by using a bootstrap class:"
+ "By setting the width of the container to 100% and adding the `center` class to it, you can center the buttons."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "label = widgets.LatexWidget(value = \"$\\\\textbf{ALERT:} Hello World!$\")\n",
- "display(label)\n",
- "\n",
- "# Apply twitter bootstrap alert class to the label.\n",
- "label.add_class(\"alert\")"
+ "container.set_css('width', '100%')\n",
+ "container.add_class('center')"
],
"language": "python",
"metadata": {},
"outputs": [],
- "prompt_number": 7
+ "prompt_number": 168
+ },
+ {
+ "cell_type": "heading",
+ "level": 2,
+ "metadata": {},
+ "source": [
+ "Style classes"
+ ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "The example below shows how bootstrap classes can be used to change button apearance."
+ "In addition to alignment classes, the classes defined by Bootstrap can also be used. This tutorial will only cover a few of the most common classes. For a full list of Bootstrap classes, please refer to [Bootstrap's website](http://getbootstrap.com/2.3.2/)."
+ ]
+ },
+ {
+ "cell_type": "heading",
+ "level": 3,
+ "metadata": {},
+ "source": [
+ "ButtonWidgets"
]
},
{
@@ -262,91 +884,189 @@
"collapsed": false,
"input": [
"# List of the bootstrap button styles\n",
- "button_classes = ['Default', 'btn-primary', 'btn-info', 'btn-success', \n",
- " 'btn-warning', 'btn-danger', 'btn-inverse', 'btn-link']\n",
+ "classes = [\n",
+ " 'btn', \n",
+ " 'btn-primary', \n",
+ " 'btn-info', \n",
+ " 'btn-success', \n",
+ " 'btn-warning', \n",
+ " 'btn-danger', \n",
+ " 'btn-inverse', \n",
+ " 'btn-link'\n",
+ "]\n",
+ "\n",
+ "# Display the buttons in a hbox\n",
+ "container = widgets.ContainerWidget(children=[widgets.ButtonWidget(description=c) for c in classes])\n",
+ "display(container)\n",
+ "\n",
+ "# Apply classes after display\n",
+ "container.remove_class('vbox')\n",
+ "container.add_class('hbox')\n",
+ "ret = [container.children[i].add_class(c) for i, c in enumerate(classes)]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 180
+ },
+ {
+ "cell_type": "heading",
+ "level": 3,
+ "metadata": {},
+ "source": [
+ "ContainerWidgets"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def create_label(cls):\n",
+ " class_name = widgets.HTMLWidget(value=cls)\n",
+ " container = widgets.ContainerWidget(children=[class_name])\n",
+ " display(container)\n",
+ " container.add_class(cls)\n",
"\n",
- "# Create each button and apply the style. Also add margin to the buttons so they space\n",
- "# themselves nicely.\n",
- "for i in range(8):\n",
- " button = widgets.ButtonWidget(description=button_classes[i])\n",
- " button.set_css(\"margin\", \"5px\")\n",
- " display(button)\n",
- " if i > 0: # Don't add a class the first button.\n",
- " button.add_class(button_classes[i])\n",
- " "
+ "ret = [create_label(c) for c in [\n",
+ " 'alert', \n",
+ " 'alert alert-error', \n",
+ " 'alert alert-success', \n",
+ " 'alert alert-info'\n",
+ "]]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 181
+ },
+ {
+ "cell_type": "heading",
+ "level": 3,
+ "metadata": {},
+ "source": [
+ "*ProgressWidgets"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "classes = [\n",
+ " 'progress-info', \n",
+ " 'progress-success', \n",
+ " 'progress-warning', \n",
+ " 'progress-danger',\n",
+ " 'progress-striped progress-info', \n",
+ " 'progress-striped progress-success', \n",
+ " 'progress-striped progress-warning', \n",
+ " 'progress-striped progress-danger',\n",
+ " 'active progress-striped progress-info', \n",
+ " 'active progress-striped progress-success', \n",
+ " 'active progress-striped progress-warning', \n",
+ " 'active progress-striped progress-danger',\n",
+ "]\n",
+ "ws = [widgets.IntProgressWidget(value=50, description=c) for c in classes]\n",
+ "ret = [display(w) for w in ws]\n",
+ "ret = [ws[i].add_class(c) for i, c in enumerate(classes)]"
],
"language": "python",
"metadata": {},
"outputs": [],
- "prompt_number": 8
+ "prompt_number": 182
+ },
+ {
+ "cell_type": "heading",
+ "level": 1,
+ "metadata": {},
+ "source": [
+ "Visibility"
+ ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "It is also useful to be able to remove CSS classes from widgets.\n",
- "The `remove_class` method allows you to remove classes from widgets that have been displayed.\n",
- "Like `add_class`, it must be called after the widget has been displayed."
+ "Sometimes it is necessary to hide or show widgets in place, without having to redisplay the widget.\n",
+ "The `visibility` property of widgets can be used to hide or show widgets that have already been displayed (as seen below)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "print(widgets.DOMWidget.remove_class.__doc__)"
+ "string = widgets.LatexWidget(value=\"Hello World!\")\n",
+ "display(string) "
],
"language": "python",
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Remove class[es] from a DOM element.\n",
- "\n",
- " Parameters\n",
- " ----------\n",
- " class_names: unicode or list\n",
- " Class name(s) to remove from the DOM element(s).\n",
- " selector: unicode (optional)\n",
- " JQuery selector to select the DOM element(s) that the class(es) will\n",
- " be removed from.\n",
- " \n"
- ]
- }
+ "outputs": [],
+ "prompt_number": 183
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "string.visible=False"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 184
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "string.visible=True"
],
- "prompt_number": 9
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 185
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "The example below animates an alert using different bootstrap styles."
+ "In the example below, a form is rendered, which conditionally displays widgets depending on the state of other widgets. Try toggling the student checkbox."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "import time\n",
- "label = widgets.LatexWidget(value = \"$\\\\textbf{ALERT:} Hello World!$\")\n",
- "display(label)\n",
+ "form = widgets.ContainerWidget()\n",
+ "first = widgets.TextWidget(description=\"First Name:\")\n",
+ "last = widgets.TextWidget(description=\"Last Name:\")\n",
+ "\n",
+ "student = widgets.CheckboxWidget(description=\"Student:\", value=False)\n",
+ "school_info = widgets.ContainerWidget(visible=False, children=[\n",
+ " widgets.TextWidget(description=\"School:\"),\n",
+ " widgets.IntTextWidget(description=\"Grade:\", min=0, max=12)\n",
+ " ])\n",
"\n",
- "# Apply twitter bootstrap alert class to the label.\n",
- "label.add_class(\"alert\")\n",
+ "pet = widgets.TextWidget(description=\"Pet's Name:\")\n",
+ "form.children = [first, last, student, school_info, pet]\n",
+ "display(form)\n",
"\n",
- "# Animate through additional bootstrap label styles 3 times\n",
- "additional_alert_styles = ['alert-error', 'alert-info', 'alert-success']\n",
- "for i in range(3 * len(additional_alert_styles)):\n",
- " label.add_class(additional_alert_styles[i % 3])\n",
- " label.remove_class(additional_alert_styles[(i-1) % 3])\n",
- " time.sleep(1)\n",
- " "
+ "def on_student_toggle(name, value):\n",
+ " if value:\n",
+ " school_info.visible = True\n",
+ " else:\n",
+ " school_info.visible = False\n",
+ "student.on_trait_change(on_student_toggle, 'value')\n"
],
"language": "python",
"metadata": {},
"outputs": [],
- "prompt_number": 10
+ "prompt_number": 186
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "[Next](Custom Widget - Hello World.ipynb)"
+ ]
}
],
"metadata": {}