{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Simple example notebook that shows how one can use widgets to build custom dialogs." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.html import widgets\n", "from IPython.display import display" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "By using Bootstrap's modal class and ContainerWidgets, we can build a simple dialog window." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def scrub_text_html(text):\n", " text = text.replace('&', '&')\n", " text = text.replace(' ', ' ')\n", " text = text.replace('<', '<')\n", " text = text.replace('>', '>')\n", " text = text.replace('\\n', '
\\n')\n", " return text\n", "\n", "def create_dialog(title=None, on_hidden=None):\n", " dialog = widgets.ContainerWidget(visible=False)\n", " dialog_header = widgets.ContainerWidget(parent=dialog)\n", " dialog_header_close = widgets.ButtonWidget(parent=dialog_header, description = '×')\n", " dialog_header_label = widgets.StringWidget(parent=dialog_header, default_view_name='HTMLView')\n", " dialog_body = widgets.ContainerWidget(parent=dialog)\n", " dialog_footer = widgets.ContainerWidget(parent=dialog)\n", " \n", " if title is None or title == '':\n", " title = ' '\n", " dialog_header_label.value = '

%s

' % scrub_text_html(title)\n", " \n", " def handle_close():\n", " dialog.visible = False\n", " if on_hidden is not None:\n", " on_hidden(dialog)\n", " dialog_header_close.on_click(handle_close)\n", " \n", " display(dialog)\n", " \n", " dialog_header.add_class('modal-header')\n", " dialog_body.add_class('modal-body')\n", " dialog_footer.add_class('modal-footer')\n", " dialog.add_class('modal')\n", " \n", " dialog_header_close.remove_class('btn')\n", " dialog_header_close.add_class('close')\n", " \n", " return dialog_body, dialog_footer, dialog\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using this `show_dialog` method, custom dialogs can be made using widgets. Below is an example of a Yes/No dialog." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Since Python has a global thread lock, everything runs on a single thread.\n", "# Because of this, we use an asynronous model (callbacks).\n", "def show_yes_no(prompt, yes_callback=None, no_callback=None, title=None):\n", " \n", " def handle_hidden(dialog_window):\n", " if no_callback is not None:\n", " no_callback()\n", " dialog_window.close()\n", " \n", " (dialog_body, dialog_footer, dialog_window) = create_dialog(title=title, on_hidden=handle_hidden)\n", " \n", " def handle_yes():\n", " dialog_window.visible = False\n", " if yes_callback is not None:\n", " yes_callback()\n", " dialog_window.close()\n", " \n", " def handle_no():\n", " dialog_window.visible = False\n", " handle_hidden(dialog_window)\n", " \n", " yes_button = widgets.ButtonWidget(parent=dialog_footer, description='Yes')\n", " yes_button.on_click(handle_yes)\n", " no_button = widgets.ButtonWidget(parent=dialog_footer, description='No')\n", " no_button.on_click(handle_no)\n", " prompt_label = widgets.StringWidget(parent=dialog_body, value=scrub_text_html(prompt), default_view_name='HTMLView')\n", " \n", " display(yes_button)\n", " display(no_button)\n", " display(prompt_label)\n", " \n", " yes_button.add_class('btn-success')\n", " no_button.add_class('btn-danger')\n", " \n", " dialog_window.visible=True\n", " \n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Test" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def yes():\n", " show_yes_no(\"Do you want to show the dialog again?\", yes, title=\"Self displaying dialog\")\n", "yes()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dialog result handlers can contain nested dialogs. The following example shows how syncronous logic can be simulated using closures." ] }, { "cell_type": "code", "collapsed": false, "input": [ "title = \"Interactive Story\"\n", "def open_door():\n", " show_yes_no(\"The house is empty. You are tired and decide to sleep. You live to see another day.\")\n", "\n", "def stay_outside():\n", " def fight():\n", " show_yes_no(\"You try to fight the wolves but die in the process.\", title=title)\n", " \n", " def panic():\n", " def flight():\n", " show_yes_no(\"You run as fast as you can. You manage to escape the\\n\" + \\\n", " \"wolves but the cold is beginning to get to you. You\\n\" + \\\n", " \"sit in the snow to take a nap. You freeze and die.\", title=title)\n", " \n", " show_yes_no(\"You panic. Do you enter the cabin now?\", open_door, flight, title=title)\n", " \n", " show_yes_no(\"A pack of wolves approach. Do you want to fight them?\", fight, panic, title=title)\n", "\n", "show_yes_no(\"You are standing outside in a blizzard on a cold winter night.\\n\" + \\\n", " \"A warm cabin with the lights on is in front of you.\\n\\n\" + \\\n", " \"Do you want to enter the cabin?\", open_door, stay_outside, title=title)\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 } ], "metadata": {} } ] }