new SplitPanel implementation
This commit is contained in:
parent
9001a45aa1
commit
835c4c92b7
2 changed files with 249 additions and 311 deletions
|
@ -8,6 +8,7 @@ Ox.Resizebar <f> Resizebar
|
||||||
elements <a|[]> Elements of the bar
|
elements <a|[]> Elements of the bar
|
||||||
orientation <s|horizontal> Orientation ('horizontal' or 'vertical')
|
orientation <s|horizontal> Orientation ('horizontal' or 'vertical')
|
||||||
panel <o|null> Panel object
|
panel <o|null> Panel object
|
||||||
|
resizeable <b|true> If true, can be resetted to default or original size
|
||||||
resizeable <b|true> If true, can be resized
|
resizeable <b|true> If true, can be resized
|
||||||
resize <a|[]> Array of sizes
|
resize <a|[]> Array of sizes
|
||||||
size <n|0> Default size
|
size <n|0> Default size
|
||||||
|
@ -21,12 +22,12 @@ Ox.Resizebar = function(options, self) {
|
||||||
var that = Ox.Element({}, self)
|
var that = Ox.Element({}, self)
|
||||||
.defaults({
|
.defaults({
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
collapsible: true,
|
collapsible: false,
|
||||||
|
defaultSize: null,
|
||||||
edge: 'left',
|
edge: 'left',
|
||||||
elements: [],
|
|
||||||
orientation: 'horizontal',
|
orientation: 'horizontal',
|
||||||
parent: null,
|
resettable: false,
|
||||||
resizable: true,
|
resizable: false,
|
||||||
resize: [],
|
resize: [],
|
||||||
size: 0,
|
size: 0,
|
||||||
tooltip: false
|
tooltip: false
|
||||||
|
@ -35,98 +36,42 @@ Ox.Resizebar = function(options, self) {
|
||||||
.update({
|
.update({
|
||||||
collapsed: function() {
|
collapsed: function() {
|
||||||
that.css({cursor: getCursor()});
|
that.css({cursor: getCursor()});
|
||||||
self.$tooltip && self.$tooltip.options({title: getTitle()});
|
self.$tooltip && self.$tooltip.options({title: getTooltipTitle()});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.addClass('OxResizebar Ox' + Ox.toTitleCase(self.options.orientation))
|
.addClass('OxResizebar Ox' + Ox.toTitleCase(self.options.orientation))
|
||||||
.bindEvent({
|
.bindEvent(Ox.extend({
|
||||||
// singleclick: toggle,
|
dragstart: onDragstart,
|
||||||
// doubleclick: reset,
|
drag: onDrag,
|
||||||
anyclick: toggle,
|
dragpause: onDragpause,
|
||||||
dragstart: dragstart,
|
dragend: onDragend
|
||||||
drag: drag,
|
}, self.options.resettable ? {
|
||||||
dragend: dragend,
|
doubleclick: reset,
|
||||||
mousedown: function() {
|
singleclick: toggle
|
||||||
triggerEvents('resizestart');
|
} : {
|
||||||
},
|
anyclick: toggle
|
||||||
mouseup: function() {
|
}))
|
||||||
triggerEvents('resizeend');
|
.append(Ox.$('<div>').addClass('OxSpace'))
|
||||||
}
|
.append(Ox.$('<div>').addClass('OxLine'))
|
||||||
})
|
.append(Ox.$('<div>').addClass('OxSpace'));
|
||||||
.append($('<div>').addClass('OxSpace'))
|
|
||||||
.append($('<div>').addClass('OxLine'))
|
|
||||||
.append($('<div>').addClass('OxSpace'));
|
|
||||||
|
|
||||||
if (self.options.tooltip) {
|
if (Ox.isString(self.options.tooltip)) {
|
||||||
// FIXME: Use Ox.Element's tooltip
|
// FIXME: Use Ox.Element's tooltip
|
||||||
self.$tooltip = Ox.Tooltip({title: getTitle()});
|
self.$tooltip = Ox.Tooltip({title: getTooltipTitle()});
|
||||||
that.on({
|
that.on({
|
||||||
mouseenter: self.$tooltip.show,
|
mouseenter: self.$tooltip.show,
|
||||||
mouseleave: self.$tooltip.hide
|
mouseleave: self.$tooltip.hide
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ox.extend(self, {
|
self.clientXY = self.options.orientation == 'horizontal'
|
||||||
clientXY: self.options.orientation == 'horizontal' ? 'clientY' : 'clientX',
|
? 'clientY' : 'clientX';
|
||||||
dimensions: Ox.UI.DIMENSIONS[self.options.orientation], // fixme: should orientation be the opposite orientation here?
|
self.dimensions = Ox.UI.DIMENSIONS[self.options.orientation];
|
||||||
edges: Ox.UI.EDGES[self.options.orientation],
|
self.edges = Ox.UI.EDGES[self.options.orientation];
|
||||||
isLeftOrTop: self.options.edge == 'left' || self.options.edge == 'top'
|
self.isLeftOrTop = self.options.edge == 'left' || self.options.edge == 'top';
|
||||||
});
|
|
||||||
|
|
||||||
that.css({cursor: getCursor()});
|
that.css({cursor: getCursor()});
|
||||||
|
|
||||||
function dragstart(data) {
|
|
||||||
if (self.options.resizable && !self.options.collapsed) {
|
|
||||||
Ox.$body.addClass('OxDragging');
|
|
||||||
self.drag = {
|
|
||||||
startPos: data[self.clientXY],
|
|
||||||
startSize: self.options.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drag(data) {
|
|
||||||
if (self.options.resizable && !self.options.collapsed) {
|
|
||||||
var d = data[self.clientXY] - self.drag.startPos,
|
|
||||||
size = self.options.size;
|
|
||||||
self.options.size = Ox.limit(
|
|
||||||
self.drag.startSize + d * (self.isLeftOrTop ? 1 : -1),
|
|
||||||
self.options.resize[0],
|
|
||||||
self.options.resize[self.options.resize.length - 1]
|
|
||||||
);
|
|
||||||
Ox.forEach(self.options.resize, function(v) {
|
|
||||||
if (self.options.size >= v - 8 && self.options.size <= v + 8) {
|
|
||||||
self.options.size = v;
|
|
||||||
return false; // break
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (self.options.size != size) {
|
|
||||||
that.css(self.edges[self.isLeftOrTop ? 2 : 3], self.options.size + 'px');
|
|
||||||
// fixme: send {size: x}, not x
|
|
||||||
if (self.isLeftOrTop) {
|
|
||||||
self.options.elements[0]
|
|
||||||
.css(self.dimensions[1], self.options.size + 'px');
|
|
||||||
self.options.elements[1]
|
|
||||||
.css(self.edges[2], (self.options.size + 1) + 'px');
|
|
||||||
} else {
|
|
||||||
self.options.elements[0]
|
|
||||||
.css(self.edges[3], (self.options.size + 1) + 'px');
|
|
||||||
self.options.elements[1]
|
|
||||||
.css(self.dimensions[1], self.options.size + 'px');
|
|
||||||
}
|
|
||||||
triggerEvents('resize');
|
|
||||||
self.options.parent.updateSize(self.isLeftOrTop ? 0 : 1, self.options.size); // fixme: listen to event instead?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragend() {
|
|
||||||
if (self.options.resizable && !self.options.collapsed) {
|
|
||||||
Ox.$body.removeClass('OxDragging');
|
|
||||||
self.options.size != self.drag.startSize && triggerEvents('resizeend');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCursor() {
|
function getCursor() {
|
||||||
var cursor = '';
|
var cursor = '';
|
||||||
if (self.options.collapsed) {
|
if (self.options.collapsed) {
|
||||||
|
@ -146,7 +91,7 @@ Ox.Resizebar = function(options, self) {
|
||||||
return cursor + '-resize';
|
return cursor + '-resize';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTitle() {
|
function getTooltipTitle() {
|
||||||
var title = '';
|
var title = '';
|
||||||
if (self.options.collapsed) {
|
if (self.options.collapsed) {
|
||||||
title = Ox._('Click to show');
|
title = Ox._('Click to show');
|
||||||
|
@ -156,54 +101,94 @@ Ox.Resizebar = function(options, self) {
|
||||||
}
|
}
|
||||||
if (self.options.collapsible) {
|
if (self.options.collapsible) {
|
||||||
title = title
|
title = title
|
||||||
? Ox._('{0} or click to hide', [title])
|
? Ox._('{0}{1} click to hide', [
|
||||||
|
title, self.options.resettable ? ',' : ' or'
|
||||||
|
])
|
||||||
: Ox._('Click to hide');
|
: Ox._('Click to hide');
|
||||||
}
|
}
|
||||||
|
if (self.options.resettable) {
|
||||||
|
title += ' or doubleclick to reset'
|
||||||
}
|
}
|
||||||
if (title && Ox.isString(self.options.tooltip)) {
|
}
|
||||||
|
if (title && self.options.tooltip) {
|
||||||
title += ' ' + self.options.tooltip;
|
title += ' ' + self.options.tooltip;
|
||||||
}
|
}
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onDragstart(data) {
|
||||||
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
|
Ox.$body.addClass('OxDragging');
|
||||||
|
self.drag = {
|
||||||
|
startPos: data[self.clientXY],
|
||||||
|
startSize: self.options.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
that.triggerEvent('resizestart', {size: self.options.size});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDrag(data) {
|
||||||
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
|
var delta = data[self.clientXY] - self.drag.startPos,
|
||||||
|
size = self.options.size;
|
||||||
|
self.options.size = Ox.limit(
|
||||||
|
self.drag.startSize + delta * (self.isLeftOrTop ? 1 : -1),
|
||||||
|
self.options.resize[0],
|
||||||
|
self.options.resize[self.options.resize.length - 1]
|
||||||
|
);
|
||||||
|
Ox.forEach(self.options.resize, function(value) {
|
||||||
|
if (
|
||||||
|
self.options.size >= value - 8
|
||||||
|
&& self.options.size <= value + 8
|
||||||
|
) {
|
||||||
|
self.options.size = value;
|
||||||
|
return false; // break
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (self.options.size != size) {
|
||||||
|
that.css(
|
||||||
|
self.edges[self.isLeftOrTop ? 2 : 3],
|
||||||
|
self.options.size + 'px'
|
||||||
|
)
|
||||||
|
.triggerEvent('resize', {size: self.options.size});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDragpause() {
|
||||||
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
|
if (self.options.size != self.drag.startSize) {
|
||||||
|
that.triggerEvent('resizepause', {size: self.options.size});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDragend() {
|
||||||
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
|
Ox.$body.removeClass('OxDragging');
|
||||||
|
if (self.options.size != self.drag.startSize) {
|
||||||
|
that.triggerEvent('resizeend', {size: self.options.size});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
if (self.options.resizable && !self.options.collapsed) {
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
// fixme: silly, pass an option
|
that.triggerEvent('reset');
|
||||||
self.options.parent.reset(
|
|
||||||
self.isLeftOrTop ? 0
|
|
||||||
: self.options.parent.options('elements').length - 1
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
if (self.options.collapsible) {
|
if (self.options.collapsible) {
|
||||||
// fixme: silly, pass an option
|
|
||||||
self.options.parent.toggle(
|
|
||||||
self.isLeftOrTop ? 0
|
|
||||||
: self.options.parent.options('elements').length - 1
|
|
||||||
);
|
|
||||||
self.options.collapsed = !self.options.collapsed;
|
self.options.collapsed = !self.options.collapsed;
|
||||||
that.css({cursor: getCursor()});
|
that.css({cursor: getCursor()});
|
||||||
self.$tooltip && self.$tooltip.hide(function() {
|
self.$tooltip && self.$tooltip.hide(function() {
|
||||||
self.$tooltip.options({title: getTitle()});
|
self.$tooltip.options({title: getTooltipTitle()});
|
||||||
});
|
});
|
||||||
|
that.triggerEvent('toggle', {collapsed: self.options.collapsed});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function triggerEvents(event) {
|
|
||||||
self.options.elements[0].triggerEvent(event, {
|
|
||||||
size: self.isLeftOrTop
|
|
||||||
? self.options.size
|
|
||||||
: self.options.elements[0][self.dimensions[1]]()
|
|
||||||
});
|
|
||||||
self.options.elements[1].triggerEvent(event, {
|
|
||||||
size: self.isLeftOrTop
|
|
||||||
? self.options.elements[1][self.dimensions[1]]()
|
|
||||||
: self.options.size
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,10 +6,14 @@ Ox.SplitPanel <f> SpliPanel Object
|
||||||
elements <[o]|[]> Array of two or three element objects
|
elements <[o]|[]> Array of two or three element objects
|
||||||
collapsible <b|false> If true, can be collapsed (if outer element)
|
collapsible <b|false> If true, can be collapsed (if outer element)
|
||||||
collapsed <b|false> If true, is collapsed (if collapsible)
|
collapsed <b|false> If true, is collapsed (if collapsible)
|
||||||
defaultSize <n|s|auto> Default size in px (restorable via reset)
|
defaultSize <n|s|"auto"> Default size in px (restorable via reset)
|
||||||
element <o> Any Ox.Element
|
element <o> Any Ox.Element
|
||||||
If any element is collapsible or resizable, all elements must
|
If any element is collapsible or resizable, all elements must
|
||||||
have an id.
|
have an id.
|
||||||
|
resettable <b|false> If true, can be resetted (if outer element)
|
||||||
|
Note that reset fires on doubleclick, and if the element is also
|
||||||
|
collapsible, toggle now fires on singleclick, no longer on click.
|
||||||
|
Singleclick happens 250 ms later.
|
||||||
resizable <b|false> If true, can be resized (if outer element)
|
resizable <b|false> If true, can be resized (if outer element)
|
||||||
resize <[n]|[]> Min size, optional snappy points, and max size
|
resize <[n]|[]> Min size, optional snappy points, and max size
|
||||||
size <n|s|"auto"> Size in px (one element must be "auto")
|
size <n|s|"auto"> Size in px (one element must be "auto")
|
||||||
|
@ -19,15 +23,16 @@ Ox.SplitPanel <f> SpliPanel Object
|
||||||
([options[, self]]) -> <o:Ox.Element> SpliPanel Object
|
([options[, self]]) -> <o:Ox.Element> SpliPanel Object
|
||||||
resize <!> resize
|
resize <!> resize
|
||||||
Fires on resize, on both elements being resized
|
Fires on resize, on both elements being resized
|
||||||
|
resizeend <!> resizeend
|
||||||
|
Fires on resize, on both elements being resized
|
||||||
|
resizepause <!> resizepause
|
||||||
|
Fires on resize, on both elements being resized
|
||||||
toggle <!> toggle
|
toggle <!> toggle
|
||||||
Fires on collapse or expand, on the element being toggled
|
Fires on collapse or expand, on the element being toggled
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.SplitPanel = function(options, self) {
|
Ox.SplitPanel = function(options, self) {
|
||||||
|
|
||||||
// fixme: doubleclick on resizebar should reset to initial size
|
|
||||||
// (but anyclick would become singleclick, i.e. less responsive)
|
|
||||||
|
|
||||||
self = self || {};
|
self = self || {};
|
||||||
var that = Ox.Element({}, self)
|
var that = Ox.Element({}, self)
|
||||||
.defaults({
|
.defaults({
|
||||||
|
@ -37,83 +42,77 @@ Ox.SplitPanel = function(options, self) {
|
||||||
.options(options || {})
|
.options(options || {})
|
||||||
.addClass('OxSplitPanel');
|
.addClass('OxSplitPanel');
|
||||||
|
|
||||||
Ox.extend(self, {
|
self.defaultSize = self.options.elements.map(function(element) {
|
||||||
dimensions: Ox.UI.DIMENSIONS[self.options.orientation],
|
|
||||||
edges: Ox.UI.EDGES[self.options.orientation],
|
|
||||||
defaultSize: self.options.elements.map(function(element) {
|
|
||||||
return !Ox.isUndefined(element.defaultSize)
|
return !Ox.isUndefined(element.defaultSize)
|
||||||
? element.defaultSize : element.size;
|
? element.defaultSize : element.size;
|
||||||
}),
|
|
||||||
length: self.options.elements.length,
|
|
||||||
resizebarElements: [],
|
|
||||||
$resizebars: []
|
|
||||||
});
|
});
|
||||||
|
self.dimensions = Ox.UI.DIMENSIONS[self.options.orientation];
|
||||||
|
self.edges = Ox.UI.EDGES[self.options.orientation];
|
||||||
|
self.initialized = false;
|
||||||
|
self.length = self.options.elements.length;
|
||||||
|
|
||||||
// create elements
|
self.$elements = [];
|
||||||
// fixme: attach to self instead?
|
self.$resizebars = [];
|
||||||
that.$elements = Ox.map(self.options.elements, function(element, i) {
|
self.options.elements.forEach(function(element, index) {
|
||||||
self.options.elements[i] = Ox.extend({
|
var elementIndices = index == 0 ? [0, 1] : index == 1 ? [1, 0] : [2, 1],
|
||||||
|
resizebarIndex = self.$resizebars.length;
|
||||||
|
self.options.elements[index] = Ox.extend({
|
||||||
collapsible: false,
|
collapsible: false,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
|
defaultSize: 'auto',
|
||||||
|
resettable: false,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
resize: [],
|
resize: [],
|
||||||
size: 'auto'
|
size: 'auto',
|
||||||
|
tooltip: false
|
||||||
}, element);
|
}, element);
|
||||||
// top and bottom (horizontal) or left and right (vertical)
|
// top and bottom (horizontal) or left and right (vertical)
|
||||||
self.edges.slice(2).forEach(function(edge) {
|
self.edges.slice(2).forEach(function(edge) {
|
||||||
element.element.css(edge, (parseInt(element.element.css(edge)) || 0) + 'px');
|
if (!element.element.css(edge)) {
|
||||||
|
element.element.css(edge, 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return element.element;
|
if (element.collapsed) {
|
||||||
});
|
// left/right (horizontal) or top/bottom (vertical)
|
||||||
|
that.css(self.edges[index == 0 ? 0 : 1], -element.size + 'px');
|
||||||
// create resizebars
|
}
|
||||||
self.options.elements.forEach(function(element, i) {
|
self.$elements[index] = element.element.appendTo(that);
|
||||||
var index = i == 0 ? 0 : 1;
|
|
||||||
that.$elements[i].appendTo(that.$element); // fixme: that.$content
|
|
||||||
if (element.collapsible || element.resizable) {
|
if (element.collapsible || element.resizable) {
|
||||||
self.resizebarElements[index] = i < 2 ? [0, 1] : [1, 2];
|
self.$resizebars[resizebarIndex] = Ox.Resizebar({
|
||||||
self.$resizebars[index] = Ox.Resizebar({
|
|
||||||
collapsed: element.collapsed,
|
collapsed: element.collapsed,
|
||||||
collapsible: element.collapsible,
|
collapsible: element.collapsible,
|
||||||
edge: self.edges[index],
|
edge: self.edges[index == 0 ? 0 : 1],
|
||||||
elements: [
|
|
||||||
that.$elements[self.resizebarElements[index][0]],
|
|
||||||
that.$elements[self.resizebarElements[index][1]]
|
|
||||||
],
|
|
||||||
id: element.element.options('id'),
|
|
||||||
orientation: self.options.orientation == 'horizontal'
|
orientation: self.options.orientation == 'horizontal'
|
||||||
? 'vertical' : 'horizontal',
|
? 'vertical' : 'horizontal',
|
||||||
parent: that, // fixme: that.$content
|
resettable: element.resettable,
|
||||||
resizable: element.resizable,
|
resizable: element.resizable,
|
||||||
resize: element.resize,
|
resize: element.resize,
|
||||||
size: element.size,
|
size: element.size,
|
||||||
tooltip: element.tooltip
|
tooltip: element.tooltip === true ? '' : element.tooltip
|
||||||
});
|
})
|
||||||
self.$resizebars[index][
|
.bindEvent({
|
||||||
i == 0 ? 'insertAfter' : 'insertBefore'
|
reset: function() {
|
||||||
](that.$elements[i]);
|
that.resetElement(index);
|
||||||
|
},
|
||||||
|
resize: function(data) {
|
||||||
|
onResize(elementIndices, data.size);
|
||||||
|
triggerEvents(elementIndices, 'resize', data);
|
||||||
|
},
|
||||||
|
resizepause: function(data) {
|
||||||
|
triggerEvents(elementIndices, 'resizepause', data);
|
||||||
|
},
|
||||||
|
resizeend: function(data) {
|
||||||
|
triggerEvents(elementIndices, 'resizeend', data);
|
||||||
|
},
|
||||||
|
toggle: function(data) {
|
||||||
|
that.toggleElement(index);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
[index == 0 ? 'insertAfter' : 'insertBefore'](self.$elements[index]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.options.elements.forEach(function(element, i) {
|
setSizes();
|
||||||
element.collapsed && that.css(
|
|
||||||
// left/right (horizontal) or top/bottom (vertical)
|
|
||||||
self.edges[i == 0 ? 0 : 1], -element.size + 'px'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
setSizes(true);
|
|
||||||
|
|
||||||
function getIndexById(id) {
|
|
||||||
var index = -1;
|
|
||||||
Ox.forEach(self.options.elements, function(element, i) {
|
|
||||||
if (element.element.options('id') == id) {
|
|
||||||
index = i;
|
|
||||||
return false; // break
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSize(index) {
|
function getSize(index) {
|
||||||
var element = self.options.elements[index];
|
var element = self.options.elements[index];
|
||||||
|
@ -125,41 +124,50 @@ Ox.SplitPanel = function(options, self) {
|
||||||
return getSize(index) * !element.collapsed;
|
return getSize(index) * !element.collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSizes(init, animate) {
|
function onResize(elementIndices, size) {
|
||||||
|
var dimension = self.dimensions[0],
|
||||||
|
edge = self.edges[elementIndices[0] == 0 ? 0 : 1];
|
||||||
|
self.options.elements[elementIndices[0]].size = size;
|
||||||
|
elementIndices.forEach(function(elementIndex, index) {
|
||||||
|
self.$elements[elementIndex].css(
|
||||||
|
index == 0 ? dimension : edge,
|
||||||
|
index == 0 ? size : size + 1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSizes(animate) {
|
||||||
// will animate if animate is truthy and call animate if it's a function
|
// will animate if animate is truthy and call animate if it's a function
|
||||||
self.options.elements.forEach(function(element, i) {
|
self.options.elements.forEach(function(element, index) {
|
||||||
// fixme: maybe we can add a conditional here, since init
|
var $resizebar,
|
||||||
// is about elements that are collapsed splitpanels
|
css = {},
|
||||||
var css = {},
|
|
||||||
edges = self.edges.slice(0, 2).map(function(edge) {
|
edges = self.edges.slice(0, 2).map(function(edge) {
|
||||||
// left/right (horizontal) or top/bottom (vertical)
|
// left/right (horizontal) or top/bottom (vertical)
|
||||||
return init && parseInt(that.$elements[i].css(edge)) || 0;
|
var value = parseInt(self.$elements[index].css(edge));
|
||||||
|
return !self.initialized && value || 0;
|
||||||
});
|
});
|
||||||
if (element.size != 'auto') {
|
if (element.size != 'auto') {
|
||||||
// width (horizontal) or height (vertical)
|
// width (horizontal) or height (vertical)
|
||||||
css[self.dimensions[0]] = element.size + 'px';
|
css[self.dimensions[0]] = element.size + 'px';
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (index == 0) {
|
||||||
// left (horizontal) or top (vertical)
|
// left (horizontal) or top (vertical)
|
||||||
css[self.edges[0]] = edges[0] + 'px';
|
css[self.edges[0]] = edges[0] + 'px';
|
||||||
// right (horizontal) or bottom (vertical)
|
// right (horizontal) or bottom (vertical)
|
||||||
if (element.size == 'auto') {
|
if (element.size == 'auto') {
|
||||||
css[self.edges[1]] = getSize(1)
|
css[self.edges[1]] = getSize(1) + (
|
||||||
+ (
|
|
||||||
self.length == 3 ? getVisibleSize(2) : 0
|
self.length == 3 ? getVisibleSize(2) : 0
|
||||||
) + 'px';
|
) + 'px';
|
||||||
}
|
}
|
||||||
} else if (i == 1) {
|
} else if (index == 1) {
|
||||||
// left (horizontal) or top (vertical)
|
// left (horizontal) or top (vertical)
|
||||||
if (self.options.elements[0].size != 'auto') {
|
if (self.options.elements[0].size != 'auto') {
|
||||||
css[self.edges[0]] = edges[0] + getSize(0) + 'px'
|
css[self.edges[0]] = edges[0] + getSize(0) + 'px';
|
||||||
} else {
|
} else {
|
||||||
css[self.edges[0]] = 'auto'; // fixme: why is this needed?
|
css[self.edges[0]] = 'auto'; // fixme: why is this needed?
|
||||||
}
|
}
|
||||||
// right (horizontal) or bottom (vertical)
|
// right (horizontal) or bottom (vertical)
|
||||||
css[self.edges[1]] = (
|
css[self.edges[1]] = (self.length == 3 ? getSize(2) : 0) + 'px';
|
||||||
self.length == 3 ? getSize(2) : 0
|
|
||||||
) + 'px';
|
|
||||||
} else {
|
} else {
|
||||||
// left (horizontal) or top (vertical)
|
// left (horizontal) or top (vertical)
|
||||||
if (element.size == 'auto') {
|
if (element.size == 'auto') {
|
||||||
|
@ -171,117 +179,74 @@ Ox.SplitPanel = function(options, self) {
|
||||||
css[self.edges[1]] = edges[1] + 'px';
|
css[self.edges[1]] = edges[1] + 'px';
|
||||||
}
|
}
|
||||||
if (animate) {
|
if (animate) {
|
||||||
that.$elements[i].animate(css, 250, function() {
|
self.$elements[index].animate(css, 250, function() {
|
||||||
i == 0 && Ox.isFunction(animate) && animate();
|
index == 0 && Ox.isFunction(animate) && animate();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
that.$elements[i].css(css);
|
self.$elements[index].css(css);
|
||||||
}
|
}
|
||||||
if (element.collapsible || element.resizable) {
|
if (element.collapsible || element.resizable) {
|
||||||
css = {};
|
$resizebar = self.$resizebars[
|
||||||
|
index < 2 ? 0 : self.$resizebars.length - 1
|
||||||
|
];
|
||||||
// left or right (horizontal) or top or bottom (vertical)
|
// left or right (horizontal) or top or bottom (vertical)
|
||||||
css[self.edges[i == 0 ? 0 : 1]] = element.size + 'px'
|
css = Ox.extend(
|
||||||
|
{}, self.edges[index == 0 ? 0 : 1], element.size + 'px'
|
||||||
|
);
|
||||||
if (animate) {
|
if (animate) {
|
||||||
self.$resizebars[i == 0 ? 0 : 1].animate(css, 250);
|
$resizebar.animate(css, 250);
|
||||||
} else {
|
} else {
|
||||||
self.$resizebars[i == 0 ? 0 : 1].css(css);
|
$resizebar.css(css);
|
||||||
}
|
}
|
||||||
self.$resizebars[i == 0 ? 0 : 1].options({size: element.size});
|
$resizebar.options({size: element.size});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
self.initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerEvents(elementIndices, event, data) {
|
||||||
|
elementIndices.forEach(function(elementIndex, index) {
|
||||||
|
var $element = self.$elements[elementIndex],
|
||||||
|
size = index == 0 ? data.size : $element[self.dimensions[0]]();
|
||||||
|
$element.triggerEvent(event, {size: size});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
getSize <f> get size of panel
|
isCollapsed <f> Tests if an outer element is collapsed
|
||||||
(id) -> <i> id or index of element, returns size
|
(index) -> <b> True if collapsed
|
||||||
id <s|i> The element's id or index
|
index <i> The element's index
|
||||||
@*/
|
@*/
|
||||||
// fixme: what is this? there is that.size()
|
that.isCollapsed = function(index) {
|
||||||
that.getSize = function(id) {
|
|
||||||
var index = Ox.isNumber(id) ? id : getIndexById(id),
|
|
||||||
element = self.options.elements[index];
|
|
||||||
return element.element[self.dimensions[0]]() * !that.isCollapsed(index);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@
|
|
||||||
isCollapsed <f> panel collapsed state
|
|
||||||
(id) -> <b> id or index of element, returns collapsed state
|
|
||||||
id <i> The element's id or index
|
|
||||||
@*/
|
|
||||||
that.isCollapsed = function(id) {
|
|
||||||
var index = Ox.isNumber(id) ? id : getIndexById(id);
|
|
||||||
return self.options.elements[index].collapsed;
|
return self.options.elements[index].collapsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
replaceElement <f> Replace panel element
|
replaceElement <f> Replaces an element
|
||||||
(id, element) -> <f> replace element
|
(index, element) -> <f> replace element
|
||||||
id <s|n> The element's id or index
|
index <n> The element's index
|
||||||
element <o> New element
|
element <o> New element
|
||||||
@*/
|
@*/
|
||||||
that.replaceElement = function(id, element) {
|
that.replaceElement = function(index, element) {
|
||||||
// one can pass index instead of id
|
|
||||||
var index = Ox.isNumber(id) ? id : getIndexById(id);
|
|
||||||
// top and bottom (horizontal) or left and right (vertical)
|
// top and bottom (horizontal) or left and right (vertical)
|
||||||
self.edges.slice(2).forEach(function(edge) {
|
self.edges.slice(2).forEach(function(edge) {
|
||||||
element.css(edge, (parseInt(element.css(edge)) || 0) + 'px');
|
element.css(edge, (parseInt(element.css(edge)) || 0) + 'px');
|
||||||
});
|
});
|
||||||
that.$elements[index] = element;
|
self.$elements[index] = element;
|
||||||
self.options.elements[index].element.replaceWith(
|
self.options.elements[index].element.replaceWith(
|
||||||
self.options.elements[index].element = element
|
self.options.elements[index].element = element
|
||||||
);
|
);
|
||||||
setSizes();
|
setSizes();
|
||||||
self.$resizebars.forEach(function($resizebar, i) {
|
|
||||||
$resizebar.options({
|
|
||||||
elements: [
|
|
||||||
that.$elements[self.resizebarElements[i][0]],
|
|
||||||
that.$elements[self.resizebarElements[i][1]]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
replaceElements <f> replace panel elements
|
resetElement <f> Resets an outer element to its initial size
|
||||||
(elements) -> <f> replace elements
|
|
||||||
elements <a> array of new elements
|
|
||||||
@*/
|
@*/
|
||||||
that.replaceElements = function(elements) {
|
that.resetElement = function(index) {
|
||||||
elements.forEach(function(element, i) {
|
var element = self.options.elements[index];
|
||||||
if (Ox.isNumber(element.size)) {
|
|
||||||
that.size(i, element.size);
|
|
||||||
if (element.collapsible || element.resizable) {
|
|
||||||
self.$resizebars[i == 0 ? 0 : 1].options({
|
|
||||||
collapsible: element.collapsible,
|
|
||||||
resizable: element.resizable,
|
|
||||||
size: element.size
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
that.replace(i, element.element);
|
|
||||||
});
|
|
||||||
self.options.elements = elements;
|
|
||||||
self.$resizebars.forEach(function($resizebar, i) {
|
|
||||||
$resizebar.options({
|
|
||||||
elements: [
|
|
||||||
that.$elements[self.resizebarElements[i][0]],
|
|
||||||
that.$elements[self.resizebarElements[i][1]]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@
|
|
||||||
reset <f> Reset an outer element to its initial size
|
|
||||||
@*/
|
|
||||||
that.reset = function(id) {
|
|
||||||
// one can pass index instead of id
|
|
||||||
var index = Ox.isNumber(id) ? id : getIndexById(id),
|
|
||||||
element = self.options.elements[index];
|
|
||||||
element.size = self.defaultSize[index];
|
element.size = self.defaultSize[index];
|
||||||
setSizes(false, function() {
|
setSizes(function() {
|
||||||
element.element.triggerEvent('resize', {
|
element.element.triggerEvent('resize', {
|
||||||
size: element.size
|
size: element.size
|
||||||
});
|
});
|
||||||
|
@ -290,72 +255,60 @@ Ox.SplitPanel = function(options, self) {
|
||||||
size: element.element[self.dimensions[0]]()
|
size: element.element[self.dimensions[0]]()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
size <f> Get or set size of an element
|
size <f> Get or set size of an element
|
||||||
(id) -> <i> Returns size
|
(index) -> <i> Returns size
|
||||||
(id, size) -> <o> Sets size, returns SplitPanel
|
(index, size) -> <o> Sets size, returns SplitPanel
|
||||||
(id, size, callback) -> <o> Sets size with animation, returns SplitPanel
|
(index, size, callback) -> <o> Sets size with animation, returns SplitPanel
|
||||||
id <i> The element's id or index
|
index <i> The element's index
|
||||||
size <i> New size, in px
|
size <i> New size, in px
|
||||||
callback <b|f> Callback function (passing true animates w/o callback)
|
callback <b|f> Callback function (passing true animates w/o callback)
|
||||||
@*/
|
@*/
|
||||||
that.size = function(id, size, callback) {
|
that.resizeElement = that.size = function(index, size, callback) {
|
||||||
// one can pass index instead of id
|
var element = self.options.elements[index];
|
||||||
var index = Ox.isNumber(id) ? id : getIndexById(id),
|
|
||||||
element = self.options.elements[index];
|
|
||||||
if (arguments.length == 1) {
|
if (arguments.length == 1) {
|
||||||
return element.element[self.dimensions[0]]() * !that.isCollapsed(index);
|
return element.element[self.dimensions[0]]()
|
||||||
|
* !that.isCollapsed(index);
|
||||||
} else {
|
} else {
|
||||||
element.size = size;
|
element.size = size;
|
||||||
setSizes(false, callback);
|
setSizes(callback);
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
toggle <f> Toggles collapsed state of an outer element
|
toggleElement <f> Toggles collapsed state of an outer element
|
||||||
(id) -> <o> The SplitPanel
|
(index) -> <o> The SplitPanel
|
||||||
id <s|i> The element's id or index
|
index <s|i> The element's index
|
||||||
@*/
|
@*/
|
||||||
// FIXME: 'toggle' is reserved by jQuery
|
that.toggleElement = function(index) {
|
||||||
that.toggle = function(id) {
|
|
||||||
// one can pass index instead of id
|
|
||||||
if (self.toggling) {
|
if (self.toggling) {
|
||||||
return false;
|
return that;
|
||||||
}
|
}
|
||||||
var index = Ox.isNumber(id) ? id : getIndexById(id),
|
var element = self.options.elements[index],
|
||||||
element = self.options.elements[index],
|
value = parseInt(that.css(self.edges[index == 0 ? 0 : 1]))
|
||||||
value = parseInt(that.css(self.edges[index == 0 ? 0 : 1]), 10)
|
+ element.element[self.dimensions[0]]()
|
||||||
+ element.element[self.dimensions[0]]() * (element.collapsed ? 1 : -1),
|
* (element.collapsed ? 1 : -1),
|
||||||
animate = {};
|
animate = Ox.extend({}, self.edges[index == 0 ? 0 : 1], value);
|
||||||
self.toggling = true;
|
self.toggling = true;
|
||||||
animate[self.edges[index == 0 ? 0 : 1]] = value;
|
|
||||||
that.animate(animate, 250, function() {
|
that.animate(animate, 250, function() {
|
||||||
element.collapsed = !element.collapsed;
|
element.collapsed = !element.collapsed;
|
||||||
element.element.triggerEvent('toggle', {
|
element.element.triggerEvent('toggle', {
|
||||||
collapsed: element.collapsed
|
collapsed: element.collapsed
|
||||||
});
|
});
|
||||||
self.$resizebars[index == 0 ? 0 : 1].options({collapsed: element.collapsed});
|
self.$resizebars[index < 2 ? 0 : self.$resizebars.length - 1].options({
|
||||||
|
collapsed: element.collapsed
|
||||||
|
});
|
||||||
element = self.options.elements[index == 0 ? 1 : index - 1];
|
element = self.options.elements[index == 0 ? 1 : index - 1];
|
||||||
element.element.triggerEvent('resize', {
|
element.element.triggerEvent('resize', {
|
||||||
size: element.element[self.dimensions[0]]()
|
size: element.element[self.dimensions[0]]()
|
||||||
});
|
});
|
||||||
self.toggling = false;
|
self.toggling = false;
|
||||||
});
|
});
|
||||||
};
|
return that;
|
||||||
|
|
||||||
/*@
|
|
||||||
updateSize <f> update size of element
|
|
||||||
(index, size) -> <o> update size of element
|
|
||||||
index <i> index of element
|
|
||||||
size <n> new size
|
|
||||||
@*/
|
|
||||||
that.updateSize = function(index, size) {
|
|
||||||
// this is called from resizebar
|
|
||||||
index = index == 0 ? 0 : self.options.elements.length - 1; // fixme: silly that 0 or 1 is passed, and not index
|
|
||||||
self.options.elements[index].size = size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
|
|
Loading…
Reference in a new issue