From d066289293640c481eeb387014e6fcb4d6ffb5ef 2014-11-18 19:29:35 From: Jonathan Frederic Date: 2014-11-18 19:29:35 Subject: [PATCH] Output Widget --- diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js index ae0afda..fb958d2 100644 --- a/IPython/html/static/notebook/js/codecell.js +++ b/IPython/html/static/notebook/js/codecell.js @@ -23,6 +23,7 @@ define([ 'notebook/js/codemirror-ipython' ], function(IPython, $, utils, keyboard, cell, outputarea, completer, celltoolbar, CodeMirror, cmpython, cmip) { "use strict"; + var Cell = cell.Cell; /* local util for codemirror */ @@ -79,6 +80,7 @@ define([ this.input_prompt_number = null; this.celltoolbar = null; this.output_area = null; + this.active_output_area = []; this.last_msg_id = null; this.completer = null; @@ -118,6 +120,31 @@ define([ CodeCell.prototype = Object.create(Cell.prototype); /** + * @method get_output_area + */ + CodeCell.prototype.get_output_area = function () { + if (this.active_output_area && this.active_output_area.length > 0) { + return this.active_output_area[this.active_output_area.length-1]; + } else { + return this.output_area; + } + }; + + /** + * @method push_output_area + */ + CodeCell.prototype.push_output_area = function (output_area) { + this.active_output_area.push(output_area); + }; + + /** + * @method pop_output_area + */ + CodeCell.prototype.pop_output_area = function () { + this.active_output_area.pop(); + }; + + /** * @method auto_highlight */ CodeCell.prototype.auto_highlight = function () { @@ -282,8 +309,8 @@ define([ console.log("Can't execute, kernel is not connected."); return; } - - this.output_area.clear_output(); + + this.get_output_area().clear_output(); // Clear widget area this.widget_subarea.html(''); @@ -312,6 +339,7 @@ define([ * @method get_callbacks */ CodeCell.prototype.get_callbacks = function () { + var that = this; return { shell : { reply : $.proxy(this._handle_execute_reply, this), @@ -321,8 +349,14 @@ define([ } }, iopub : { - output : $.proxy(this.output_area.handle_output, this.output_area), - clear_output : $.proxy(this.output_area.handle_clear_output, this.output_area), + output : function() { + var output_area = that.get_output_area(); + output_area.handle_output.apply(output_area, arguments); + }, + clear_output : function() { + var output_area = that.get_output_area(); + output_area.handle_clear_output.apply(output_area, arguments); + }, }, input : $.proxy(this._handle_input_request, this) }; @@ -356,7 +390,7 @@ define([ * @private */ CodeCell.prototype._handle_input_request = function (msg) { - this.output_area.append_raw_input(msg); + this.get_output_area().append_raw_input(msg); }; @@ -459,7 +493,7 @@ define([ CodeCell.prototype.clear_output = function (wait) { - this.output_area.clear_output(wait); + this.get_output_area().clear_output(wait); this.set_input_prompt(); }; diff --git a/IPython/html/static/widgets/js/init.js b/IPython/html/static/widgets/js/init.js index cfbd134..a65ffe4 100644 --- a/IPython/html/static/widgets/js/init.js +++ b/IPython/html/static/widgets/js/init.js @@ -9,6 +9,7 @@ define([ "widgets/js/widget_float", "widgets/js/widget_image", "widgets/js/widget_int", + "widgets/js/widget_output", "widgets/js/widget_selection", "widgets/js/widget_selectioncontainer", "widgets/js/widget_string", diff --git a/IPython/html/static/widgets/js/widget_output.js b/IPython/html/static/widgets/js/widget_output.js new file mode 100644 index 0000000..1a77b68 --- /dev/null +++ b/IPython/html/static/widgets/js/widget_output.js @@ -0,0 +1,41 @@ +// Copyright (c) IPython Development Team. +// Distributed under the terms of the Modified BSD License. + +define([ + "widgets/js/widget", + "jquery", + 'notebook/js/outputarea', +], function(widget, $, outputarea){ + + var OutputView = widget.DOMWidgetView.extend({ + initialize: function (parameters) { + // Public constructor + OutputView.__super__.initialize.apply(this, [parameters]); + this.model.on('msg:custom', this._handle_route_msg, this); + }, + + render: function(){ + // Called when view is rendered. + this.output_area = new outputarea.OutputArea({ + selector: this.$el, + prompt_area: false, + events: this.model.widget_manager.notebook.events, + keyboard_manager: this.model.widget_manager.keyboard_manager }); + }, + + _handle_route_msg: function(content) { + var cell = this.options.cell; + if (content && cell) { + if (content.method == 'push') { + cell.push_output_area(this.output_area); + } else if (content.method == 'pop') { + cell.pop_output_area(this.output_area); + } + } + }, + }); + + return { + 'OutputView': OutputView, + }; +}); diff --git a/IPython/html/widgets/__init__.py b/IPython/html/widgets/__init__.py index 8766356..d62a3d2 100644 --- a/IPython/html/widgets/__init__.py +++ b/IPython/html/widgets/__init__.py @@ -6,6 +6,7 @@ from .widget_box import Box, Popup, FlexBox, HBox, VBox from .widget_float import FloatText, BoundedFloatText, FloatSlider, FloatProgress, FloatRangeSlider from .widget_image import Image from .widget_int import IntText, BoundedIntText, IntSlider, IntProgress, IntRangeSlider +from .widget_output import Output from .widget_selection import RadioButtons, ToggleButtons, Dropdown, Select from .widget_selectioncontainer import Tab, Accordion from .widget_string import HTML, Latex, Text, Textarea diff --git a/IPython/html/widgets/widget_output.py b/IPython/html/widgets/widget_output.py new file mode 100644 index 0000000..f07f6dd --- /dev/null +++ b/IPython/html/widgets/widget_output.py @@ -0,0 +1,32 @@ +"""Output class. + +Represents a widget that can be used to display output within the widget area. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +from .widget import DOMWidget +import sys +from IPython.utils.traitlets import Unicode, List +from IPython.display import clear_output + +class Output(DOMWidget): + """Displays multiple widgets in a group.""" + _view_name = Unicode('OutputView', sync=True) + + def clear_output(self, *pargs, **kwargs): + with self: + clear_output(*pargs, **kwargs) + + def __enter__(self): + self._flush() + self.send({'method': 'push'}) + + def __exit__(self, exception_type, exception_value, traceback): + self._flush() + self.send({'method': 'pop'}) + + def _flush(self): + sys.stdout.flush() + sys.stderr.flush()