mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-13 09:28:29 +01:00
Convert et2_widget_split to TS
This commit is contained in:
parent
7d01281fa0
commit
91119891cd
7
api/js/etemplate/et2_types.d.ts
vendored
7
api/js/etemplate/et2_types.d.ts
vendored
@ -67,7 +67,12 @@ declare var et2_nextmatch_header_bar : any;
|
|||||||
declare var et2_nextmatch_header : any;
|
declare var et2_nextmatch_header : any;
|
||||||
declare var et2_nextmatch_customfields : any;
|
declare var et2_nextmatch_customfields : any;
|
||||||
declare var et2_nextmatch_controller : any;
|
declare var et2_nextmatch_controller : any;
|
||||||
declare var et2_dynheight : any;
|
declare class et2_dynheight {
|
||||||
|
constructor(_outerNode, _innerNode, _minHeight);
|
||||||
|
outerNode : any;
|
||||||
|
update : any;
|
||||||
|
free : any;
|
||||||
|
}
|
||||||
declare class et2_nextmatch_rowProvider {}
|
declare class et2_nextmatch_rowProvider {}
|
||||||
declare var et2_nextmatch_rowWidget : any;
|
declare var et2_nextmatch_rowWidget : any;
|
||||||
declare var et2_nextmatch_rowTemplateWidget : any;
|
declare var et2_nextmatch_rowTemplateWidget : any;
|
||||||
|
@ -1,457 +1,374 @@
|
|||||||
|
"use strict";
|
||||||
/**
|
/**
|
||||||
* EGroupware eTemplate2 - Split panel
|
* EGroupware eTemplate2 - Split panel
|
||||||
*
|
*
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @package etemplate
|
* @package etemplate
|
||||||
* @subpackage api
|
* @subpackage api
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Nathan Gray
|
* @author Nathan Gray
|
||||||
* @copyright Nathan Gray 2013
|
* @copyright Nathan Gray 2013
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
|
||||||
|
|
||||||
/*egw:uses
|
|
||||||
/vendor/bower-asset/jquery/dist/jquery.js;
|
|
||||||
jquery.splitter;
|
|
||||||
et2_core_baseWidget;
|
|
||||||
*/
|
*/
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = function (d, b) {
|
||||||
|
extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||||
|
return extendStatics(d, b);
|
||||||
|
};
|
||||||
|
return function (d, b) {
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
/*egw:uses
|
||||||
|
/vendor/bower-asset/jquery/dist/jquery.js;
|
||||||
|
jquery.splitter;
|
||||||
|
et2_core_baseWidget;
|
||||||
|
*/
|
||||||
|
var et2_core_DOMWidget_1 = require("./et2_core_DOMWidget");
|
||||||
|
var et2_core_widget_1 = require("./et2_core_widget");
|
||||||
|
var et2_core_inheritance_1 = require("./et2_core_inheritance");
|
||||||
/**
|
/**
|
||||||
* A container widget that accepts 2 children, and puts a resize bar between them.
|
* A container widget that accepts 2 children, and puts a resize bar between them.
|
||||||
*
|
*
|
||||||
* This is the etemplate2 implementation of the traditional split pane / split panel.
|
* This is the etemplate2 implementation of the traditional split pane / split panel.
|
||||||
* The split can be horizontal or vertical, and can be limited in size. You can also
|
* The split can be horizontal or vertical, and can be limited in size. You can also
|
||||||
* turn on double-click docking to minimize one of the children.
|
* turn on double-click docking to minimize one of the children.
|
||||||
*
|
*
|
||||||
* @see http://methvin.com/splitter/ Uses Splitter
|
* @see http://methvin.com/splitter/ Uses Splitter
|
||||||
* @augments et2_DOMWidget
|
* @augments et2_DOMWidget
|
||||||
*/
|
*/
|
||||||
var et2_split = (function(){ "use strict"; return et2_DOMWidget.extend([et2_IResizeable,et2_IPrint],
|
var et2_split = /** @class */ (function (_super) {
|
||||||
{
|
__extends(et2_split, _super);
|
||||||
attributes: {
|
function et2_split(_parent, _attrs, _child) {
|
||||||
"orientation": {
|
var _this =
|
||||||
"name": "Orientation",
|
// Call the inherited constructor
|
||||||
"description": "Horizontal or vertical (v or h)",
|
_super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_split._attributes, _child || {})) || this;
|
||||||
"default": "v",
|
_this.div = null;
|
||||||
"type": "string"
|
_this.dynheight = null;
|
||||||
},
|
_this.div = jQuery(document.createElement("div"))
|
||||||
"outline": {
|
.addClass('et2_split');
|
||||||
"name": "Outline",
|
// Create the dynheight component which dynamically scales the inner
|
||||||
"description": "Use a 'ghosted' copy of the splitbar and does not resize the panes until the mouse button is released. Reduces flickering or unwanted re-layout during resize",
|
// container.
|
||||||
"default": false,
|
_this.dynheight = new et2_dynheight(_this.getParent().getDOMNode() || _this.getInstanceManager().DOMContainer, _this.div, 100);
|
||||||
"type": "boolean"
|
// Add something so we can see it - will be replaced if there's children
|
||||||
},
|
_this.left = jQuery("<div>Top / Left</div>").appendTo(_this.div);
|
||||||
"dock_side": {
|
_this.right = jQuery("<div>Bottom / Right</div>").appendTo(_this.div);
|
||||||
"name": "Dock",
|
// Deferred object so we can wait for children
|
||||||
"description": "Allow the user to 'Dock' the splitbar to one side of the splitter, essentially hiding one pane and using the entire splitter area for the other pane. One of leftDock, rightDock, topDock, bottomDock.",
|
_this.loading = jQuery.Deferred();
|
||||||
"default": et2_no_init,
|
// Flag to temporarily ignore resizing
|
||||||
"type": "string"
|
_this.stop_resize = false;
|
||||||
},
|
return _this;
|
||||||
"width": {
|
}
|
||||||
"default": "100%"
|
et2_split.prototype.destroy = function () {
|
||||||
},
|
// Stop listening
|
||||||
// Not needed
|
this.left.next().off("mouseup");
|
||||||
"overflow": {"ignore": true},
|
// Destroy splitter, restore children
|
||||||
"no_lang": {"ignore": true},
|
this.div.trigger("destroy");
|
||||||
"rows": {"ignore": true},
|
// Destroy dynamic full-height
|
||||||
"cols": {"ignore": true}
|
this.dynheight.free();
|
||||||
},
|
_super.prototype.destroy.call(this);
|
||||||
|
// Remove placeholder children
|
||||||
DOCK_TOLERANCE: 15,
|
if (this._children.length == 0) {
|
||||||
|
this.div.empty();
|
||||||
/**
|
}
|
||||||
* Constructor
|
this.div.remove();
|
||||||
*
|
};
|
||||||
* @memberOf et2_split
|
/**
|
||||||
*/
|
* Tap in here to check if we have real children, because all children should be created
|
||||||
init: function() {
|
* by this point. If there are, replace the placeholders.
|
||||||
this._super.apply(this, arguments);
|
*/
|
||||||
|
et2_split.prototype.loadFromXML = function (_node) {
|
||||||
this.div = jQuery(document.createElement("div"))
|
_super.prototype.loadFromXML.call(this, _node);
|
||||||
.addClass('et2_split');
|
if (this._children.length > 0) {
|
||||||
|
if (this._children[0]) {
|
||||||
// Create the dynheight component which dynamically scales the inner
|
this.left.detach();
|
||||||
// container.
|
this.left = jQuery(this._children[0].getDOMNode(this._children[0]))
|
||||||
this.dynheight = new et2_dynheight(
|
.appendTo(this.div);
|
||||||
this.getParent().getDOMNode() || this.getInstanceManager().DOMContainer,
|
}
|
||||||
this.div, 100
|
if (this._children[1]) {
|
||||||
);
|
this.right.detach();
|
||||||
|
this.right = jQuery(this._children[1].getDOMNode(this._children[1]))
|
||||||
// Add something so we can see it - will be replaced if there's children
|
.appendTo(this.div);
|
||||||
this.left = jQuery("<div>Top / Left</div>").appendTo(this.div);
|
}
|
||||||
this.right = jQuery("<div>Bottom / Right</div>").appendTo(this.div);
|
}
|
||||||
|
// Nextmatches (and possibly other "full height" widgets) need to be adjusted
|
||||||
// Deferred object so we can wait for children
|
// Trigger the dynamic height thing to re-initialize
|
||||||
this.loading = jQuery.Deferred();
|
for (var i = 0; i < this._children.length; i++) {
|
||||||
|
if (this._children[i].dynheight) {
|
||||||
// Flag to temporarily ignore resizing
|
this._children[i].dynheight.outerNode = (i == 0 ? this.left : this.right);
|
||||||
this.stop_resize = false;
|
this._children[i].dynheight.initialized = false;
|
||||||
},
|
}
|
||||||
|
}
|
||||||
destroy: function() {
|
};
|
||||||
// Stop listening
|
et2_split.prototype.doLoadingFinished = function () {
|
||||||
this.left.next().off("mouseup");
|
_super.prototype.doLoadingFinished.call(this);
|
||||||
|
// Use a timeout to give the children a chance to finish
|
||||||
// Destroy splitter, restore children
|
var self = this;
|
||||||
this.div.trigger("destroy");
|
window.setTimeout(function () {
|
||||||
|
self._init_splitter();
|
||||||
// Destroy dynamic full-height
|
}, 1);
|
||||||
this.dynheight.free();
|
// Not done yet, but widget will let you know
|
||||||
|
return this.loading.promise();
|
||||||
this._super.apply(this, arguments);
|
};
|
||||||
|
/**
|
||||||
// Remove placeholder children
|
* Initialize the splitter UI
|
||||||
if(this._children.length == 0)
|
* Internal.
|
||||||
{
|
*/
|
||||||
this.div.empty();
|
et2_split.prototype._init_splitter = function () {
|
||||||
}
|
if (!this.isAttached())
|
||||||
this.div.remove();
|
return;
|
||||||
},
|
// Avoid trying to do anything while hidden - it ruins all the calculations
|
||||||
|
// Try again in resize()
|
||||||
/**
|
if (!this.div.is(':visible'))
|
||||||
* Tap in here to check if we have real children, because all children should be created
|
return;
|
||||||
* by this point. If there are, replace the placeholders.
|
var options = {
|
||||||
*/
|
type: this.orientation,
|
||||||
loadFromXML: function() {
|
dock: this.dock_side,
|
||||||
this._super.apply(this, arguments);
|
splitterClass: "et2_split",
|
||||||
if(this._children.length > 0)
|
outline: true,
|
||||||
{
|
eventNamespace: '.et2_split.' + this.id,
|
||||||
if(this._children[0])
|
// Default sizes, in case the preference doesn't work
|
||||||
{
|
// Splitter would normally just go to 50%, but our deferred loading
|
||||||
this.left.detach();
|
// ruins sizing for it
|
||||||
this.left = jQuery(this._children[0].getDOMNode(this._children[0]))
|
sizeTop: this.dynheight.outerNode.height() / 2,
|
||||||
.appendTo(this.div);
|
sizeLeft: this.dynheight.outerNode.width() / 2
|
||||||
}
|
};
|
||||||
if(this._children[1])
|
var widget = this;
|
||||||
{
|
//Convert pixel size to percent
|
||||||
this.right.detach();
|
var pix2per = function (_size) {
|
||||||
this.right = jQuery(this._children[1].getDOMNode(this._children[1]))
|
var per;
|
||||||
.appendTo(this.div);
|
if (widget.orientation == "v") {
|
||||||
}
|
per = _size * 100 / widget.dynheight.outerNode.width();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
// Nextmatches (and possibly other "full height" widgets) need to be adjusted
|
per = _size * 100 / widget.dynheight.outerNode.height();
|
||||||
// Trigger the dynamic height thing to re-initialize
|
}
|
||||||
for(var i = 0; i < this._children.length; i++)
|
return per.toFixed(2) + "%";
|
||||||
{
|
};
|
||||||
if(this._children[i].dynheight)
|
// Check for position preference, load it in
|
||||||
{
|
if (this.id) {
|
||||||
this._children[i].dynheight.outerNode = (i == 0 ? this.left : this.right);
|
var pref = this.egw().preference('splitter-size-' + this.id, this.egw().getAppName());
|
||||||
this._children[i].dynheight.initialized = false;
|
if (pref) {
|
||||||
}
|
if (this.orientation == "v" && pref['sizeLeft'] < this.dynheight.outerNode.width() ||
|
||||||
}
|
this.orientation == "h" && pref['sizeTop'] < this.dynheight.outerNode.height()) {
|
||||||
},
|
options = jQuery.extend(options, pref);
|
||||||
|
this.prefSize = pref[this.orientation == "v" ? 'sizeLeft' : 'sizeTop'];
|
||||||
doLoadingFinished: function() {
|
}
|
||||||
this._super.apply(this, arguments);
|
}
|
||||||
|
// If there is no preference yet, set it to half size
|
||||||
// Use a timeout to give the children a chance to finish
|
// Otherwise the right pane gets the fullsize
|
||||||
var self = this;
|
if (typeof this.prefSize == 'undefined' || !this.prefSize) {
|
||||||
window.setTimeout(function() {
|
this.prefSize = this.orientation == "v" ? options.sizeLeft : options.sizeTop;
|
||||||
self._init_splitter();
|
}
|
||||||
},1);
|
}
|
||||||
|
// Avoid double init
|
||||||
|
if (this.div.hasClass(options.splitterClass)) {
|
||||||
// Not done yet, but widget will let you know
|
this.div.trigger("destroy");
|
||||||
return this.loading.promise();
|
}
|
||||||
},
|
// Initialize splitter
|
||||||
|
this.div.splitter(options);
|
||||||
/**
|
this.div.trigger('resize', [options.sizeTop || options.sizeLeft || 0]);
|
||||||
* Initialize the splitter UI
|
// Start docked?
|
||||||
* Internal.
|
if (options.dock) {
|
||||||
*/
|
if (options.dock == "bottomDock" && Math.abs(options.sizeTop - this.div.height()) < et2_split.DOCK_TOLERANCE ||
|
||||||
_init_splitter: function() {
|
options.dock == "topDock" && options.sizeTop == 0 ||
|
||||||
if(!this.isAttached()) return;
|
!this.div.is(':visible') // Starting docked if hidden simplifies life when resizing
|
||||||
|
) {
|
||||||
// Avoid trying to do anything while hidden - it ruins all the calculations
|
this.dock();
|
||||||
// Try again in resize()
|
}
|
||||||
if(!this.div.is(':visible')) return;
|
}
|
||||||
|
// Add icon to splitter bar
|
||||||
var options = {
|
var icon = "ui-icon-grip-"
|
||||||
type: this.orientation,
|
+ (this.dock_side ? "solid" : "dotted") + "-"
|
||||||
dock: this.dock_side,
|
+ (this.orientation == "h" ? "horizontal" : "vertical");
|
||||||
splitterClass: "et2_split",
|
jQuery(document.createElement("div"))
|
||||||
outline: true,
|
.addClass("ui-icon")
|
||||||
eventNamespace: '.et2_split.'+this.id,
|
.addClass(icon)
|
||||||
|
.appendTo(this.left.next());
|
||||||
// Default sizes, in case the preference doesn't work
|
// Save preference when size changed
|
||||||
// Splitter would normally just go to 50%, but our deferred loading
|
if (this.id && this.egw().getAppName()) {
|
||||||
// ruins sizing for it
|
var self_1 = this;
|
||||||
sizeTop: this.dynheight.outerNode.height() / 2,
|
this.left.on("resize" + options.eventNamespace, function (e) {
|
||||||
sizeLeft: this.dynheight.outerNode.width() / 2
|
// Force immediate layout, so proper layout & sizes are available
|
||||||
};
|
// for resize(). Chrome defers layout, so current DOM node sizes
|
||||||
|
// are not available to widgets if they ask.
|
||||||
var widget = this;
|
var display = this.style.display;
|
||||||
//Convert percent size to pixel
|
this.style.display = 'none';
|
||||||
var per2pix = function(_size)
|
this.offsetHeight;
|
||||||
{
|
this.style.display = display;
|
||||||
var size = _size.replace("%",'');
|
if (e.namespace == options.eventNamespace.substr(1) && !self_1.isDocked()) {
|
||||||
var pix = 0;
|
// Store current position in preferences
|
||||||
if (widget.orientation == "v")
|
var size = self_1.orientation == "v" ? { sizeLeft: self_1.left.width() } : { sizeTop: self_1.left.height() };
|
||||||
{
|
self_1.prefSize = size[self_1.orientation == "v" ? 'sizeLeft' : 'sizeTop'];
|
||||||
pix = size * widget.dynheight.outerNode.width() / 100;
|
var prefInPercent = self_1.orientation == "v" ? { sizeLeft: pix2per(size.sizeLeft) } : { sizeTop: pix2per(size.sizeTop) };
|
||||||
}
|
if (parseInt(self_1.orientation == 'v' ? prefInPercent.sizeLeft : prefInPercent.sizeTop) < 100) {
|
||||||
else
|
self_1.egw().set_preference(self_1.egw().getAppName(), 'splitter-size-' + self_1.id, prefInPercent);
|
||||||
{
|
}
|
||||||
pix = size * widget.dynheight.outerNode.height() / 100;
|
}
|
||||||
}
|
// Ok, update children
|
||||||
return pix.toFixed(2);
|
self_1.iterateOver(function (widget) {
|
||||||
};
|
// Extra resize would cause stalling chrome
|
||||||
|
// as resize might confilict with bottom download bar
|
||||||
//Convert pixel size to percent
|
// in chrome which does a window resize, so better to not
|
||||||
var pix2per = function (_size)
|
// trigger second resize and leave that to an application
|
||||||
{
|
// if it is neccessary.
|
||||||
var per = 0;
|
// Above forcing is not enough for Firefox, defer
|
||||||
if (widget.orientation == "v")
|
window.setTimeout(jQuery.proxy(function () { this.resize(); }, widget), 200);
|
||||||
{
|
}, self_1, et2_IResizeable);
|
||||||
per = _size * 100 / widget.dynheight.outerNode.width();
|
});
|
||||||
}
|
}
|
||||||
else
|
this.loading.resolve();
|
||||||
{
|
};
|
||||||
per = _size * 100 / widget.dynheight.outerNode.height();
|
/**
|
||||||
}
|
* Implement the et2_IResizable interface to resize
|
||||||
return per.toFixed(2) + "%";
|
*/
|
||||||
};
|
et2_split.prototype.resize = function () {
|
||||||
|
// Avoid doing anything while hidden - check here, and init if needed
|
||||||
// Check for position preference, load it in
|
if (this.div.children().length <= 2) {
|
||||||
if(this.id)
|
this._init_splitter();
|
||||||
{
|
}
|
||||||
var pref = this.egw().preference('splitter-size-' + this.id, this.egw().getAppName());
|
if (this.dynheight && !this.stop_resize) {
|
||||||
if(pref)
|
var old_1 = { w: this.div.width(), h: this.div.height() };
|
||||||
{
|
this.dynheight.update(function (w, h) {
|
||||||
// TODO:This condition can be removed for the next release
|
if (this.orientation == "v") {
|
||||||
// because this is a correction data and supposely all new prefs size
|
this.left.height(h);
|
||||||
// are all in percent
|
this.right.height(h);
|
||||||
if (pref[Object.keys(pref)].toString().match(/%/g))
|
if (this.left.width() + this.right.width() + this.div.find('.splitter-bar').outerWidth() < this.div.width() ||
|
||||||
{
|
this.left.width() + this.right.width() - this.div.find('.splitter-bar').outerWidth() > this.div.width())
|
||||||
pref [Object.keys(pref)] = per2pix(pref [Object.keys(pref)]);
|
this.div.trigger('resize.et2_split.' + this.id, this.prefSize);
|
||||||
}
|
}
|
||||||
|
if (this.orientation == "h") {
|
||||||
if(this.orientation == "v" && pref['sizeLeft'] < this.dynheight.outerNode.width() ||
|
this.left.width(w);
|
||||||
this.orientation == "h" && pref['sizeTop'] < this.dynheight.outerNode.height())
|
this.right.width(w);
|
||||||
{
|
if (this.isDocked()) {
|
||||||
options = jQuery.extend(options, pref);
|
if (this.dock_side == "topDock") {
|
||||||
this.prefSize = pref[this.orientation == "v" ?'sizeLeft' : 'sizeTop'];
|
this.right.height(h);
|
||||||
}
|
this.left.height(0);
|
||||||
}
|
}
|
||||||
// If there is no preference yet, set it to half size
|
else {
|
||||||
// Otherwise the right pane gets the fullsize
|
this.left.height(h);
|
||||||
if (typeof this.prefSize == 'undefined' || !this.prefSize)
|
this.right.height(0);
|
||||||
{
|
}
|
||||||
this.prefSize = this.orientation == "v" ? options.sizeLeft: options.sizeTop;
|
}
|
||||||
}
|
}
|
||||||
}
|
if (w != old_1.w || h != old_1.h) {
|
||||||
|
this.div.trigger('resize.et2_split.' + this.id, this.prefSize);
|
||||||
// Avoid double init
|
}
|
||||||
if(this.div.hasClass(options.splitterClass))
|
}, this);
|
||||||
{
|
}
|
||||||
this.div.trigger("destroy");
|
};
|
||||||
}
|
et2_split.prototype.getDOMNode = function () {
|
||||||
|
return this.div[0];
|
||||||
// Initialize splitter
|
};
|
||||||
this.div.splitter(options);
|
/**
|
||||||
|
* Set splitter orientation
|
||||||
this.div.trigger('resize',[options.sizeTop || options.sizeLeft || 0]);
|
*
|
||||||
|
* @param orient String "v" or "h"
|
||||||
// Start docked?
|
*/
|
||||||
if(options.dock)
|
et2_split.prototype.set_orientation = function (orient) {
|
||||||
{
|
this.orientation = orient;
|
||||||
if(options.dock == "bottomDock" && Math.abs(options.sizeTop - this.div.height()) < et2_split.DOCK_TOLERANCE ||
|
this._init_splitter();
|
||||||
options.dock == "topDock" && options.sizeTop == 0 ||
|
};
|
||||||
!this.div.is(':visible') // Starting docked if hidden simplifies life when resizing
|
/**
|
||||||
)
|
* Set the side for docking
|
||||||
{
|
*
|
||||||
this.dock();
|
* @param dock String One of leftDock, rightDock, topDock, bottomDock
|
||||||
}
|
*/
|
||||||
}
|
et2_split.prototype.set_dock_side = function (dock) {
|
||||||
|
this.dock_side = dock;
|
||||||
// Add icon to splitter bar
|
this._init_splitter();
|
||||||
var icon = "ui-icon-grip-"
|
};
|
||||||
+ (this.dock_side ? "solid" : "dotted") + "-"
|
/**
|
||||||
+ (this.orientation == "h" ? "horizontal" : "vertical");
|
* Turn on or off resizing while dragging
|
||||||
|
*
|
||||||
jQuery(document.createElement("div"))
|
* @param outline boolean
|
||||||
.addClass("ui-icon")
|
*/
|
||||||
.addClass(icon)
|
et2_split.prototype.set_outline = function (outline) {
|
||||||
.appendTo(this.left.next());
|
this.outline = outline;
|
||||||
|
this._init_splitter();
|
||||||
// Save preference when size changed
|
};
|
||||||
if(this.id && this.egw().getAppName())
|
/**
|
||||||
{
|
* If the splitter has a dock direction set, dock it.
|
||||||
var self = this;
|
* Docking requires the dock attribute to be set.
|
||||||
this.left.on("resize"+options.eventNamespace, function(e) {
|
*/
|
||||||
|
et2_split.prototype.dock = function () {
|
||||||
// Force immediate layout, so proper layout & sizes are available
|
if (this.isDocked())
|
||||||
// for resize(). Chrome defers layout, so current DOM node sizes
|
return;
|
||||||
// are not available to widgets if they ask.
|
this.div.trigger("dock");
|
||||||
var display = this.style.display;
|
};
|
||||||
this.style.display = 'none';
|
/**
|
||||||
this.offsetHeight;
|
* If the splitter is docked, restore it to previous size
|
||||||
this.style.display = display;
|
* Docking requires the dock attribute to be set.
|
||||||
|
*/
|
||||||
if(e.namespace == options.eventNamespace.substr(1) && !self.isDocked())
|
et2_split.prototype.undock = function () {
|
||||||
{
|
this.div.trigger("undock");
|
||||||
// Store current position in preferences
|
};
|
||||||
var size = self.orientation == "v" ? {sizeLeft: self.left.width()} : {sizeTop: self.left.height()};
|
/**
|
||||||
self.prefSize = size[self.orientation == "v" ?'sizeLeft' : 'sizeTop'];
|
* Determine if the splitter is docked
|
||||||
var prefInPercent = self.orientation == "v" ?{sizeLeft:pix2per(size.sizeLeft)}:{sizeTop:pix2per(size.sizeTop)};
|
* @return boolean
|
||||||
if(parseInt(self.orientation == 'v' ? prefInPercent.sizeLeft : prefInPercent.sizeTop) < 100)
|
*/
|
||||||
{
|
et2_split.prototype.isDocked = function () {
|
||||||
self.egw().set_preference(self.egw().getAppName(), 'splitter-size-' + self.id, prefInPercent);
|
var bar = jQuery('.splitter-bar', this.div);
|
||||||
}
|
return bar.hasClass('splitter-bar-horizontal-docked') || bar.hasClass('splitter-bar-vertical-docked');
|
||||||
}
|
};
|
||||||
|
/**
|
||||||
// Ok, update children
|
* Toggle the splitter's docked state.
|
||||||
self.iterateOver(function(widget) {
|
* Docking requires the dock attribute to be set.
|
||||||
// Extra resize would cause stalling chrome
|
*/
|
||||||
// as resize might confilict with bottom download bar
|
et2_split.prototype.toggleDock = function () {
|
||||||
// in chrome which does a window resize, so better to not
|
this.div.trigger("toggleDock");
|
||||||
// trigger second resize and leave that to an application
|
};
|
||||||
// if it is neccessary.
|
// Printing
|
||||||
|
/**
|
||||||
// Above forcing is not enough for Firefox, defer
|
* Prepare for printing by stopping all the fuss
|
||||||
window.setTimeout(jQuery.proxy(function() {this.resize();},widget),200);
|
*
|
||||||
},self,et2_IResizeable);
|
*/
|
||||||
});
|
et2_split.prototype.beforePrint = function () {
|
||||||
}
|
// Resizing causes preference changes & relayouts. Don't do it.
|
||||||
|
this.stop_resize = true;
|
||||||
this.loading.resolve();
|
// Add the class, if needed
|
||||||
},
|
this.div.addClass('print');
|
||||||
|
// Don't return anything, just work normally
|
||||||
/**
|
};
|
||||||
* Implement the et2_IResizable interface to resize
|
et2_split.prototype.afterPrint = function () {
|
||||||
*/
|
this.div.removeClass('print');
|
||||||
resize: function() {
|
this.stop_resize = false;
|
||||||
// Avoid doing anything while hidden - check here, and init if needed
|
};
|
||||||
if(this.div.children().length <= 2)
|
et2_split._attributes = {
|
||||||
{
|
"orientation": {
|
||||||
this._init_splitter();
|
"name": "Orientation",
|
||||||
}
|
"description": "Horizontal or vertical (v or h)",
|
||||||
if(this.dynheight && !this.stop_resize )
|
"default": "v",
|
||||||
{
|
"type": "string"
|
||||||
var old = {w: this.div.width(), h: this.div.height()};
|
},
|
||||||
this.dynheight.update(function(w,h) {
|
"outline": {
|
||||||
if(this.orientation == "v")
|
"name": "Outline",
|
||||||
{
|
"description": "Use a 'ghosted' copy of the splitbar and does not resize the panes until the mouse button is released. Reduces flickering or unwanted re-layout during resize",
|
||||||
this.left.height(h);
|
"default": false,
|
||||||
this.right.height(h);
|
"type": "boolean"
|
||||||
if(this.left.width() + this.right.width() + this.div.find('.splitter-bar').outerWidth() < this.div.width() ||
|
},
|
||||||
this.left.width() + this.right.width()- this.div.find('.splitter-bar').outerWidth() > this.div.width())
|
"dock_side": {
|
||||||
this.div.trigger('resize.et2_split.'+this.id, this.prefSize);
|
"name": "Dock",
|
||||||
}
|
"description": "Allow the user to 'Dock' the splitbar to one side of the splitter, essentially hiding one pane and using the entire splitter area for the other pane. One of leftDock, rightDock, topDock, bottomDock.",
|
||||||
if(this.orientation == "h")
|
"default": et2_no_init,
|
||||||
{
|
"type": "string"
|
||||||
this.left.width(w);
|
},
|
||||||
this.right.width(w);
|
"width": {
|
||||||
if(this.isDocked()) {
|
"default": "100%"
|
||||||
if(this.dock_side == "topDock")
|
},
|
||||||
{
|
// Not needed
|
||||||
this.right.height(h);
|
"overflow": { "ignore": true },
|
||||||
this.left.height(0);
|
"no_lang": { "ignore": true },
|
||||||
}
|
"rows": { "ignore": true },
|
||||||
else
|
"cols": { "ignore": true }
|
||||||
{
|
};
|
||||||
this.left.height(h);
|
et2_split.DOCK_TOLERANCE = 15;
|
||||||
this.right.height(0);
|
return et2_split;
|
||||||
}
|
}(et2_core_DOMWidget_1.et2_DOMWidget));
|
||||||
}
|
et2_core_widget_1.et2_register_widget(et2_split, ["split"]);
|
||||||
}
|
//# sourceMappingURL=et2_widget_split.js.map
|
||||||
if(w != old.w || h != old.h)
|
|
||||||
{
|
|
||||||
this.div.trigger('resize.et2_split.'+this.id, this.prefSize);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getDOMNode: function() {
|
|
||||||
return this.div[0];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set splitter orientation
|
|
||||||
*
|
|
||||||
* @param orient String "v" or "h"
|
|
||||||
*/
|
|
||||||
set_orientation: function(orient) {
|
|
||||||
this.orientation = orient;
|
|
||||||
|
|
||||||
this._init_splitter();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the side for docking
|
|
||||||
*
|
|
||||||
* @param dock String One of leftDock, rightDock, topDock, bottomDock
|
|
||||||
*/
|
|
||||||
set_dock_side: function(dock) {
|
|
||||||
this.dock_side = dock;
|
|
||||||
|
|
||||||
this._init_splitter();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn on or off resizing while dragging
|
|
||||||
*
|
|
||||||
* @param outline boolean
|
|
||||||
*/
|
|
||||||
set_outline: function(outline) {
|
|
||||||
this.outline = outline;
|
|
||||||
this._init_splitter();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the splitter has a dock direction set, dock it.
|
|
||||||
* Docking requires the dock attribute to be set.
|
|
||||||
*/
|
|
||||||
dock: function() {
|
|
||||||
if(this.isDocked()) return;
|
|
||||||
this.div.trigger("dock");
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the splitter is docked, restore it to previous size
|
|
||||||
* Docking requires the dock attribute to be set.
|
|
||||||
*/
|
|
||||||
undock: function() {
|
|
||||||
this.div.trigger("undock");
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the splitter is docked
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
isDocked: function() {
|
|
||||||
var bar = jQuery('.splitter-bar',this.div);
|
|
||||||
return bar.hasClass('splitter-bar-horizontal-docked') || bar.hasClass('splitter-bar-vertical-docked');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle the splitter's docked state.
|
|
||||||
* Docking requires the dock attribute to be set.
|
|
||||||
*/
|
|
||||||
toggleDock: function() {
|
|
||||||
this.div.trigger("toggleDock");
|
|
||||||
},
|
|
||||||
|
|
||||||
// Printing
|
|
||||||
/**
|
|
||||||
* Prepare for printing by stopping all the fuss
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
beforePrint: function() {
|
|
||||||
// Resizing causes preference changes & relayouts. Don't do it.
|
|
||||||
this.stop_resize = true;
|
|
||||||
|
|
||||||
// Add the class, if needed
|
|
||||||
this.div.addClass('print');
|
|
||||||
|
|
||||||
// Don't return anything, just work normally
|
|
||||||
},
|
|
||||||
afterPrint: function() {
|
|
||||||
this.div.removeClass('print');
|
|
||||||
this.stop_resize = false;
|
|
||||||
}
|
|
||||||
});}).call(this);
|
|
||||||
|
|
||||||
et2_register_widget(et2_split, ["split"]);
|
|
460
api/js/etemplate/et2_widget_split.ts
Normal file
460
api/js/etemplate/et2_widget_split.ts
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
/**
|
||||||
|
* EGroupware eTemplate2 - Split panel
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package etemplate
|
||||||
|
* @subpackage api
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Nathan Gray
|
||||||
|
* @copyright Nathan Gray 2013
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*egw:uses
|
||||||
|
/vendor/bower-asset/jquery/dist/jquery.js;
|
||||||
|
jquery.splitter;
|
||||||
|
et2_core_baseWidget;
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {et2_DOMWidget} from "./et2_core_DOMWidget";
|
||||||
|
import {WidgetConfig, et2_register_widget} from "./et2_core_widget";
|
||||||
|
import {ClassWithAttributes} from "./et2_core_inheritance";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container widget that accepts 2 children, and puts a resize bar between them.
|
||||||
|
*
|
||||||
|
* This is the etemplate2 implementation of the traditional split pane / split panel.
|
||||||
|
* The split can be horizontal or vertical, and can be limited in size. You can also
|
||||||
|
* turn on double-click docking to minimize one of the children.
|
||||||
|
*
|
||||||
|
* @see http://methvin.com/splitter/ Uses Splitter
|
||||||
|
* @augments et2_DOMWidget
|
||||||
|
*/
|
||||||
|
class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPrint
|
||||||
|
{
|
||||||
|
static readonly _attributes : any = {
|
||||||
|
"orientation": {
|
||||||
|
"name": "Orientation",
|
||||||
|
"description": "Horizontal or vertical (v or h)",
|
||||||
|
"default": "v",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outline": {
|
||||||
|
"name": "Outline",
|
||||||
|
"description": "Use a 'ghosted' copy of the splitbar and does not resize the panes until the mouse button is released. Reduces flickering or unwanted re-layout during resize",
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"dock_side": {
|
||||||
|
"name": "Dock",
|
||||||
|
"description": "Allow the user to 'Dock' the splitbar to one side of the splitter, essentially hiding one pane and using the entire splitter area for the other pane. One of leftDock, rightDock, topDock, bottomDock.",
|
||||||
|
"default": et2_no_init,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"default": "100%"
|
||||||
|
},
|
||||||
|
// Not needed
|
||||||
|
"overflow": {"ignore": true},
|
||||||
|
"no_lang": {"ignore": true},
|
||||||
|
"rows": {"ignore": true},
|
||||||
|
"cols": {"ignore": true}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly DOCK_TOLERANCE : number = 15;
|
||||||
|
|
||||||
|
div : JQuery = null;
|
||||||
|
dynheight : et2_dynheight = null;
|
||||||
|
left : JQuery;
|
||||||
|
right : JQuery;
|
||||||
|
loading : JQueryDeferred<void>;
|
||||||
|
stop_resize : boolean;
|
||||||
|
orientation : "v" | "h";
|
||||||
|
dock_side : "leftDock" | "rightDock" | "topDock" | "bottomDock";
|
||||||
|
prefSize : number;
|
||||||
|
outline : boolean;
|
||||||
|
|
||||||
|
constructor(_parent, _attrs? : WidgetConfig, _child? : object)
|
||||||
|
{
|
||||||
|
// Call the inherited constructor
|
||||||
|
super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_split._attributes, _child || {}));
|
||||||
|
|
||||||
|
this.div = jQuery(document.createElement("div"))
|
||||||
|
.addClass('et2_split');
|
||||||
|
|
||||||
|
// Create the dynheight component which dynamically scales the inner
|
||||||
|
// container.
|
||||||
|
this.dynheight = new et2_dynheight(
|
||||||
|
(<et2_DOMWidget><unknown>this.getParent()).getDOMNode() || this.getInstanceManager().DOMContainer,
|
||||||
|
this.div, 100
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add something so we can see it - will be replaced if there's children
|
||||||
|
this.left = jQuery("<div>Top / Left</div>").appendTo(this.div);
|
||||||
|
this.right = jQuery("<div>Bottom / Right</div>").appendTo(this.div);
|
||||||
|
|
||||||
|
// Deferred object so we can wait for children
|
||||||
|
this.loading = jQuery.Deferred();
|
||||||
|
|
||||||
|
// Flag to temporarily ignore resizing
|
||||||
|
this.stop_resize = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy()
|
||||||
|
{
|
||||||
|
// Stop listening
|
||||||
|
this.left.next().off("mouseup");
|
||||||
|
|
||||||
|
// Destroy splitter, restore children
|
||||||
|
this.div.trigger("destroy");
|
||||||
|
|
||||||
|
// Destroy dynamic full-height
|
||||||
|
this.dynheight.free();
|
||||||
|
|
||||||
|
super.destroy();
|
||||||
|
|
||||||
|
// Remove placeholder children
|
||||||
|
if(this._children.length == 0)
|
||||||
|
{
|
||||||
|
this.div.empty();
|
||||||
|
}
|
||||||
|
this.div.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tap in here to check if we have real children, because all children should be created
|
||||||
|
* by this point. If there are, replace the placeholders.
|
||||||
|
*/
|
||||||
|
loadFromXML(_node)
|
||||||
|
{
|
||||||
|
super.loadFromXML(_node);
|
||||||
|
if(this._children.length > 0)
|
||||||
|
{
|
||||||
|
if(this._children[0])
|
||||||
|
{
|
||||||
|
this.left.detach();
|
||||||
|
this.left = jQuery(this._children[0].getDOMNode(this._children[0]))
|
||||||
|
.appendTo(this.div);
|
||||||
|
}
|
||||||
|
if(this._children[1])
|
||||||
|
{
|
||||||
|
this.right.detach();
|
||||||
|
this.right = jQuery(this._children[1].getDOMNode(this._children[1]))
|
||||||
|
.appendTo(this.div);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nextmatches (and possibly other "full height" widgets) need to be adjusted
|
||||||
|
// Trigger the dynamic height thing to re-initialize
|
||||||
|
for(var i = 0; i < this._children.length; i++)
|
||||||
|
{
|
||||||
|
if(this._children[i].dynheight)
|
||||||
|
{
|
||||||
|
this._children[i].dynheight.outerNode = (i == 0 ? this.left : this.right);
|
||||||
|
this._children[i].dynheight.initialized = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doLoadingFinished()
|
||||||
|
{
|
||||||
|
super.doLoadingFinished();
|
||||||
|
|
||||||
|
// Use a timeout to give the children a chance to finish
|
||||||
|
var self = this;
|
||||||
|
window.setTimeout(function() {
|
||||||
|
self._init_splitter();
|
||||||
|
},1);
|
||||||
|
|
||||||
|
// Not done yet, but widget will let you know
|
||||||
|
return this.loading.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the splitter UI
|
||||||
|
* Internal.
|
||||||
|
*/
|
||||||
|
private _init_splitter()
|
||||||
|
{
|
||||||
|
if(!this.isAttached()) return;
|
||||||
|
|
||||||
|
// Avoid trying to do anything while hidden - it ruins all the calculations
|
||||||
|
// Try again in resize()
|
||||||
|
if(!this.div.is(':visible')) return;
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
type: this.orientation,
|
||||||
|
dock: this.dock_side,
|
||||||
|
splitterClass: "et2_split",
|
||||||
|
outline: true,
|
||||||
|
eventNamespace: '.et2_split.'+this.id,
|
||||||
|
|
||||||
|
// Default sizes, in case the preference doesn't work
|
||||||
|
// Splitter would normally just go to 50%, but our deferred loading
|
||||||
|
// ruins sizing for it
|
||||||
|
sizeTop: this.dynheight.outerNode.height() / 2,
|
||||||
|
sizeLeft: this.dynheight.outerNode.width() / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
let widget = this;
|
||||||
|
|
||||||
|
//Convert pixel size to percent
|
||||||
|
let pix2per = function (_size)
|
||||||
|
{
|
||||||
|
let per;
|
||||||
|
if (widget.orientation == "v")
|
||||||
|
{
|
||||||
|
per = _size * 100 / widget.dynheight.outerNode.width();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
per = _size * 100 / widget.dynheight.outerNode.height();
|
||||||
|
}
|
||||||
|
return per.toFixed(2) + "%";
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check for position preference, load it in
|
||||||
|
if(this.id)
|
||||||
|
{
|
||||||
|
let pref = this.egw().preference('splitter-size-' + this.id, this.egw().getAppName());
|
||||||
|
if(pref)
|
||||||
|
{
|
||||||
|
if(this.orientation == "v" && pref['sizeLeft'] < this.dynheight.outerNode.width() ||
|
||||||
|
this.orientation == "h" && pref['sizeTop'] < this.dynheight.outerNode.height())
|
||||||
|
{
|
||||||
|
options = jQuery.extend(options, pref);
|
||||||
|
this.prefSize = pref[this.orientation == "v" ?'sizeLeft' : 'sizeTop'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If there is no preference yet, set it to half size
|
||||||
|
// Otherwise the right pane gets the fullsize
|
||||||
|
if (typeof this.prefSize == 'undefined' || !this.prefSize)
|
||||||
|
{
|
||||||
|
this.prefSize = this.orientation == "v" ? options.sizeLeft: options.sizeTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid double init
|
||||||
|
if(this.div.hasClass(options.splitterClass))
|
||||||
|
{
|
||||||
|
this.div.trigger("destroy");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize splitter
|
||||||
|
this.div.splitter(options);
|
||||||
|
|
||||||
|
this.div.trigger('resize',[options.sizeTop || options.sizeLeft || 0]);
|
||||||
|
|
||||||
|
// Start docked?
|
||||||
|
if(options.dock)
|
||||||
|
{
|
||||||
|
if(options.dock == "bottomDock" && Math.abs(options.sizeTop - this.div.height()) < et2_split.DOCK_TOLERANCE ||
|
||||||
|
options.dock == "topDock" && options.sizeTop == 0 ||
|
||||||
|
!this.div.is(':visible') // Starting docked if hidden simplifies life when resizing
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.dock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add icon to splitter bar
|
||||||
|
let icon = "ui-icon-grip-"
|
||||||
|
+ (this.dock_side ? "solid" : "dotted") + "-"
|
||||||
|
+ (this.orientation == "h" ? "horizontal" : "vertical");
|
||||||
|
|
||||||
|
jQuery(document.createElement("div"))
|
||||||
|
.addClass("ui-icon")
|
||||||
|
.addClass(icon)
|
||||||
|
.appendTo(this.left.next());
|
||||||
|
|
||||||
|
// Save preference when size changed
|
||||||
|
if(this.id && this.egw().getAppName())
|
||||||
|
{
|
||||||
|
let self = this;
|
||||||
|
this.left.on("resize"+options.eventNamespace, function(e) {
|
||||||
|
|
||||||
|
// Force immediate layout, so proper layout & sizes are available
|
||||||
|
// for resize(). Chrome defers layout, so current DOM node sizes
|
||||||
|
// are not available to widgets if they ask.
|
||||||
|
var display = this.style.display;
|
||||||
|
this.style.display = 'none';
|
||||||
|
this.offsetHeight;
|
||||||
|
this.style.display = display;
|
||||||
|
|
||||||
|
if(e.namespace == options.eventNamespace.substr(1) && !self.isDocked())
|
||||||
|
{
|
||||||
|
// Store current position in preferences
|
||||||
|
var size = self.orientation == "v" ? {sizeLeft: self.left.width()} : {sizeTop: self.left.height()};
|
||||||
|
self.prefSize = size[self.orientation == "v" ?'sizeLeft' : 'sizeTop'];
|
||||||
|
var prefInPercent = self.orientation == "v" ?{sizeLeft:pix2per(size.sizeLeft)}:{sizeTop:pix2per(size.sizeTop)};
|
||||||
|
if(parseInt(self.orientation == 'v' ? prefInPercent.sizeLeft : prefInPercent.sizeTop) < 100)
|
||||||
|
{
|
||||||
|
self.egw().set_preference(self.egw().getAppName(), 'splitter-size-' + self.id, prefInPercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok, update children
|
||||||
|
self.iterateOver(function(widget) {
|
||||||
|
// Extra resize would cause stalling chrome
|
||||||
|
// as resize might confilict with bottom download bar
|
||||||
|
// in chrome which does a window resize, so better to not
|
||||||
|
// trigger second resize and leave that to an application
|
||||||
|
// if it is neccessary.
|
||||||
|
|
||||||
|
// Above forcing is not enough for Firefox, defer
|
||||||
|
window.setTimeout(jQuery.proxy(function() {this.resize();}, widget),200);
|
||||||
|
},self,et2_IResizeable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement the et2_IResizable interface to resize
|
||||||
|
*/
|
||||||
|
resize()
|
||||||
|
{
|
||||||
|
// Avoid doing anything while hidden - check here, and init if needed
|
||||||
|
if(this.div.children().length <= 2)
|
||||||
|
{
|
||||||
|
this._init_splitter();
|
||||||
|
}
|
||||||
|
if(this.dynheight && !this.stop_resize )
|
||||||
|
{
|
||||||
|
let old = {w: this.div.width(), h: this.div.height()};
|
||||||
|
this.dynheight.update(function(w,h) {
|
||||||
|
if(this.orientation == "v")
|
||||||
|
{
|
||||||
|
this.left.height(h);
|
||||||
|
this.right.height(h);
|
||||||
|
if(this.left.width() + this.right.width() + this.div.find('.splitter-bar').outerWidth() < this.div.width() ||
|
||||||
|
this.left.width() + this.right.width()- this.div.find('.splitter-bar').outerWidth() > this.div.width())
|
||||||
|
this.div.trigger('resize.et2_split.'+this.id, this.prefSize);
|
||||||
|
}
|
||||||
|
if(this.orientation == "h")
|
||||||
|
{
|
||||||
|
this.left.width(w);
|
||||||
|
this.right.width(w);
|
||||||
|
if(this.isDocked()) {
|
||||||
|
if(this.dock_side == "topDock")
|
||||||
|
{
|
||||||
|
this.right.height(h);
|
||||||
|
this.left.height(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.left.height(h);
|
||||||
|
this.right.height(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(w != old.w || h != old.h)
|
||||||
|
{
|
||||||
|
this.div.trigger('resize.et2_split.'+this.id, this.prefSize);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDOMNode()
|
||||||
|
{
|
||||||
|
return this.div[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set splitter orientation
|
||||||
|
*
|
||||||
|
* @param orient String "v" or "h"
|
||||||
|
*/
|
||||||
|
set_orientation(orient)
|
||||||
|
{
|
||||||
|
this.orientation = orient;
|
||||||
|
|
||||||
|
this._init_splitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the side for docking
|
||||||
|
*
|
||||||
|
* @param dock String One of leftDock, rightDock, topDock, bottomDock
|
||||||
|
*/
|
||||||
|
set_dock_side(dock)
|
||||||
|
{
|
||||||
|
this.dock_side = dock;
|
||||||
|
|
||||||
|
this._init_splitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn on or off resizing while dragging
|
||||||
|
*
|
||||||
|
* @param outline boolean
|
||||||
|
*/
|
||||||
|
set_outline(outline)
|
||||||
|
{
|
||||||
|
this.outline = outline;
|
||||||
|
this._init_splitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the splitter has a dock direction set, dock it.
|
||||||
|
* Docking requires the dock attribute to be set.
|
||||||
|
*/
|
||||||
|
dock()
|
||||||
|
{
|
||||||
|
if(this.isDocked()) return;
|
||||||
|
this.div.trigger("dock");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the splitter is docked, restore it to previous size
|
||||||
|
* Docking requires the dock attribute to be set.
|
||||||
|
*/
|
||||||
|
undock()
|
||||||
|
{
|
||||||
|
this.div.trigger("undock");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the splitter is docked
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
isDocked()
|
||||||
|
{
|
||||||
|
var bar = jQuery('.splitter-bar',this.div);
|
||||||
|
return bar.hasClass('splitter-bar-horizontal-docked') || bar.hasClass('splitter-bar-vertical-docked');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle the splitter's docked state.
|
||||||
|
* Docking requires the dock attribute to be set.
|
||||||
|
*/
|
||||||
|
toggleDock()
|
||||||
|
{
|
||||||
|
this.div.trigger("toggleDock");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printing
|
||||||
|
/**
|
||||||
|
* Prepare for printing by stopping all the fuss
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
beforePrint()
|
||||||
|
{
|
||||||
|
// Resizing causes preference changes & relayouts. Don't do it.
|
||||||
|
this.stop_resize = true;
|
||||||
|
|
||||||
|
// Add the class, if needed
|
||||||
|
this.div.addClass('print');
|
||||||
|
|
||||||
|
// Don't return anything, just work normally
|
||||||
|
}
|
||||||
|
afterPrint()
|
||||||
|
{
|
||||||
|
this.div.removeClass('print');
|
||||||
|
this.stop_resize = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
et2_register_widget(et2_split, ["split"]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user