##// END OF EJS Templates
Minor tweaks to the css to enable single cell hide/show.
Brian Granger -
Show More
@@ -1,72 +1,75
1 1 /* Css for the metadata edit area */
2 2
3 3
4 4 .celltoolbar {
5 5 border: thin solid #DDD;
6 6 margin-left: 0px;
7 7 border-bottom: none;
8 8 background : #EEE;
9 9 border-top-right-radius: 3px;
10 10 border-top-left-radius: 3px;
11 11 }
12 12
13 13 .no_input_radius {
14 14 border-top-right-radius: 0px;
15 15 border-top-left-radius: 0px;
16 16 }
17 17
18 18 .text_cell .ctb_prompt {
19 19 display: none;
20 20 }
21 21
22 22 .code_cell .ctb_prompt {
23 23 display: block;
24 24 }
25 25
26 26 .ctb_hideshow {
27 27 display: none;
28 28 }
29 29
30 .ctb_show.ctb_hideshow {
30 /*ctb_show is added to either body or the ctb_hideshow div to show
31 all or one cell's toolbars.
32 */
33 .ctb_show.ctb_hideshow, .ctb_show .ctb_hideshow {
31 34 display: block;
32 35 }
33 36
34 37 .ctb_show .ctb_hideshow + div > div.input_area,
35 38 .ctb_show .ctb_hideshow + div.text_cell_input {
36 39 border-top-right-radius: 0px;
37 40 border-top-left-radius: 0px;
38 41 }
39 42
40 43 .ctb_show > .celltoolbar {
41 44 border-bottom-right-radius: 0px;
42 45 border-bottom-left-radius: 0px;
43 46 }
44 47
45 48 .button_container {
46 49 float: right;
47 50 }
48 51
49 52 .button_container .ui-state-default, .button_container .ui-state-hover, .button_container .ui-state-hover span{
50 53 border-radius : 0 0 0 0;
51 54 border : none;
52 55 }
53 56
54 57 .celltoolbar .button_container select {
55 58 margin: 10px;
56 59 margin-top: 0px;
57 60 margin-bottom: 0px;
58 61 font-size: 77%;
59 62 }
60 63
61 64 .celltoolbar label span {
62 65 font-size: 77%;
63 66 }
64 67
65 68 .celltoolbar input[type=checkbox] {
66 69 margin-bottom: 1px;
67 70 }
68 71
69 72 .celltoolbar ui-button {
70 73 border: none;
71 74 }
72 75
@@ -1,388 +1,394
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2012 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.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // CellToolbar
10 10 //============================================================================
11 11
12 12
13 13 /**
14 14 * A Module to control the per-cell toolbar.
15 15 * @module IPython
16 16 * @namespace IPython
17 17 * @submodule CellToolbar
18 18 */
19 19 var IPython = (function (IPython) {
20 20 "use strict";
21 21
22 22 /**
23 23 * @constructor
24 24 * @class CellToolbar
25 25 * @param {The cell to attach the metadata UI to} cell
26 26 */
27 27 var CellToolbar = function (cell) {
28 28 CellToolbar._instances.push(this);
29 29 this.cell = cell;
30 30 this.create_element();
31 31 this.rebuild();
32 32 return this;
33 33 };
34 34
35 35
36 36 CellToolbar.prototype.create_element = function () {
37 37 this.inner_element = $('<div/>');
38 38 var ctb_element = $('<div/>').addClass('celltoolbar')
39 39 .append(this.inner_element);
40 40 ctb_element.addClass('box-flex1');
41 41 var ctb_area = $('<div/>').addClass('ctb_area hbox');
42 42 var ctb_prompt = $('<div/>').addClass('ctb_prompt prompt');
43 43 ctb_area.append(ctb_prompt).append(ctb_element);
44 44 this.element = $('<div/>').addClass('ctb_hideshow')
45 45 .append(ctb_area);
46 46 };
47 47
48 48
49 49 CellToolbar.dropdown_preset_element = $('<select/>')
50 50 .addClass('ui-widget ui-widget-content')
51 51 .attr('id', 'celltoolbar_selector')
52 52 .append($('<option/>').attr('value', '').text('None'))
53 53
54 54
55 55 CellToolbar.dropdown_preset_element.change(function() {
56 56 var val = CellToolbar.dropdown_preset_element.val()
57 57 if(val ==''){
58 58 CellToolbar.global_hide();
59 59 } else {
60 60 CellToolbar.global_show();
61 61 CellToolbar.activate_preset(val);
62 62 }
63 63 })
64 64
65 // The default css style for the outer celltoolbar div
66 // (ctb_hideshow) is display: none. We add the ctb_show
67 // class to either 1) the body to show all cell's toolbars
68 // or 2) to the individual celltoolbar divs to show just one
69 // cell's toolbar.
65 70
66 71 CellToolbar.global_hide = function () {
67 72 $('body').removeClass('ctb_show');
68 73 }
69 74
70 75
71 76 CellToolbar.global_show = function () {
72 77 $('body').addClass('ctb_show');
73 78 }
74
79
80
75 81 CellToolbar.prototype.hide = function () {
76 82 this.element.removeClass('ctb_show');
77 83 }
78 84
79 85
80 86 CellToolbar.prototype.show = function () {
81 87 this.element.addClass('ctb_show');
82 88 }
83 89
84 90
85 91 /**
86 92 * Class variable that should contain a dict of all availlable callback
87 93 * we need to think of wether or not we allow nested namespace
88 94 * @property _callback_dict
89 95 * @private
90 96 * @static
91 97 * @type Dict
92 98 */
93 99 CellToolbar._callback_dict = {};
94 100
95 101 /**
96 102 * Class variable that should contain the reverse order list of the button
97 103 * to add to the toolbar of each cell
98 104 * @property _ui_controls_list
99 105 * @private
100 106 * @static
101 107 * @type List
102 108 */
103 109 CellToolbar._ui_controls_list = [];
104 110
105 111 /**
106 112 * Class variable that should contains the CellToolbar instances for each
107 113 * cell of the notebook
108 114 *
109 115 * @private
110 116 * @property _instances
111 117 * @static
112 118 * @type List
113 119 */
114 120 CellToolbar._instances =[]
115 121
116 122 /**
117 123 * keep a list of all the availlabel presets for the toolbar
118 124 * @private
119 125 * @property _presets
120 126 * @static
121 127 * @type Dict
122 128 */
123 129 CellToolbar._presets ={}
124 130
125 131 // this is by design not a prototype.
126 132 /**
127 133 * Register a callback to create an UI element in a cell toolbar.
128 134 * @method register_callback
129 135 * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name
130 136 * for easier sorting and avoid collision
131 137 * @param callback {function(div, cell)} callback that will be called to generate the ui element
132 138 *
133 139 *
134 140 * The callback will receive the following element :
135 141 *
136 142 * * a div in which to add element.
137 143 * * the cell it is responsible from
138 144 *
139 145 * @example
140 146 *
141 147 * Example that create callback for a button that toggle between `true` and `false` label,
142 148 * with the metadata under the key 'foo' to reflect the status of the button.
143 149 *
144 150 * // first param reference to a DOM div
145 151 * // second param reference to the cell.
146 152 * var toggle = function(div, cell) {
147 153 * var button_container = $(div)
148 154 *
149 155 * // let's create a button that show the current value of the metadata
150 156 * var button = $('<div/>').button({label:String(cell.metadata.foo)});
151 157 *
152 158 * // On click, change the metadata value and update the button label
153 159 * button.click(function(){
154 160 * var v = cell.metadata.foo;
155 161 * cell.metadata.foo = !v;
156 162 * button.button("option", "label", String(!v));
157 163 * })
158 164 *
159 165 * // add the button to the DOM div.
160 166 * button_container.append(button);
161 167 * }
162 168 *
163 169 * // now we register the callback under the name `foo` to give the
164 170 * // user the ability to use it later
165 171 * CellToolbar.register_callback('foo', toggle);
166 172 */
167 173 CellToolbar.register_callback = function(name, callback){
168 174 // Overwrite if it already exists.
169 175 CellToolbar._callback_dict[name] = callback;
170 176 };
171 177
172 178 /**
173 179 * Register a preset of UI element in a cell toolbar.
174 180 * Not supported Yet.
175 181 * @method register_preset
176 182 * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name
177 183 * for easier sorting and avoid collision
178 184 * @param preset_list {List of String} reverse order of the button in the toolbar. Each String of the list
179 185 * should correspond to a name of a registerd callback.
180 186 *
181 187 * @private
182 188 * @example
183 189 *
184 190 * CellToolbar.register_callback('foo.c1', function(div, cell){...});
185 191 * CellToolbar.register_callback('foo.c2', function(div, cell){...});
186 192 * CellToolbar.register_callback('foo.c3', function(div, cell){...});
187 193 * CellToolbar.register_callback('foo.c4', function(div, cell){...});
188 194 * CellToolbar.register_callback('foo.c5', function(div, cell){...});
189 195 *
190 196 * CellToolbar.register_preset('foo.foo_preset1', ['foo.c1', 'foo.c2', 'foo.c5'])
191 197 * CellToolbar.register_preset('foo.foo_preset2', ['foo.c4', 'foo.c5'])
192 198 */
193 199 CellToolbar.register_preset = function(name, preset_list){
194 200 CellToolbar._presets[name] = preset_list
195 201 CellToolbar.dropdown_preset_element.append(
196 202 $('<option/>').attr('value', name).text(name)
197 203 )
198 204 }
199 205 /**
200 206 * Activate an UI preset from `register_preset`
201 207 *
202 208 * This does not update the selection UI.
203 209 *
204 210 * @method activate_preset
205 211 * @param preset_name {String} string corresponding to the preset name
206 212 *
207 213 * @static
208 214 * @private
209 215 * @example
210 216 *
211 217 * CellToolbar.activate_preset('foo.foo_preset1');
212 218 */
213 219 CellToolbar.activate_preset= function(preset_name){
214 220 var preset = CellToolbar._presets[preset_name];
215 221
216 222 if(preset != undefined){
217 223 CellToolbar._ui_controls_list = preset;
218 224 CellToolbar.rebuild_all();
219 225 }
220 226 }
221 227
222 228
223 229 // this is by design not a prototype.
224 230 /**
225 231 * This should be called on the class and not on a instance as it will trigger
226 232 * rebuild of all the instances.
227 233 * @method rebuild_all
228 234 * @static
229 235 *
230 236 */
231 237 CellToolbar.rebuild_all = function(){
232 238 for(var i in CellToolbar._instances){
233 239 CellToolbar._instances[i].rebuild();
234 240 }
235 241 }
236 242
237 243 /**
238 244 * Rebuild all the button on the toolbar to update it's state.
239 245 * @method rebuild
240 246 */
241 247 CellToolbar.prototype.rebuild = function(){
242 248 // strip evrything from the div
243 249 // which is probabli metainner.
244 250 // or this.element.
245 251 this.inner_element.empty();
246 252
247 253 var cdict = CellToolbar._callback_dict;
248 254 var preset = CellToolbar._ui_controls_list;
249 255 // Yes we iterate on the class varaible, not the instance one.
250 256 for ( var index in CellToolbar._ui_controls_list){
251 257 var local_div = $('<div/>').addClass('button_container');
252 258 // Note,
253 259 // do this the other way, wrap in try/catch and don't append if any errors.
254 260 this.inner_element.append(local_div)
255 261 cdict[preset[index]](local_div, this.cell)
256 262 }
257 263
258 264 }
259 265
260 266
261 267 /**
262 268 */
263 269 CellToolbar.utils = {};
264 270
265 271 /**
266 272 * A utility function to generate bindings between a checkbox and cell/metadata
267 273 * @method utils.checkbox_ui_generator
268 274 * @static
269 275 *
270 276 * @param name {string} Label in front of the checkbox
271 277 * @param setter {function( cell, newValue )}
272 278 * A setter method to set the newValue
273 279 * @param getter {function( cell )}
274 280 * A getter methods which return the current value.
275 281 *
276 282 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
277 283 *
278 284 * @example
279 285 *
280 286 * An exmple that bind the subkey `slideshow.isSectionStart` to a checkbox with a `New Slide` label
281 287 *
282 288 * var newSlide = CellToolbar.utils.checkbox_ui_generator('New Slide',
283 289 * // setter
284 290 * function(cell, value){
285 291 * // we check that the slideshow namespace exist and create it if needed
286 292 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
287 293 * // set the value
288 294 * cell.metadata.slideshow.isSectionStart = value
289 295 * },
290 296 * //geter
291 297 * function(cell){ var ns = cell.metadata.slideshow;
292 298 * // if the slideshow namespace does not exist return `undefined`
293 299 * // (will be interpreted as `false` by checkbox) otherwise
294 300 * // return the value
295 301 * return (ns == undefined)? undefined: ns.isSectionStart
296 302 * }
297 303 * );
298 304 *
299 305 * CellToolbar.register_callback('newSlide', newSlide);
300 306 *
301 307 */
302 308 CellToolbar.utils.checkbox_ui_generator = function(name, setter, getter){
303 309 return function(div, cell) {
304 310 var button_container = $(div)
305 311
306 312 var chkb = $('<input/>').attr('type', 'checkbox');
307 313 var lbl = $('<label/>').append($('<span/>').text(name));
308 314 lbl.append(chkb);
309 315 chkb.attr("checked", getter(cell));
310 316
311 317 chkb.click(function(){
312 318 var v = getter(cell);
313 319 setter(cell, !v);
314 320 chkb.attr("checked", !v);
315 321 })
316 322 button_container.append($('<div/>').append(lbl));
317 323
318 324 }
319 325 }
320 326
321 327 /**
322 328 * A utility function to generate bindings between a dropdown list cell
323 329 * @method utils.select_ui_generator
324 330 * @static
325 331 *
326 332 * @param list_list {list of sublist} List of sublist of metadata value and name in the dropdown list.
327 333 * subslit shoud contain 2 element each, first a string that woul be displayed in the dropdown list,
328 334 * and second the corresponding value to be passed to setter/return by getter.
329 335 * @param setter {function( cell, newValue )}
330 336 * A setter method to set the newValue
331 337 * @param getter {function( cell )}
332 338 * A getter methods which return the current value of the metadata.
333 339 * @param [label=""] {String} optionnal label for the dropdown menu
334 340 *
335 341 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
336 342 *
337 343 * @example
338 344 *
339 345 * var select_type = CellToolbar.utils.select_ui_generator([
340 346 * ["<None>" , undefined ],
341 347 * ["Header Slide" , "header_slide" ],
342 348 * ["Slide" , "slide" ],
343 349 * ["Fragment" , "fragment" ],
344 350 * ["Skip" , "skip" ],
345 351 * ],
346 352 * // setter
347 353 * function(cell, value){
348 354 * // we check that the slideshow namespace exist and create it if needed
349 355 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
350 356 * // set the value
351 357 * cell.metadata.slideshow.slide_type = value
352 358 * },
353 359 * //geter
354 360 * function(cell){ var ns = cell.metadata.slideshow;
355 361 * // if the slideshow namespace does not exist return `undefined`
356 362 * // (will be interpreted as `false` by checkbox) otherwise
357 363 * // return the value
358 364 * return (ns == undefined)? undefined: ns.slide_type
359 365 * }
360 366 * CellToolbar.register_callback('slideshow.select', select_type);
361 367 *
362 368 */
363 369 CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label){
364 370 label= label? label: "";
365 371 return function(div, cell) {
366 372 var button_container = $(div)
367 373 var lbl = $("<label/>").append($('<span/>').text(label));
368 374 var select = $('<select/>').addClass('ui-widget ui-widget-content');
369 375 for(var itemn in list_list){
370 376 var opt = $('<option/>');
371 377 opt.attr('value', list_list[itemn][1])
372 378 opt.text(list_list[itemn][0])
373 379 select.append(opt);
374 380 }
375 381 select.val(getter(cell));
376 382 select.change(function(){
377 383 setter(cell, select.val());
378 384 });
379 385 button_container.append($('<div/>').append(lbl).append(select));
380 386
381 387 }
382 388 };
383 389
384 390
385 391 IPython.CellToolbar = CellToolbar;
386 392
387 393 return IPython;
388 394 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now