/*!
* Web Cabin Docker - Docking Layout Interface.
*
* Dependencies:
* JQuery 1.11.1
* JQuery-contextMenu 1.6.6
* font-awesome 4.2.0
*
* Author: Jeff Houde (lochemage@webcabin.org)
* Web: https://docker.webcabin.org/
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
* GPL v3 http://opensource.org/licenses/GPL-3.0
*
*/
/**
* @class
* The main docker instance. This manages all of the docking panels and user input.
* There should only be one instance of this, although it is not enforced.
* See {@tutorial getting-started}
*
* @constructor
* @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element to store the contents of wcDocker.
* @param {wcDocker~Options} [options] - Options for constructing the instance.
*/
function wcDocker(container, options) {
this.$outer = $(container);
this.$container = $('
');
this.$transition = $('
');
this.$loading = null;
this.$outer.append(this.$container);
this.$container.append(this.$transition);
this._canOrientTabs = true;
this._events = {};
this._root = null;
this._frameList = [];
this._floatingList = [];
this._modalList = [];
this._focusFrame = null;
this._placeholderPanel = null;
this._contextTimer = 0;
this._dirty = false;
this._splitterList = [];
this._tabList = [];
this._collapser = {};
this._dockPanelTypeList = [];
this._creatingPanel = false;
this._draggingSplitter = null;
this._draggingFrame = null;
this._draggingFrameSizer = null;
this._draggingFrameTab = null;
this._draggingFrameTopper = false;
this._draggingCustomTabFrame = null;
this._ghost = null;
this._menuTimer = 0;
this._mouseOrigin = {x: 0, y: 0};
this._resizeData = {
time: -1,
timeout: false,
delta: 150,
};
var defaultOptions = {
themePath: 'Themes',
theme: 'default',
loadingClass: 'fa fa-spinner fa-pulse',
allowContextMenu: true,
hideOnResize: false,
allowCollapse: true,
responseRate: 10
};
this._options = {};
for (var prop in defaultOptions) {
this._options[prop] = defaultOptions[prop];
}
for (var prop in options) {
this._options[prop] = options[prop];
}
this.__init();
};
/**
* Enumerated Docking positions.
* @version 3.0.0
* @enum {String}
*/
wcDocker.DOCK = {
/** A floating panel that blocks input until closed */
MODAL : 'modal',
/** A floating panel */
FLOAT : 'float',
/** Docks to the top of a target or window */
TOP : 'top',
/** Docks to the left of a target or window */
LEFT : 'left',
/** Docks to the right of a target or window */
RIGHT : 'right',
/** Docks to the bottom of a target or window */
BOTTOM : 'bottom',
/** Docks as another tabbed item along with the target */
STACKED : 'stacked'
};
/**
* Enumerated Internal events
* @version 3.0.0
* @enum {String}
*/
wcDocker.EVENT = {
/** When the panel is initialized */
INIT : 'panelInit',
/** When all panels have finished loading */
LOADED : 'dockerLoaded',
/** When the panel is updated */
UPDATED : 'panelUpdated',
/**
* When the panel has changed its visibility
* This event is called with the current visibility state as the first parameter.
*/
VISIBILITY_CHANGED : 'panelVisibilityChanged',
/** When the user begins moving any panel from its current docked position */
BEGIN_DOCK : 'panelBeginDock',
/** When the user finishes moving or docking a panel */
END_DOCK : 'panelEndDock',
/** When the user brings any panel within a tabbed frame into focus */
GAIN_FOCUS : 'panelGainFocus',
/** When the user leaves focus on any panel within a tabbed frame */
LOST_FOCUS : 'panelLostFocus',
/** When the panel is being closed */
CLOSED : 'panelClosed',
/** When a custom button is clicked, See [wcPanel.addButton]{@link wcPanel#addButton} */
BUTTON : 'panelButton',
/** When the panel has moved from floating to a docked position */
ATTACHED : 'panelAttached',
/** When the panel has moved from a docked position to floating */
DETACHED : 'panelDetached',
/**
* When the user has started moving the panel (top-left coordinates changed)
* This event is called with an object of the current {x, y} position as the first parameter.
*/
MOVE_STARTED : 'panelMoveStarted',
/**
* When the user has finished moving the panel
* This event is called with an object of the current {x, y} position as the first parameter.
*/
MOVE_ENDED : 'panelMoveEnded',
/**
* When the top-left coordinates of the panel has changed
* This event is called with an object of the current {x, y} position as the first parameter.
*/
MOVED : 'panelMoved',
/**
* When the user has started resizing the panel (width or height changed)
* This event is called with an object of the current {width, height} size as the first parameter.
*/
RESIZE_STARTED : 'panelResizeStarted',
/**
* When the user has finished resizing the panel
* This event is called with an object of the current {width, height} size as the first parameter.
*/
RESIZE_ENDED : 'panelResizeEnded',
/**
* When the panels width or height has changed
* This event is called with an object of the current {width, height} size as the first parameter.
*/
RESIZED : 'panelResized',
/** When the contents of the panel has been scrolled */
SCROLLED : 'panelScrolled',
/** When the layout is being saved, See [wcDocker.save]{@link wcDocker#save} */
SAVE_LAYOUT : 'layoutSave',
/** When the layout is being restored, See [wcDocker.restore]{@link wcDocker#restore} */
RESTORE_LAYOUT : 'layoutRestore',
/** When the current tab on a custom tab widget associated with this panel has changed, See {@link wcTabFrame} */
CUSTOM_TAB_CHANGED : 'customTabChanged',
/** When a tab has been closed on a custom tab widget associated with this panel, See {@link wcTabFrame} */
CUSTOM_TAB_CLOSED : 'customTabClosed'
};
/**
* The name of the placeholder panel.
* @constant {String}
*/
wcDocker.PANEL_PLACEHOLDER = '__wcDockerPlaceholderPanel';
/**
* Used when [adding]{@link wcDocker#addPanel} or [moving]{@link wcDocker#movePanel} a panel to designate the target location as collapsed.
* Must be used with [docking]{@link wcDocker.DOCK} positions LEFT, RIGHT, or BOTTOM only.
* @constant {String}
*/
wcDocker.COLLAPSED = '__wcDockerCollapsedPanel';
/**
* Used for the splitter bar orientation.
* @version 3.0.0
* @enum {Boolean}
*/
wcDocker.ORIENTATION = {
/** Top and Bottom panes */
VERTICAL : false,
/** Left and Right panes */
HORIZONTAL : true
};
/**
* Used to determine the position of tabbed widgets for stacked panels.
* Note: Not supported on IE8 or below.
* @version 3.0.0
* @enum {String}
*/
wcDocker.TAB = {
/** The default, puts tabs at the top of the frame */
TOP : 'top',
/** Puts tabs on the left side of the frame */
LEFT : 'left',
/** Puts tabs on the right side of the frame */
RIGHT : 'right',
/** Puts tabs on the bottom of the frame */
BOTTOM : 'bottom'
}
wcDocker.prototype = {
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Public Functions
///////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Gets, or Sets the path where all theme files can be found.
* "Themes" is the default folder path.
* @param {String} path - If supplied, will set the path where all themes can be found.
* @returns {String} - The currently assigned path.
*/
themePath: function(path) {
if (path !== undefined) {
this._options.themePath = path;
}
return this._options.themePath;
},
/**
* Gets, or Sets the current theme used by docker.
* @param {String} themeName - If supplied, will activate a theme with the given name.
* @returns {String} - The currently active theme.
*/
theme: function(themeName) {
if (themeName !== undefined) {
var $oldTheme = $('#wcTheme');
// The default theme requires no additional theme css file.
var cacheBreak = (new Date()).getTime();
var ext = themeName.indexOf('.css');
if (ext > -1) {
themeName = themeName.substring(0, ext);
}
var $link = $('');
this._options.theme = themeName;
var self = this;
$link[0].onload = function() {
$oldTheme.remove();
self.__update();
}
$('head').append($link);
}
return this._options.theme;
},
/**
* Retrieves whether panel collapsers are enabled.
* @version 3.0.0
* @returns {Boolean} - Collapsers are enabled.
*/
isCollapseEnabled: function() {
return (this._canOrientTabs && this._options.allowCollapse);
},
/**
* Registers a new docking panel type to be used later.
* @version 3.0.0
* @param {String} name - The name identifier for the new panel type.
* @param {wcDocker~registerOptions} options - An options object for describing the panel type.
* @param {Boolean} [isPrivate] - DEPRECATED: Use [options]{@link wcDocker~registerOptions} instead.
* @returns {Boolean} - Success or failure. Failure usually indicates the type name already exists.
*/
registerPanelType: function(name, optionsOrCreateFunc, isPrivate) {
var options = optionsOrCreateFunc;
if (typeof options === 'function') {
options = {
onCreate: optionsOrCreateFunc,
};
console.log("WARNING: Passing in the creation function directly to wcDocker.registerPanelType parameter 2 is now deprecated and will be removed in the next version! Please use the preferred options object instead.");
}
if (typeof isPrivate != 'undefined') {
options.isPrivate = isPrivate;
console.log("WARNING: Passing in the isPrivate flag to wcDocker.registerPanelType parameter 3 is now deprecated and will be removed in the next version! Please use the preferred options object instead.");
}
if ($.isEmptyObject(options)) {
options = null;
}
for (var i = 0; i < this._dockPanelTypeList.length; ++i) {
if (this._dockPanelTypeList[i].name === name) {
return false;
}
}
this._dockPanelTypeList.push({
name: name,
options: options,
});
var $menu = $('menu').find('menu');
$menu.append($('