##// END OF EJS Templates
Fix the cell reference in views...
Fix the cell reference in views This solution is kludgy, but it does fix what broke when we tried to take the cell references out of views. Conflicts: IPython/html/static/notebook/js/widgets/widget.js

File last commit:

r14446:81608774
r14617:6d0b62ec
Show More
Dialogs.ipynb
199 lines | 6.8 KiB | text/plain | TextLexer

Simple example notebook that shows how one can use widgets to build custom dialogs.

In [1]:
from IPython.html import widgets
from IPython.display import display

By using Bootstrap's modal class and ContainerWidgets, we can build a simple dialog window.

In [2]:
def scrub_text_html(text):
    text = text.replace('&', '&')
    text = text.replace(' ', ' ')
    text = text.replace('<', '&lt;')
    text = text.replace('>', '&gt;')
    text = text.replace('\n', '<br>\n')
    return text

def create_dialog(title=None, on_hidden=None):
    dialog = widgets.ContainerWidget(visible=False)
    dialog_header = widgets.ContainerWidget(parent=dialog)
    dialog_header_close = widgets.ButtonWidget(parent=dialog_header, description = '&times;')
    dialog_header_label = widgets.StringWidget(parent=dialog_header, default_view_name='HTMLView')
    dialog_body = widgets.ContainerWidget(parent=dialog)
    dialog_footer = widgets.ContainerWidget(parent=dialog)
    
    if title is None or title == '':
        title = ' '
    dialog_header_label.value = '<h3>%s</h3>' % scrub_text_html(title)
    
    def handle_close():
        dialog.visible = False
        if on_hidden is not None:
            on_hidden(dialog)
    dialog_header_close.on_click(handle_close)
    
    display(dialog)
    
    dialog_header.add_class('modal-header')
    dialog_body.add_class('modal-body')
    dialog_footer.add_class('modal-footer')
    dialog.add_class('modal')
    
    dialog_header_close.remove_class('btn')
    dialog_header_close.add_class('close')
    
    return dialog_body, dialog_footer, dialog

Using this show_dialog method, custom dialogs can be made using widgets. Below is an example of a Yes/No dialog.

In [3]:
# Since Python has a global thread lock, everything runs on a single thread.
# Because of this, we use an asynronous model (callbacks).
def show_yes_no(prompt, yes_callback=None, no_callback=None, title=None):
    
    def handle_hidden(dialog_window):
        if no_callback is not None:
            no_callback()
        dialog_window.close()
        
    (dialog_body, dialog_footer, dialog_window) = create_dialog(title=title, on_hidden=handle_hidden)
    
    def handle_yes():
        dialog_window.visible = False
        if yes_callback is not None:
            yes_callback()
        dialog_window.close()
            
    def handle_no():
        dialog_window.visible = False
        handle_hidden(dialog_window)
    
    yes_button = widgets.ButtonWidget(parent=dialog_footer, description='Yes')
    yes_button.on_click(handle_yes)
    no_button = widgets.ButtonWidget(parent=dialog_footer, description='No')
    no_button.on_click(handle_no)
    prompt_label = widgets.StringWidget(parent=dialog_body, value=scrub_text_html(prompt), default_view_name='HTMLView')
    
    display(yes_button)
    display(no_button)
    display(prompt_label)
    
    yes_button.add_class('btn-success')
    no_button.add_class('btn-danger')
    
    dialog_window.visible=True
    
    

Test

In [4]:
def yes():
    show_yes_no("Do you want to show the dialog again?", yes, title="Self displaying dialog")
yes()

Dialog result handlers can contain nested dialogs. The following example shows how syncronous logic can be simulated using closures.

In [5]:
title = "Interactive Story"
def open_door():
    show_yes_no("The house is empty.  You are tired and decide to sleep.  You live to see another day.")

def stay_outside():
    def fight():
        show_yes_no("You try to fight the wolves but die in the process.", title=title)
        
    def panic():
        def flight():
            show_yes_no("You run as fast as you can.  You manage to escape the\n" + \
                        "wolves but the cold is beginning to get to you.  You\n" + \
                        "sit in the snow to take a nap.  You freeze and die.", title=title)
        
        show_yes_no("You panic.  Do you enter the cabin now?", open_door, flight, title=title)
        
    show_yes_no("A pack of wolves approach.  Do you want to fight them?", fight, panic, title=title)

show_yes_no("You are standing outside in a blizzard on a cold winter night.\n" + \
            "A warm cabin with the lights on is in front of you.\n\n" + \
            "Do you want to enter the cabin?", open_door, stay_outside, title=title)