Skip to content
This repository

Ability to build toolbar in JS #2127

Merged
merged 13 commits into from almost 2 years ago

6 participants

Matthias Bussonnier Damián Avila Fernando Perez Brian E. Granger Don't Add Me To Your Organization a.k.a The Travis Bot Bradley M. Froehle
Matthias Bussonnier
Collaborator

Description:

This allow to easily create new toolbar/append buttons on existing one purely in JS.
This is done by passing dict of icon , label , callback [,id] to a methods of toolbar.

Details:

I changed the current ToolBar implementation to use this, and named it MainToolBar which inherit of IPython.ToolBar. The only instance is now named IPython.maintoolbar.
IPython.ToolBar is more general and can be use as a template to create any toolbar with buttons.
I removed the toolbar content from the html template and left only the <div id='toolbar'>

code example :

maintoolbar.addButtonsGroup([
            {
                'label'   : 'Insert Cell Above',
                'icon'    : 'ui-icon-arrowthickstop-1-n',
                'callback': IPython.notebook.insert_cell_above
            },
            {
                'label'   : 'Insert Cell Below',
                'icon'    : 'ui-icon-arrowthickstop-1-s',
                'callback': IPython.notebook.insert_cell_below
            }
        ]);

Demo

I made a quick demo of what can be done by copy pasting this js file (gist) into a MD cell:

Notice the slideshow icon on the right of markdown that is inserted if you uses the above script
Imgur
( CSS looks broken, but it's chrome dev, master have same issues)

And what it look like when clicked. One can get back to normal view by clicking the stop button or go to next/prev slide. One cell == one slide , and the notebook is still fully functional, cell can be edited and run live.
Imgur

Carreau added some commits
Matthias Bussonnier Carreau Allow toolbar construction in js
Base of allowing a full toolbar construction in js without altering the
html template, and use it to construct our toolbar as example.

still need some work to be totally decoupled.
31a6158
Matthias Bussonnier Carreau add maintoolbar file e45a24b
Matthias Bussonnier Carreau load maintoolbar.js dd25e33
Matthias Bussonnier Carreau correcty inherign the main toolbar 4fd138f
Matthias Bussonnier Carreau dont use string as dict key, better redability a6b6d75
Damián Avila

This is great, I like the idea of a live presentation (vIPer only provided static presentations). Maybe it would be great to have more that one cell per slide because you have more power to build the content (maybe a new type or subtype of cell, in vIPer I use markdown and (----) to separate slides). BTW, I really enjoy the fact of a native solution for this issue.

Matthias Bussonnier
Collaborator

The slideshow demo is not the goal of this PR. But a demo of what can be done.

Is SO want to take over, there is a lot to add like displaying cell/output separately... etc.
And we could store data in cell metadata attributes.

But first let's see if we can merge this PR !

Please fork the gist and have fun !

Damián Avila

I have to get some insight with JS first, but I will play with that for sure.

Thanks.

Matthias Bussonnier
Collaborator

anybody ?
You saw what it can do when building js-extension at SciPy.
WIll merge in 48h unless SO have an issue with it.

Fernando Perez
Owner
fperez commented

Hold tight: while I love the idea, there's enough new JS code in here that it really should get a real review by someone else. While we need to keep the PR queue moving, and I realize it's a bummer that we're so rate-limited with our small team, we need to be a little patient with larger PRs; sometimes just pinging others and giving them a couple of extra days is enough to get good feedback.

@ellisonbg, if you have a minute to look at this, it would be fantastic. I should say I'm totally +1 on the idea, which proved its value at Scipy, but given it touches so much JS you originally wrote, you might have some feedback before merge...

Brian E. Granger
Owner
Brian E. Granger
Owner

Does #2193 replace this? What is their relationship?

Matthias Bussonnier
Collaborator

Yes, there is a relationship.
This one does not bundle anything about slideshow.
Just internal change, ability to create easily a toolbar totally in js.

#2193 is the draft I made on top of this to build slideshow extension.

@fperez github did hear you and brought back the user/branch on the headers of PR :-)

Matthias Bussonnier
Collaborator

fix Here the comment you made in #2193 about the CamelCase of methods names.

Matthias Bussonnier
Collaborator

@ellisonbg

What do you think of this one ? I'm building #2193 on top of this one, so I would prefer to merge this to build on top of master.

