started testing the panel constructors + found a bug: open/close events get triggered on panel drag/sort...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2014-01-05 09:32:14 +04:00
parent 431cde0560
commit 9e4c3cdb1f
2 changed files with 100 additions and 21 deletions

View File

@ -69,6 +69,7 @@ $(function(){
makeSubPanel('Test Sub Panel B', $('<h2>Panel B</h2>'), panel, true) makeSubPanel('Test Sub Panel B', $('<h2>Panel B</h2>'), panel, true)
makeSubPanel('Test Sub Panel C', $('<h3>Panel C</h3>'), panel, false) makeSubPanel('Test Sub Panel C', $('<h3>Panel C</h3>'), panel, false)
makeFilterPanel(panel, '.moo') makeFilterPanel(panel, '.moo')
makeSnapshotsPanel(panel, '.moo') makeSnapshotsPanel(panel, '.moo')
@ -79,6 +80,18 @@ $(function(){
left: 400, left: 400,
}) })
makePanelController('Test Sub Panel E',
function(){
return $('<h1>Panel E</h1>')
},
function(panel){
panel
.on('panelOpening', function(){ console.log('>>> opening!') })
.on('panelClosing', function(){ console.log('>>> closing!') })
},
true)
}) })
</script> </script>

View File

@ -15,6 +15,11 @@ var PANEL_HELPER_HIDE_DELAY = 50
var PANEL_HELPER_HIDE_DELAY_NO_ROOT = 100 var PANEL_HELPER_HIDE_DELAY_NO_ROOT = 100
var PANELS = {
}
/********************************************************************** /**********************************************************************
* Helpers... * Helpers...
*/ */
@ -84,6 +89,7 @@ function _resetSortedElem(elem){
} }
// XXX add visibility test here...
function isPanelVisible(panel){ function isPanelVisible(panel){
return panel.prop('open') return panel.prop('open')
&& (panel.parents('.panel').prop('open') && (panel.parents('.panel').prop('open')
@ -103,19 +109,73 @@ function wrapWithPanel(panel, parent, offset){
} }
// close the panel and fire close events on it and all sub-panels... function getPanel(title){
return $('[id="'+ title +'"]')
}
function openPanel(panel){
var title = typeof(panel) == typeof('str') ? panel : null
panel = typeof(panel) == typeof('str')
? getPanel(panel)
: panel
title = title == null ? panel.attr('id') : title
var open = false
// create a new panel...
if(panel.length == 0){
if(title in PANELS){
var builder = PANELS[title]
panel = builder(null, true)
}
// show/open the panel and all it's parents...
} else {
open = isPanelVisible(panel)
panel
.prop('open', true)
.parents('.panel')
.prop('open', true)
// XXX show side panels too...
}
// if the panel was not open trigger the event...
if(!open){
panel.trigger('panelOpening', panel)
}
return panel
}
// Close the panel...
// //
// NOTE: this does not care if it's a panel or sub-panel...
// XXX do we need a panelRemoved event??? // XXX do we need a panelRemoved event???
// ...and a symmetrical panelCreated?? // ...and a symmetrical panelCreated??
function closePanel(panel){ function closePanel(panel){
panel = typeof(panel) == typeof('str')
? getPanel(panel)
: panel
panel.find('.sub-panel').each(function(){ panel.find('.sub-panel').each(function(){
var p = $(this) var p = $(this)
if(p.prop('open')){ if(p.prop('open')){
p.trigger('panelClosing', p) p.trigger('panelClosing', p)
} }
}) })
panel return panel
.prop('open', false)
.trigger('panelClosing', panel) .trigger('panelClosing', panel)
}
// Remove the panel after firing close events on it and all sub-panels...
//
function removePanel(panel){
panel = typeof(panel) == typeof('str')
? getPanel(panel)
: panel
return closePanel(panel)
.remove() .remove()
} }
@ -142,7 +202,7 @@ function makePanel(title, parent, open, keep_empty, close_button){
.append($('<span/>') .append($('<span/>')
.addClass('close-button') .addClass('close-button')
.click(function(){ .click(function(){
closePanel(panel) removePanel(panel)
return false return false
}) })
.html('&times;')) .html('&times;'))
@ -211,8 +271,7 @@ function makePanel(title, parent, open, keep_empty, close_button){
// remove the panel when it runs out of sub-panels... // remove the panel when it runs out of sub-panels...
if(!keep_empty && panel.find('.sub-panel').length-c <= 0){ if(!keep_empty && panel.find('.sub-panel').length-c <= 0){
// XXX need to trigger sub-panel's 'closing' event... removePanel(panel, true)
closePanel(panel, true)
} }
_resetSidePanels() _resetSidePanels()
_resetSortedElem(ui.item) _resetSortedElem(ui.item)
@ -333,12 +392,12 @@ function makeSubPanel(title, content, parent, open, content_resizable){
: content_resizable : content_resizable
var content_elem = $('<div class="sub-panel-content content"/>') var content_elem = $('<div class="sub-panel-content content"/>')
.attr('id', title)
if(content != null){ if(content != null){
content_elem content_elem
.append(content) .append(content)
} }
var sub_panel = $('<details/>') var sub_panel = $('<details/>')
.attr('id', title)
.addClass('sub-panel noScroll') .addClass('sub-panel noScroll')
.prop('open', open) .prop('open', open)
.append($('<summary>'+title+'</summary>') .append($('<summary>'+title+'</summary>')
@ -353,7 +412,7 @@ function makeSubPanel(title, content, parent, open, content_resizable){
})) }))
.append(content_elem) .append(content_elem)
if(parent != null){ if(parent != null && parent != false){
if(parent.hasClass('panel-content')){ if(parent.hasClass('panel-content')){
sub_panel.appendTo(parent) sub_panel.appendTo(parent)
} else { } else {
@ -387,10 +446,6 @@ function makeSubPanel(title, content, parent, open, content_resizable){
* High level interface... * High level interface...
*/ */
var PANELS = {
}
// //
// content_builder() - should build and setup panel content // content_builder() - should build and setup panel content
// panel_setup(panel) - should register panel open/close event // panel_setup(panel) - should register panel open/close event
@ -398,22 +453,18 @@ var PANELS = {
// //
// NOTE: this will search an element by title, so if it is not unique // NOTE: this will search an element by title, so if it is not unique
// an existing element will be returned... // an existing element will be returned...
function buildPanelController(title, content_builder, panel_setup){ function makePanelController(title, content_builder, panel_setup, content_resizable){
var builder = function(parent){ var controller = function(parent, open){
// 1) search for panel and return it if it exists... // 1) search for panel and return it if it exists...
var panel = $('[id="'+ title +'"]') var panel = getPanel(title)
// 2) if no panel exists, create it // 2) if no panel exists, create it
// - content_builder() must return panel content // - content_builder() must return panel content
if(panel.length == 0){ if(panel.length == 0){
parent = parent == null ? $(PANEL_ROOT) : parent panel = makeSubPanel(title, content_builder(), parent, open, content_resizable)
panel = makeSubPanel(title, content_builder(), false)
.attr('id', title) .attr('id', title)
panel.appendTo(parent)
// XXX should this be before or after the append??? // XXX should this be before or after the append???
panel_setup(panel) panel_setup(panel)
@ -421,17 +472,32 @@ function buildPanelController(title, content_builder, panel_setup){
if(isPanelVisible(panel)){ if(isPanelVisible(panel)){
panel.trigger('panelOpening', panel) panel.trigger('panelOpening', panel)
} }
} else {
var v = isPanelVisible(panel)
if(open && !v){
openPanel(panel)
} else if(!open && v){
closePanel(panel)
}
} }
return panel return panel
} }
PANELS[title] = builder PANELS[title] = controller
return builder return controller
} }
// XXX also need:
// - togglePanels()
// show/hide all the panels (a-la Photoshop's Tab action)
/*********************************************************************/ /*********************************************************************/