Add notion of actions to celltoolbar

modify toolbar.js to be able to deal with actions.

modify maintoolbar to deal with the new action architecture

add a way to triger notification widget hiding
Matthias Bussonnier 12 years ago
parent f1a167ee19
commit f43d8585d1

@ -38,6 +38,14 @@ define([
// for this particular combination
this.element.addClass('notification_widget btn btn-xs navbar-btn');
};
/**
* hide the widget and empty the text
**/
NotificationWidget.prototype.hide = function () {
var that = this;
this.element.fadeOut(100, function(){that.inner.text('');});
};
/**
* Set the notification widget message to display for a certain

@ -2,149 +2,109 @@
// Distributed under the terms of the Modified BSD License.
define([
'require',
'base/js/namespace',
'jquery',
'notebook/js/toolbar',
'notebook/js/celltoolbar',
], function(IPython, $, toolbar, celltoolbar) {
'./toolbar',
'./celltoolbar',
], function(require, IPython, $, toolbar, celltoolbar) {
"use strict";
var MainToolBar = function (selector, options) {
/**
* Constructor
*
* Parameters:
* selector: string
* options: dictionary
* Dictionary of keyword arguments.
* events: $(Events) instance
* notebook: Notebook instance
*/
toolbar.ToolBar.apply(this, arguments);
// Constructor
//
// Parameters:
// selector: string
// options: dictionary
// Dictionary of keyword arguments.
// events: $(Events) instance
// notebook: Notebook instance
toolbar.ToolBar.apply(this, [selector, undefined ,options] );
this.events = options.events;
this.notebook = options.notebook;
this.construct();
this.add_celltype_list();
this.add_celltoolbar_list();
this.bind_events();
this._make();
Object.seal(this);
};
MainToolBar.prototype = Object.create(toolbar.ToolBar.prototype);
MainToolBar.prototype.construct = function () {
var that = this;
this.add_buttons_group([
{
id : 'save_b',
label : 'Save and Checkpoint',
icon : 'fa-save',
callback : function () {
that.notebook.save_checkpoint();
}
}
]);
this.add_buttons_group([
{
id : 'insert_below_b',
label : 'Insert Cell Below',
icon : 'fa-plus',
callback : function () {
that.notebook.insert_cell_below('code');
that.notebook.select_next();
that.notebook.focus_cell();
}
}
],'insert_above_below');
this.add_buttons_group([
{
id : 'cut_b',
label : 'Cut Cell',
icon : 'fa-cut',
callback : function () {
that.notebook.cut_cell();
}
},
{
id : 'copy_b',
label : 'Copy Cell',
icon : 'fa-copy',
callback : function () {
that.notebook.copy_cell();
}
},
{
id : 'paste_b',
label : 'Paste Cell Below',
icon : 'fa-paste',
callback : function () {
that.notebook.paste_cell_below();
}
}
],'cut_copy_paste');
this.add_buttons_group([
{
id : 'move_up_b',
label : 'Move Cell Up',
icon : 'fa-arrow-up',
callback : function () {
that.notebook.move_cell_up();
}
},
{
id : 'move_down_b',
label : 'Move Cell Down',
icon : 'fa-arrow-down',
callback : function () {
that.notebook.move_cell_down();
}
}
],'move_up_down');
this.add_buttons_group([
{
id : 'run_b',
label : 'Run Cell',
icon : 'fa-play',
callback : function () {
/**
* emulate default shift-enter behavior
*/
that.notebook.execute_cell_and_select_below();
}
},
{
id : 'interrupt_b',
label : 'Interrupt',
icon : 'fa-stop',
callback : function () {
that.notebook.kernel.interrupt();
}
},
{
id : 'repeat_b',
label : 'Restart Kernel',
icon : 'fa-repeat',
callback : function () {
that.notebook.restart_kernel();
}
}
],'run_int');
// thought, this might not be the best way as dict might not keep the right order.
// Might want to put the group name as second to make it optional
//
MainToolBar.prototype._make = function () {
var grps = [
[
['ipython.save-notebook'],
'save-notbook'
],
[
['ipython.insert-cell-after'],
'insert_above_below'],
[
['ipython.cut-selected-cell',
'ipython.copy-selected-cell',
'ipython.paste-cell-after'
] ,
'cut_copy_paste'],
[
['ipython.move-selected-cell-up',
'ipython.move-selected-cell-down'
],
'move_up_down'],
[ ['ipython.run-select-next',
'ipython.interrupt-kernel',
'ipython.restart-kernel',
],
'run_int'],
['<add_celltype_list>'],
['<add_celltoolbar_list>'],
];
this.construct(grps);
};
// add a cell type drop down to the maintoolbar.
// trigged when the pseudo action `<add_celltype_list>` is
// encountered when building a toolbar.
// there supposed to be only one of these, but many should work in most cases;
MainToolBar.prototype.add_celltype_list = function () {
this.element
.append($('<select/>')
.attr('id','cell_type')
.addClass('form-control select-xs')
.append($('<option/>').attr('value','code').text('Code'))
.append($('<option/>').attr('value','markdown').text('Markdown'))
.append($('<option/>').attr('value','raw').text('Raw NBConvert'))
.append($('<option/>').attr('value','heading').text('Heading'))
);
var that = this;
var sel = $('<select/>')
.attr('id','cell_type')
.addClass('form-control select-xs')
.append($('<option/>').attr('value','code').text('Code'))
.append($('<option/>').attr('value','markdown').text('Markdown'))
.append($('<option/>').attr('value','raw').text('Raw NBConvert'))
.append($('<option/>').attr('value','heading').text('Heading'));
this.events.on('selected_cell_type_changed.Notebook', function (event, data) {
if (data.cell_type === 'heading') {
sel.val('Markdown');
} else {
sel.val(data.cell_type);
}
});
sel.change(function () {
var cell_type = $(this).val();
switch (cell_type) {
case 'code':
that.notebook.to_code();
break;
case 'markdown':
that.notebook.to_markdown();
break;
case 'raw':
that.notebook.to_raw();
break;
case 'heading':
that.notebook._warn_heading();
that.notebook.to_heading();
sel.val('markdown')
break;
default:
console.log("unrecognized cell type:", cell_type);
}
});
this.element.append(sel);
};
MainToolBar.prototype.add_celltoolbar_list = function () {
@ -184,40 +144,7 @@ define([
});
};
MainToolBar.prototype.bind_events = function () {
var that = this;
this.element.find('#cell_type').change(function () {
var cell_type = $(this).val();
switch (cell_type) {
case 'code':
that.notebook.to_code();
break;
case 'markdown':
that.notebook.to_markdown();
break;
case 'raw':
that.notebook.to_raw();
break;
case 'heading':
that.notebook._warn_heading();
that.notebook.to_heading();
that.element.find('#cell_type').val("markdown");
break;
default:
console.log("unrecognized cell type:", cell_type);
}
});
this.events.on('selected_cell_type_changed.Notebook', function (event, data) {
if (data.cell_type === 'heading') {
that.element.find('#cell_type').val(data.cell_type+data.level);
} else {
that.element.find('#cell_type').val(data.cell_type);
}
});
};
// Backwards compatability.
// Backwards compatibility.
IPython.MainToolBar = MainToolBar;
return {'MainToolBar': MainToolBar};

@ -11,22 +11,53 @@ define([
* A generic toolbar on which one can add button
* @class ToolBar
* @constructor
* @param {Dom object} selector
* @param {Dom_object} selector
*/
var ToolBar = function (selector) {
var ToolBar = function (selector, options) {
this.selector = selector;
this.actions = (options||{}).actions;
if (this.selector !== undefined) {
this.element = $(selector);
this.style();
}
};
// thought, this might not be the best way as dict might not keep the right order.
// Might want to put the group name as second to make it optional
//
ToolBar.prototype.construct = function (config) {
for(var k in config){
this.add_buttons_group(config[k][0],k[1]);
}
};
/**
* add a group of button into the current toolbar.
* Add a group of button into the current toolbar.
*
* Use a [dict of [list of action name]] to trigger
* on click to the button
*
* @example
*
* ... todo, maybe use a list of list to keep ordering.
*
* [
* [
* [
* action_name_1,
* action_name_2,
* action_name_3,
* ],
* optional_group_name
* ],
* ...
* ]
*
* For backward compatibility this also support the
* old methods of adding busson directly bound to callbacks:
* @example
* # deprecate, do not use
* IPython.toolbar.add_buttons_group([
* {
* label:'my button',
@ -52,27 +83,61 @@ define([
* @param [list.id] {String} id to give to the button
* @param [group_id] {String} optionnal id to give to the group
*
*
* for private usage, the key can also be strings starting with '<' and ending with '>' to inject custom element that cannot
* be bound to an action.
*
*/
// TODO JUPYTER:
// get rid of legacy code that handle things that are not actions.
ToolBar.prototype.add_buttons_group = function (list, group_id) {
// handle custom call of pseudoaction binding.
if(typeof(list) == 'string' && list.slice(0,1) == '<' && list.slice(-1) == '>'){
try{
var _n = list.slice(1,-1)
var fun = this[_n]();
} catch (e) {
console.warn('ouch, calling ', _n, 'does not seem to work...:')
}
return ;
}
var that = this;
var btn_group = $('<div/>').addClass("btn-group");
if( group_id !== undefined ) {
btn_group.attr('id',group_id);
}
var el;
for(var i=0; i < list.length; i++) {
// IIFE because Fucking javascript don't have loop scope so
// action_name would otherwise be the same on all iteration
// of the loop
// TODO: Indent this thing once reviewed:
(function(){
el = list[i];
var action_name;
var action;
if(typeof(el) === 'string'){
action = that.actions.get(el);
action_name = el;
}
var button = $('<button/>')
.addClass('btn btn-default')
.attr("title", el.label)
.attr("title", el.label||action.help)
.append(
$("<i/>").addClass(el.icon).addClass('fa')
$("<i/>").addClass(el.icon||action.icon).addClass('fa')
);
var id = el.id;
if( id !== undefined )
button.attr('id',id);
var fun = el.callback;
var fun = el.callback|| function(){
that.actions.call(action_name);
};
button.click(fun);
btn_group.append(button);
})();
// END IIFE
}
$(this.selector).append(btn_group);
};

@ -495,7 +495,7 @@ div.input {
}
/* input_area and input_prompt must match in top border and margin for alignment */
div.input_prompt {
color: navy;
color: #000080;
border-top: 1px solid transparent;
}
div.input_area > div.highlight {
@ -767,7 +767,7 @@ div.out_prompt_overlay:hover {
background: rgba(240, 240, 240, 0.5);
}
div.output_prompt {
color: darkred;
color: #8b0000;
}
/* This class is the outer container of all output sections. */
div.output_area {
@ -840,7 +840,7 @@ div.output_area pre {
padding: 0;
border: 0;
vertical-align: baseline;
color: black;
color: #000000;
background-color: transparent;
border-radius: 0;
}
@ -1033,8 +1033,8 @@ div.output_unrecognized a:hover {
margin-top: 1em;
}
.rendered_html hr {
color: black;
background-color: black;
color: #000000;
background-color: #000000;
}
.rendered_html pre {
margin: 1em 2em;
@ -1053,13 +1053,13 @@ div.output_unrecognized a:hover {
.rendered_html table {
margin-left: auto;
margin-right: auto;
border: 1px solid black;
border: 1px solid #000000;
border-collapse: collapse;
}
.rendered_html tr,
.rendered_html th,
.rendered_html td {
border: 1px solid black;
border: 1px solid #000000;
border-collapse: collapse;
margin: 1em 2em;
}
@ -1555,4 +1555,4 @@ h6:hover .anchor-link {
left: 0px !important;
margin-left: 0px !important;
}
/*# sourceMappingURL=ipython.min.css.map */
/*# sourceMappingURL=../style/ipython.min.css.map */

@ -8358,7 +8358,7 @@ div.input {
}
/* input_area and input_prompt must match in top border and margin for alignment */
div.input_prompt {
color: navy;
color: #000080;
border-top: 1px solid transparent;
}
div.input_area > div.highlight {
@ -8630,7 +8630,7 @@ div.out_prompt_overlay:hover {
background: rgba(240, 240, 240, 0.5);
}
div.output_prompt {
color: darkred;
color: #8b0000;
}
/* This class is the outer container of all output sections. */
div.output_area {
@ -8703,7 +8703,7 @@ div.output_area pre {
padding: 0;
border: 0;
vertical-align: baseline;
color: black;
color: #000000;
background-color: transparent;
border-radius: 0;
}
@ -8896,8 +8896,8 @@ div.output_unrecognized a:hover {
margin-top: 1em;
}
.rendered_html hr {
color: black;
background-color: black;
color: #000000;
background-color: #000000;
}
.rendered_html pre {
margin: 1em 2em;
@ -8916,13 +8916,13 @@ div.output_unrecognized a:hover {
.rendered_html table {
margin-left: auto;
margin-right: auto;
border: 1px solid black;
border: 1px solid #000000;
border-collapse: collapse;
}
.rendered_html tr,
.rendered_html th,
.rendered_html td {
border: 1px solid black;
border: 1px solid #000000;
border-collapse: collapse;
margin: 1em 2em;
}
@ -10404,4 +10404,4 @@ span.autosave_status {
#terminado-container {
margin: 8px;
}
/*# sourceMappingURL=style.min.css.map */
/*# sourceMappingURL=../style/style.min.css.map */

@ -66,7 +66,7 @@ casper.notebook_test(function () {
IPython.notebook.select(0);
cell.clear_output();
cell.set_text('a=13; print(a)');
$('#run_b').click();
$('#maintoolbar .btn-group:nth(4) .btn:first').click()
});
this.wait_for_output(0);

@ -29,7 +29,7 @@ casper.notebook_test(function () {
$('#cell_type').val('markdown').change();
var cell = IPython.notebook.get_selected_cell();
cell.set_text('*Baz*');
$('#run_b').click();
$('#maintoolbar .btn-group:nth(4) .btn:first').click()
return cell.get_rendered();
});
this.test.assertEquals(output.trim(), '<p><em>Baz</em></p>', 'Markdown toolbar items work.');

Loading…
Cancel
Save