Brian E. Granger ellisonbg commented on the diff
IPython/frontend/html/notebook/static/css/notebook.css
@@ -60,7 +60,7 @@ span#notebook_name {
60 60 z-index: 10;
61 61 }
62 62
63   -#toolbar {
  63 +.toolbar {
2
Brian E. Granger Owner
ellisonbg added a note

I see you have made this a class but in the main html template, it is still the toolbar id. Is this right?

Matthias Bussonnier Collaborator
Carreau added a note

yes, need the #id to pass it as the selector for the constructor.
toolbar class is added by js.
changing id to #maintoolbarfor consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/html/notebook/static/js/maintoolbar.js
... ... @@ -0,0 +1,182 @@
  1 +//----------------------------------------------------------------------------
  2 +// Copyright (C) 2008 The IPython Development Team
2
Brian E. Granger Owner
ellisonbg added a note

File was created in 2011.

Matthias Bussonnier Collaborator
Carreau added a note

done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/html/notebook/static/js/toolbar.js
((5 lines not shown))
20 19 }
21 20 };
22 21
  22 + // add a group of button into the current toolbar.
  23 + //
  24 + // First argument : Mandatory
  25 + // list of dict as argument, each dict should contain
  26 + // 3 mandatory keys and values :
  27 + // label : string -- the text to show on hover
  28 + // icon : string -- the jQuery-ui icon to add on this button
  29 + // callback : function -- the callback to execute on a click
  30 + //
  31 + // and optionnaly an 'id' key that is assigned to the button element
  32 + //
  33 + // Second Argument, optionnal,
2
Brian E. Granger Owner
ellisonbg added a note

optional

Matthias Bussonnier Collaborator
Carreau added a note

fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/html/notebook/static/js/toolbar.js
((24 lines not shown))
  38 + // IPython.toolbar.add_button_group([
  39 + // {label:'my button',
  40 + // icon:'ui-icon-disk',
  41 + // callback:function(){alert('hoho'),
  42 + // id : 'my_button_id', // this is optionnal
  43 + // }
  44 + // },
  45 + // {label:'my second button',
  46 + // icon:'ui-icon-scissors',
  47 + // callback:function(){alert('be carefull I cut')}
  48 + // }
  49 + // ],
  50 + // "my_button_group_id"
  51 + // )
  52 + //
  53 + ToolBar.prototype.add_button_group = function(list, group_id){
2
Brian E. Granger Owner
ellisonbg added a note

functions (list, group_id) (

Matthias Bussonnier Collaborator
Carreau added a note

fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/html/notebook/static/js/maintoolbar.js
((1 lines not shown))
  1 +//----------------------------------------------------------------------------
  2 +// Copyright (C) 2008 The IPython Development Team
  3 +//
  4 +// Distributed under the terms of the BSD License. The full license is in
  5 +// the file COPYING, distributed as part of this software.
  6 +//----------------------------------------------------------------------------
  7 +
  8 +//============================================================================
  9 +// ToolBar
  10 +//============================================================================
  11 +
  12 +var IPython = (function (IPython) {
  13 +
  14 + var MainToolBar = function (selector) {
  15 + this.selector = selector;
  16 + if (this.selector !== undefined) {
2
Brian E. Granger Owner
ellisonbg added a note

This type of if statement only needs to be on the base classes. I would just put the code in this block at the top level and get rid of the test. See Cell and TextCell for an example. I know this is very weird.

Matthias Bussonnier Collaborator
Carreau added a note

hu... ok, hum not sure I understand.
Just the if statement, or the methods called inside ?
because this.add_drop_down_list(); might not exist exist on other subclasses...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/html/notebook/static/js/maintoolbar.js
((31 lines not shown))
  31 + .addClass('ui-widget ui-widget-content')
  32 + .append($('<option/>').attr('value','code').text('Code'))
  33 + .append($('<option/>').attr('value','markdown').text('Markdown'))
  34 + .append($('<option/>').attr('value','raw').text('Raw Text'))
  35 + .append($('<option/>').attr('value','heading1').text('Heading 1'))
  36 + .append($('<option/>').attr('value','heading2').text('Heading 2'))
  37 + .append($('<option/>').attr('value','heading3').text('Heading 3'))
  38 + .append($('<option/>').attr('value','heading4').text('Heading 4'))
  39 + .append($('<option/>').attr('value','heading5').text('Heading 5'))
  40 + .append($('<option/>').attr('value','heading6').text('Heading 6'))
  41 + .append($('<option/>').attr('value','heading7').text('Heading 7'))
  42 + .append($('<option/>').attr('value','heading8').text('Heading 8'))
  43 + );
  44 + }
  45 +
  46 + MainToolBar.prototype.construct = function() {
2
Brian E. Granger Owner
ellisonbg added a note

I would put construct before add_drop_down_list as it is called first.

Matthias Bussonnier Collaborator
Carreau added a note

done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/html/notebook/static/js/maintoolbar.js
((32 lines not shown))
  32 + .append($('<option/>').attr('value','code').text('Code'))
  33 + .append($('<option/>').attr('value','markdown').text('Markdown'))
  34 + .append($('<option/>').attr('value','raw').text('Raw Text'))
  35 + .append($('<option/>').attr('value','heading1').text('Heading 1'))
  36 + .append($('<option/>').attr('value','heading2').text('Heading 2'))
  37 + .append($('<option/>').attr('value','heading3').text('Heading 3'))
  38 + .append($('<option/>').attr('value','heading4').text('Heading 4'))
  39 + .append($('<option/>').attr('value','heading5').text('Heading 5'))
  40 + .append($('<option/>').attr('value','heading6').text('Heading 6'))
  41 + .append($('<option/>').attr('value','heading7').text('Heading 7'))
  42 + .append($('<option/>').attr('value','heading8').text('Heading 8'))
  43 + );
  44 + }
  45 +
  46 + MainToolBar.prototype.construct = function() {
  47 + this.add_buttons_group([
2
Brian E. Granger Owner
ellisonbg added a note

The notebook is currently broken in this branch. Due to typo here: should be add_button_group.

Matthias Bussonnier Collaborator
Carreau added a note

done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/html/notebook/static/js/maintoolbar.js
((90 lines not shown))
  90 + IPython.notebook.move_cell_up();
  91 + },
  92 + },
  93 + {
  94 + id:'move_down_b',
  95 + label:'Move Cell Down',
  96 + icon:'ui-icon-arrowthick-1-s',
  97 + callback:function(){
  98 + IPython.notebook.move_cell_down();
  99 + },
  100 + },
  101 + ],'move_up_down');
  102 +
  103 + this.add_buttons_group([
  104 + {
  105 + id:'insert_above_b',
2
Brian E. Granger Owner
ellisonbg added a note

Code style comments. Put spaces before and after : in each of these dict elements. Spacing of callback to be function () {.

Matthias Bussonnier Collaborator
Carreau added a note

done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Brian E. Granger
Owner

This looks like pretty solid straightforward code. Once you fix the typo that is breaking things I will do a functionality test to make sure everything is working. One other comment, the toggle method of the toolbar calls IPython.layout_manager.do_resize();. But there is a chance this code could be used outside this page where layout_manager is defined. Should we first test for its existence before calling its do_resize method?

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 7aefb27 into bf4aa6d).

Matthias Bussonnier
Collaborator

Except the test for selector where i'm not sure what to do, I should have fixed everything, including test for layout_manager.
I let you test now, and hopefully TravisBot will soon says that he is happy.

Brian E. Granger
Owner

Having second thoughts about this one. I have been looking more at bootstrap and it would be easy to transition to bootstrap if we keep the toolbar in HTML. Moving it to Javascript binds us more closely to jQuery UI. I don't think we can transition completely to bootstrap and stop using jQuery UI, but for something bootstrap would be a huge improvement.

Matthias Bussonnier
Collaborator

I don't see why you couldn't build the toolbar in JS using bootstrap.
Can you develop why ?

And nothing prevent us from having a jQueryUI toolbar below a bootstrap menubar, it it ?

Matthias Bussonnier
Collaborator

@ellisonbg,
Adding button to a toolbar in JS with bootstrap works, and is even easier, as you have less class to worry about (rounded left, right, up, down...) I just did it live by adding working button here from the JS console to the "toolbar" example.

Switching is not an easy task, and are we even sure it will work or will be done for 0.14 ?

Anyway, if we switch to bootstrap I will take care of converting this code if it is what worries you.

If you wish, I can even try to re-write this PR using Bootstrap for the toolbar to start the migration.

Matthias Bussonnier
Collaborator

FYI, I tried injecting bootstrap css into the notebook and build a toolbar in Js with it.

  • Js uses less lines (ok, 11 instead of 13) and is more readable.
  • There are css name conflict/inheritnaces making bootstrap change the appearance of some element.
  • Someting in our CSS/(jqueryUI CSS?) prevent the bootstrap icons to work.
  • It works.

Though, bootstrap use css3 heavily, meaning that lots of animation won't append on older browser.

Matthias Bussonnier
Collaborator

Most of the icon we use right now are not in bootstrap, but one can use Font-Awesome

after some css tweeking, it look like this.
Imgur
Not exactly as before but shouldn't be too hard.
See if you wan't to try.
https://github.com/Carreau/ipython/compare/jstoolbar-bootstrap

Bradley M. Froehle
Collaborator

I can't comment on the technical merits of the jstoolbar-bootstrap branch, but I have played around with it for a while and haven't noticed any functional issues.

In terms of aesthetics, the buttons seem too tiny (compared to the rest of the application which is relatively spacious). Removing the btn-small class helps a lot. I think there was, and will continue to be, confusion between the "move cell up/down" and "insert cell up/down" buttons. Looking through Font Awesome, the most similar to the previous icons are icon-upload-alt and icon-download-alt, but it's not clear to me that they are any more obvious.

The play icon has bugged me for a while, I think it should be a "step-foward" button to indicate that it just runs one cell and advances to the next cell.

Matthias Bussonnier
Collaborator

The js-bootstrap is a proof of concept to see what can be done with bootstrap. Next step would be tweak bootstrap css to have the same look as the actual.

As for the icons, we could roll our own font with
http://keyamoon.com/icomoon/app/

Matthias Bussonnier Carreau referenced this pull request
Merged

UI For Metadata #2333

Matthias Bussonnier
Collaborator

@ellisonbg
Can I merge this one, or do you want me to focus on first bringing bootstrap for notebook ?
BTW there is a new 5 day old version of bootstrap, which bring toolbar and submenu.

Matthias Bussonnier
Collaborator

Pinging @ellisonbg , what do you think I should do with this one ?
It is doable with the same api in bootstrap, and once the number of open PR decrease, I would like to start migrating the notebook to bootstrap.
Could I then merge it ?

Brian E. Granger
Owner

I think we can merge this now. A few things to keep in mind:

  • I am +1 on moving to bootstrap, but let's do that in a separate PR.
  • In general, I am trying to keep as much of our page structure in the HTML template as possible. IOW, I want most of the DOM to be created in HTML, not dynamically in JS. That is why I have been a bit hesitant on this one. But I understand we do need this to be resuable, so I am OK with this being in JS. But please keep this in mind in other development work.

Great work!

Brian E. Granger ellisonbg merged commit d9a42fe into from
Matthias Bussonnier
Collaborator

Great ! Thanks!
Nice to have you Back !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
2  IPython/frontend/html/notebook/static/css/notebook.css
@@ -60,7 +60,7 @@ span#notebook_name {
60 60 z-index: 10;
61 61 }
62 62
63   -#toolbar {
  63 +.toolbar {
64 64 padding: 3px 15px;
65 65 }
66 66
4 IPython/frontend/html/notebook/static/js/layoutmanager.js
@@ -32,10 +32,10 @@ var IPython = (function (IPython) {
32 32 }
33 33 var menubar_height = $('div#menubar').outerHeight(true);
34 34 var toolbar_height;
35   - if ($('div#toolbar').css('display') === 'none') {
  35 + if ($('div#maintoolbar').css('display') === 'none') {
36 36 toolbar_height = 0;
37 37 } else {
38   - toolbar_height = $('div#toolbar').outerHeight(true);
  38 + toolbar_height = $('div#maintoolbar').outerHeight(true);
39 39 }
40 40 return h-header_height-menubar_height-toolbar_height; // content height
41 41 }
179 IPython/frontend/html/notebook/static/js/maintoolbar.js
... ... @@ -0,0 +1,179 @@
  1 +//----------------------------------------------------------------------------
  2 +// Copyright (C) 2011 The IPython Development Team
  3 +//
  4 +// Distributed under the terms of the BSD License. The full license is in
  5 +// the file COPYING, distributed as part of this software.
  6 +//----------------------------------------------------------------------------
  7 +
  8 +//============================================================================
  9 +// ToolBar
  10 +//============================================================================
  11 +
  12 +var IPython = (function (IPython) {
  13 +
  14 + var MainToolBar = function (selector) {
  15 + this.selector = selector;
  16 + IPython.ToolBar.apply(this, arguments);
  17 + this.construct();
  18 + this.add_drop_down_list();
  19 + this.bind_events();
  20 + };
  21 +
  22 + MainToolBar.prototype = new IPython.ToolBar();
  23 +
  24 + MainToolBar.prototype.construct = function () {
  25 + this.add_buttons_group([
  26 + {
  27 + id : 'save_b',
  28 + label : 'Save',
  29 + icon : 'ui-icon-disk',
  30 + callback : function () {
  31 + IPython.notebook.save_notebook();
  32 + }
  33 + }
  34 + ]);
  35 + this.add_buttons_group([
  36 + {
  37 + id : 'cut_b',
  38 + label : 'Cut Cell',
  39 + icon : 'ui-icon-scissors',
  40 + callback : function () {
  41 + IPython.notebook.cut_cell();
  42 + }
  43 + },
  44 + {
  45 + id : 'copy_b',
  46 + label : 'Copy Cell',
  47 + icon : 'ui-icon-copy',
  48 + callback : function () {
  49 + IPython.notebook.copy_cell();
  50 + }
  51 + },
  52 + {
  53 + id : 'paste_b',
  54 + label : 'Paste Cell',
  55 + icon : 'ui-icon-clipboard',
  56 + callback : function () {
  57 + IPython.notebook.paste_cell();
  58 + }
  59 + }
  60 + ],'cut_copy_paste');
  61 +
  62 + this.add_buttons_group([
  63 + {
  64 + id : 'move_up_b',
  65 + label : 'Move Cell Up',
  66 + icon : 'ui-icon-arrowthick-1-n',
  67 + callback : function () {
  68 + IPython.notebook.move_cell_up();
  69 + }
  70 + },
  71 + {
  72 + id : 'move_down_b',
  73 + label : 'Move Cell Down',
  74 + icon : 'ui-icon-arrowthick-1-s',
  75 + callback : function () {
  76 + IPython.notebook.move_cell_down();
  77 + }
  78 + }
  79 + ],'move_up_down');
  80 +
  81 + this.add_buttons_group([
  82 + {
  83 + id : 'insert_above_b',
  84 + label : 'Insert Cell Above',
  85 + icon : 'ui-icon-arrowthickstop-1-n',
  86 + callback : function () {
  87 + IPython.notebook.insert_cell_above('code');
  88 + }
  89 + },
  90 + {
  91 + id : 'insert_below_b',
  92 + label : 'Insert Cell Below',
  93 + icon : 'ui-icon-arrowthickstop-1-s',
  94 + callback : function () {
  95 + IPython.notebook.insert_cell_below('code');
  96 + }
  97 + }
  98 + ],'insert_above_below');
  99 +
  100 + this.add_buttons_group([
  101 + {
  102 + id : 'run_b',
  103 + label : 'Run Cell',
  104 + icon : 'ui-icon-play',
  105 + callback : function () {
  106 + IPython.notebook.execute_selected_cell();
  107 + }
  108 + },
  109 + {
  110 + id : 'interrupt_b',
  111 + label : 'Interrupt',
  112 + icon : 'ui-icon-stop',
  113 + callback : function () {
  114 + IPython.notebook.kernel.interrupt();
  115 + }
  116 + }
  117 + ],'run_int');
  118 +
  119 +
  120 + };
  121 +
  122 + MainToolBar.prototype.add_drop_down_list = function () {
  123 + var select = $(this.selector)
  124 + .append($('<select/>')
  125 + .attr('id','cell_type')
  126 + .addClass('ui-widget ui-widget-content')
  127 + .append($('<option/>').attr('value','code').text('Code'))
  128 + .append($('<option/>').attr('value','markdown').text('Markdown'))
  129 + .append($('<option/>').attr('value','raw').text('Raw Text'))
  130 + .append($('<option/>').attr('value','heading1').text('Heading 1'))
  131 + .append($('<option/>').attr('value','heading2').text('Heading 2'))
  132 + .append($('<option/>').attr('value','heading3').text('Heading 3'))
  133 + .append($('<option/>').attr('value','heading4').text('Heading 4'))
  134 + .append($('<option/>').attr('value','heading5').text('Heading 5'))
  135 + .append($('<option/>').attr('value','heading6').text('Heading 6'))
  136 + .append($('<option/>').attr('value','heading7').text('Heading 7'))
  137 + .append($('<option/>').attr('value','heading8').text('Heading 8'))
  138 + );
  139 + };
  140 +
  141 + MainToolBar.prototype.bind_events = function () {
  142 + var that = this;
  143 +
  144 + this.element.find('#cell_type').change(function () {
  145 + var cell_type = $(this).val();
  146 + if (cell_type === 'code') {
  147 + IPython.notebook.to_code();
  148 + } else if (cell_type === 'markdown') {
  149 + IPython.notebook.to_markdown();
  150 + } else if (cell_type === 'raw') {
  151 + IPython.notebook.to_raw();
  152 + } else if (cell_type === 'heading1') {
  153 + IPython.notebook.to_heading(undefined, 1);
  154 + } else if (cell_type === 'heading2') {
  155 + IPython.notebook.to_heading(undefined, 2);
  156 + } else if (cell_type === 'heading3') {
  157 + IPython.notebook.to_heading(undefined, 3);
  158 + } else if (cell_type === 'heading4') {
  159 + IPython.notebook.to_heading(undefined, 4);
  160 + } else if (cell_type === 'heading5') {
  161 + IPython.notebook.to_heading(undefined, 5);
  162 + } else if (cell_type === 'heading6') {
  163 + IPython.notebook.to_heading(undefined, 6);
  164 + }
  165 + });
  166 + $([IPython.events]).on('selected_cell_type_changed.Notebook', function (event, data) {
  167 + if (data.cell_type === 'heading') {
  168 + that.element.find('#cell_type').val(data.cell_type+data.level);
  169 + } else {
  170 + that.element.find('#cell_type').val(data.cell_type);
  171 + }
  172 + });
  173 + };
  174 +
  175 + IPython.MainToolBar = MainToolBar;
  176 +
  177 + return IPython;
  178 +
  179 +}(IPython));
2  IPython/frontend/html/notebook/static/js/notebookmain.js
@@ -29,7 +29,7 @@ $(document).ready(function () {
29 29 IPython.notebook = new IPython.Notebook('div#notebook');
30 30 IPython.save_widget = new IPython.SaveWidget('span#save_widget');
31 31 IPython.menubar = new IPython.MenuBar('#menubar')
32   - IPython.toolbar = new IPython.ToolBar('#toolbar')
  32 + IPython.toolbar = new IPython.MainToolBar('#maintoolbar')
33 33 IPython.tooltip = new IPython.Tooltip()
34 34 IPython.notification_widget = new IPython.NotificationWidget('#notification')
35 35
170 IPython/frontend/html/notebook/static/js/toolbar.js
... ... @@ -1,5 +1,5 @@
1 1 //----------------------------------------------------------------------------
2   -// Copyright (C) 2008-2011 The IPython Development Team
  2 +// Copyright (C) 2008 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
@@ -16,132 +16,76 @@ var IPython = (function (IPython) {
16 16 if (this.selector !== undefined) {
17 17 this.element = $(selector);
18 18 this.style();
19   - this.bind_events();
20 19 }
21 20 };
22 21
  22 + // add a group of button into the current toolbar.
  23 + //
  24 + // First argument : Mandatory
  25 + // list of dict as argument, each dict should contain
  26 + // 3 mandatory keys and values :
  27 + // label : string -- the text to show on hover
  28 + // icon : string -- the jQuery-ui icon to add on this button
  29 + // callback : function -- the callback to execute on a click
  30 + //
  31 + // and optionally an 'id' key that is assigned to the button element
  32 + //
  33 + // Second Argument, optional,
  34 + // string reprensenting the id to give to the button group.
  35 + //
  36 + // Example
  37 + //
  38 + // IPython.toolbar.add_button_group([
  39 + // {label:'my button',
  40 + // icon:'ui-icon-disk',
  41 + // callback:function(){alert('hoho'),
  42 + // id : 'my_button_id', // this is optional
  43 + // }
  44 + // },
  45 + // {label:'my second button',
  46 + // icon:'ui-icon-scissors',
  47 + // callback:function(){alert('be carefull I cut')}
  48 + // }
  49 + // ],
  50 + // "my_button_group_id"
  51 + // )
  52 + //
  53 + ToolBar.prototype.add_buttons_group = function (list, group_id) {
  54 + var span_group = $('<span/>');
  55 + if( group_id != undefined ) {
  56 + span_group.attr('id',group_id);
  57 + }
  58 + for(var el in list) {
  59 + var button = $('<button/>').button({
  60 + icons : {primary : list[el].icon},
  61 + text : false,
  62 + label : list[el].label
  63 + });
  64 + var id = list[el].id;
  65 + if( id != undefined )
  66 + button.attr('id',id);
  67 + var fun = list[el].callback;
  68 + button.click(fun);
  69 + span_group.append(button);
  70 + }
  71 + span_group.buttonset();
  72 + $(this.selector).append(span_group);
  73 + };
23 74
24 75 ToolBar.prototype.style = function () {
25 76 this.element.addClass('border-box-sizing').
26   - addClass('ui-widget ui-widget-content').
  77 + addClass('ui-widget ui-widget-content toolbar').
27 78 css('border-top-style','none').
28 79 css('border-left-style','none').
29 80 css('border-right-style','none');
30   - this.element.find('#cell_type').addClass('ui-widget ui-widget-content');
31   - this.element.find('#save_b').button({
32   - icons : {primary: 'ui-icon-disk'},
33   - text : false
34   - });
35   - this.element.find('#cut_b').button({
36   - icons: {primary: 'ui-icon-scissors'},
37   - text : false
38   - });
39   - this.element.find('#copy_b').button({
40   - icons: {primary: 'ui-icon-copy'},
41   - text : false
42   - });
43   - this.element.find('#paste_b').button({
44   - icons: {primary: 'ui-icon-clipboard'},
45   - text : false
46   - });
47   - this.element.find('#cut_copy_paste').buttonset();
48   - this.element.find('#move_up_b').button({
49   - icons: {primary: 'ui-icon-arrowthick-1-n'},
50   - text : false
51   - });
52   - this.element.find('#move_down_b').button({
53   - icons: {primary: 'ui-icon-arrowthick-1-s'},
54   - text : false
55   - });
56   - this.element.find('#move_up_down').buttonset();
57   - this.element.find('#insert_above_b').button({
58   - icons: {primary: 'ui-icon-arrowthickstop-1-n'},
59   - text : false
60   - });
61   - this.element.find('#insert_below_b').button({
62   - icons: {primary: 'ui-icon-arrowthickstop-1-s'},
63   - text : false
64   - });
65   - this.element.find('#insert_above_below').buttonset();
66   - this.element.find('#run_b').button({
67   - icons: {primary: 'ui-icon-play'},
68   - text : false
69   - });
70   - this.element.find('#interrupt_b').button({
71   - icons: {primary: 'ui-icon-stop'},
72   - text : false
73   - });
74   - this.element.find('#run_int').buttonset();
75   - };
76   -
77   -
78   - ToolBar.prototype.bind_events = function () {
79   - var that = this;
80   - this.element.find('#save_b').click(function () {
81   - IPython.notebook.save_notebook();
82   - });
83   - this.element.find('#cut_b').click(function () {
84   - IPython.notebook.cut_cell();
85   - });
86   - this.element.find('#copy_b').click(function () {
87   - IPython.notebook.copy_cell();
88   - });
89   - this.element.find('#paste_b').click(function () {
90   - IPython.notebook.paste_cell();
91   - });
92   - this.element.find('#move_up_b').click(function () {
93   - IPython.notebook.move_cell_up();
94   - });
95   - this.element.find('#move_down_b').click(function () {
96   - IPython.notebook.move_cell_down();
97   - });
98   - this.element.find('#insert_above_b').click(function () {
99   - IPython.notebook.insert_cell_above('code');
100   - });
101   - this.element.find('#insert_below_b').click(function () {
102   - IPython.notebook.insert_cell_below('code');
103   - });
104   - this.element.find('#run_b').click(function () {
105   - IPython.notebook.execute_selected_cell();
106   - });
107   - this.element.find('#interrupt_b').click(function () {
108   - IPython.notebook.kernel.interrupt();
109   - });
110   - this.element.find('#cell_type').change(function () {
111   - var cell_type = $(this).val();
112   - if (cell_type === 'code') {
113   - IPython.notebook.to_code();
114   - } else if (cell_type === 'markdown') {
115   - IPython.notebook.to_markdown();
116   - } else if (cell_type === 'raw') {
117   - IPython.notebook.to_raw();
118   - } else if (cell_type === 'heading1') {
119   - IPython.notebook.to_heading(undefined, 1);
120   - } else if (cell_type === 'heading2') {
121   - IPython.notebook.to_heading(undefined, 2);
122   - } else if (cell_type === 'heading3') {
123   - IPython.notebook.to_heading(undefined, 3);
124   - } else if (cell_type === 'heading4') {
125   - IPython.notebook.to_heading(undefined, 4);
126   - } else if (cell_type === 'heading5') {
127   - IPython.notebook.to_heading(undefined, 5);
128   - } else if (cell_type === 'heading6') {
129   - IPython.notebook.to_heading(undefined, 6);
130   - };
131   - });
132   - $([IPython.events]).on('selected_cell_type_changed.Notebook', function (event, data) {
133   - if (data.cell_type === 'heading') {
134   - that.element.find('#cell_type').val(data.cell_type+data.level);
135   - } else {
136   - that.element.find('#cell_type').val(data.cell_type);
137   - }
138   - });
139 81 };
140 82
141 83
142 84 ToolBar.prototype.toggle = function () {
143 85 this.element.toggle();
144   - IPython.layout_manager.do_resize();
  86 + if (IPython.layout_manager != undefined) {
  87 + IPython.layout_manager.do_resize();
  88 + }
145 89 };
146 90
147 91
39 IPython/frontend/html/notebook/templates/notebook.html
@@ -154,43 +154,7 @@
154 154 </div>
155 155
156 156
157   -<div id="toolbar">
158   -
159   - <span>
160   - <button id="save_b">Save</button>
161   - </span>
162   - <span id="cut_copy_paste">
163   - <button id="cut_b" title="Cut Cell">Cut Cell</button>
164   - <button id="copy_b" title="Copy Cell">Copy Cell</button>
165   - <button id="paste_b" title="Paste Cell">Paste Cell</button>
166   - </span>
167   - <span id="move_up_down">
168   - <button id="move_up_b" title="Move Cell Up">Move Cell Up</button>
169   - <button id="move_down_b" title="Move Cell Down">Move Down</button>
170   - </span>
171   - <span id="insert_above_below">
172   - <button id="insert_above_b" title="Insert Cell Above">Insert Cell Above</button>
173   - <button id="insert_below_b" title="Insert Cell Below">Insert Cell Below</button>
174   - </span>
175   - <span id="run_int">
176   - <button id="run_b" title="Run Cell">Run Cell</button>
177   - <button id="interrupt_b" title="Interrupt">Interrupt</button>
178   - </span>
179   - <span>
180   - <select id="cell_type">
181   - <option value="code">Code</option>
182   - <option value="markdown">Markdown</option>
183   - <option value="raw">Raw Text</option>
184   - <option value="heading1">Heading 1</option>
185   - <option value="heading2">Heading 2</option>
186   - <option value="heading3">Heading 3</option>
187   - <option value="heading4">Heading 4</option>
188   - <option value="heading5">Heading 5</option>
189   - <option value="heading6">Heading 6</option>
190   - </select>
191   - </span>
192   -
193   -</div>
  157 +<div id="maintoolbar"></div>
194 158
195 159 <div id="main_app">
196 160
@@ -238,6 +202,7 @@
238 202 <script src="{{ static_url("js/pager.js") }}" type="text/javascript" charset="utf-8"></script>
239 203 <script src="{{ static_url("js/menubar.js") }}" type="text/javascript" charset="utf-8"></script>
240 204 <script src="{{ static_url("js/toolbar.js") }}" type="text/javascript" charset="utf-8"></script>
  205 +<script src="{{ static_url("js/maintoolbar.js") }}" type="text/javascript" charset="utf-8"></script>
241 206 <script src="{{ static_url("js/notebook.js") }}" type="text/javascript" charset="utf-8"></script>
242 207 <script src="{{ static_url("js/notificationwidget.js") }}" type="text/javascript" charset="utf-8"></script>
243 208 <script src="{{ static_url("js/tooltip.js") }}" type="text/javascript" charset="utf-8"></script>

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.