quicksearch.html
361 KB
<html>
<head>
</head>
<body style="background: transparent;">
<script src="scripts/docstrap.lib.js"></script>
<script src="scripts/lunr.min.js"></script>
<script src="scripts/fulltext-search.js"></script>
<script type="text/x-docstrap-searchdb">
{"ext.jsdoc.html":{"id":"ext.jsdoc.html","title":"Source: ext.jsdoc","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: ext.jsdoc /** * A Document Object Model Element used by HTML. * @external domNode * @see http://www.w3schools.com/jsref/dom_obj_all.asp */ /** * jQuery library. Part of the listed dependencies. * * @external jQuery * @see http://jquery.com/ */ /** * A jQuery selector string. * * @typedef {String} external:jQuery~selector * @see http://api.jquery.com/category/selectors/ */ /** * A jQuery object. * * @typedef {Object} external:jQuery~Object * @see https://learn.jquery.com/using-jquery-core/jquery-object/ */ /** * jQuery contextMenu library. Part of the listed dependencies. * * @typedef {Object} external:jQuery#contextMenu * @extends jQuery * @see http://medialize.github.io/jQuery-contextMenu/docs.html/ */ /** * A jQuery contextMenu item object. * * @typedef {Object} external:jQuery#contextMenu~item * @property {String} name - The name of the menu item. * @property {external:contextMenu~onSelect} callback - A callback handler when this option has been selected. */ /** * A callback handler when a menu option has been selected. * * @callback external:jQuery#contextMenu~onSelect * @param {String} key - The triggered menu key. * @param {Object} opts - Menu event object. * @param {module:wcPanel|Boolean} panel - The target panel, if one exists. */ × Search results Close "},"base.js.html":{"id":"base.js.html","title":"Source: base.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: base.js /** @module wcBase */ define([ "dcl/dcl" ], function(dcl) { /** * Base class for all docker classes * @class module:wcBase */ return dcl(null, { /** * Returns this or the docker's options * @TODO: better looking through the parents? * @function module:wcBase#getOptions * @returns {Object|null} */ getOptions: function() { return this._options || this.docker()._options || {}; }, /** * Return an option found in this or in the docker. * @function module:wcBase#option * @param name * @param _default {Object|null} * @returns {Object|null} */ option: function(name,_default) { return this.getOptions()[name] || _default; }, /** * Class eq function * @function module:wcBase#instanceOf * @param {string} what * @param {object} [who] * @returns {boolean} */ instanceOf: function(what, who) { who = who || this; return !!(who && (who.declaredClass.indexOf(what)!=-1)); }, /** * Retrieves the main [docker]{@link module:wcDocker} instance. * @function module:wcBase#docker * @returns {module:wcDocker} - The top level docker object. */ docker: function(startNode) { var parent = startNode || this._parent; while (parent && !(parent.instanceOf('wcDocker'))) { parent = parent._parent; } return parent; }, /** * Return a module (dcl) by class name. * @function module:wcBase#__getClass * @param name {string} the class name, for instance "wcPanel", "wcSplitter" and so forth. Please see in wcDocker#defaultClasses for available class names. * @returns {object} the dcl module found in options * @private */ __getClass: function(name) { return this.getOptions()[name+'Class']; } }); }); × Search results Close "},"collapser.js.html":{"id":"collapser.js.html","title":"Source: collapser.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: collapser.js /** @module wcCollapser */ define([ "dcl/dcl", "./types", "./splitter", "./drawer", "./base" ], function (dcl, wcDocker, wcSplitter, wcDrawer, base) { /** * A collapsable container for carrying panels.<br> * * @class module:wcCollapser * @version 3.0.0 * @description A docker container for carrying its own arrangement of docked panels as a slide out drawer.<br/> * <b><i>PRIVATE<i> - Handled internally by [docker]{@link module:wcDocker} and <u>should never be constructed by the user.</u></b> */ var Module = dcl(base, { declaredClass:'wcCollapser', /** * @memberOf module:wcCollapser * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element for this drawer. * @param {module:wcSplitter|wcDocker} parent - The drawer's parent object. * @param {module:wcDocker.DOCK} position - A docking position to place this drawer. */ constructor: function (container, parent, position) { this.$container = $(container); this.$frame = null; this._position = position; this._parent = parent; this._splitter = null; this._drawer = null; this._size = 0; this._orientation = (this._position === wcDocker.DOCK.LEFT || this._position === wcDocker.DOCK.RIGHT) ? wcDocker.ORIENTATION.HORIZONTAL : wcDocker.ORIENTATION.VERTICAL; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collapses the drawer to its respective side wall. * @function module:wcCollapser#collapse */ collapse: function (instant) { this._drawer.collapse(); }, /** * Expands the drawer. * @function module:wcCollapser#expand */ expand: function () { this._drawer.expand(); }, /** * Gets whether the drawer is expanded. * @function module:wcCollapser#isExpanded * @returns {Boolean} - The current expanded state. */ isExpanded: function () { return this._drawer.isExpanded(); }, /** * The minimum size constraint for the side bar area. * @function module:wcCollapser#minSize * @returns {module:wcDocker~Size} - The minimum size. */ minSize: function () { return {x: this._size, y: this._size}; }, /** * The maximum size constraint for the side bar area. * @function module:wcCollapser#maxSize * @returns {module:wcDocker~Size} - The maximum size. */ maxSize: function () { var isHorizontal = (this._orientation === wcDocker.ORIENTATION.HORIZONTAL) ? true : false; return { x: (isHorizontal ? this._size : Infinity), y: (!isHorizontal ? this._size : Infinity) }; }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// __init: function () { this.$frame = $('<div class="wcCollapserFrame">'); this.__container(this.$container); var docker = this.docker(); this._splitter = new (this.docker().__getClass('wcSplitter'))(docker.$container, this, this._orientation); this._drawer = new (this.docker().__getClass('wcDrawer'))(docker.$transition, this._splitter, this._position); switch (this._position) { case wcDocker.DOCK.LEFT: this._splitter.pane(0, this._drawer); this._splitter.$pane[1].remove(); this._splitter.$pane[0].addClass('wcDrawer'); this._splitter.pos(0); break; case wcDocker.DOCK.RIGHT: case wcDocker.DOCK.BOTTOM: this._splitter.pane(1, this._drawer); this._splitter.$pane[0].remove(); this._splitter.$pane[1].addClass('wcDrawer'); this._splitter.pos(1); break; } this._parent.$bar.addClass('wcSplitterHidden'); }, // Updates the size of the collapser. __update: function (opt_dontMove) { this._splitter.__update(); this.__adjustSize(); }, // Adjusts the size of the collapser based on css __adjustSize: function () { if (this._drawer._frame._panelList.length) { this._size = this._drawer._frame.$tabBar.outerHeight(); } else { this._size = 0; } }, // Retrieves the bounding rect for this collapser. __rect: function () { return this._drawer.__rect(); }, // Saves the current panel configuration into a meta // object that can be used later to restore it. __save: function () { var data = {}; data.size = this._size; data.drawer = this._drawer.__save(); return data; }, // Restores a previously saved configuration. __restore: function (data, docker) { this._size = data.size; this._drawer.__restore(data.drawer, docker); this.__adjustSize(); }, // Gets, or Sets a new container for this layout. // Params: // $container If supplied, sets a new container for this layout. // parent If supplied, sets a new parent for this layout. // Returns: // JQuery collection The current container. __container: function ($container) { if (typeof $container === 'undefined') { return this.$container; } this.$container = $container; if (this.$container) { this.$container.append(this.$frame); } else { this.$frame.remove(); } return this.$container; }, // Disconnects and prepares this widget for destruction. __destroy: function () { if (this._splitter) { this._splitter.__destroy(); this._splitter = null; this._frame = null; } this.__container(null); this._parent = null; } }); return Module; }); × Search results Close "},"docker.js.html":{"id":"docker.js.html","title":"Source: docker.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: docker.js /*! * 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 * */ /** @module wcDocker */ define([ "dcl/dcl", "./types", './panel', './ghost', './splitter', './frame', './collapser', './layoutsimple', './layouttable', './tabframe', './drawer', './base', 'lodash' ], function (dcl, wcDocker, wcPanel, wcGhost, wcSplitter, wcFrame, wcCollapser, wcLayoutSimple, wcLayoutTable, wcTabFrame, wcDrawer, base,_) { /** * Default class name to module mapping, being used for default options */ var defaultClasses = { 'wcPanel': wcPanel, 'wcGhost': wcGhost, 'wcSplitter': wcSplitter, 'wcFrame': wcFrame, 'wcCollapser': wcCollapser, 'wcLayoutSimple': wcLayoutSimple, 'wcLayoutTable': wcLayoutTable, 'wcDrawer': wcDrawer, 'wcTabFrame': wcTabFrame }; /** * @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.<br> * See {@tutorial getting-started} */ var Module = dcl(base, { declaredClass: 'wcDocker', /** * * @memberOf module:wcDocker * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element to store the contents of wcDocker. * @param {module:wcDocker~Options} [options] - Options for constructing the instance. */ constructor: function (container, options) { this.$outer = $(container); this.$container = $('<div class="wcDocker">'); this.$transition = $('<div class="wcDockerTransition">'); 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._persistentList = []; this._focusFrame = null; this._placeholderPanel = null; this._contextTimer = 0; this._dirty = false; this._dirtyDontMove = 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, moveStartDelay: 300, edgeAnchorSize: 50, panelAnchorSize: '15%', detachToWidth: '50%', detachToHeight: '50%' }; this._options = {}; //replay default classes into default options for (var prop in defaultClasses) { defaultOptions[prop+'Class'] = defaultClasses[prop]; } for (var prop in defaultOptions) { this._options[prop] = defaultOptions[prop]; } for (var prop in options) { this._options[prop] = options[prop]; } this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets, or Sets the path where all theme files can be found. * "Themes" is the default folder path. * @function module:wcDocker#themePath * @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. * @function module:wcDocker#theme * @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 = $('<link id="wcTheme" rel="stylesheet" type="text/css" href="' + this._options.themePath + '/' + themeName + '.css?v=' + cacheBreak + '"/>'); 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. * @function module:wcDocker#isCollapseEnabled * @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. * @function module:wcDocker#registerPanelType * @version 3.0.0 * @param {String} name - The name identifier for the new panel type. * @param {module:wcDocker~registerOptions} options An options object for describing the panel type. * @param {Boolean} [isPrivate] - <b>DEPRECATED:</b> Use [options.isPrivate]{@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($('<menuitem label="' + name + '">')); return true; }, /** * Retrieves a list of all currently registered panel types. * @function module:wcDocker#panelTypes * @param {Boolean} includePrivate - If true, panels registered as private will also be included with this list. * @returns {String[]} - A list of panel type names. */ panelTypes: function (includePrivate) { var result = []; for (var i = 0; i < this._dockPanelTypeList.length; ++i) { if (includePrivate || !this._dockPanelTypeList[i].options.isPrivate) { result.push(this._dockPanelTypeList[i].name); } } return result; }, /** * Retrieves the options data associated with a given panel type when it was registered. * @function module:wcDocker#panelTypeInfo * @param {String} typeName - The name identifier of the panel. * @returns {module:wcDocker~registerOptions} - Registered options of the panel type, or false if the panel was not found. */ panelTypeInfo: function (typeName) { for (var i = 0; i < this._dockPanelTypeList.length; ++i) { if (this._dockPanelTypeList[i].name == typeName) { return this._dockPanelTypeList[i].options; } } return false; }, /** * Add a new docked panel to the docker instance.<br> * <b>Note:</b> It is best to use {@link wcDocker.COLLAPSED} after you have added your other docked panels, as it may ensure proper placement. * @function module:wcDocker#addPanel * @param {String} typeName - The name identifier of the panel to create. * @param {module:wcDocker.DOCK} location - The docking location to place this panel. * @param {module:wcPanel|module:wcDocker.COLLAPSED} [targetPanel] - A target panel to dock relative to, or use {@link wcDocker.COLLAPSED} to collapse it to the side or bottom. * @param {module:wcDocker~PanelOptions} [options] - Other options for panel placement. * @returns {module:wcPanel|Boolean} - The newly created panel object, or false if no panel was created. */ addPanel: function (typeName, location, targetPanel, options) { function __addPanel(panel) { if (location === wcDocker.DOCK.STACKED) { this.__addPanelGrouped(panel, targetPanel, options); } else { this.__addPanelAlone(panel, location, targetPanel, options); } if (this._placeholderPanel && panel.moveable() && location !== wcDocker.DOCK.FLOAT && location !== wcDocker.DOCK.MODAL) { if (this.removePanel(this._placeholderPanel)) { this._placeholderPanel = null; } } this.__forceUpdate(); } // Find out if we have a persistent version of this panel type first. for (var a = 0; a < this._persistentList.length; ++a) { if (this._persistentList[a]._type === typeName) { var panel = this._persistentList.splice(a, 1)[0]; __addPanel.call(this, panel); panel.__trigger(wcDocker.EVENT.PERSISTENT_OPENED); return panel; } } for (var i = 0; i < this._dockPanelTypeList.length; ++i) { if (this._dockPanelTypeList[i].name === typeName) { var panelType = this._dockPanelTypeList[i]; var panel = new (this.__getClass('wcPanel'))(this, typeName, panelType.options); panel.__container(this.$transition); var panelOptions = (panelType.options && panelType.options.options) || {}; panel._panelObject = new panelType.options.onCreate(panel, panelOptions); __addPanel.call(this, panel); return panel; } } return false; }, /** * Removes a docked panel from the window. * @function module:wcDocker#removePanel * @param {module:wcPanel} panel - The panel to remove. * @param {Boolean} dontDestroy - If true, the panel itself will not be destroyed. * @returns {Boolean} - Success or failure. */ removePanel: function (panel, dontDestroy) { if (!panel) { return false; } // Do not remove if this is the last moveable panel. var lastPanel = this.__isLastPanel(panel); var parentFrame = panel._parent; if (parentFrame && parentFrame.instanceOf('wcFrame')) { // Trigger the closing event, if any explicitely returned false, we cancel the close event. var results = panel.__trigger(wcDocker.EVENT.CLOSING); for (var i = 0; i < results.length; ++i) { if (!results[i]) { return false; } } if (dontDestroy) { // Keep the panel in a hidden transition container so as to not // destroy any event handlers that may be on it. panel.__container(this.$transition); panel._parent = null; } else { panel.__trigger(wcDocker.EVENT.CLOSED); } // If no more panels remain in this frame, remove the frame. if (!parentFrame.removePanel(panel) && !parentFrame.isCollapser()) { // If this is the last frame, create a dummy panel to take up // the space until another one is created. if (lastPanel) { this.__addPlaceholder(parentFrame); if (!dontDestroy) { panel.__destroy(); } else { panel.__trigger(wcDocker.EVENT.PERSISTENT_CLOSED); } return true; } var index = this._floatingList.indexOf(parentFrame); if (index !== -1) { this._floatingList.splice(index, 1); } index = this._frameList.indexOf(parentFrame); if (index !== -1) { this._frameList.splice(index, 1); } index = this._modalList.indexOf(parentFrame); if (index !== -1) { this._modalList.splice(index, 1); } if (this._modalList.length) { this.__focus(this._modalList[this._modalList.length - 1]); } else if (this._floatingList.length) { this.__focus(this._floatingList[this._floatingList.length - 1]); } var parentSplitter = parentFrame._parent; if (parentSplitter && parentSplitter.instanceOf('wcSplitter')) { parentSplitter.__removeChild(parentFrame); var other; if (parentSplitter.pane(0)) { other = parentSplitter.pane(0); parentSplitter._pane[0] = null; } else { other = parentSplitter.pane(1); parentSplitter._pane[1] = null; } // Keep the panel in a hidden transition container so as to not // destroy any event handlers that may be on it. other.__container(this.$transition); other._parent = null; index = this._splitterList.indexOf(parentSplitter); if (index !== -1) { this._splitterList.splice(index, 1); } var parent = parentSplitter._parent; parentContainer = parentSplitter.__container(); parentSplitter.__destroy(); if (parent && parent.instanceOf('wcSplitter')) { parent.__removeChild(parentSplitter); if (!parent.pane(0)) { parent.pane(0, other); } else { parent.pane(1, other); } } else if (parent === this) { this._root = other; other._parent = this; other.__container(parentContainer); } this.__update(); } else if (parentFrame === this._root) { this._root = null; } if (this._focusFrame === parentFrame) { this._focusFrame = null; } parentFrame.__destroy(); } if (!dontDestroy) { panel.__destroy(); } else { panel.__trigger(wcDocker.EVENT.PERSISTENT_CLOSED); } return true; } return false; }, /** * Moves a docking panel from its current location to another. * @function module:wcDocker#movePanel * @param {module:wcPanel} panel - The panel to move. * @param {module:wcDocker.DOCK} location - The new docking location of the panel. * @param {module:wcPanel|wcDocker.COLLAPSED} [targetPanel] - A target panel to dock relative to, or use {@link wcDocker.COLLAPSED} to collapse it to the side or bottom. * @param {module:wcDocker~PanelOptions} [options] - Other options for panel placement. * @returns {module:wcPanel|Boolean} - The panel that was created, or false on failure. */ movePanel: function (panel, location, targetPanel, options) { var lastPanel = this.__isLastPanel(panel); var $elem = panel.$container; if (panel._parent && panel._parent.instanceOf('wcFrame')) { $elem = panel._parent.$frame; } var offset = $elem.offset(); var width = $elem.width(); var height = $elem.height(); var parentFrame = panel._parent; var floating = false; if (parentFrame && parentFrame.instanceOf('wcFrame')) { floating = parentFrame._isFloating; // Remove the panel from the frame. for (var i = 0; i < parentFrame._panelList.length; ++i) { if (parentFrame._panelList[i] === panel) { if (parentFrame.isCollapser()) { parentFrame._curTab = -1; } else if (parentFrame._curTab >= i) { parentFrame._curTab--; } // Keep the panel in a hidden transition container so as to not // destroy any event handlers that may be on it. panel.__container(this.$transition); panel._parent = null; parentFrame._panelList.splice(i, 1); break; } } if (!parentFrame.isCollapser() && parentFrame._curTab === -1 && parentFrame._panelList.length) { parentFrame._curTab = 0; } parentFrame.__updateTabs(); parentFrame.collapse(); // If no more panels remain in this frame, remove the frame. if (!parentFrame.isCollapser() && parentFrame._panelList.length === 0) { // If this is the last frame, create a dummy panel to take up // the space until another one is created. if (lastPanel) { this.__addPlaceholder(parentFrame); } else { var index = this._floatingList.indexOf(parentFrame); if (index !== -1) { this._floatingList.splice(index, 1); } index = this._frameList.indexOf(parentFrame); if (index !== -1) { this._frameList.splice(index, 1); } var parentSplitter = parentFrame._parent; if (parentSplitter && parentSplitter.instanceOf('wcSplitter')) { parentSplitter.__removeChild(parentFrame); var other; if (parentSplitter.pane(0)) { other = parentSplitter.pane(0); parentSplitter._pane[0] = null; } else { other = parentSplitter.pane(1); parentSplitter._pane[1] = null; } if (targetPanel === parentSplitter) { targetPanel._shift = other; } // Keep the item in a hidden transition container so as to not // destroy any event handlers that may be on it. other.__container(this.$transition); other._parent = null; index = this._splitterList.indexOf(parentSplitter); if (index !== -1) { this._splitterList.splice(index, 1); } var parent = parentSplitter._parent; parentContainer = parentSplitter.__container(); parentSplitter.__destroy(); if (parent && parent.instanceOf('wcSplitter')) { parent.__removeChild(parentSplitter); if (!parent.pane(0)) { parent.pane(0, other); } else { parent.pane(1, other); } } else if (parent === this) { this._root = other; other._parent = this; other.__container(parentContainer); } this.__update(); } if (this._focusFrame === parentFrame) { this._focusFrame = null; } parentFrame.__destroy(); } } } panel.initSize(width, height); if (location === wcDocker.DOCK.STACKED) { this.__addPanelGrouped(panel, targetPanel, options); } else { this.__addPanelAlone(panel, location, targetPanel, options); } if (targetPanel == this._placeholderPanel) { this.removePanel(this._placeholderPanel); this._placeholderPanel = null; } var frame = panel._parent; if (frame && frame.instanceOf('wcFrame')) { if (frame._panelList.length === 1) { frame.pos(offset.left + width / 2 + 20, offset.top + height / 2 + 20, true); } } this.__update(true); if (frame && frame.instanceOf('wcFrame')) { if (floating !== frame._isFloating) { if (frame._isFloating) { panel.__trigger(wcDocker.EVENT.DETACHED); } else { panel.__trigger(wcDocker.EVENT.ATTACHED); } } } panel.__trigger(wcDocker.EVENT.MOVED); return panel; }, /** * Finds all instances of a given panel type. * @function module:wcDocker#findPanels * @param {String} [typeName] - The name identifier for the panel. If not supplied, all panels are retrieved. * @returns {module:wcPanel[]} - A list of all panels found of the given type. */ findPanels: function (typeName) { var result = []; for (var i = 0; i < this._frameList.length; ++i) { var frame = this._frameList[i]; for (var a = 0; a < frame._panelList.length; ++a) { var panel = frame._panelList[a]; if (!typeName || panel._type === typeName) { result.push(panel); } } } return result; }, /** * Shows the loading screen. * @function module:wcDocker#startLoading * @param {String} [label] - An optional label to display. * @param {Number} [opacity=0.4] - If supplied, assigns a custom opacity value to the loading screen. * @param {Number} [textOpacity=1] - If supplied, assigns a custom opacity value to the loading icon and text displayed. */ startLoading: function (label, opacity, textOpacity) { if (!this.$loading) { this.$loading = $('<div class="wcLoadingContainer"></div>'); this.$outer.append(this.$loading); var $background = $('<div class="wcLoadingBackground"></div>'); if (typeof opacity !== 'number') { opacity = 0.4; } $background.css('opacity', opacity); this.$loading.append($background); var $icon = $('<div class="wcLoadingIconContainer"><i class="wcLoadingIcon ' + this._options.loadingClass + '"></i></div>'); this.$loading.append($icon); if (label) { var $label = $('<span class="wcLoadingLabel">' + label + '</span>'); this.$loading.append($label); } if (typeof textOpacity !== 'number') { textOpacity = 1; } $icon.css('opacity', textOpacity); if ($label) { $label.css('opacity', textOpacity); } } }, /** * Hides the loading screen. * @function module:wcDocker#finishLoading * @param {Number} [fadeDuration=0] - The fade out duration for the loading screen. */ finishLoading: function (fadeDuration) { if (this.$loading) { if (fadeDuration > 0) { var self = this; this.$loading.fadeOut(fadeDuration, function () { self.$loading.remove(); self.$loading = null; }); } else { this.$loading.remove(); this.$loading = null; } } }, /** * Registers a global [event]{@link wcDocker.EVENT}. * @function module:wcDocker#on * @param {module:wcDocker.EVENT} eventType - The event type, can be a custom event string or a [predefined event]{@link wcDocker.EVENT}. * @param {module:wcDocker~event:onEvent} handler - A handler function to be called for the event. * @returns {Boolean} Success or failure that the event has been registered. */ on: function (eventType, handler) { if (!eventType) { return false; } if (!this._events[eventType]) { this._events[eventType] = []; } if (this._events[eventType].indexOf(handler) !== -1) { return false; } this._events[eventType].push(handler); return true; }, /** * Unregisters a global [event]{@link wcDocker.EVENT}. * @function module:wcDocker#off * @param {module:wcDocker.EVENT} eventType - The event type, can be a custom event string or a [predefined event]{@link wcDocker.EVENT}. * @param {module:wcDocker~event:onEvent} [handler] - The handler function registered with the event. If omitted, all events registered to the event type are unregistered. */ off: function (eventType, handler) { if (typeof eventType === 'undefined') { this._events = {}; } else { if (this._events[eventType]) { if (typeof handler === 'undefined') { this._events[eventType] = []; } else { for (var i = 0; i < this._events[eventType].length; ++i) { if (this._events[eventType][i] === handler) { this._events[eventType].splice(i, 1); break; } } } } } }, /** * Trigger an [event]{@link wcDocker.EVENT} on all panels. * @function module:wcDocker#trigger * @fires wcDocker~event:onEvent * @param {module:wcDocker.EVENT} eventType - The event type, can be a custom event string or a [predefined event]{@link wcDocker.EVENT}. * @param {Object} [data] - A custom data object to be passed along with the event. * @returns {Object[]} results - Returns an array with all results returned by event handlers. */ trigger: function (eventName, data) { if (!eventName) { return false; } var results = []; for (var i = 0; i < this._frameList.length; ++i) { var frame = this._frameList[i]; for (var a = 0; a < frame._panelList.length; ++a) { var panel = frame._panelList[a]; results = results.concat(panel.__trigger(eventName, data)); } } return results.concat(this.__trigger(eventName, data)); }, /** * Assigns a basic context menu to a selector element. The context * Menu is a simple list of options, no nesting or special options.<br><br> * * If you wish to use a more complex context menu, you can use * [jQuery.contextMenu]{@link http://medialize.github.io/jQuery-contextMenu/docs.html} directly. * @function module:wcDocker#basicMenu * @deprecated Renamed to [wcDocker.menu}{@link wcDocker#menu}. * @param {external:jQuery~selector} selector - A selector string that designates the elements who use this menu. * @param {external:jQuery#contextMenu~item[]|Function} itemListOrBuildFunc - An array with each context menu item in it, or a function to call that returns one. * @param {Boolean} includeDefault - If true, all default menu options will be included. */ basicMenu: function (selector, itemListOrBuildFunc, includeDefault) { console.log('WARNING: wcDocker.basicMenu is deprecated, please use wcDocker.menu instead.'); this.menu(selector, itemListOrBuildFunc, includeDefault); }, /** * Assigns a basic context menu to a selector element. The context * Menu is a simple list of options, no nesting or special options.<br><br> * * If you wish to use a more complex context menu, you can use * [jQuery.contextMenu]{@link http://medialize.github.io/jQuery-contextMenu/docs.html} directly. * @function module:wcDocker#menu * @param {external:jQuery~selector} selector - A selector string that designates the elements who use this menu. * @param {external:jQuery#contextMenu~item[]|Function} itemListOrBuildFunc - An array with each context menu item in it, or a function to call that returns one. * @param {Boolean} includeDefault - If true, all default menu options will be included. */ menu: function (selector, itemListOrBuildFunc, includeDefault) { var self = this; $.contextMenu({ selector: selector, build: function ($trigger, event) { var mouse = self.__mouse(event); var myFrame; for (var i = 0; i < self._frameList.length; ++i) { var $frame = $trigger.hasClass('wcFrame') && $trigger || $trigger.parents('.wcFrame'); if (self._frameList[i].$frame[0] === $frame[0]) { myFrame = self._frameList[i]; break; } } var isTitle = false; if ($(event.target).hasClass('wcTabScroller')) { isTitle = true; } var windowTypes = {}; for (var i = 0; i < self._dockPanelTypeList.length; ++i) { var type = self._dockPanelTypeList[i]; if (!type.options.isPrivate) { if (type.options.limit > 0) { if (self.findPanels(type.name).length >= type.options.limit) { continue; } } var icon = null; var faicon = null; var label = type.name; if (type.options) { if (type.options.faicon) { faicon = type.options.faicon; } if (type.options.icon) { icon = type.options.icon; } if (type.options.title) { label = type.options.title; } } windowTypes[type.name] = { name: label, icon: icon, faicon: faicon, className: 'wcMenuCreatePanel' }; } } var separatorIndex = 0; var finalItems = {}; var itemList = itemListOrBuildFunc; if (typeof itemListOrBuildFunc === 'function') { itemList = itemListOrBuildFunc($trigger, event); } for (var i = 0; i < itemList.length; ++i) { if ($.isEmptyObject(itemList[i])) { finalItems['sep' + separatorIndex++] = "---------"; continue; } var callback = itemList[i].callback; if (callback) { (function (listItem, callback) { listItem.callback = function (key, opts) { var panel = null; var $frame = opts.$trigger.parents('.wcFrame').first(); if ($frame.length) { for (var a = 0; a < self._frameList.length; ++a) { if ($frame[0] === self._frameList[a].$frame[0]) { panel = self._frameList[a].panel(); } } } callback(key, opts, panel); }; })(itemList[i], callback); } finalItems[itemList[i].name] = itemList[i]; } var collapseTypes = {}; var defaultCollapse = ''; if (self.isCollapseEnabled()) { var $icon = myFrame.$collapse.children('div'); if ($icon.hasClass('wcCollapseLeft')) { defaultCollapse = ' wcCollapseLeft'; } else if ($icon.hasClass('wcCollapseRight')) { defaultCollapse = ' wcCollapseRight'; } else { defaultCollapse = ' wcCollapseBottom'; } collapseTypes[wcDocker.DOCK.LEFT] = { name: wcDocker.DOCK.LEFT, faicon: 'sign-in wcCollapseLeft wcCollapsible' }; collapseTypes[wcDocker.DOCK.RIGHT] = { name: wcDocker.DOCK.RIGHT, faicon: 'sign-in wcCollapseRight wcCollapsible' }; collapseTypes[wcDocker.DOCK.BOTTOM] = { name: wcDocker.DOCK.BOTTOM, faicon: 'sign-in wcCollapseBottom wcCollapsible' }; } var items = finalItems; if (includeDefault) { if (!$.isEmptyObject(finalItems)) { items['sep' + separatorIndex++] = "---------"; } if (isTitle) { items['Close Panel'] = { name: 'Remove Panel', faicon: 'close', disabled: !myFrame.panel().closeable() }; if (self.isCollapseEnabled()) { if (!myFrame.isCollapser()) { items.fold1 = { name: 'Collapse Panel', faicon: 'sign-in' + defaultCollapse + ' wcCollapsible', items: collapseTypes, disabled: !myFrame.panel().moveable() } } else { items['Attach Panel'] = { name: 'Dock Panel', faicon: 'sign-out' + defaultCollapse + ' wcCollapsed', disabled: !myFrame.panel().moveable() } } } if (!myFrame._isFloating) { items['Detach Panel'] = { name: 'Detach Panel', faicon: 'level-up', disabled: !myFrame.panel().moveable() || !myFrame.panel().detachable() || myFrame.panel()._isPlaceholder }; } items['sep' + separatorIndex++] = "---------"; items.fold2 = { name: 'Add Panel', faicon: 'columns', items: windowTypes, disabled: !(myFrame.panel()._titleVisible && (!myFrame._isFloating || self._modalList.indexOf(myFrame) === -1)), className: 'wcMenuCreatePanel' }; } else { if (myFrame) { items['Close Panel'] = { name: 'Remove Panel', faicon: 'close', disabled: !myFrame.panel().closeable() }; if (self.isCollapseEnabled()) { if (!myFrame.isCollapser()) { items.fold1 = { name: 'Collapse Panel', faicon: 'sign-in' + defaultCollapse + ' wcCollapsible', items: collapseTypes, disabled: !myFrame.panel().moveable() } } else { items['Attach Panel'] = { name: 'Dock Panel', faicon: 'sign-out' + defaultCollapse + ' wcCollapsed', disabled: !myFrame.panel().moveable() } } } if (!myFrame._isFloating) { items['Detach Panel'] = { name: 'Detach Panel', faicon: 'level-up', disabled: !myFrame.panel().moveable() || !myFrame.panel().detachable() || myFrame.panel()._isPlaceholder }; } items['sep' + separatorIndex++] = "---------"; } items.fold2 = { name: 'Add Panel', faicon: 'columns', items: windowTypes, disabled: !(!myFrame || (!myFrame._isFloating && myFrame.panel().moveable())), className: 'wcMenuCreatePanel' }; } if (myFrame && !myFrame._isFloating && myFrame.panel().moveable()) { var rect = myFrame.__rect(); self._ghost = new (self.__getClass('wcGhost'))(rect, mouse, self); myFrame.__checkAnchorDrop(mouse, false, self._ghost, true, false, false); self._ghost.$ghost.hide(); } } return { callback: function (key, options) { if (key === 'Close Panel') { setTimeout(function () { myFrame.panel().close(); }, 10); } else if (key === 'Detach Panel') { self.movePanel(myFrame.panel(), wcDocker.DOCK.FLOAT, false); } else if (key === 'Attach Panel') { var $icon = myFrame.$collapse.children('div'); var position = wcDocker.DOCK.BOTTOM; if ($icon.hasClass('wcCollapseLeft')) { position = wcDocker.DOCK.LEFT; } else if ($icon.hasClass('wcCollapseRight')) { position = wcDocker.DOCK.RIGHT; } var opts = {}; switch (position) { case wcDocker.DOCK.LEFT: opts.w = myFrame.$frame.width(); break; case wcDocker.DOCK.RIGHT: opts.w = myFrame.$frame.width(); break; case wcDocker.DOCK.BOTTOM: opts.h = myFrame.$frame.height(); break; } var target = self._collapser[wcDocker.DOCK.LEFT]._parent.right(); myFrame.collapse(true); self.movePanel(myFrame.panel(), position, target, opts); } else if (key === wcDocker.DOCK.LEFT) { self.movePanel(myFrame.panel(), wcDocker.DOCK.LEFT, wcDocker.COLLAPSED); } else if (key === wcDocker.DOCK.RIGHT) { self.movePanel(myFrame.panel(), wcDocker.DOCK.RIGHT, wcDocker.COLLAPSED); } else if (key === wcDocker.DOCK.BOTTOM) { self.movePanel(myFrame.panel(), wcDocker.DOCK.BOTTOM, wcDocker.COLLAPSED); } else { if (self._ghost && (myFrame)) { var anchor = self._ghost.anchor(); var target = myFrame.panel(); if (anchor.item) { target = anchor.item._parent; } var newPanel = self.addPanel(key, anchor.loc, target, self._ghost.rect()); newPanel.focus(); } } }, events: { show: function (opt) { (function (items) { // Whenever them menu is shown, we update and add the faicons. // Grab all those menu items, and propogate a list with them. var menuItems = {}; var options = opt.$menu.find('.context-menu-item'); for (var i = 0; i < options.length; ++i) { var $option = $(options[i]); var $span = $option.find('span'); if ($span.length) { menuItems[$span[0].innerHTML] = $option; } } // function calls itself so that we get nice icons inside of menus as well. (function recursiveIconAdd(items) { for (var it in items) { var item = items[it]; var $menu = menuItems[item.name]; if ($menu) { var $icon = $('<div class="wcMenuIcon">'); $menu.prepend($icon); if (item.icon) { $icon.addClass(item.icon); } if (item.faicon) { $icon.addClass('fa fa-menu fa-' + item.faicon + ' fa-lg fa-fw'); } // Custom submenu arrow. if ($menu.hasClass('context-menu-submenu')) { var $expander = $('<div class="wcMenuSubMenu fa fa-caret-right fa-lg">'); $menu.append($expander); } } // Iterate through sub-menus. if (item.items) { recursiveIconAdd(item.items); } } })(items); })(items); }, hide: function (opt) { if (self._ghost) { self._ghost.destroy(); self._ghost = false; } } }, animation: {duration: 250, show: 'fadeIn', hide: 'fadeOut'}, reposition: false, autoHide: true, zIndex: 200, items: items }; } }); }, /** * Bypasses the next context menu event. * Use this during a mouse up event in which you do not want the * context menu to appear when it normally would have. * @function module:wcDocker#bypassMenu */ bypassMenu: function () { if (this._menuTimer) { clearTimeout(this._menuTimer); } for (var i in $.contextMenu.menus) { var menuSelector = $.contextMenu.menus[i].selector; $(menuSelector).contextMenu(false); } var self = this; this._menuTimer = setTimeout(function () { for (var i in $.contextMenu.menus) { var menuSelector = $.contextMenu.menus[i].selector; $(menuSelector).contextMenu(true); } self._menuTimer = null; }, 0); }, /** * Saves the current panel configuration into a serialized * string that can be used later to restore it. * @function module:wcDocker#save * @returns {String} - A serialized string that describes the current panel configuration. */ save: function () { var data = {}; data.floating = []; for (var i = 0; i < this._floatingList.length; ++i) { data.floating.push(this._floatingList[i].__save()); } data.root = this._root.__save(); if (!$.isEmptyObject(this._collapser)) { data.collapsers = { left: this._collapser[wcDocker.DOCK.LEFT].__save(), right: this._collapser[wcDocker.DOCK.RIGHT].__save(), bottom: this._collapser[wcDocker.DOCK.BOTTOM].__save() }; } return JSON.stringify(data, function (key, value) { if (value == Infinity) { return "Infinity"; } return value; }); }, /** * Restores a previously saved configuration. * @function module:wcDocker#restore * @param {String} dataString - A previously saved serialized string, See [wcDocker.save]{@link wcDocker#save}. */ restore: function (dataString) { var data = JSON.parse(dataString, function (key, value) { if (value === 'Infinity') { return Infinity; } return value; }); this.clear(); this._root = this.__create(data.root, this, this.$container); this._root.__restore(data.root, this); for (var i = 0; i < data.floating.length; ++i) { var panel = this.__create(data.floating[i], this, this.$container); panel.__restore(data.floating[i], this); } this.__forceUpdate(false); if (!$.isEmptyObject(data.collapsers) && this.isCollapseEnabled()) { this.__initCollapsers(); this._collapser[wcDocker.DOCK.LEFT].__restore(data.collapsers.left, this); this._collapser[wcDocker.DOCK.RIGHT].__restore(data.collapsers.right, this); this._collapser[wcDocker.DOCK.BOTTOM].__restore(data.collapsers.bottom, this); var self = this; setTimeout(function () { self.__forceUpdate(); }); } }, /** * Clears all contents from the docker instance. * @function module:wcDocker#clear */ clear: function () { this._root = null; // Make sure we notify all panels that they are closing. this.trigger(wcDocker.EVENT.CLOSED); for (var i = 0; i < this._splitterList.length; ++i) { this._splitterList[i].__destroy(); } for (var i = 0; i < this._frameList.length; ++i) { this._frameList[i].__destroy(); } if (!$.isEmptyObject(this._collapser)) { this._collapser[wcDocker.DOCK.LEFT].__destroy(); this._collapser[wcDocker.DOCK.RIGHT].__destroy(); this._collapser[wcDocker.DOCK.BOTTOM].__destroy(); this._collapser = {}; } while (this._frameList.length) this._frameList.pop(); while (this._floatingList.length) this._floatingList.pop(); while (this._splitterList.length) this._splitterList.pop(); this.off(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// __init: function () { var self = this; this.__compatibilityCheck(); this._root = null; this.__addPlaceholder(); // Setup our context menus. if (this._options.allowContextMenu) { this.menu('.wcFrame', [], true); } this.theme(this._options.theme); // Set up our responsive updater. this._updateId = setInterval(function () { if (self._dirty) { self._dirty = false; if (self._root) { self._root.__update(self._dirtyDontMove); } for (var i = 0; i < self._floatingList.length; ++i) { self._floatingList[i].__update(); } } }, this._options.responseRate); $(window).resize(this.__resize.bind(this)); // $('body').on('contextmenu', 'a, img', __onContextShowNormal); $('body').on('contextmenu', '.wcSplitterBar', __onContextDisable); // $('body').on('selectstart', '.wcFrameTitleBar, .wcPanelTab, .wcFrameButton', function(event) { // event.preventDefault(); // }); // Hovering over a panel creation context menu. $('body').on('mouseenter', '.wcMenuCreatePanel', __onEnterCreatePanel); $('body').on('mouseleave', '.wcMenuCreatePanel', __onLeaveCreatePanel); // Mouse move will allow you to move an object that is being dragged. $('body').on('mousemove', __onMouseMove); $('body').on('touchmove', __onMouseMove); // A catch all on mouse down to record the mouse origin position. $('body').on('mousedown', __onMouseDown); $('body').on('touchstart', __onMouseDown); $('body').on('mousedown', '.wcModalBlocker', __onMouseDownModalBlocker); $('body').on('touchstart', '.wcModalBlocker', __onMouseDownModalBlocker); // On some browsers, clicking and dragging a tab will drag it's graphic around. // Here I am disabling this as it interferes with my own drag-drop. $('body').on('mousedown', '.wcPanelTab', __onPreventDefault); $('body').on('touchstart', '.wcPanelTab', __onPreventDefault); $('body').on('mousedown', '.wcFrameButtonBar > .wcFrameButton', __onMouseSelectionBlocker); $('body').on('touchstart', '.wcFrameButtonBar > .wcFrameButton', __onMouseSelectionBlocker); // Mouse down on a frame title will allow you to move them. $('body').on('mousedown', '.wcFrameTitleBar', __onMouseDownFrameTitle); $('body').on('touchstart', '.wcFrameTitleBar', __onMouseDownFrameTitle); // Mouse down on a splitter bar will allow you to resize them. $('body').on('mousedown', '.wcSplitterBar', __onMouseDownSplitter); $('body').on('touchstart', '.wcSplitterBar', __onMouseDownSplitter); // Middle mouse button on a panel tab to close it. $('body').on('mousedown', '.wcPanelTab', __onMouseDownPanelTab); $('body').on('touchstart', '.wcPanelTab', __onMouseDownPanelTab); // Middle mouse button on a panel tab to close it. $('body').on('mouseup', '.wcPanelTab', __onReleasePanelTab); $('body').on('touchend', '.wcPanelTab', __onReleasePanelTab); // Mouse down on a panel will put it into focus. $('body').on('mousedown', '.wcLayout', __onMouseDownLayout); $('body').on('touchstart', '.wcLayout', __onMouseDownLayout); // Floating frames have resizable edges. $('body').on('mousedown', '.wcFrameEdge', __onMouseDownResizeFrame); $('body').on('touchstart', '.wcFrameEdge', __onMouseDownResizeFrame); // Create new panels. $('body').on('mousedown', '.wcCreatePanel', __onMouseDownCreatePanel); $('body').on('touchstart', '.wcCreatePanel', __onMouseDownCreatePanel); // Mouse released $('body').on('mouseup', __onMouseUp); $('body').on('touchend', __onMouseUp); // Clicking on a custom tab button. $('body').on('click', '.wcCustomTab .wcFrameButton', __onClickCustomTabButton); // Clicking on a panel frame button. $('body').on('click', '.wcFrameButtonBar > .wcFrameButton', __onClickPanelButton); // Escape key to cancel drag operations. $('body').on('keyup', __onKeyup); // on mousedown function __onMouseDown(event) { var mouse = self.__mouse(event); self._mouseOrigin.x = mouse.x; self._mouseOrigin.y = mouse.y; } // on mouseup function __onMouseUp(event) { var mouse = self.__mouse(event); if (mouse.which === 3) { return true; } $('body').removeClass('wcDisableSelection'); if (self._draggingFrame) { for (var i = 0; i < self._frameList.length; ++i) { self._frameList[i].__shadow(false); } } if (self._ghost && (self._draggingFrame || self._creatingPanel)) { var anchor = self._ghost.anchor(); if (self._draggingFrame) { if (!anchor) { if (!self._draggingFrameTab) { self._draggingFrame.panel(0); } var panel = self._draggingFrame.panel(parseInt($(self._draggingFrameTab).attr('id'))); self.movePanel(panel, wcDocker.DOCK.FLOAT, null, self._ghost.__rect()); // Dragging the entire frame. if (!self._draggingFrameTab) { var count = self._draggingFrame._panelList.length; if (count > 1 || self._draggingFrame.panel() !== self._placeholderPanel) { for (var i = 0; i < count; ++i) { self.movePanel(self._draggingFrame.panel(), wcDocker.DOCK.STACKED, panel, {tabOrientation: self._draggingFrame._tabOrientation}); } } } var frame = panel._parent; if (frame && frame.instanceOf('wcFrame')) { frame.pos(mouse.x, mouse.y + self._ghost.__rect().h / 2 - 10, true); frame._size.x = self._ghost.__rect().w; frame._size.y = self._ghost.__rect().h; } frame.__update(); self.__focus(frame); } else if (!anchor.self && anchor.loc !== undefined) { // Changing tab location on the same frame. if (anchor.tab && anchor.item._parent._parent == self._draggingFrame) { self._draggingFrame.tabOrientation(anchor.tab); } else { var index = 0; if (self._draggingFrameTab) { index = parseInt($(self._draggingFrameTab).attr('id')); } else { self._draggingFrame.panel(0); } var panel; if (anchor.item) { panel = anchor.item._parent; } // If we are dragging a tab to split its own container, find another // tab item within the same frame and split from there. if (self._draggingFrame._panelList.indexOf(panel) > -1) { // Can not split the frame if it is the only panel inside. if (self._draggingFrame._panelList.length === 1) { return; } for (var i = 0; i < self._draggingFrame._panelList.length; ++i) { if (panel !== self._draggingFrame._panelList[i]) { panel = self._draggingFrame._panelList[i]; index--; break; } } } var movingPanel = null; if (self._draggingFrameTab) { movingPanel = self._draggingFrame.panel(parseInt($(self._draggingFrameTab).attr('id'))); } else { movingPanel = self._draggingFrame.panel(); } panel = self.movePanel(movingPanel, anchor.loc, panel, self._ghost.rect()); panel._parent.panel(panel._parent._panelList.length - 1, true); // Dragging the entire frame. if (!self._draggingFrameTab) { var rect = self._ghost.rect(); if (!rect.tabOrientation) { rect.tabOrientation = self._draggingFrame.tabOrientation(); } var count = self._draggingFrame._panelList.length; if (count > 1 || self._draggingFrame.panel() !== self._placeholderPanel) { for (var i = 0; i < count; ++i) { self.movePanel(self._draggingFrame.panel(), wcDocker.DOCK.STACKED, panel, rect); } } } else { var frame = panel._parent; if (frame && frame.instanceOf('wcFrame')) { index = index + frame._panelList.length; } } var frame = panel._parent; if (frame && frame.instanceOf('wcFrame')) { frame.panel(index); } self.__focus(frame); } } } else if (self._creatingPanel) { var loc = wcDocker.DOCK.FLOAT; var target = null; if (anchor) { loc = anchor.loc; if (anchor.item) { target = anchor.item._parent; } else { target = anchor.panel; } } self.addPanel(self._creatingPanel, loc, target, self._ghost.rect()); } self._ghost.destroy(); self._ghost = null; self.trigger(wcDocker.EVENT.END_DOCK); self.__update(); } if (self._draggingSplitter) { self._draggingSplitter.$pane[0].removeClass('wcResizing'); self._draggingSplitter.$pane[1].removeClass('wcResizing'); } self._draggingSplitter = null; self._draggingFrame = null; self._draggingFrameSizer = null; self._draggingFrameTab = null; self._draggingFrameTopper = false; self._draggingCustomTabFrame = null; self._removingPanel = null; return true; } // on mousemove var lastMouseMove = new Date().getTime(); var lastMouseEvent = null; var moveTimeout = 0; var lastLButtonDown = 0; function __onMouseMove(event) { lastMouseEvent = event; var mouse = self.__mouse(event); if (mouse.which === 3 || ( !self._draggingSplitter && !self._draggingFrameSizer && !self._draggingCustomTabFrame && !self._ghost && !self._draggingFrame && !self._draggingFrameTab)) { return true; } var t = new Date().getTime(); if (t - lastMouseMove < self._options.responseRate) { if (!moveTimeout) { moveTimeout = setTimeout(function () { lastMouseMove = 0; moveTimeout = 0; __onMouseMove(lastMouseEvent); }, self._options.responseRate); } return true; } lastMouseMove = new Date().getTime(); if (self._draggingSplitter) { self._draggingSplitter.__moveBar(mouse); } else if (self._draggingFrameSizer) { var offset = self.$container.offset(); mouse.x += offset.left; mouse.y += offset.top; self._draggingFrame.__resize(self._draggingFrameSizer, mouse); self._draggingFrame.__update(); } else if (self._draggingCustomTabFrame) { if (self._draggingCustomTabFrame.moveable()) { var $hoverTab = $(event.target).hasClass('wcPanelTab') ? $(event.target) : $(event.target).parents('.wcPanelTab'); if (self._draggingFrameTab && $hoverTab && $hoverTab.length && self._draggingFrameTab !== event.target) { self._draggingFrameTab = self._draggingCustomTabFrame.moveTab(parseInt($(self._draggingFrameTab).attr('id')), parseInt($hoverTab.attr('id'))); } } } else if (self._ghost) { if (self._draggingFrame) { self._ghost.__move(mouse); var forceFloat = !(self._draggingFrame._isFloating || mouse.which === 1); var found = false; // Check anchoring with self. if (!self._draggingFrame.__checkAnchorDrop(mouse, true, self._ghost, self._draggingFrame._panelList.length > 1 && self._draggingFrameTab, self._draggingFrameTopper, !self.__isLastFrame(self._draggingFrame))) { // Introduce a delay before a panel begins movement to a new docking position. if (new Date().getTime() - lastLButtonDown < self._options.moveStartDelay) { return; } self._draggingFrame.__shadow(true); self.__focus(); if (!forceFloat) { for (var i = 0; i < self._frameList.length; ++i) { if (self._frameList[i] !== self._draggingFrame) { if (self._frameList[i].__checkAnchorDrop(mouse, false, self._ghost, true, self._draggingFrameTopper, !self.__isLastFrame(self._draggingFrame))) { self._draggingFrame.__shadow(true); return; } } } } if (self._draggingFrame.panel().detachable()) { self._ghost.anchor(mouse, null); } } else { self._draggingFrame.__shadow(false); var $target = $(document.elementFromPoint(mouse.x, mouse.y)); var $hoverTab = $target.hasClass('wcPanelTab') ? $target : $target.parents('.wcPanelTab'); if (self._draggingFrameTab && $hoverTab.length && self._draggingFrameTab !== $hoverTab[0]) { self._draggingFrameTab = self._draggingFrame.__tabMove(parseInt($(self._draggingFrameTab).attr('id')), parseInt($hoverTab.attr('id'))); } } } else if (self._creatingPanel) { self._ghost.update(mouse, !self._creatingPanelNoFloating); } } else if (self._draggingFrame && !self._draggingFrameTab) { self._draggingFrame.__move(mouse); self._draggingFrame.__update(); } return true; } // on contextmenu for a, img function __onContextShowNormal() { if (self._contextTimer) { clearTimeout(self._contextTimer); } $(".wcFrame").contextMenu(false); self._contextTimer = setTimeout(function () { $(".wcFrame").contextMenu(true); self._contextTimer = null; }, 100); return true; } // on contextmenu for .wcSplitterBar function __onContextDisable() { return false; } // on mouseenter for .wcMenuCreatePanel function __onEnterCreatePanel() { if (self._ghost) { self._ghost.$ghost.stop().fadeIn(200); } } // on mouseleave for .wcMenuCreatePanel function __onLeaveCreatePanel() { if (self._ghost) { self._ghost.$ghost.stop().fadeOut(200); } } // on mousedown for .wcModalBlocker function __onMouseDownModalBlocker(event) { // for (var i = 0; i < self._modalList.length; ++i) { // self._modalList[i].__focus(true); // } if (self._modalList.length) { self._modalList[self._modalList.length - 1].__focus(true); } } // on mousedown for .wcPanelTab function __onPreventDefault(event) { event.preventDefault(); event.returnValue = false; } // on mousedown for .wcFrameButtonBar > .wcFrameButton function __onMouseSelectionBlocker() { $('body').addClass('wcDisableSelection'); } // on click for .wcCustomTab .wcFrameButton function __onClickCustomTabButton(event) { $('body').removeClass('wcDisableSelection'); for (var i = 0; i < self._tabList.length; ++i) { var customTab = self._tabList[i]; if (customTab.$close[0] === this) { var tabIndex = customTab.tab(); customTab.removeTab(tabIndex); event.stopPropagation(); return; } if (customTab.$tabLeft[0] === this) { customTab._tabScrollPos -= customTab.$tabBar.width() / 2; if (customTab._tabScrollPos < 0) { customTab._tabScrollPos = 0; } customTab.__updateTabs(); event.stopPropagation(); return; } if (customTab.$tabRight[0] === this) { customTab._tabScrollPos += customTab.$tabBar.width() / 2; customTab.__updateTabs(); event.stopPropagation(); return; } } } // on click for .wcFrameButtonBar > .wcFrameButton function __onClickPanelButton() { $('body').removeClass('wcDisableSelection'); for (var i = 0; i < self._frameList.length; ++i) { var frame = self._frameList[i]; if (frame.$close[0] === this) { self.__closePanel(frame.panel()); return; } if (frame.$collapse[0] === this) { var $icon = frame.$collapse.children('div'); var position = wcDocker.DOCK.BOTTOM; if ($icon.hasClass('wcCollapseLeft')) { position = wcDocker.DOCK.LEFT; } else if ($icon.hasClass('wcCollapseRight')) { position = wcDocker.DOCK.RIGHT; } if (frame.isCollapser()) { // Un-collapse // var target; var opts = {}; switch (position) { case wcDocker.DOCK.LEFT: // target = frame._parent._parent.right(); opts.w = frame.$frame.width(); break; case wcDocker.DOCK.RIGHT: // target = frame._parent._parent.left(); opts.w = frame.$frame.width(); break; case wcDocker.DOCK.BOTTOM: // target = frame._parent._parent.top(); opts.h = frame.$frame.height(); break; } var target = self._collapser[wcDocker.DOCK.LEFT]._parent.right(); frame.collapse(true); self.movePanel(frame.panel(), position, target, opts); } else { // collapse. self.movePanel(frame.panel(), position, wcDocker.COLLAPSED); } self.__update(); return; } if (frame.$tabLeft[0] === this) { frame._tabScrollPos -= frame.$tabBar.width() / 2; if (frame._tabScrollPos < 0) { frame._tabScrollPos = 0; } frame.__updateTabs(); return; } if (frame.$tabRight[0] === this) { frame._tabScrollPos += frame.$tabBar.width() / 2; frame.__updateTabs(); return; } for (var a = 0; a < frame._buttonList.length; ++a) { if (frame._buttonList[a][0] === this) { var $button = frame._buttonList[a]; var result = { name: $button.data('name'), isToggled: false }; if ($button.hasClass('wcFrameButtonToggler')) { $button.toggleClass('wcFrameButtonToggled'); if ($button.hasClass('wcFrameButtonToggled')) { result.isToggled = true; } } var panel = frame.panel(); panel.buttonState(result.name, result.isToggled); panel.__trigger(wcDocker.EVENT.BUTTON, result); return; } } } } // on mouseup for .wcPanelTab function __onReleasePanelTab(event) { var mouse = self.__mouse(event); if (mouse.which !== 2) { return; } var index = parseInt($(this).attr('id')); for (var i = 0; i < self._frameList.length; ++i) { var frame = self._frameList[i]; if (frame.$tabBar[0] === $(this).parents('.wcFrameTitleBar')[0]) { var panel = frame._panelList[index]; if (self._removingPanel === panel) { self.removePanel(panel); self.__update(); } return; } } } // on mousedown for .wcSplitterBar function __onMouseDownSplitter(event) { var mouse = self.__mouse(event); if (mouse.which !== 1) { return true; } $('body').addClass('wcDisableSelection'); for (var i = 0; i < self._splitterList.length; ++i) { if (self._splitterList[i].$bar[0] === this) { self._draggingSplitter = self._splitterList[i]; self._draggingSplitter.$pane[0].addClass('wcResizing'); self._draggingSplitter.$pane[1].addClass('wcResizing'); event.preventDefault(); break; } } return true; } // on mousedown for .wcFrameTitleBar function __onMouseDownFrameTitle(event) { var mouse = self.__mouse(event); if (mouse.which === 3) { return true; } // Skip frame buttons, they are handled elsewhere (Buttons may also have a child image or span so we check parent as well); if ($(event.target).hasClass('wcFrameButton') || $(event.target).parents('.wcFrameButton').length) { return true; } lastLButtonDown = new Date().getTime(); $('body').addClass('wcDisableSelection'); for (var i = 0; i < self._frameList.length; ++i) { if (self._frameList[i].$titleBar[0] == this || self._frameList[i].$tabBar[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrame.__anchorMove(mouse); var $panelTab = $(event.target).hasClass('wcPanelTab') ? $(event.target) : $(event.target).parents('.wcPanelTab'); if ($panelTab && $panelTab.length) { var index = parseInt($panelTab.attr('id')); self._draggingFrame.panel(index, true); self._draggingFrameTab = $panelTab[0]; $(window).focus(); } // If the window is able to be docked, give it a dark shadow tint and begin the movement process var shouldMove = true; if (self._draggingFrameTab) { if ($panelTab.hasClass('wcNotMoveable')) { shouldMove = false; } } else { if (self._draggingFrame._isFloating && mouse.which === 1) { shouldMove = false; } } // if (((!$panelTab.hasClass('wcNotMoveable') && self._draggingFrameTab) || // !(self._draggingFrame.$titleBar.hasClass('wcNotMoveable') || self._draggingFrame.$tabBar.hasClass('wcNotMoveable'))) && // (!self._draggingFrame._isFloating || mouse.which !== 1 || self._draggingFrameTab)) { if (shouldMove) { // Special case to allow users to drag out only a single collapsed tab even by dragging the title bar (which normally would drag out the entire frame). if (!self._draggingFrameTab && self._draggingFrame.isCollapser()) { self._draggingFrameTab = self._draggingFrame.panel(); } self._draggingFrameTopper = $(event.target).parents('.wcFrameTopper').length > 0; var rect = self._draggingFrame.__rect(); self._ghost = new (self.__getClass('wcGhost'))(rect, mouse, self); self._draggingFrame.__checkAnchorDrop(mouse, true, self._ghost, true, self._draggingFrameTopper, !self.__isLastFrame(self._draggingFrame)); self.trigger(wcDocker.EVENT.BEGIN_DOCK); } break; } } for (var i = 0; i < self._tabList.length; ++i) { if (self._tabList[i].$tabBar[0] == this) { self._draggingCustomTabFrame = self._tabList[i]; var $panelTab = $(event.target).hasClass('wcPanelTab') ? $(event.target) : $(event.target).parents('.wcPanelTab'); if ($panelTab && $panelTab.length) { var index = parseInt($panelTab.attr('id')); self._draggingCustomTabFrame.tab(index, true); self._draggingFrameTab = $panelTab[0]; } break; } } if (self._draggingFrame) { self.__focus(self._draggingFrame); } return true; } // on mousedown for .wcLayout function __onMouseDownLayout(event) { var mouse = self.__mouse(event); if (mouse.which === 3) { return true; } for (var i = 0; i < self._frameList.length; ++i) { if (self._frameList[i].panel() && self._frameList[i].panel().layout().scene()[0] == this) { setTimeout(function () { self.__focus(self._frameList[i]); }, 10); break; } } return true; } // on mousedown for .wcFrameEdge function __onMouseDownResizeFrame(event) { var mouse = self.__mouse(event); if (mouse.which === 3) { return true; } $('body').addClass('wcDisableSelection'); for (var i = 0; i < self._frameList.length; ++i) { if (self._frameList[i]._isFloating) { if (self._frameList[i].$top[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['top']; break; } else if (self._frameList[i].$bottom[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['bottom']; break; } else if (self._frameList[i].$left[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['left']; break; } else if (self._frameList[i].$right[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['right']; break; } else if (self._frameList[i].$corner1[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['top', 'left']; break; } else if (self._frameList[i].$corner2[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['top', 'right']; break; } else if (self._frameList[i].$corner3[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['bottom', 'right']; break; } else if (self._frameList[i].$corner4[0] == this) { self._draggingFrame = self._frameList[i]; self._draggingFrameSizer = ['bottom', 'left']; break; } } } if (self._draggingFrame) { self.__focus(self._draggingFrame); } return true; } // on mousedown for .wcCreatePanel function __onMouseDownCreatePanel(event) { var mouse = self.__mouse(event); if (mouse.which !== 1) { return true; } var panelType = $(this).data('panel'); var info = self.panelTypeInfo(panelType); if (info) { var rect = { x: mouse.x - 250, y: mouse.y, w: 500, h: 500 }; $('body').addClass('wcDisableSelection'); self._ghost = new (self.__getClass('wcGhost'))(rect, mouse, self); self._ghost.update(mouse); self._ghost.anchor(mouse, self._ghost.anchor()); self._creatingPanel = panelType; self._creatingPanelNoFloating = !$(this).data('nofloating'); self.__focus(); self.trigger(wcDocker.EVENT.BEGIN_DOCK); } } // on mousedown for .wcPanelTab function __onMouseDownPanelTab(event) { var mouse = self.__mouse(event); if (mouse.which !== 2) { return true; } var index = parseInt($(this).attr('id')); for (var i = 0; i < self._frameList.length; ++i) { var frame = self._frameList[i]; if (frame.$tabBar[0] === $(this).parents('.wcFrameTitleBar')[0]) { var panel = frame._panelList[index]; if (panel && panel.closeable()) { self._removingPanel = frame._panelList[index]; } return true; } } return true; } // on keyup function __onKeyup(event) { if (event.keyCode == 27) { if (self._ghost) { self._ghost.destroy(); self._ghost = false; self.trigger(wcDocker.EVENT.END_DOCK); if (self._draggingFrame) { self._draggingFrame.__shadow(false); } self._creatingPanel = false; self._draggingSplitter = null; self._draggingFrame = null; self._draggingFrameSizer = null; self._draggingFrameTab = null; self._draggingFrameTopper = false; self._draggingCustomTabFrame = null; self._removingPanel = null; } } } }, // Test for load completion. __testLoadFinished: function () { for (var i = 0; i < this._frameList.length; ++i) { var frame = this._frameList[i]; for (var a = 0; a < frame._panelList.length; ++a) { var panel = frame._panelList[a]; // Skip if any panels are not initialized yet. if (panel._isVisible && !panel._initialized) { return; } // Skip if any panels still have a loading screen. if (panel.$loading) { return; } } } // If we reach this point, all existing panels are initialized and loaded! var self = this; setTimeout(function() { self.trigger(wcDocker.EVENT.LOADED); // Now unregister all loaded events so they do not fire again. self.off(wcDocker.EVENT.LOADED); for (var i = 0; i < self._frameList.length; ++i) { var frame = self._frameList[i]; for (var a = 0; a < frame._panelList.length; ++a) { var panel = frame._panelList[a]; panel.off(wcDocker.EVENT.LOADED); } } }, 0); }, // Test for browser compatability issues. __compatibilityCheck: function () { // Provide backward compatibility for IE8 and other such older browsers. if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }; } if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len; for (; from < len; from++) { if (from in this && this[from] === elt) return from; } return -1; }; } // Check if the browser supports transformations. If not, we cannot rotate tabs or collapse panels. var ie = (function () { var v = 3; var div = document.createElement('div'); var all = div.getElementsByTagName('i'); while ( div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->', all[0] ); return v > 4 ? v : undefined; }()); if (ie < 9) { this._canOrientTabs = false; } else { function getSupportedTransform() { var prefixes = 'transform WebkitTransform MozTransform OTransform msTransform'.split(' '); var div = document.createElement('div'); for (var i = 0; i < prefixes.length; i++) { if (div && div.style[prefixes[i]] !== undefined) { return true; } } return false; } this._canOrientTabs = getSupportedTransform(); } // Check if we are running on a mobile device so we can alter themes accordingly. var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); $('body').addClass(isMobile ? "wcMobile" : "wcDesktop"); }, /* * Searches docked panels and splitters for a container that is within any static areas. */ __findInner: function () { function isPaneStatic(pane) { return !!(pane && (pane.instanceOf('wcFrame') && pane.panel() && !pane.panel().moveable()) || (pane.instanceOf('wcCollapser'))); } var parent = this._root; while (parent) { if (parent.instanceOf('wcSplitter')) { var pane0 = isPaneStatic(parent._pane[0]); var pane1 = isPaneStatic(parent._pane[1]); if (pane0 && !pane1) { parent = parent._pane[1]; } else if (pane1 && !pane0) { parent = parent._pane[0]; } else if (!pane0 && !pane1) { break; } } else { break; } } return parent; }, /* * Sets up the collapsers for the panel.<br> * <b>Note: </b> This should be called AFTER you have initialized your panel layout, but BEFORE you add * any static panels that you do not wish to be overlapped by the collapsers (such as file menu panels). */ __initCollapsers: function () { // Initialize collapsers if it is enabled and not already initialized. if (!this.isCollapseEnabled() || !$.isEmptyObject(this._collapser)) { return; } var parent = this.__findInner(); function __createCollapser(location) { this._collapser[location] = this.__addCollapser(location, parent); parent = this._collapser[location]._parent; this._frameList.push(this._collapser[location]._drawer._frame); } __createCollapser.call(this, wcDocker.DOCK.LEFT); __createCollapser.call(this, wcDocker.DOCK.RIGHT); __createCollapser.call(this, wcDocker.DOCK.BOTTOM); var self = this; setTimeout(function () { self.__update(); }); }, // Updates the sizing of all panels inside this window. __update: function (opt_dontMove) { this._dirty = true; this._dirtyDontMove = opt_dontMove; }, // Forces an update, regardless of the response rate. __forceUpdate: function (opt_dontMove) { this._dirty = false; if (this._root) { this._root.__update(opt_dontMove); } for (var i = 0; i < this._floatingList.length; ++i) { this._floatingList[i].__update(); } }, __orderPanels: function () { if (this._floatingList.length === 0) { return; } var from = this._floatingList.indexOf(this._focusFrame); var to = this._floatingList.length - 1; this._floatingList.splice(to, 0, this._floatingList.splice(from, 1)[0]); var length = this._floatingList.length; var start = 10; var step = 5; var index = 0; var panel; for (var i = 0; i < this._floatingList.length; ++i) { panel = this._floatingList[i]; if (panel) { var layer = start + (i * step); panel.$frame.css('z-index', layer); panel.__trigger(wcDocker.EVENT.ORDER_CHANGED, layer); } } }, // Retrieve mouse or touch position. __mouse: function (event) { if (event.originalEvent && (event.originalEvent.touches || event.originalEvent.changedTouches)) { var touch = event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]; return { x: touch.clientX, y: touch.clientY, which: 1 }; } return { x: event.clientX || event.pageX, y: event.clientY || event.pageY, which: event.which || 1 }; }, // On window resized event. __resize: function (event) { this._resizeData.time = new Date(); if (!this._resizeData.timeout) { this._resizeData.timeout = true; setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); this.__trigger(wcDocker.EVENT.RESIZE_STARTED); } this.__trigger(wcDocker.EVENT.RESIZED); this.__update(false); }, // On window resize event ended. __resizeEnd: function () { if (new Date() - this._resizeData.time < this._resizeData.delta) { setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); } else { this._resizeData.timeout = false; this.__trigger(wcDocker.EVENT.RESIZE_ENDED); } }, // Brings a floating window to the top. // Params: // frame The frame to focus. // flash Whether to flash the frame. __focus: function (frame, flash) { var differentFrames = this._focusFrame != frame; if (this._focusFrame) { if (this._focusFrame._isFloating) { this._focusFrame.$frame.removeClass('wcFloatingFocus'); } var oldFocusFrame = this._focusFrame; this._focusFrame = null; oldFocusFrame.__trigger(wcDocker.EVENT.LOST_FOCUS); if (oldFocusFrame.isCollapser() && differentFrames) { oldFocusFrame.collapse(); oldFocusFrame.panel(-1); } } this._focusFrame = frame; if (this._focusFrame) { if (this._focusFrame._isFloating) { this._focusFrame.$frame.addClass('wcFloatingFocus'); if (differentFrames) { $('body').append(this._focusFrame.$frame); } } this._focusFrame.__focus(flash); this._focusFrame.__trigger(wcDocker.EVENT.GAIN_FOCUS); } this.__orderPanels(); }, // Triggers an event exclusively on the docker and none of its panels. // Params: // eventName The name of the event. // data A custom data parameter to pass to all handlers. __trigger: function (eventName, data) { if (!eventName) { return; } var results = []; if (this._events[eventName]) { var events = this._events[eventName].slice(0); for (var i = 0; i < events.length; ++i) { results.push(events[i].call(this, data)); } } return results; }, // Checks a given panel to see if it is the final remaining // moveable panel in the docker. // Params: // panel The panel. // Returns: // true The panel is the last. // false The panel is not the last. __isLastPanel: function (panel) { for (var i = 0; i < this._frameList.length; ++i) { var testFrame = this._frameList[i]; if (testFrame._isFloating || testFrame.isCollapser()) { continue; } for (var a = 0; a < testFrame._panelList.length; ++a) { var testPanel = testFrame._panelList[a]; if (testPanel !== panel && testPanel.moveable()) { return false; } } } return true; }, // Checks a given frame to see if it is the final remaining // moveable frame in the docker. // Params: // frame The frame. // Returns: // true The panel is the last. // false The panel is not the last. __isLastFrame: function (frame) { for (var i = 0; i < this._frameList.length; ++i) { var testFrame = this._frameList[i]; if (testFrame._isFloating || testFrame === frame || testFrame.isCollapser()) { continue; } for (var a = 0; a < testFrame._panelList.length; ++a) { var testPanel = testFrame._panelList[a]; if (testPanel.moveable()) { return false; } } } return true; }, // For restore, creates the appropriate object type. __create: function (data, parent, $container) { switch (data.type) { case 'wcSplitter': var splitter = new (this.__getClass('wcSplitter'))($container, parent, data.horizontal); splitter.scrollable(0, false, false); splitter.scrollable(1, false, false); return splitter; case 'wcFrame': var frame = new (this.__getClass('wcFrame'))($container, parent, data.floating); this._frameList.push(frame); if (data.floating) { this._floatingList.push(frame); } return frame; case 'wcPanel': if (data.panelType === wcDocker.PANEL_PLACEHOLDER) { if (!this._placeholderPanel) { this._placeholderPanel = new (this.__getClass('wcPanel'))(parent, wcDocker.PANEL_PLACEHOLDER, {}); this._placeholderPanel._isPlaceholder = true; this._placeholderPanel.__container(this.$transition); this._placeholderPanel._panelObject = new function (myPanel) { myPanel.title(false); myPanel.closeable(false); }(this._placeholderPanel); this._placeholderPanel.__container($container); } return this._placeholderPanel; } else { for (var i = 0; i < this._dockPanelTypeList.length; ++i) { if (this._dockPanelTypeList[i].name === data.panelType) { var panel = new (this.__getClass('wcPanel'))(parent, data.panelType, this._dockPanelTypeList[i].options); panel.__container(this.$transition); var options = (this._dockPanelTypeList[i].options && this._dockPanelTypeList[i].options.options) || {}; panel._panelObject = new this._dockPanelTypeList[i].options.onCreate(panel, options); panel.__container($container); break; } } return panel; } } return null; }, // Attempts to insert a given dock panel into an already existing frame. // If insertion is not possible for any reason, the panel will be // placed in its own frame instead. // Params: // panel The panel to insert. // targetPanel An optional panel to 'split', if not supplied the // new panel will split the center window. __addPanelGrouped: function (panel, targetPanel, options) { var frame = targetPanel; if (frame && frame.instanceOf('wcPanel')) { frame = targetPanel._parent; } if (frame && frame.instanceOf('wcFrame')) { if (options && options.tabOrientation) { frame.tabOrientation(options.tabOrientation); } frame.addPanel(panel); return; } // If we did not manage to find a place for this panel, last resort is to put it in its own frame. this.__addPanelAlone(panel, wcDocker.DOCK.LEFT, targetPanel, options); }, // Creates a new frame for the panel and then attaches it // to the window. // Params: // panel The panel to insert. // location The desired location for the panel. // targetPanel An optional panel to 'split', if not supplied the // new panel will split the center window. __addPanelAlone: function (panel, location, targetPanel, options) { if (targetPanel && targetPanel._shift) { var target = targetPanel; targetPanel = targetPanel._shift; target._shift = undefined; } if (options) { var width = this.$container.width(); var height = this.$container.height(); if (options.hasOwnProperty('x')) { options.x = this.__stringToPixel(options.x, width); } if (options.hasOwnProperty('y')) { options.y = this.__stringToPixel(options.y, height); } if (!options.hasOwnProperty('w')) { options.w = panel.initSize().x; } if (!options.hasOwnProperty('h')) { options.h = panel.initSize().y; } options.w = this.__stringToPixel(options.w, width); options.h = this.__stringToPixel(options.h, height); panel._size.x = options.w; panel._size.y = options.h; } // If we are collapsing the panel, put it into the collapser. if (targetPanel === wcDocker.COLLAPSED) { this.__initCollapsers(); if (this._collapser[location]) { targetPanel = this._collapser[location]._drawer._frame.addPanel(panel); var self = this; setTimeout(function () { self.__update(); }); return panel; } else { console.log('ERROR: Attempted to collapse panel "' + panel._type + '" to invalid location: ' + location); return false; } } // Floating windows need no placement. if (location === wcDocker.DOCK.FLOAT || location === wcDocker.DOCK.MODAL) { var frame = new (this.__getClass('wcFrame'))(this.$container, this, true); if (options && options.tabOrientation) { frame.tabOrientation(options.tabOrientation); } this._frameList.push(frame); this._floatingList.push(frame); this.__focus(frame); frame.addPanel(panel); frame.pos(panel._pos.x, panel._pos.y, false); if (location === wcDocker.DOCK.MODAL) { frame.$modalBlocker = $('<div class="wcModalBlocker"></div>'); frame.$frame.prepend(frame.$modalBlocker); panel.moveable(false); frame.$frame.addClass('wcModal'); this._modalList.push(frame); } if (options) { var pos = frame.pos(undefined, undefined, true); if (options.hasOwnProperty('x')) { pos.x = options.x + options.w / 2; } if (options.hasOwnProperty('y')) { pos.y = options.y + options.h / 2; } frame.pos(pos.x, pos.y, true); frame._size = { x: options.w, y: options.h }; } this.__orderPanels(); return; } if (targetPanel) { var parentSplitter = targetPanel._parent; var splitterChild = targetPanel; while (parentSplitter && !(parentSplitter.instanceOf('wcSplitter') || parentSplitter.instanceOf('wcDocker'))) { splitterChild = parentSplitter; parentSplitter = parentSplitter._parent; } if (parentSplitter && parentSplitter.instanceOf('wcSplitter')) { var splitter; var left = parentSplitter.pane(0); var right = parentSplitter.pane(1); var size = { x: -1, y: -1 }; if (left === splitterChild) { splitter = new (this.__getClass('wcSplitter'))(this.$transition, parentSplitter, location !== wcDocker.DOCK.BOTTOM && location !== wcDocker.DOCK.TOP); size.x = parentSplitter.$pane[0].width(); size.y = parentSplitter.$pane[0].height(); parentSplitter.pane(0, splitter); } else { splitter = new (this.__getClass('wcSplitter'))(this.$transition, parentSplitter, location !== wcDocker.DOCK.BOTTOM && location !== wcDocker.DOCK.TOP); size.x = parentSplitter.$pane[1].width(); size.y = parentSplitter.$pane[1].height(); parentSplitter.pane(1, splitter); } if (splitter) { splitter.scrollable(0, false, false); splitter.scrollable(1, false, false); if (!options) { options = { w: panel._size.x, h: panel._size.y }; } if (options) { if (options.w < 0) { options.w = size.x / 2; } if (options.h < 0) { options.h = size.y / 2; } switch (location) { case wcDocker.DOCK.LEFT: splitter.pos(options.w / size.x); break; case wcDocker.DOCK.RIGHT: splitter.pos(1.0 - (options.w / size.x)); break; case wcDocker.DOCK.TOP: splitter.pos(options.h / size.y); break; case wcDocker.DOCK.BOTTOM: splitter.pos(1.0 - (options.h / size.y)); break; } } else { splitter.pos(0.5); } frame = new (this.__getClass('wcFrame'))(this.$transition, splitter, false); this._frameList.push(frame); if (location === wcDocker.DOCK.LEFT || location === wcDocker.DOCK.TOP) { splitter.pane(0, frame); splitter.pane(1, splitterChild); } else { splitter.pane(0, splitterChild); splitter.pane(1, frame); } frame.addPanel(panel); } return; } } var parent = this; var $container = this.$container; var frame = new (this.__getClass('wcFrame'))(this.$transition, parent, false); this._frameList.push(frame); if (!parent._root) { parent._root = frame; frame.__container($container); } else { var splitter = new (this.__getClass('wcSplitter'))($container, parent, location !== wcDocker.DOCK.BOTTOM && location !== wcDocker.DOCK.TOP); if (splitter) { frame._parent = splitter; splitter.scrollable(0, false, false); splitter.scrollable(1, false, false); var size = { x: $container.width(), y: $container.height() }; if (!options) { splitter.__findBestPos(); } else { if (options.w < 0) { options.w = size.x / 2; } if (options.h < 0) { options.h = size.y / 2; } switch (location) { case wcDocker.DOCK.LEFT: splitter.pos(options.w / size.x); break; case wcDocker.DOCK.RIGHT: splitter.pos(1.0 - (options.w / size.x)); break; case wcDocker.DOCK.TOP: splitter.pos(options.h / size.y); break; case wcDocker.DOCK.BOTTOM: splitter.pos(1.0 - (options.h / size.y)); break; } } if (location === wcDocker.DOCK.LEFT || location === wcDocker.DOCK.TOP) { splitter.pane(0, frame); splitter.pane(1, parent._root); } else { splitter.pane(0, parent._root); splitter.pane(1, frame); } parent._root = splitter; } } frame.addPanel(panel); }, __addCollapser: function (location, parent) { var collapser = null; if (parent) { var parentSplitter = parent._parent; var splitterChild = parent; var _d = dcl; while (parentSplitter && !(parentSplitter.instanceOf('wcSplitter') || parentSplitter.instanceOf('wcDocker'))){ splitterChild = parentSplitter; parentSplitter = parentSplitter._parent; } var splitter = new (this.__getClass('wcSplitter'))(this.$transition, parentSplitter, location !== wcDocker.DOCK.BOTTOM && location !== wcDocker.DOCK.TOP); if (parentSplitter && parentSplitter.instanceOf('wcDocker')){ this._root = splitter; splitter.__container(this.$container); } if (parentSplitter && parentSplitter.instanceOf('wcSplitter')) { var left = parentSplitter.left(); var right = parentSplitter.right(); var size = { x: -1, y: -1 }; if (left === splitterChild) { size.x = parentSplitter.$pane[0].width(); size.y = parentSplitter.$pane[0].height(); parentSplitter.pane(0, splitter); } else { splitter = new (this.__getClass('wcSplitter'))(this.$transition, parentSplitter, location !== wcDocker.DOCK.BOTTOM && location !== wcDocker.DOCK.TOP); size.x = parentSplitter.$pane[1].width(); size.y = parentSplitter.$pane[1].height(); parentSplitter.pane(1, splitter); } } if (splitter) { splitter.scrollable(0, false, false); splitter.scrollable(1, false, false); collapser = new (this.__getClass('wcCollapser'))(this.$transition, splitter, location); switch (location) { case wcDocker.DOCK.TOP: case wcDocker.DOCK.LEFT: splitter.pos(0); break; case wcDocker.DOCK.BOTTOM: case wcDocker.DOCK.RIGHT: splitter.pos(1); break; } if (location === wcDocker.DOCK.LEFT || location === wcDocker.DOCK.TOP) { splitter.pane(0, collapser); splitter.pane(1, splitterChild); } else { splitter.pane(0, splitterChild); splitter.pane(1, collapser); } } } return collapser; }, // Adds the placeholder panel as needed __addPlaceholder: function (targetPanel) { if (this._placeholderPanel) { console.log('WARNING: wcDocker creating placeholder panel when one already exists'); } this._placeholderPanel = new (this.__getClass('wcPanel'))(this, wcDocker.PANEL_PLACEHOLDER, {}); this._placeholderPanel._isPlaceholder = true; this._placeholderPanel.__container(this.$transition); this._placeholderPanel._panelObject = new function (myPanel) { myPanel.title(false); myPanel.closeable(false); }(this._placeholderPanel); if (targetPanel) { this.__addPanelGrouped(this._placeholderPanel, targetPanel); } else { this.__addPanelAlone(this._placeholderPanel, wcDocker.DOCK.TOP); } this.__update(); }, __closePanel: function(panel) { // If the panel is persistent, instead of destroying it, add it to a persistent list instead. var dontDestroy = false; var panelOptions = this.panelTypeInfo(panel._type); if (panelOptions && panelOptions.isPersistent) { dontDestroy = true; this._persistentList.push(panel); } this.removePanel(panel, dontDestroy); this.__update(); }, // Converts a potential string value to a percentage. __stringToPercent: function (value, size) { if (typeof value === 'string') { if (value.indexOf('%', value.length - 1) !== -1) { return parseFloat(value) / 100; } else if (value.indexOf('px', value.length - 2) !== -1) { return parseFloat(value) / size; } } return parseFloat(value); }, // Converts a potential string value to a pixel value. __stringToPixel: function (value, size) { if (typeof value === 'string') { if (value.indexOf('%', value.length - 1) !== -1) { return (parseFloat(value) / 100) * size; } else if (value.indexOf('px', value.length - 2) !== -1) { return parseFloat(value); } } return parseFloat(value); } }); //merge types into module for(var prop in wcDocker){ Module[prop] = wcDocker[prop]; } //track and expose default classes Module.defaultClasses = defaultClasses; return Module; }); × Search results Close "},"types.js.html":{"id":"types.js.html","title":"Source: types.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: types.js define([], function () { //stub var wcDocker = {}; /** * Enumerated Docking positions. * @member module:wcDocker.DOCK * @property {String} MODAL="modal" - A floating panel that blocks input until closed * @property {String} FLOAT="float" - A floating panel * @property {String} TOP="top" - Docks to the top of a target or window * @property {String} LEFT="left" - Docks to the left of a target or window * @property {String} RIGHT="right" - Docks to the right of a target or window * @property {String} BOTTOM="bottom" - Docks to the bottom of a target or window * @property {String} STACKED="stacked" - Docks as another tabbed item along with the target * @version 3.0.0 * @const */ wcDocker.DOCK = { MODAL: 'modal', FLOAT: 'float', TOP: 'top', LEFT: 'left', RIGHT: 'right', BOTTOM: 'bottom', STACKED: 'stacked' }; /** * Enumerated Layout wcDocker. * @member module:wcDocker.LAYOUT * @property {String} SIMPLE="wcLayoutSimple" - Contains a single div item without management using a {@link module:wcLayoutSimple}, it is up to you to populate it however you wish. * @property {String} TABLE="wcLayoutTable" - Manages a table grid layout using {@link module:wcLayoutTable}, this is the default layout used if none is specified. * @version 3.0.0 * @const */ wcDocker.LAYOUT = { SIMPLE: 'wcLayoutSimple', TABLE: 'wcLayoutTable' }; /** * Enumerated Internal events * @member module:wcDocker.EVENT * @property {String} INIT="panelInit" - When the panel is initialized * @property {String} LOADED="dockerLoaded" - When all panels have finished loading * @property {String} UPDATED="panelUpdated" - When the panel is updated * @property {String} VISIBILITY_CHANGED="panelVisibilityChanged" - When the panel has changed its visibility<br>This event is called with the current visibility state as the first parameter * @property {String} BEGIN_DOCK="panelBeginDock" - When the user begins moving any panel from its current docked position * @property {String} END_DOCK="panelEndDock" - When the user finishes moving or docking a panel * @property {String} GAIN_FOCUS="panelGainFocus" - When the user brings any panel within a tabbed frame into focus * @property {String} LOST_FOCUS="panelLostFocus" - When the user leaves focus on any panel within a tabbed frame * @property {String} CLOSING="panelClosing" - When the panel is about to be closed, but before it closes. If any event handler returns a falsey value, the close action will be canceled. * @property {String} CLOSED="panelClosed" - When the panel is being closed * @property {String} PERSISTENT_CLOSED="panelPersistentClosed" - When a persistent panel is being hidden * @property {String} PERSISTENT_OPENED="panelPersistentOpened" - When a persistent panel is being shown * @property {String} BUTTON="panelButton" - When a custom button is clicked, See [wcPanel.addButton]{@link module:wcPanel~addButton} * @property {String} ATTACHED="panelAttached" - When the panel has moved from floating to a docked position * @property {String} DETACHED="panelDetached" - When the panel has moved from a docked position to floating * @property {String} MOVE_STARTED="panelMoveStarted" - When the user has started moving the panel (top-left coordinates changed)<br>This event is called with an object of the current {x, y} position as the first parameter * @property {String} MOVE_ENDED="panelMoveEnded" - When the user has finished moving the panel<br>This event is called with an object of the current {x, y} position as the first parameter * @property {String} MOVED="panelMoved" - When the top-left coordinates of the panel has changed<br>This event is called with an object of the current {x, y} position as the first parameter * @property {String} RESIZE_STARTED="panelResizeStarted" - When the user has started resizing the panel (width or height changed)<br>This event is called with an object of the current {width, height} size as the first parameter * @property {String} RESIZE_ENDED="panelResizeEnded" - When the user has finished resizing the panel<br>This event is called with an object of the current {width, height} size as the first parameter * @property {String} RESIZED="panelResized" - When the panels width or height has changed<br>This event is called with an object of the current {width, height} size as the first parameter * @property {String} ORDER_CHANGED="panelOrderChanged" - This only happens with floating windows when the order of the windows have changed. * @property {String} SCROLLED="panelScrolled" - When the contents of the panel has been scrolled * @property {String} SAVE_LAYOUT="layoutSave" - When the layout is being saved, See [wcDocker.save]{@link module:wcDocker#save} * @property {String} RESTORE_LAYOUT="layoutRestore" - When the layout is being restored, See [wcDocker.restore]{@link module:wcDocker#restore} * @property {String} CUSTOM_TAB_CHANGED="customTabChanged" - When the current tab on a custom tab widget associated with this panel has changed, See {@link module:wcTabFrame} * @property {String} CUSTOM_TAB_CLOSED="customTabClosed" - When a tab has been closed on a custom tab widget associated with this panel, See {@link module:wcTabFrame} * @version 3.0.0 * @const */ wcDocker.EVENT = { INIT: 'panelInit', LOADED: 'dockerLoaded', UPDATED: 'panelUpdated', VISIBILITY_CHANGED: 'panelVisibilityChanged', BEGIN_DOCK: 'panelBeginDock', END_DOCK: 'panelEndDock', GAIN_FOCUS: 'panelGainFocus', LOST_FOCUS: 'panelLostFocus', CLOSING: 'panelClosing', CLOSED: 'panelClosed', PERSISTENT_CLOSED: 'panelPersistentClosed', PERSISTENT_OPENED: 'panelPersistentOpened', BUTTON: 'panelButton', ATTACHED: 'panelAttached', DETACHED: 'panelDetached', MOVE_STARTED: 'panelMoveStarted', MOVE_ENDED: 'panelMoveEnded', MOVED: 'panelMoved', RESIZE_STARTED: 'panelResizeStarted', RESIZE_ENDED: 'panelResizeEnded', RESIZED: 'panelResized', ORDER_CHANGED: 'panelOrderChanged', SCROLLED: 'panelScrolled', SAVE_LAYOUT: 'layoutSave', RESTORE_LAYOUT: 'layoutRestore', CUSTOM_TAB_CHANGED: 'customTabChanged', CUSTOM_TAB_CLOSED: 'customTabClosed' }; /** * The name of the placeholder panel. * @private * @memberOf module:wcDocker * @constant {String} module:wcDocker.PANEL_PLACEHOLDER */ wcDocker.PANEL_PLACEHOLDER = '__wcDockerPlaceholderPanel'; /** * Used when [adding]{@link module:wcDocker#addPanel} or [moving]{@link module:wcDocker#movePanel} a panel to designate the target location as collapsed.<br> * Must be used with [docking]{@link module:wcDocker.DOCK} positions LEFT, RIGHT, or BOTTOM only. * @memberOf module:wcDocker * @constant {String} module:wcDocker.COLLAPSED */ wcDocker.COLLAPSED = '__wcDockerCollapsedPanel'; /** * Used for the splitter bar orientation. * @member module:wcDocker.ORIENTATION * @property {Boolean} VERTICAL=false - Top and Bottom panes * @property {Boolean} HORIZONTAL=true - Left and Right panes * @version 3.0.0 * @const */ wcDocker.ORIENTATION = { VERTICAL: false, HORIZONTAL: true }; /** * Used to determine the position of tabbed widgets for stacked panels.<br> * <b>Note:</b> Not supported on IE8 or below. * @member module:wcDocker.TAB * @property {String} TOP="top" - The default, puts tabs at the top of the frame * @property {String} LEFT="left" - Puts tabs on the left side of the frame * @property {String} RIGHT="right" - Puts tabs on the right side of the frame * @property {String} BOTTOM="bottom" - Puts tabs on the bottom of the frame * @version 3.0.0 * @const */ wcDocker.TAB = { TOP: 'top', LEFT: 'left', RIGHT: 'right', BOTTOM: 'bottom' }; return wcDocker; }); × Search results Close "},"docker.jsdoc.html":{"id":"docker.jsdoc.html","title":"Source: docker.jsdoc","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: docker.jsdoc /** * Options for a [docker]{@link module:wcDocker} instance. * * @typedef {Object} module:wcDocker~Options * @property {String} [themePath='Themes'] - A folder path where all docker theme files can be found. * @property {String} [theme='default'] - The active docker theme. * @property {String} [loadingClass='fa fa-spinner fa-pulse'] - Any class name to use for the loading screen icon. * @property {Boolean} [allowContextMenu=true] - Overrides the default right click menu with ones that interact with docker. * @property {Boolean} [hideOnResize=false] - If true, panels will hide their contents as they are being resized. * @property {Boolean} [allowCollapse=true] - Allows users to collapse panels to the sides of the docker view. * @property {Number} [responseRate=10] - This determines how often updates are performed (in milliseconds). * @property {Number} [moveStartDelay=300] - The time delay (in milliseconds) before a panel drag operation will start. * @property {Number|String} [edgeAnchorSize=50] - Determines the size of the anchor points when docking a panel to the outer edge of the window. Can be a pixel value, or a string with a 'px' or '%' suffix. * @property {Number|String} [panelAnchorSize='15%'] - Determines the size of the anchor points when docking a panel along the side of another panel. Can be a pixel value, or a string with a 'px' or '%' suffix. * @property {Number|String} [detachToWidth=600] - Determines the new width when a panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. * @property {Number|String} [detachToHeight=400] - Determines the new height when a panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. * @property {Object} [wcPanelClass] - Defines a class object to use in replacement of the default wcPanel object. * @property {Object} [wcGhostClass] - Defines a class object to use in replacement of the default wcGhost object. * @property {Object} [wcSplitterClass] - Defines a class object to use in replacement of the default wcSplitter object. * @property {Object} [wcFrameClass] - Defines a class object to use in replacement of the default wcFrame object. * @property {Object} [wcCollapserClass] - Defines a class object to use in replacement of the default wcCollapser object. * @property {Object} [wcLayoutSimpleClass] - Defines a class object to use in replacement of the default wcLayoutSimple object. * @property {Object} [wcLayoutTableClass] - Defines a class object to use in replacement of the default wcLayoutTable object. * @property {Object} [wcDrawerClass] - Defines a class object to use in replacement of the default wcDrawer object. * @property {Object} [wcTabFrameClass] - Defines a class object to use in replacement of the default wcTabFrame object. */ /** * A rectangle structure. * @typedef {Object} module:wcDocker~Rect * @property {Number|String} [x] - X coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [y] - Y coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [w] - Width of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [h] - Height of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. */ /** * A rectangle structure. * @typedef {Object} module:wcDocker~AnchorRect * @property {Number|String} [x] - X coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [y] - Y coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [w] - Width of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [h] - Height of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {module:wcDocker.TAB} [tabOrientation] - Desired orientation of tab widgets. */ /** * A bounding structure * @typedef {Object} module:wcDocker~Bounds * @property {Number} top - The upper, or top bound (percentage value between 0 and 1). * @property {Number} bottom - The lower, or bottom bound (percentage value between 0 and 1). * @property {Number} left - The left bound (percentage value between 0 and 1). * @property {Number} right - The right bound (percentage value between 0 and 1). */ /** * A coordinate structure. * @typedef {Object} module:wcDocker~Coordinate * @property {Number} x - X coordinate. * @property {Number} y - Y coordinate. */ /** * A 2D size structure. * @typedef {Object} module:wcDocker~Size * @property {Number} x - Width. * @property {Number} y - Height. */ /** * Determines whether the container will allow scroll bars to appear on each axis. * @typedef {Object} module:wcDocker~Scrollable * @property {Boolean} x - Whether scrolling is enabled in the horizontal direction. * @property {Boolean} y - Whether scrolling is enabled in the vertical direction. */ /** * Determines whether the container should fit the size of its contents instead of scroll for each axis. * @typedef {Object} module:wcDocker~FitContents * @property {Boolean} x - Whether scrolling is enabled in the horizontal direction. * @property {Boolean} y - Whether scrolling is enabled in the vertical direction. */ /** * Options for adding a new panel. * @typedef {Object} module:wcDocker~PanelOptions * @property {Number|String} [x] - X coordinate of the panel center (if floating). Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [y] - Y coordinate of the panel center (if floating). Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [w] - Desired width of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {Number|String} [h] - Desired height of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @property {module:wcDocker.TAB} [tabOrientation] - Desired position of tab widgets when using [wcDocker.DOCK.STACKED]{@link module:wcDocker.DOCK}. <b>Not supported on IE8 or below.</b> */ /** * Options object for registering new panel types. * @typedef module:wcDocker~registerOptions * @property {module:wcDocker~onCreatePanel} onCreate - A function or an object constructor for the panel. * @property {module:wcDocker.LAYOUT} [layout=wcDocker.LAYOUT.TABLE] - If supplied, overrides the default layout used for this panel. * @property {String} [icon] - A CSS class name to draw an icon in the panels tab widget. * @property {String} [faicon] - An icon name using the [Font-Awesome]{@link http://fortawesome.github.io/Font-Awesome/} library. You must download and link to the library first. * @property {String|Boolean} [title] - Assign a custom name to the panels tab. A false value will hide the tab entirely. * @property {Boolean} [isPrivate] - If true, the user will not be able to create this panel type. * @property {Boolean} [isPersistent] - If true, when the user closes this panel, it will only be hidden instead of completely destroyed. When the user creates an instance of this panel, it will first attempt to un-hide an already existing panel before creating a new instance. * @property {Number} [limit] - Enforces a limited number of this panel type from being created by the user. * @property {Object} [options] - A custom options object to be passed into the new panel constructor or creation function as the second parameter. */ /** * A function or an object constructor for the panel. This function is called using the 'new' operator. * @callback module:wcDocker~onCreatePanel * @param {module:wcPanel} panel - The panel being constructed. * @param {module:wcPanel~options} [options] - An options object passed in from [wcDocker.registerPanelType()]{@link module:wcDocker#registerPanelType}'s options.options parameter. */ /** * An event handler callback. Each is registered to a event type using the [wcDocker.on()]{@link module:wcDocker#on} or [wcPanel.on()]{@link module:wcPanel~on} functions. * @event module:wcDocker#onEvent * @type {Function} * @param {module:wcPanel|NULL} panel - The panel invoking the event, or NULL if global. * @param {Object} [data] - A data object passed by the invoker. */ /** * Anchor data. * @typedef {Object} module:wcDocker~Anchor * @property {Boolean} self - Whether the anchor is hovering over the moving panel. * @property {module:wcDocker.DOCK} loc - The location of the anchor on the panel. * @property {module:wcLayout} item - The panel layout being hovered over. * @property {module:wcDocker.TAB} tab - The tab location. * @property {} * @property {Number} [x] - X coordinate of the anchor. * @property {Number} [y] - Y coordinate of the anchor. * @property {Number} [w] - Width of the anchor. * @property {Number} [h] - Height of the anchor. */ × Search results Close "},"drawer.js.html":{"id":"drawer.js.html","title":"Source: drawer.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: drawer.js /** @module wcDrawer */ define([ "dcl/dcl", "./types", "./frame", "./base" ], function (dcl, wcDocker, wcFrame, base) { /** * A docker container for carrying its own arrangement of docked panels as a slide out drawer. * @class module:wcDrawer * A collapsable container for carrying panels.<br> * * @version 3.0.0 * @description <b><i>PRIVATE<i> - Handled internally by [docker]{@link module:wcDocker} and <u>should never be constructed by the user.</u></b> */ var Module = dcl(base,{ declaredClass: 'wcDrawer', /** * @memberOf module:wcDrawer * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element for this drawer. * @param {wcSplitter|wcDocker} parent - The drawer's parent object. * @param {module:wcDocker.DOCK} position - A docking position to place this drawer. */ constructor:function (container, parent, position) { this.$container = $(container); this.$frame = null; this._position = position; this._parent = parent; this._frame = null; this._closeSize = 0; this._expanded = false; this._sliding = false; this._orientation = (this._position === wcDocker.DOCK.LEFT || this._position === wcDocker.DOCK.RIGHT) ? wcDocker.ORIENTATION.HORIZONTAL : wcDocker.ORIENTATION.VERTICAL; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Collapses the drawer to its respective side wall. * @function module:wcDrawer#collapse */ collapse: function (instant) { if (this._expanded) { // Collapse happens before the tab is de-selected, so record the // current size and assign it to the current panel. var panel = this._frame.panel(); if (panel) { var size = this._parent.pos(); if (this._position !== wcDocker.DOCK.LEFT) { size = 1.0 - size; } var max; if (this._position === wcDocker.DOCK.BOTTOM) { max = this.docker().$container.height(); panel._size.y = size * max; } else { max = this.docker().$container.width(); panel._size.x = size * max; } } this._expanded = false; if (instant) { switch (this._position) { case wcDocker.DOCK.TOP: case wcDocker.DOCK.LEFT: this._parent.pos(0); break; case wcDocker.DOCK.RIGHT: case wcDocker.DOCK.BOTTOM: this._parent.pos(1); break; } } else { this._sliding = true; var self = this; var fin = function () { self._sliding = false; self._parent.__update(); }; switch (this._position) { case wcDocker.DOCK.TOP: case wcDocker.DOCK.LEFT: this._parent.animPos(0, fin); break; case wcDocker.DOCK.RIGHT: case wcDocker.DOCK.BOTTOM: this._parent.animPos(1, fin); break; } } } }, /** * Expands the drawer. * @function module:wcDrawer#expand */ expand: function () { if (!this._expanded) { this._expanded = true; this._sliding = true; var panel = this._frame.panel(); if (panel) { // Determine the size to expand the drawer based on the size of the panel. var size, max; if (this._position === wcDocker.DOCK.BOTTOM) { size = panel._size.y; max = this.docker().$container.height(); } else { size = panel._size.x; max = this.docker().$container.width(); } if (this._position !== wcDocker.DOCK.LEFT) { size = max - size; } size = size / max; var self = this; this._parent.animPos(size, function () { self._sliding = false; self._parent.__update(); }); } } }, /** * Gets whether the drawer is expanded. * @function module:wcDrawer#isExpanded * @returns {Boolean} - The current expanded state. */ isExpanded: function () { return this._expanded; }, /** * The minimum size constraint for the drawer area. * @function module:wcDrawer#minSize * @returns {module:wcDocker~Size} - The minimum size. */ minSize: function () { if (this._expanded) { if (this._root && typeof this._root.minSize === 'function') { return this._root.minSize(); } else { return {x: 100, y: 100}; } } this.__adjustCollapsedSize(); return {x: this._closeSize, y: this._closeSize}; }, /** * The maximum size constraint for the drawer area. * @function module:wcDrawer#maxSize * @returns {module:wcDocker~Size} - The maximum size. */ maxSize: function () { var isHorizontal = (this._orientation === wcDocker.ORIENTATION.HORIZONTAL) ? true : false; if (this._expanded || this._sliding) { if (this._root && typeof this._root.maxSize === 'function') { return { x: (isHorizontal ? this._root.maxSize().x : Infinity), y: (!isHorizontal ? this._root.maxSize().y : Infinity) }; } else { return {x: Infinity, y: Infinity}; } } this.__adjustCollapsedSize(); return { x: (isHorizontal ? this._closeSize : Infinity), y: (!isHorizontal ? this._closeSize : Infinity) }; }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// __init: function () { this.$frame = $('<div class="wcCollapserFrame">'); this.__container(this.$container); this._frame = new (this.docker().__getClass('wcFrame'))(this.$frame, this, false); this._frame.tabOrientation(this._position); }, // Updates the size of the collapser. __update: function (opt_dontMove) { this.__adjustCollapsedSize(); this._frame.__update(); }, // Adjusts the size of the collapser when it is closed. __adjustCollapsedSize: function () { if (this._frame._panelList.length) { this._closeSize = this._frame.$tabBar.outerHeight(); this._parent.$bar.removeClass('wcSplitterHidden'); } else { this._closeSize = 0; this._parent.$bar.addClass('wcSplitterHidden'); } }, // Retrieves the bounding rect for this collapser. __rect: function () { var offset = this.$frame.offset(); var width = this.$frame.width(); var height = this.$frame.height(); var panel = this._frame.panel(); if (panel) { // Determine the size to expand the drawer based on the size of the panel. if (this._position === wcDocker.DOCK.BOTTOM) { height = panel._size.y; width = width / 3; } else { width = panel._size.x; height = height / 3; } } return { x: offset.left, y: offset.top, w: width, h: height }; }, // Saves the current panel configuration into a meta // object that can be used later to restore it. __save: function () { var data = {}; data.closeSize = this._closeSize; data.frame = this._frame.__save(); return data; }, // Restores a previously saved configuration. __restore: function (data, docker) { this._closeSize = data.closeSize; this._frame.__restore(data.frame, docker); this.__adjustCollapsedSize(); }, // Gets, or Sets a new container for this layout. // Params: // $container If supplied, sets a new container for this layout. // parent If supplied, sets a new parent for this layout. // Returns: // JQuery collection The current container. __container: function ($container) { if (typeof $container === 'undefined') { return this.$container; } this.$container = $container; if (this.$container) { this.$container.append(this.$frame); } else { this.$frame.remove(); } return this.$container; }, // Disconnects and prepares this widget for destruction. __destroy: function () { if (this._frame) { this._frame.__destroy(); this._frame = null; } this.__container(null); this._parent = null; } }); return Module; }); × Search results Close "},"frame.js.html":{"id":"frame.js.html","title":"Source: frame.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: frame.js /** @module wcFrame */ define([ "dcl/dcl", "./types", "./base" ], function (dcl, wcDocker, base) { /** * @class module:wcFrame * The frame is a [panel]{@link module:wcPanel} container. * Each panel appears as a tabbed item inside a frame. */ var Module = dcl(base, { declaredClass: 'wcFrame', LEFT_TAB_BUFFER: 15, /** * <b><i>PRIVATE<i> - Handled internally by [docker]{@link module:wcDocker} and <u>should never be constructed by the user.</u></b> * @memberOf module:wcFrame * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element for this frame. * @param {module:wcSplitter|wcDocker} parent - The frames parent object. * @param {Boolean} isFloating - If true, the frame will be a floating window. */ constructor: function (container, parent, isFloating) { /** * The container that holds the frame. * @member {external:jQuery~Object} */ this.$container = $(container); this._parent = parent; this._isFloating = isFloating; /** * The outer frame element. * @member {external:jQuery~Object} */ this.$frame = null; this.$title = null; this.$titleBar = null; this.$tabBar = null; this.$tabScroll = null; this.$center = null; this.$tabLeft = null; this.$tabRight = null; this.$close = null; this.$collapse = null; this.$top = null; this.$bottom = null; this.$left = null; this.$right = null; this.$corner1 = null; this.$corner2 = null; this.$corner3 = null; this.$corner4 = null; this.$buttonBar = null; this.$shadower = null; this.$modalBlocker = null; this._titleVisible = true; this._canScrollTabs = false; this._tabOrientation = wcDocker.TAB.TOP; this._tabScrollPos = 0; this._curTab = -1; this._panelList = []; this._buttonList = []; this._resizeData = { time: -1, timeout: false, delta: 150 }; this._pos = { x: 0.5, y: 0.5 }; this._size = { x: 400, y: 400 }; this._lastSize = { x: 400, y: 400 }; this._anchorMouse = { x: 0, y: 0 }; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets, or Sets the position of the frame. * @function module:wcFrame#pos * @param {Number} [x] - If supplied, assigns a new horizontal position. * @param {Number} [y] - If supplied, assigns a new vertical position. * @param {Boolean} [pixels] - If true, the coordinates passed in will be treated as a pixel position rather than a percentage. * @returns {module:wcDocker~Coordinate} - The current position of the frame. If the pixel parameter was true, the position will be in pixels. */ pos: function (x, y, pixels) { var width = this.$container.width(); var height = this.$container.height(); if (typeof x === 'undefined') { if (pixels) { return {x: this._pos.x * width, y: this._pos.y * height}; } else { return {x: this._pos.x, y: this._pos.y}; } } if (pixels) { this._pos.x = x / width; this._pos.y = y / height; } else { this._pos.x = x; this._pos.y = y; } }, /** * Gets the initially desired size of the panel. * @function module:wcFrame#initSize * @returns {module:wcDocker~Size} - The initially desired size. */ initSize: function () { var size = { x: -1, y: -1 }; for (var i = 0; i < this._panelList.length; ++i) { if (size.x < this._panelList[i].initSize().x) { size.x = this._panelList[i].initSize().x; } if (size.y < this._panelList[i].initSize().y) { size.y = this._panelList[i].initSize().y; } } if (size.x < 0 || size.y < 0) { return false; } return size; }, /** * Gets the minimum size of the frame. * @function module:wcFrame#minSize * @returns {module:wcDocker~Size} - The minimum size of the frame. */ minSize: function () { var size = { x: 0, y: 0 }; for (var i = 0; i < this._panelList.length; ++i) { size.x = Math.max(size.x, this._panelList[i].minSize().x); size.y = Math.max(size.y, this._panelList[i].minSize().y); } return size; }, /** * Gets the maximum size of the frame. * @function module:wcFrame#maxSize * @returns {module:wcDocker~Size} - The maximum size of the frame. */ maxSize: function () { var size = { x: Infinity, y: Infinity }; for (var i = 0; i < this._panelList.length; ++i) { size.x = Math.min(size.x, this._panelList[i].maxSize().x); size.y = Math.min(size.y, this._panelList[i].maxSize().y); } return size; }, /** * Gets, or Sets the tab orientation for the frame. This puts the tabbed widgets visually on any side of the frame. * @version 3.0.0 * @function module:wcFrame#tabOrientation * @param {module:wcDocker.TAB} [orientation] - Assigns the orientation of the tab items displayed. * @returns {module:wcDocker.TAB} - The current orientation. */ tabOrientation: function (orientation) { if (orientation !== undefined) { if (this._tabOrientation !== orientation && this.docker()._canOrientTabs) { this._tabOrientation = orientation; this.__updateTabs(); this.__updateTabs(); } } return this._tabOrientation }, /** * Adds a given panel as a new tab item to the frame. * @function module:wcFrame#addPanel * @param {module:wcPanel} panel - The panel to add. * @param {Number} [index] - Insert index. */ addPanel: function (panel, index) { var found = this._panelList.indexOf(panel); if (found !== -1) { this._panelList.splice(found, 1); } if (typeof index === 'undefined') { this._panelList.push(panel); } else { this._panelList.splice(index, 0, panel); } if (this._curTab === -1 && this._panelList.length) { if (!this.isCollapser()) { this._curTab = 0; } this._size = this.initSize(); } this.__updateTabs(); }, /** * Removes a given panel from the frame. * @function module:wcFrame#removePanel * @param {module:wcPanel} panel - The panel to remove. * @returns {Boolean} - True if any panels still remain after the removal. */ removePanel: function (panel) { for (var i = 0; i < this._panelList.length; ++i) { if (this._panelList[i] === panel) { if (this.isCollapser()) { this._curTab = -1; } else if (this._curTab >= i) { this._curTab--; } // Only null out the container if it is still attached to this frame. if (this._panelList[i]._parent === this) { this._panelList[i].__container(null); this._panelList[i]._parent = null; } this._panelList.splice(i, 1); panel._isVisible = false; break; } } if (this._curTab === -1) { if (!this.collapse() && this._panelList.length) { this._curTab = 0; } } this.__updateTabs(); return this._panelList.length > 0; }, /** * Gets, or Sets the currently visible panel. * @function module:wcFrame#panel * @param {Number} [tabIndex] - If supplied, sets the current panel index. * @param {Boolean} [autoFocus] - If true, this tab will be focused (brought to front). * @returns {module:wcPanel} - The currently visible panel. */ panel: function (tabIndex, autoFocus) { if (typeof tabIndex !== 'undefined') { if (this.isCollapser() && tabIndex === this._curTab) { this.collapse(); tabIndex = -1; } if (tabIndex < this._panelList.length) { this.$tabBar.find('> .wcTabScroller > .wcPanelTab[id="' + this._curTab + '"]').removeClass('wcPanelTabActive'); this.$center.children('.wcPanelTabContent[id="' + this._curTab + '"]').addClass('wcPanelTabContentHidden'); if (this._curTab !== tabIndex) { this.collapse(); } this._curTab = tabIndex; if (tabIndex > -1) { this.$tabBar.find('> .wcTabScroller > .wcPanelTab[id="' + tabIndex + '"]').addClass('wcPanelTabActive'); this.$center.children('.wcPanelTabContent[id="' + tabIndex + '"]').removeClass('wcPanelTabContentHidden'); this.expand(); } this.__updateTabs(autoFocus); } } if (this._curTab > -1 && this._curTab < this._panelList.length) { return this._panelList[this._curTab]; } else if (this.isCollapser() && this._panelList.length) { return this._panelList[0]; } return false; }, /** * Gets whether this frame is inside a collapser. * @function module:wcFrame#isCollapser * @returns {Boolean} - Whether this frame is inside a collapser. */ isCollapser: function () { return (this._parent && this._parent.declaredClass === 'wcDrawer'); }, /** * Collapses the frame, if it is a collapser. * @function module:wcFrame#collapse * @param {Boolean} [instant] - If true, collapses without animating. */ collapse: function (instant) { if (this.isCollapser()) { this._parent.collapse(instant); return true; } return false; }, /** * Expands the frame, if it is a collapser. * @function module:wcFrame#expand */ expand: function () { if (this.isCollapser()) { this._parent.expand(); return true; } return false; }, /** * Gets whether the frame is expanded, if it is a collapser. * @function module:wcFrame#isExpanded * @returns {Boolean|undefined} - The current expanded state, or undefined if it is not a collapser. */ isExpanded: function () { if (this.isCollapser()) { return this._parent.isExpanded(); } }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function () { this.$frame = $('<div class="wcFrame wcWide wcTall">'); this.$title = $('<div class="wcFrameTitle">'); this.$titleBar = $('<div class="wcFrameTitleBar wcFrameTopper">'); this.$tabBar = $('<div class="wcFrameTitleBar">'); this.$tabScroll = $('<div class="wcTabScroller">'); this.$center = $('<div class="wcFrameCenter wcPanelBackground">'); this.$tabLeft = $('<div class="wcFrameButton" title="Scroll tabs to the left."><span class="fa fa-arrow-left"></span>&lt;</div>'); this.$tabRight = $('<div class="wcFrameButton" title="Scroll tabs to the right."><span class="fa fa-arrow-right"></span>&gt;</div>'); this.$close = $('<div class="wcFrameButton" title="Close the currently active panel tab"><div class="fa fa-close"></div>X</div>'); this.$collapse = $('<div class="wcFrameButton" title="Collapse the active panel"><div class="fa fa-download"></div>C</div>'); this.$buttonBar = $('<div class="wcFrameButtonBar">'); this.$tabButtonBar = $('<div class="wcFrameButtonBar">'); this.$tabBar.append(this.$tabScroll); this.$tabBar.append(this.$tabButtonBar); this.$frame.append(this.$buttonBar); this.$buttonBar.append(this.$close); this.$buttonBar.append(this.$collapse); this.$frame.append(this.$center); if (this._isFloating) { this.$top = $('<div class="wcFrameEdgeH wcFrameEdge"></div>').css('top', '-6px').css('left', '0px').css('right', '0px'); this.$bottom = $('<div class="wcFrameEdgeH wcFrameEdge"></div>').css('bottom', '-6px').css('left', '0px').css('right', '0px'); this.$left = $('<div class="wcFrameEdgeV wcFrameEdge"></div>').css('left', '-6px').css('top', '0px').css('bottom', '0px'); this.$right = $('<div class="wcFrameEdgeV wcFrameEdge"></div>').css('right', '-6px').css('top', '0px').css('bottom', '0px'); this.$corner1 = $('<div class="wcFrameCornerNW wcFrameEdge"></div>').css('top', '-6px').css('left', '-6px'); this.$corner2 = $('<div class="wcFrameCornerNE wcFrameEdge"></div>').css('top', '-6px').css('right', '-6px'); this.$corner3 = $('<div class="wcFrameCornerNW wcFrameEdge"></div>').css('bottom', '-6px').css('right', '-6px'); this.$corner4 = $('<div class="wcFrameCornerNE wcFrameEdge"></div>').css('bottom', '-6px').css('left', '-6px'); this.$frame.append(this.$top); this.$frame.append(this.$bottom); this.$frame.append(this.$left); this.$frame.append(this.$right); this.$frame.append(this.$corner1); this.$frame.append(this.$corner2); this.$frame.append(this.$corner3); this.$frame.append(this.$corner4); } this.__container(this.$container); if (this._isFloating) { this.$frame.addClass('wcFloating'); } this.$center.scroll(this.__scrolled.bind(this)); }, // Updates the size of the frame. __update: function () { var width = this.$container.width(); var height = this.$container.height(); // Floating windows manage their own sizing. if (this._isFloating) { var left = (this._pos.x * width) - this._size.x / 2; var top = (this._pos.y * height) - this._size.y / 2; if (top < 0) { top = 0; } if (left + this._size.x / 2 < 0) { left = -this._size.x / 2; } if (left + this._size.x / 2 > width) { left = width - this._size.x / 2; } if (top + parseInt(this.$center.css('top')) > height) { top = height - parseInt(this.$center.css('top')); } this.$frame.css('left', left + 'px'); this.$frame.css('top', top + 'px'); this.$frame.css('width', this._size.x + 'px'); this.$frame.css('height', this._size.y + 'px'); } if (width !== this._lastSize.x || height !== this._lastSize.y) { this._lastSize.x = width; this._lastSize.y = height; this._resizeData.time = new Date(); if (!this._resizeData.timeout) { this._resizeData.timeout = true; setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); } } // this.__updateTabs(); this.__onTabChange(); }, __resizeEnd: function () { this.__updateTabs(); if (new Date() - this._resizeData.time < this._resizeData.delta) { setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); } else { this._resizeData.timeout = false; } }, // Triggers an event exclusively on the docker and none of its panels. // Params: // eventName The name of the event. // data A custom data parameter to pass to all handlers. __trigger: function (eventName, data) { for (var i = 0; i < this._panelList.length; ++i) { this._panelList[i].__trigger(eventName, data); } }, // Saves the current panel configuration into a meta // object that can be used later to restore it. __save: function () { var data = {}; data.type = 'wcFrame'; data.floating = this._isFloating; data.isFocus = this.$frame.hasClass('wcFloatingFocus'); data.tabOrientation = this._tabOrientation; data.pos = { x: this._pos.x, y: this._pos.y }; data.size = { x: this._size.x, y: this._size.y }; data.tab = this._curTab; data.panels = []; for (var i = 0; i < this._panelList.length; ++i) { data.panels.push(this._panelList[i].__save()); } return data; }, // Restores a previously saved configuration. __restore: function (data, docker) { this._isFloating = data.floating; this._tabOrientation = data.tabOrientation || wcDocker.TAB.TOP; this._pos.x = data.pos.x; this._pos.y = data.pos.y; this._size.x = data.size.x; this._size.y = data.size.y; this._curTab = data.tab; for (var i = 0; i < data.panels.length; ++i) { var panel = docker.__create(data.panels[i], this, this.$center); panel.__restore(data.panels[i], docker); this._panelList.push(panel); } this.__update(); if (data.isFocus) { this.$frame.addClass('wcFloatingFocus'); } }, __updateTabs: function (autoFocus) { this.$tabScroll.empty(); var getOffset = function ($item) { switch (this._tabOrientation) { case wcDocker.TAB.BOTTOM: return $item.offset().left; case wcDocker.TAB.TOP: return $item.offset().left; case wcDocker.TAB.LEFT: return $item.offset().top; case wcDocker.TAB.RIGHT: return $item.offset().top; } }.bind(this); var visibilityChanged = []; var tabPositions = []; var totalWidth = 0; var parentLeft = getOffset(this.$tabScroll); var showTabs = this._panelList.length > 1 || this._isFloating || this.isCollapser(); var self = this; if (this.isCollapser()) { // this.$titleBar.addClass('wcNotMoveable'); this.$tabBar.addClass('wcNotMoveable'); } else { this.$titleBar.removeClass('wcNotMoveable'); this.$tabBar.removeClass('wcNotMoveable'); } this.$center.children('.wcPanelTabContent').each(function () { $(this).addClass('wcPanelTabContentHidden wcPanelTabUnused'); }); this._titleVisible = true; this.$title.html(''); // Determine if the title and tabs are visible based on the panels inside. for (var i = 0; i < this._panelList.length; ++i) { var panel = this._panelList[i]; var $tab = null; if (showTabs) { $tab = panel.$title; panel.$title.attr('id', i); this.$tabScroll.append(panel.$title); } if (!panel.moveable()) { this.$titleBar.addClass('wcNotMoveable'); this.$tabBar.addClass('wcNotMoveable'); } if (!panel._titleVisible) { this._titleVisible = false; } var $tabContent = this.$center.children('.wcPanelTabContent[id="' + i + '"]'); if (!$tabContent.length) { $tabContent = $('<div class="wcPanelTabContent wcPanelTabContentHidden" id="' + i + '">'); this.$center.append($tabContent); } panel.__container($tabContent); panel._parent = this; var isVisible = this._curTab === i; if (panel.isVisible() !== isVisible) { visibilityChanged.push({ panel: panel, isVisible: isVisible }); } $tabContent.removeClass('wcPanelTabUnused'); if (isVisible) { $tab && $tab.addClass('wcPanelTabActive'); $tabContent.removeClass('wcPanelTabContentHidden'); this.$title.html(panel.title()); if (panel.$icon) { var $icon = panel.$icon.clone(); this.$title.prepend($icon); } } if ($tab) { totalWidth = getOffset($tab) - parentLeft; tabPositions.push(totalWidth); totalWidth += $tab.outerWidth(); } } var $topBar = this.$titleBar; var tabWidth = 0; if (this._titleVisible) { if (!this.$frame.parent()) { this.$center.css('top', ''); } switch (this._tabOrientation) { case wcDocker.TAB.TOP: this.$frame.prepend(this.$tabBar); this.$titleBar.remove(); this.$tabBar.addClass('wcTabTop').removeClass('wcTabLeft wcTabRight wcTabBottom'); // this.$tabBar.css('margin-top', ''); if (showTabs) { this.$title.remove(); } else { this.$tabBar.prepend(this.$title); } $topBar = this.$tabBar; this.$center.css('left', 0).css('right', 0).css('bottom', 0); tabWidth = this.$center.width(); break; case wcDocker.TAB.BOTTOM: this.$frame.prepend(this.$titleBar); this.$titleBar.append(this.$title); if (showTabs) { var titleSize = this.$titleBar.height(); this.$frame.append(this.$tabBar); this.$tabBar.addClass('wcTabBottom').removeClass('wcTabTop wcTabLeft wcTabRight'); // this.$tabBar.css('margin-top', ''); this.$center.css('left', 0).css('right', 0).css('bottom', titleSize); } else { this.$tabBar.remove(); } tabWidth = this.$center.width(); break; case wcDocker.TAB.LEFT: this.$frame.prepend(this.$titleBar); this.$titleBar.append(this.$title); if (showTabs) { var titleSize = this.$titleBar.height(); this.$frame.append(this.$tabBar); this.$tabBar.addClass('wcTabLeft').removeClass('wcTabTop wcTabRight wcTabBottom'); // this.$tabBar.css('margin-top', titleSize); this.$center.css('left', titleSize).css('right', 0).css('bottom', 0); } else { this.$tabBar.remove(); } tabWidth = this.$center.height(); break; case wcDocker.TAB.RIGHT: this.$frame.prepend(this.$titleBar); this.$titleBar.append(this.$title); if (showTabs) { var titleSize = this.$titleBar.height(); this.$frame.append(this.$tabBar); this.$tabBar.addClass('wcTabRight').removeClass('wcTabTop wcTabLeft wcTabBottom'); // this.$tabBar.css('margin-top', titleSize); this.$center.css('left', 0).css('right', titleSize).css('bottom', 0); } else { this.$tabBar.remove(); } tabWidth = this.$center.height(); break; } if (!showTabs) { this.$center.css('left', 0).css('right', 0).css('bottom', 0); } } else { this.$titleBar.remove(); this.$tabBar.remove(); this.$center.css('top', 0).css('left', 0).css('right', 0).css('bottom', 0); } // Now remove all unused panel tabs. this.$center.children('.wcPanelTabUnused').each(function () { $(this).remove(); }); if (this._titleVisible) { var buttonSize = this.__onTabChange(); if (autoFocus) { for (var i = 0; i < tabPositions.length; ++i) { if (i === this._curTab) { var left = tabPositions[i]; var right = totalWidth; if (i + 1 < tabPositions.length) { right = tabPositions[i + 1]; } var scrollPos = -parseInt(this.$tabScroll.css('left')); var titleWidth = tabWidth - buttonSize; // If the tab is behind the current scroll position. if (left < scrollPos) { this._tabScrollPos = left - this.LEFT_TAB_BUFFER; if (this._tabScrollPos < 0) { this._tabScrollPos = 0; } } // If the tab is beyond the current scroll position. else if (right - scrollPos > titleWidth) { this._tabScrollPos = right - titleWidth + this.LEFT_TAB_BUFFER; } break; } } } this._canScrollTabs = false; if (totalWidth > tabWidth - buttonSize) { this._canScrollTabs = this._titleVisible; if (this._canScrollTabs) { this.$tabButtonBar.append(this.$tabRight); this.$tabButtonBar.append(this.$tabLeft); buttonSize += this.$tabRight.outerWidth(); buttonSize += this.$tabLeft.outerWidth(); } var scrollLimit = totalWidth - (tabWidth - buttonSize) / 2; // If we are beyond our scroll limit, clamp it. if (this._tabScrollPos > scrollLimit) { var children = this.$tabScroll.children(); for (var i = 0; i < children.length; ++i) { var $tab = $(children[i]); totalWidth = getOffset($tab) - parentLeft; if (totalWidth + $tab.outerWidth() > scrollLimit) { this._tabScrollPos = totalWidth - this.LEFT_TAB_BUFFER; if (this._tabScrollPos < 0) { this._tabScrollPos = 0; } break; } } } } else { this._tabScrollPos = 0; this.$tabLeft.remove(); this.$tabRight.remove(); } this.$tabScroll.stop().animate({left: -this._tabScrollPos + 'px'}, 'fast'); // Update visibility on panels. for (var i = 0; i < visibilityChanged.length; ++i) { visibilityChanged[i].panel.__isVisible(visibilityChanged[i].isVisible); } } }, __onTabChange: function () { var buttonSize = 0; var tabButtonSize = 0; var panel = this.panel(); this.$tabLeft.remove(); this.$tabRight.remove(); this.$close.hide(); this.$collapse.hide(); while (this._buttonList.length) { this._buttonList.pop().remove(); } if (panel) { var scrollable = panel.scrollable(); this.$center.toggleClass('wcScrollableX', scrollable.x); this.$center.toggleClass('wcScrollableY', scrollable.y); this.$frame.toggleClass('wcOverflowVisible', panel.overflowVisible()); this.$center.toggleClass('wcOverflowVisible', panel.overflowVisible()); if (!this.isCollapser() || this.isExpanded()) { if (panel.closeable()) { this.$close.show(); buttonSize += this.$close.outerWidth(); } var docker = this.docker(); if (docker.isCollapseEnabled() && panel.moveable() && panel.collapsible() && !this._isFloating && !panel._isPlaceholder) { if (this.isCollapser()) { // Un-collapse var $icon = this.$collapse.children('div'); $icon[0].className = 'fa fa-sign-out'; switch (this._parent._position) { case wcDocker.DOCK.LEFT: $icon.addClass('wcCollapseLeft'); break; case wcDocker.DOCK.RIGHT: $icon.addClass('wcCollapseRight'); break; case wcDocker.DOCK.BOTTOM: $icon.addClass('wcCollapseBottom'); break; } $icon.addClass('wcCollapsed'); this.$collapse.show(); this.$collapse.attr('title', 'Dock this collapsed panel back into the main layout.'); buttonSize += this.$collapse.outerWidth(); } else { var direction = wcDocker.DOCK.BOTTOM; if (panel._collapseDirection === wcDocker.DOCK.LEFT || panel._collapseDirection === wcDocker.DOCK.RIGHT || panel._collapseDirection === wcDocker.DOCK.BOTTOM) { // Static collapse direction. direction = panel._collapseDirection; } else { // Determine the direction to collapse based on the frame center. var $inner = docker.$container; if (!$.isEmptyObject(docker._collapser) && docker._collapser.hasOwnProperty(wcDocker.DOCK.RIGHT)) { // Get the inner contents element not taken up by the collapsible drawers. $inner = docker._collapser[wcDocker.DOCK.RIGHT]._parent.$pane[0]; } var outer = $inner.offset(); var bounds = this.$container.offset(); bounds.right = (bounds.left + this.$container.width() - outer.left) / $inner.width(); bounds.bottom = (bounds.top + this.$container.height() - outer.top) / $inner.height(); bounds.top = (bounds.top - outer.top) / $inner.height(); bounds.left = (bounds.left - outer.left) / $inner.width(); if (typeof panel._collapseDirection === 'function') { // Custom collapse handler. direction = panel._collapseDirection(bounds); } else { // Default collapse calculation. if (bounds.top > 0.5 && bounds.bottom > 0.95) { direction = wcDocker.DOCK.BOTTOM; } else if (bounds.left <= 0.05) { direction = wcDocker.DOCK.LEFT; } else if (bounds.right >= 0.95) { direction = wcDocker.DOCK.RIGHT; } else if (bounds.bottom > 0.95) { direction = wcDocker.DOCK.BOTTOM; } } } var directionLabel = ''; var directionClass = ''; switch (direction) { case wcDocker.DOCK.LEFT: directionLabel = 'left side.'; directionClass = 'wcCollapseLeft'; break; case wcDocker.DOCK.RIGHT: directionLabel = 'right side.'; directionClass = 'wcCollapseRight'; break; case wcDocker.DOCK.BOTTOM: directionLabel = 'bottom.'; directionClass = 'wcCollapseBottom'; break; } if (directionLabel) { var $icon = this.$collapse.children('div'); $icon[0].className = 'fa fa-sign-in'; $icon.addClass(directionClass); $icon.addClass('wcCollapsible'); this.$collapse.show(); this.$collapse.attr('title', 'Collapse this panel into the ' + directionLabel); buttonSize += this.$collapse.outerWidth(); } } } for (var i = 0; i < panel._buttonList.length; ++i) { var buttonData = panel._buttonList[i]; var $button = $('<div>'); var buttonClass = buttonData.className; $button.addClass('wcFrameButton'); if (buttonData.isTogglable) { $button.addClass('wcFrameButtonToggler'); if (buttonData.isToggled) { $button.addClass('wcFrameButtonToggled'); buttonClass = buttonData.toggleClassName || buttonClass; } } $button.attr('title', buttonData.tip); $button.data('name', buttonData.name); $button.text(buttonData.text); if (buttonClass) { $button.prepend($('<div class="' + buttonClass + '">')); } this._buttonList.push($button); this.$buttonBar.append($button); buttonSize += $button.outerWidth(); } } if (this._canScrollTabs) { this.$tabButtonBar.append(this.$tabRight); this.$tabButtonBar.append(this.$tabLeft); tabButtonSize += this.$tabRight.outerWidth() + this.$tabLeft.outerWidth(); } if (this._titleVisible) { this.$buttonBar.css('right', ''); switch (this._tabOrientation) { case wcDocker.TAB.RIGHT: this.$buttonBar.css('right', this.$tabBar.height()); case wcDocker.TAB.LEFT: this.$tabBar.css('width', this.$center.height() + this.$tabBar.height()); break; case wcDocker.TAB.TOP: case wcDocker.TAB.BOTTOM: this.$tabBar.css('width', this.$center.width()); break; default: break; } } panel.__update(); this.$center.scrollLeft(panel._scroll.x); this.$center.scrollTop(panel._scroll.y); } this.$buttonBar.css('min-width', buttonSize).css('width', buttonSize); this.$tabButtonBar.css('min-width', tabButtonSize).css('width', tabButtonSize); if (this._tabOrientation === wcDocker.TAB.TOP) { this.$tabButtonBar.css('right', buttonSize); return buttonSize + tabButtonSize; } else { this.$tabButtonBar.css('right', 0); return tabButtonSize; } }, // Handles scroll notifications. __scrolled: function () { var panel = this.panel(); panel._scroll.x = this.$center.scrollLeft(); panel._scroll.y = this.$center.scrollTop(); panel.__trigger(wcDocker.EVENT.SCROLLED); }, // Brings the frame into focus. // Params: // flash Optional, if true will flash the window. __focus: function (flash) { if (flash) { var $flasher = $('<div class="wcFrameFlasher">'); this.$frame.append($flasher); $flasher.animate({ opacity: 1 }, 100) .animate({ opacity: 0.0 }, 100) .animate({ opacity: 0.6 }, 50) .animate({ opacity: 0.0 }, 50) .queue(function (next) { $flasher.remove(); next(); }); } }, // Moves the panel based on mouse dragging. // Params: // mouse The current mouse position. __move: function (mouse) { var width = this.$container.width(); var height = this.$container.height(); this._pos.x = (mouse.x + this._anchorMouse.x) / width; this._pos.y = (mouse.y + this._anchorMouse.y) / height; }, // Sets the anchor position for moving the panel. // Params: // mouse The current mouse position. __anchorMove: function (mouse) { var width = this.$container.width(); var height = this.$container.height(); this._anchorMouse.x = (this._pos.x * width) - mouse.x; this._anchorMouse.y = (this._pos.y * height) - mouse.y; }, // Moves a tab from a given index to another index. // Params: // fromIndex The current tab index to move. // toIndex The new index to move to. // Returns: // element The new element of the moved tab. // false If an error occurred. __tabMove: function (fromIndex, toIndex) { if (fromIndex >= 0 && fromIndex < this._panelList.length && toIndex >= 0 && toIndex < this._panelList.length) { var panel = this._panelList.splice(fromIndex, 1); this._panelList.splice(toIndex, 0, panel[0]); // Preserve the currently active tab. if (this._curTab === fromIndex) { this._curTab = toIndex; } this.__updateTabs(); return this.$tabBar.find('> .wcTabScroller > .wcPanelTab[id="' + toIndex + '"]')[0]; } return false; }, // Checks if the mouse is in a valid anchor position for docking a panel. // Params: // mouse The current mouse position. // same Whether the moving frame and this one are the same. // ghost The ghost object. // canSplit Whether the frame can be split // isTopper Whether the user is dragging the topper (top title bar). // allowEdges Whether to allow edge docking. __checkAnchorDrop: function (mouse, same, ghost, canSplit, isTopper, allowEdges) { var panel = this.panel(); if (panel && panel.moveable()) { return panel.layout().__checkAnchorDrop(mouse, same && this._tabOrientation, ghost, (!this._isFloating && !this.isCollapser() && canSplit), this.$frame, panel.moveable() && panel.title(), isTopper, this.isCollapser() ? this._tabOrientation : undefined, allowEdges); } return false; }, // Resizes the panel based on mouse dragging. // Params: // edges A list of edges being moved. // mouse The current mouse position. __resize: function (edges, mouse) { var width = this.$container.width(); var height = this.$container.height(); var offset = this.$container.offset(); mouse.x -= offset.left; mouse.y -= offset.top; var minSize = this.minSize(); var maxSize = this.maxSize(); var pos = { x: (this._pos.x * width) - this._size.x / 2, y: (this._pos.y * height) - this._size.y / 2 }; for (var i = 0; i < edges.length; ++i) { switch (edges[i]) { case 'top': this._size.y += pos.y - mouse.y - 2; pos.y = mouse.y + 2; if (this._size.y < minSize.y) { pos.y += this._size.y - minSize.y; this._size.y = minSize.y; } if (this._size.y > maxSize.y) { pos.y += this._size.y - maxSize.y; this._size.y = maxSize.y; } break; case 'bottom': this._size.y = mouse.y - 4 - pos.y; if (this._size.y < minSize.y) { this._size.y = minSize.y; } if (this._size.y > maxSize.y) { this._size.y = maxSize.y; } break; case 'left': this._size.x += pos.x - mouse.x - 2; pos.x = mouse.x + 2; if (this._size.x < minSize.x) { pos.x += this._size.x - minSize.x; this._size.x = minSize.x; } if (this._size.x > maxSize.x) { pos.x += this._size.x - maxSize.x; this._size.x = maxSize.x; } break; case 'right': this._size.x = mouse.x - 4 - pos.x; if (this._size.x < minSize.x) { this._size.x = minSize.x; } if (this._size.x > maxSize.x) { this._size.x = maxSize.x; } break; } this._pos.x = (pos.x + this._size.x / 2) / width; this._pos.y = (pos.y + this._size.y / 2) / height; } }, // Turn off or on a shadowing effect to signify this widget is being moved. // Params: // enabled Whether to enable __shadow mode. __shadow: function (enabled) { if (enabled) { if (!this.$shadower) { this.$shadower = $('<div class="wcFrameShadower">'); this.$frame.append(this.$shadower); this.$shadower.animate({ opacity: 0.5 }, 300); } } else { if (this.$shadower) { var self = this; this.$shadower.animate({ opacity: 0.0 }, 300) .queue(function (next) { self.$shadower.remove(); self.$shadower = null; next(); }); } } }, // Retrieves the bounding rect for this frame. __rect: function () { if (this.isCollapser()) { return this._parent.__rect(); } var offset = this.$frame.offset(); var width = this.$frame.width(); var height = this.$frame.height(); return { x: offset.left, y: offset.top, w: width, h: height }; }, // Gets, or Sets a new container for this layout. // Params: // $container If supplied, sets a new container for this layout. // parent If supplied, sets a new parent for this layout. // Returns: // JQuery collection The current container. __container: function ($container) { if (typeof $container === 'undefined') { return this.$container; } this.$container = $container; if (this.$container) { this.$container.append(this.$frame); } else { this.$frame.remove(); } return this.$container; }, // Disconnects and prepares this widget for destruction. __destroy: function () { this._curTab = -1; for (var i = 0; i < this._panelList.length; ++i) { this._panelList[i].__destroy(); } while (this._panelList.length) this._panelList.pop(); if (this.$modalBlocker) { this.$modalBlocker.remove(); this.$modalBlocker = null; } this.__container(null); this._parent = null; } }); // window['wcFrame'] = Module; return Module; }); × Search results Close "},"ghost.js.html":{"id":"ghost.js.html","title":"Source: ghost.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: ghost.js /** @module wcGhost **/ define([ "dcl/dcl", "./types" ], function (dcl, wcDocker) { /** * @class module:wcGhost * A ghost object that follows the mouse around during dock movement. */ var Module = dcl(null, { declaredClass: 'wcGhost', /** * @memberOf module:wcGhost * @param {module:wcDocker~Rect} rect - A rectangle area to begin the ghost highlighting. * @param {module:wcDocker~Coordinate} mouse - The mouse position. * @param {module:wcDocker} docker - The docker object. */ constructor: function (rect, mouse, docker) { this.$ghost = null; this._rect; this._anchorMouse = false; this._anchor = null; this._docker = docker; this._outer = docker.__findInner(); if (this._outer && this._outer.instanceOf('wcSplitter')) { this._inner = this._outer.right(); } this.__init(rect, mouse); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Updates the ghost based on the given screen position. * @function module:wcGhost#update * @param {module:wcDocker~Coordinate} position - The mouse position. * @param {Boolean} [disableFloating] - If true, the ghost will not float. */ update: function (position, disableFloating) { this.__move(position); for (var i = 0; i < this._docker._floatingList.length; ++i) { var rect = this._docker._floatingList[i].__rect(); if (position.x > rect.x && position.y > rect.y && position.x < rect.x + rect.w && position.y < rect.y + rect.h) { if (!this._docker._floatingList[i].__checkAnchorDrop(position, false, this, true, undefined, true)) { if (!disableFloating) { this.anchor(position, null); } } else { this._anchor.panel = this._docker._floatingList[i].panel(); } return; } } for (var i = 0; i < this._docker._frameList.length; ++i) { var rect = this._docker._frameList[i].__rect(); if (position.x > rect.x && position.y > rect.y && position.x < rect.x + rect.w && position.y < rect.y + rect.h) { if (!this._docker._frameList[i].__checkAnchorDrop(position, false, this, true, undefined, true)) { if (!disableFloating) { this.anchor(position, null); } } else { this._anchor.panel = this._docker._frameList[i].panel(); } return; } } }, /** * Get, or Sets the ghost's anchor. * @function module:wcGhost#anchor * @param {module:wcDocker~Coordinate} [mouse] - If supplied with the anchor, . * @param {module:wcDocker~Anchor} [anchor] - If supplied, assigns a new anchor. */ anchor: function (mouse, anchor) { if (typeof mouse === 'undefined') { return this._anchor; } if (anchor && this._anchor && anchor.loc === this._anchor.loc && anchor.item === this._anchor.item) { return; } var rect = { x: parseInt(this.$ghost.css('left')), y: parseInt(this.$ghost.css('top')), w: parseInt(this.$ghost.css('width')), h: parseInt(this.$ghost.css('height')) }; this._anchorMouse = { x: rect.x - mouse.x, y: rect.y - mouse.y }; this._rect.x = -this._anchorMouse.x; this._rect.y = -this._anchorMouse.y; if (!anchor) { if (!this._anchor) { return; } if (this._docker._draggingFrame && this._docker._draggingFrame.$container) { var detachToWidth = this._docker._draggingFrame._panelList[0]._options.detachToWidth || this._docker._options.detachToWidth || this._rect.w; var detachToHeight = this._docker._draggingFrame._panelList[0]._options.detachToHeight || this._docker._options.detachToHeight || this._rect.h; this._rect.w = this._docker.__stringToPixel(detachToWidth, this._docker.$container.width()); this._rect.h = this._docker.__stringToPixel(detachToHeight, this._docker.$container.height()); } this._anchor = null; this.$ghost.show(); this.$ghost.stop().animate({ opacity: 0.3, 'margin-left': this._rect.x - this._rect.w / 2 + 'px', 'margin-top': this._rect.y - 10 + 'px', width: this._rect.w + 'px', height: this._rect.h + 'px' }, 150); return; } this._anchor = anchor; var opacity = 0.8; if (anchor.self && anchor.loc === wcDocker.DOCK.STACKED) { opacity = 0; this.$ghost.hide(); } else { this.$ghost.show(); } this.$ghost.stop().animate({ opacity: opacity, 'margin-left': '2px', 'margin-top': '2px', border: '0px', left: anchor.x + 'px', top: anchor.y + 'px', width: anchor.w + 'px', height: anchor.h + 'px' }, 150); }, /** * Retrieves the rectangle area of the ghost's anchor. * @function module:wcGhost#rect * @returns {module:wcDocker~AnchorRect} - The rectangle area of the anchor. */ rect: function () { return { x: this.$ghost.offset().left, y: this.$ghost.offset().top, w: parseInt(this.$ghost.css('width')), h: parseInt(this.$ghost.css('height')), tabOrientation: this._anchor && this._anchor.tab }; }, /** * Destroys the instance of the ghost. * @function module:wcGhost#destroy */ destroy: function () { this.__destroy(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function (rect, mouse) { this.$ghost = $('<div class="wcGhost">') .css('opacity', 0) .css('top', rect.y + 'px') .css('left', rect.x + 'px') .css('width', rect.w + 'px') .css('height', rect.h + 'px'); this._anchorMouse = { x: rect.x - mouse.x, y: rect.y - mouse.y }; this._rect = { x: -this._anchorMouse.x, y: -this._anchorMouse.y, w: rect.w, h: rect.h }; $('body').append(this.$ghost); this.anchor(mouse, rect); }, // Updates the size of the layout. __move: function (mouse) { if (this._anchor) { return; } var x = parseInt(this.$ghost.css('left')); var y = parseInt(this.$ghost.css('top')); x = mouse.x + this._anchorMouse.x; y = mouse.y + this._anchorMouse.y; this.$ghost.css('left', x + 'px'); this.$ghost.css('top', y + 'px'); }, // Gets the original size of the moving widget. __rect: function () { return this._rect; }, // Exorcise the ghost. __destroy: function () { this.$ghost.stop().animate({ opacity: 0.0 }, { duration: 175, complete: function () { $(this).remove(); } }); } }); // window['wcGhost'] = Module; return Module; }); × Search results Close "},"iframe.js.html":{"id":"iframe.js.html","title":"Source: iframe.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: iframe.js /** @module wcIFrame */ define([ "dcl/dcl", "./types", "./base" ], function (dcl, wcDocker, base) { /** * @class module:wcIFrame * The wcIFrame widget makes it easier to include an iFrame element into your panel. * Because an iFrame's contents is cleared whenever it is moved in the DOM heirarchy * (and changing a panels docking position causes DOM movement), special care must * be taken when using them.<br><br> * * This will create an iFrame element and place it in a static (non-changing) DOM * location. It will then sync its size and position to match the container area of * this wcIFrame widget. It works rather well, but has its limitations. Since the * iFrame is essentially on top of the window, it can not be only partially hidden. * If the wcIFrame container is partially hidden outside the bounds of the panel, * the iFrame will not be hidden. * {@tutorial 3.0-widgets} */ var Module = dcl(base, { declaredClass: 'wcIFrame', /** * @memberOf module:wcIFrame * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element for this layout. * @param {module:wcPanel} parent - The iframes's parent panel. */ constructor:function(container, panel) { this._panel = panel; this._layout = panel.layout(); this.$container = $(container); this.$frame = null; this.$focus = null; /** * The iFrame element. * @member {external:jQuery~Object} */ this.$iFrame = null; this._window = null; this._isDocking = false; this._isHovering = false; this._boundEvents = []; this._onLoadFuncs = []; this._onClosedFuncs = []; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Opens a given URL address into the iFrame. * @function module:wcIFrame#openURL * @param {String} url - The full, or relative, path to the page. */ openURL: function (url) { this.__clearFrame(); this.$iFrame = $('<iframe>iFrames not supported on your device!</iframe>'); this.$frame.prepend(this.$iFrame); this.__onMoved(); this._window = this.$iFrame[0].contentWindow || this.$iFrame[0]; this.__updateFrame(); this._window.location.replace(url); this.$iFrame[0].focus(); this.$iFrame.hover(this.__onHoverEnter.bind(this), this.__onHoverExit.bind(this)); var self = this; this.$iFrame.load(function () { for (var i = 0; i < self._onLoadFuncs.length; ++i) { self._onLoadFuncs[i](); } self._onLoadFuncs = []; }); }, /** * Populates the iFrame with the given HTML source code using the document to write data. * @function module:wcIFrame#openHTML * @param {String} html - The HTML source code. */ openHTML: function (html) { this.__clearFrame(); this.$iFrame = $('<iframe>iFrames not supported on your device!</iframe>'); this.$frame.prepend(this.$iFrame); this.__onMoved(); this._window = this.$iFrame[0].contentWindow || this.$iFrame[0]; this.__updateFrame(); // Write the frame source. this._window.document.open(); this._window.document.write(html); this._window.document.close(); this.$iFrame[0].focus(); this.$iFrame.hover(this.__onHoverEnter.bind(this), this.__onHoverExit.bind(this)); var self = this; this.$iFrame.load(function () { for (var i = 0; i < self._onLoadFuncs.length; ++i) { self._onLoadFuncs[i](); } self._onLoadFuncs = []; }); }, /** * Populates the iFrame with the given HTML source code using the srcdoc attribute. * @version 3.0.0 * @function module:wcIFrame#openSRC * @param {String} html - The HTML source code. */ openSRC: function (html) { this.__clearFrame(); this.$iFrame = $('<iframe>iFrames not supported on your device!</iframe>'); this.$frame.prepend(this.$iFrame); this.__onMoved(); this._window = this.$iFrame[0].contentWindow || this.$iFrame[0]; this.__updateFrame(); // Write the frame source. this.$iFrame[0].srcdoc = html; this.$iFrame[0].focus(); this.$iFrame.hover(this.__onHoverEnter.bind(this), this.__onHoverExit.bind(this)); var self = this; this.$iFrame.load(function () { for (var i = 0; i < self._onLoadFuncs.length; ++i) { self._onLoadFuncs[i](); } self._onLoadFuncs = []; }); }, /** * Registers an event handler when the contents of this iFrame has loaded. * @function module:wcIFrame#onLoaded * @param {Function} onLoadedFunc - A function to call when the iFrame has loaded. */ onLoaded: function(onLoadedFunc) { this._onLoadFuncs.push(onLoadedFunc); }, /** * Registers an event handler when the iFrame has been closed. * @function module:wcIFrame#onClosed * @param {Function} onClosedFunc - A function to call when the iFrame has closed. */ onClosed: function(onClosedFunc) { this._onClosedFuncs.push(onClosedFunc); }, /** * Allows the iFrame to be visible when the panel is visible. * @function module:wcIFrame#show */ show: function () { if (this.$frame) { this.$frame.removeClass('wcIFrameHidden'); } }, /** * Forces the iFrame to be hidden, regardless of whether the panel is visible. * @function module:wcIFrame#hide */ hide: function () { if (this.$frame) { this.$frame.addClass('wcIFrameHidden'); } }, /** * Retrieves the window object from the iFrame element. * @function module:wcIFrame#window * @returns {Object} - The window object. */ window: function () { return this._window; }, /** * Destroys the iFrame element and clears all references.<br> * <b>Note:</b> This is automatically called when the owner panel is destroyed. * @function module:wcIFrame#destroy */ destroy: function () { // Remove all registered events. while (this._boundEvents.length) { this._panel.off(this._boundEvents[0].event, this._boundEvents[0].handler); this._boundEvents.shift(); } this.__clearFrame(); this._panel = null; this._layout = null; this.$container = null; this.$frame.remove(); this.$frame = null; this.$focus = null; }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// __init: function () { this.$frame = $('<div class="wcIFrame">'); this.$focus = $('<div class="wcIFrameFocus">'); this._panel.docker().$container.append(this.$frame); this.$frame.append(this.$focus); this._boundEvents.push({event: wcDocker.EVENT.VISIBILITY_CHANGED, handler: this.__onVisibilityChanged.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.BEGIN_DOCK, handler: this.__onBeginDock.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.END_DOCK, handler: this.__onEndDock.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.MOVE_STARTED, handler: this.__onMoveStarted.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.RESIZE_STARTED, handler: this.__onMoveStarted.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.MOVE_ENDED, handler: this.__onMoveFinished.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.RESIZE_ENDED, handler: this.__onMoveFinished.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.MOVED, handler: this.__onMoved.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.RESIZED, handler: this.__onMoved.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.ATTACHED, handler: this.__onAttached.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.DETACHED, handler: this.__updateFrame.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.GAIN_FOCUS, handler: this.__updateFrame.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.LOST_FOCUS, handler: this.__updateFrame.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.PERSISTENT_OPENED, handler: this.__updateFrame.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.PERSISTENT_CLOSED, handler: this.__updateFrame.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.CLOSED, handler: this.__onClosed.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.ORDER_CHANGED, handler: this.__onOrderChanged.bind(this)}); for (var i = 0; i < this._boundEvents.length; ++i) { this._panel.on(this._boundEvents[i].event, this._boundEvents[i].handler); } $(window).blur(this.__onBlur.bind(this)); }, __clearFrame: function () { if (this.$iFrame) { for (var i = 0; i < this._onClosedFuncs.length; ++i) { this._onClosedFuncs[i](); } this._onClosedFuncs = []; this.$iFrame[0].srcdoc = ''; this.$iFrame.remove(); this.$iFrame = null; this._window = null; } }, __updateFrame: function () { if (this.$frame && this._panel) { var floating = this._panel.isFloating(); this.$frame.toggleClass('wcIFrameFloating', floating); if (floating) { this.$frame.toggleClass('wcIFrameFloatingFocus', focus); } else { this.$frame.removeClass('wcIFrameFloatingFocus'); } this.$frame.toggleClass('wcIFramePanelHidden', !this._panel.isVisible()); if (this._panel && this._panel._parent && this._panel._parent.instanceOf('wcFrame')) { this.$frame.toggleClass('wcDrawer', this._panel._parent.isCollapser()); } } }, __focusFix: function () { // Fixes a bug where the frame stops responding to mouse wheel after // it has been assigned and unassigned pointer-events: none in css. this.$frame.css('left', parseInt(this.$frame.css('left')) + 1); this.$frame.css('left', parseInt(this.$frame.css('left')) - 1); }, __onHoverEnter: function () { this._isHovering = true; }, __onHoverExit: function () { this._isHovering = false; }, __onBlur: function () { if (this._isHovering) { this.__onFocus(); } }, __onFocus: function () { if (this._panel) { this.docker(this._panel).__focus(this._panel._parent); } }, __onVisibilityChanged: function () { this.__updateFrame(); if (this._panel.isVisible()) { this.__onMoved(); } }, __onBeginDock: function () { if (this.$frame) { this._isDocking = true; this.$frame.addClass('wcIFrameMoving'); } }, __onEndDock: function () { if (this.$frame) { this._isDocking = false; this.$frame.removeClass('wcIFrameMoving'); this.__focusFix(); } }, __onAttached: function() { this.$frame.css('z-index', ''); this.__updateFrame(); }, __onMoveStarted: function () { if (this.$frame && !this._isDocking) { this.$frame.addClass('wcIFrameMoving'); } }, __onMoveFinished: function () { if (this.$frame && !this._isDocking) { this.$frame.removeClass('wcIFrameMoving'); this.__focusFix(); } }, __onMoved: function () { if (this.$frame && this._panel) { // Size, position, and show the frame once the move is finished. var docker = this.docker(this._panel);//in base if(docker) { var dockerPos = docker.$container.offset(); var pos = this.$container.offset(); var width = this.$container.width(); var height = this.$container.height(); this.$frame.css('top', pos.top - dockerPos.top); this.$frame.css('left', pos.left - dockerPos.left); this.$frame.css('width', width); this.$frame.css('height', height); }else{ console.error('have no docker'); } } }, __onOrderChanged: function(layer) { this.$frame.css('z-index', layer+1); }, __onClosed: function () { this.destroy(); } }); // window['wcIFrame'] = Module; return Module; }); × Search results Close "},"layout.js.html":{"id":"layout.js.html","title":"Source: layout.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: layout.js /** @module wcLayout */ define([ "dcl/dcl", "./types" ], function (dcl, wcDocker) { /** * @class * The base class for all panel layouts. [Panels]{@link wcPanel}, [splitter widgets]{@link wcSplitter} * and [tab widgets]{@link wcTabFrame} contain these to organize their contents. */ var Module = dcl(null, { declaredClass: 'wcLayout', /** * @memberOf module:wcLayout * <b><i>PRIVATE</i> - <u>This should never be constructed directly by the user</u></b> * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element for this layout. * @param {wcLayout|wcSplitter|wcDocker} parent - The layout's parent object. */ constructor: function (container, parent) { /** * The outer container element of the panel. * * @member {external:jQuery~Object} */ this.$container = $(container); this._parent = parent; /** * The table DOM element for the layout. * * @member {external:jQuery~Object} */ this.$elem = null; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Adds an item into the layout, appending it to the main element. * @function module:wcLayout#addItem * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} item - A DOM element to add. */ addItem: function (item) { // Should be implemented by a sub-class. }, /** * Clears the contents of the layout and squashes all rows and columns from the grid. * @function module:wcLayout#clear */ clear: function () { // Should be implemented by a sub-class. }, /** * Retrieves the main element. * @function module:wcLayout#scene * @returns {external:jQuery~Object} - The div item that makes this layout scene. */ scene: function () { return this.$elem; }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function () { // Should be implemented by a sub-class. }, // Updates the size of the layout. __update: function () { // Should be implemented by a sub-class. }, // Checks if the mouse is in a valid anchor position for nesting another widget. // Params: // mouse The current mouse position. // same Whether we are hovering over the same panel that is being moved. // ghost An instance to the ghost object. // canSplit Whether the original panel can be split. // $elem The container element for the target panel. // title Whether the panel has a title bar visible. // isTopper Whether the item being dragged is the top title bar, as apposed to dragging a side or bottom tab/bar. // forceTabOrientation Force a specific tab orientation. // allowEdges Whether to allow edge docking. __checkAnchorDrop: function (mouse, same, ghost, canSplit, $elem, title, isTopper, forceTabOrientation, allowEdges) { var docker = this._parent.docker(); var width = $elem.outerWidth(); var height = $elem.outerHeight(); var offset = $elem.offset(); var titleSize = $elem.find('.wcFrameTitleBar').height(); if (!title) { titleSize = 0; } function __getAnchorSizes(value, w, h) { if (typeof value === 'number' || (typeof value === 'string' && value.indexOf('px', value.length - 2) !== -1)) { // Pixel sizing. value = parseInt(value); return { x: value, y: value }; } else if (typeof value === 'string' && value.indexOf('%', value.length - 1) !== -1) { value = parseInt(value) / 100; // Percentage sizing. return { x: w * value, y: h * value }; } else { // Invalid value. return {x: 0, y: 0}; } } var edgeAnchor = __getAnchorSizes(docker._options.edgeAnchorSize, docker.$container.outerWidth(), docker.$container.outerHeight()); var panelAnchor = __getAnchorSizes(docker._options.panelAnchorSize, width, height); // If the target panel has a title, hovering over it (on all sides) will cause stacking // and also change the orientation of the tabs (if enabled). if (title) { // Top title bar if ((!forceTabOrientation || forceTabOrientation === wcDocker.TAB.TOP) && mouse.y >= offset.top && mouse.y <= offset.top + titleSize && mouse.x >= offset.left && mouse.x <= offset.left + width) { // Stacking with top orientation. ghost.anchor(mouse, { x: offset.left - 2, y: offset.top - 2, w: width, h: titleSize - 2, loc: wcDocker.DOCK.STACKED, tab: wcDocker.TAB.TOP, item: this, self: same === wcDocker.TAB.TOP || (isTopper && same) }); return true; } // Any other tab orientation is only valid if tab orientation is enabled. else if (docker._canOrientTabs) { // Bottom bar if ((!forceTabOrientation || forceTabOrientation === wcDocker.TAB.BOTTOM) && mouse.y >= offset.top + height - titleSize && mouse.y <= offset.top + height && mouse.x >= offset.left && mouse.x <= offset.left + width) { // Stacking with bottom orientation. ghost.anchor(mouse, { x: offset.left - 2, y: offset.top + height - titleSize - 2, w: width, h: titleSize, loc: wcDocker.DOCK.STACKED, tab: wcDocker.TAB.BOTTOM, item: this, self: same === wcDocker.TAB.BOTTOM }); return true; } // Left bar else if ((!forceTabOrientation || forceTabOrientation === wcDocker.TAB.LEFT) && mouse.y >= offset.top && mouse.y <= offset.top + height && mouse.x >= offset.left && mouse.x <= offset.left + titleSize) { // Stacking with bottom orientation. ghost.anchor(mouse, { x: offset.left - 2, y: offset.top - 2, w: titleSize - 2, h: height, loc: wcDocker.DOCK.STACKED, tab: wcDocker.TAB.LEFT, item: this, self: same === wcDocker.TAB.LEFT }); return true; } // Right bar else if ((!forceTabOrientation || forceTabOrientation === wcDocker.TAB.RIGHT) && mouse.y >= offset.top && mouse.y <= offset.top + height && mouse.x >= offset.left + width - titleSize && mouse.x <= offset.left + width) { // Stacking with bottom orientation. ghost.anchor(mouse, { x: offset.left + width - titleSize - 2, y: offset.top - 2, w: titleSize, h: height, loc: wcDocker.DOCK.STACKED, tab: wcDocker.TAB.RIGHT, item: this, self: same === wcDocker.TAB.RIGHT }); return true; } } } // Test for edge anchoring. if (allowEdges && ghost._outer && ghost._inner) { var outerWidth = ghost._outer.$container.outerWidth(); var outerHeight = ghost._outer.$container.outerHeight(); var outerOffset = ghost._outer.$container.offset(); // Left edge if (mouse.y >= outerOffset.top && mouse.y <= outerOffset.top + outerHeight && mouse.x >= outerOffset.left + titleSize && mouse.x <= outerOffset.left + titleSize + edgeAnchor.x) { ghost.anchor(mouse, { x: outerOffset.left - 2, y: outerOffset.top - 2, w: outerWidth / 3, h: outerHeight, loc: wcDocker.DOCK.LEFT, item: ghost._inner, self: false }); return true; } // Right edge else if (mouse.y >= outerOffset.top && mouse.y <= outerOffset.top + outerHeight && mouse.x >= outerOffset.left + outerWidth - edgeAnchor.x - titleSize && mouse.x <= outerOffset.left + outerWidth - titleSize) { ghost.anchor(mouse, { x: outerOffset.left + outerWidth - (outerWidth / 3) - 2, y: outerOffset.top - 2, w: outerWidth / 3, h: outerHeight, loc: wcDocker.DOCK.RIGHT, item: ghost._inner, self: false }); return true; } // Top edge else if (mouse.y >= outerOffset.top + titleSize && mouse.y <= outerOffset.top + titleSize + edgeAnchor.y && mouse.x >= outerOffset.left && mouse.x <= outerOffset.left + outerWidth) { ghost.anchor(mouse, { x: outerOffset.left - 2, y: outerOffset.top - 2, w: outerWidth, h: outerHeight / 3, loc: wcDocker.DOCK.TOP, item: ghost._inner, self: false }); return true; } // Bottom edge else if (mouse.y >= outerOffset.top + outerHeight - titleSize - edgeAnchor.y && mouse.y <= outerOffset.top + outerHeight - titleSize && mouse.x >= outerOffset.left && mouse.x <= outerOffset.left + outerWidth) { ghost.anchor(mouse, { x: outerOffset.left - 2, y: outerOffset.top + outerHeight - (outerHeight / 3) - 2, w: outerWidth, h: outerHeight / 3, loc: wcDocker.DOCK.BOTTOM, item: ghost._inner, self: false }); return true; } } if (!canSplit) { return false; } // Check for placeholder. if (this._parent && this._parent.instanceOf('wcPanel') && this._parent._isPlaceholder) { ghost.anchor(mouse, { x: offset.left - 2, y: offset.top - 2, w: width, h: height, loc: wcDocker.DOCK.TOP, item: this, self: false }); return true; } if (width < height) { // Top docking. if (mouse.y >= offset.top && mouse.y <= offset.top + titleSize + panelAnchor.y && mouse.x >= offset.left && mouse.x <= offset.left + width) { ghost.anchor(mouse, { x: offset.left - 2, y: offset.top - 2, w: width, h: height * 0.5, loc: wcDocker.DOCK.TOP, item: this, self: false }); return true; } // Bottom side docking. if (mouse.y >= offset.top + height - panelAnchor.y - titleSize && mouse.y <= offset.top + height && mouse.x >= offset.left && mouse.x <= offset.left + width) { ghost.anchor(mouse, { x: offset.left - 2, y: offset.top + (height - height * 0.5) - 2, w: width, h: height * 0.5, loc: wcDocker.DOCK.BOTTOM, item: this, self: false }); return true; } } // Left side docking if (mouse.y >= offset.top && mouse.y <= offset.top + height) { if (mouse.x >= offset.left && mouse.x <= offset.left + panelAnchor.x + titleSize) { ghost.anchor(mouse, { x: offset.left - 2, y: offset.top - 2, w: width * 0.5, h: height, loc: wcDocker.DOCK.LEFT, item: this, self: false }); return true; } // Right side docking if (mouse.x >= offset.left + width - panelAnchor.x - titleSize && mouse.x <= offset.left + width) { ghost.anchor(mouse, { x: offset.left + width * 0.5 - 2, y: offset.top - 2, w: width * 0.5, h: height, loc: wcDocker.DOCK.RIGHT, item: this, self: false }); return true; } } if (width >= height) { // Top docking. if (mouse.y >= offset.top && mouse.y <= offset.top + panelAnchor.y + titleSize && mouse.x >= offset.left && mouse.x <= offset.left + width) { ghost.anchor(mouse, { x: offset.left - 2, y: offset.top - 2, w: width, h: height * 0.5, loc: wcDocker.DOCK.TOP, item: this, self: false }); return true; } // Bottom side docking. if (mouse.y >= offset.top + height - panelAnchor.y - titleSize && mouse.y <= offset.top + height && mouse.x >= offset.left && mouse.x <= offset.left + width) { ghost.anchor(mouse, { x: offset.left - 2, y: offset.top + (height - height * 0.5) - 2, w: width, h: height * 0.5, loc: wcDocker.DOCK.BOTTOM, item: this, self: false }); return true; } } return false; }, // Gets, or Sets a new container for this layout. // Params: // $container If supplied, sets a new container for this layout. // Returns: // JQuery collection The current container. __container: function ($container) { if (typeof $container === 'undefined') { return this.$container; } this.$container = $container; if (this.$container) { this.$container.append(this.$elem); } else { this.$elem.remove(); } return this.$container; }, // Destroys the layout. __destroy: function () { this.__container(null); this._parent = null; this.clear(); this.$elem.remove(); this.$elem = null; } }); return Module; }); × Search results Close "},"layoutsimple.js.html":{"id":"layoutsimple.js.html","title":"Source: layoutsimple.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: layoutsimple.js /** @module wcLayoutSimple */ define([ "dcl/dcl", "./types", "./layout" ], function (dcl, wcDocker, wcLayout) { /** * @class * A simple layout for containing elements in a panel. [Panels]{@link wcPanel}, [splitter widgets]{@link wcSplitter} * and [tab widgets]{@link wcTabFrame} can optionally contain these instead of the default {@link wcLayoutTable}. */ var Module = dcl(wcLayout, { declaredClass: 'wcLayoutSimple', /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Adds an item into the layout, appending it to the main element. * @function module:wcLayoutSimple#addItem * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} item - A DOM element to add. */ addItem: function (item) { this.$elem.append(item); }, /** * Clears the contents of the layout and squashes all rows and columns from the grid. * @function module:wcLayoutSimple#clear */ clear: function () { this.$elem.remove(); this.$elem = null; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function () { this.$elem = $('<div class="wcLayout wcWide wcTall"></div>'); this.__container(this.$container); }, // Updates the size of the layout. __update: function () { }, }); return Module; }); × Search results Close "},"layouttable.js.html":{"id":"layouttable.js.html","title":"Source: layouttable.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: layouttable.js /** @module wcLayoutTable */ define([ "dcl/dcl", "./types", "./layout" ], function (dcl, wcDocker, wcLayout) { /** * @class module:wcLayoutTable * A gridded layout for arranging elements. [Panels]{@link wcPanel}, [splitter widgets]{@link wcSplitter} * and [tab widgets]{@link wcTabFrame} contain these by default to handle their contents. */ var Module = dcl(wcLayout, { declaredClass: 'wcLayoutTable', /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Adds an item into the layout, expanding the grid size if necessary. * @function module:wcLayoutTable#addItem * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} item - A DOM element to add. * @param {Number} [x=0] - The horizontal grid position to place the element. * @param {Number} [y=0] - The vertical grid position to place the element. * @param {Number} [w=1] - The number of horizontal cells this item will take within the grid. * @param {Number} [h=1] - The number of vertical cells this item will take within the grid. * @returns {module:wcLayoutTable~tableItem|Boolean} The table data element of the cell that contains the item, or false if there was a problem. */ addItem: function (item, x, y, w, h) { if (typeof x === 'undefined' || x < 0) { x = 0; } if (typeof y === 'undefined' || y < 0) { y = 0; } if (typeof w === 'undefined' || w <= 0) { w = 1; } if (typeof h === 'undefined' || h <= 0) { h = 1; } this.__resizeGrid(x + w - 1, y + h - 1); if (w > 1 || h > 1) { if (!this.__mergeGrid(x, y, w, h)) { return false; } } this._grid[y][x].$el.append($(item)); return this.item(x, y); }, /** * Retrieves the table item at a given grid position, if it exists. * Note, if an item spans multiple cells, only the top-left most * cell will actually contain the table item. * @function module:wcLayoutTable#item * @param {Number} x - The horizontal grid position. * @param {Number} y - The vertical grid position. * @returns {module:wcLayoutTable~tableItem|Boolean} - The table item, or false if none was found. */ item: function (x, y) { if (y >= this._grid.length) { return false; } if (x >= this._grid[y].length) { return false; } // Some cells are a merging of multiple cells. If this cell is // part of a merge for another cell, use that cell instead. // if (this._grid[y][x].x < 0 || this._grid[y][x].y < 0) { // var grid = this._grid[y][x]; // x -= grid.x; // y -= grid.y; // } var self = this; /** * The table item is an object that represents one cell in the layout table, it contains * convenient methods for cell alteration and supports chaining. Its purpose is * to remove the need to alter &lt;tr&gt; and &lt;td&gt; elements of the table directly. * @version 3.0.0 * @example myPanel.addItem(domNode).css('text-align', 'right').css('border', '1px solid black').stretch('100%', '100%'); * @typedef module:wcLayoutTable#tableItem * @property {jQuery~Object} $ - If you truely need the table cell [jQuery object]{@link jQuery~Object}, here it is. * @property {module:wcLayoutTable~tableItem_css} css - Wrapper to alter [jQuery's css]{@link http://api.jquery.com/css/} function. * @property {module:wcLayoutTable~tableItem_stretch} stretch - More reliable method for setting the table item width/height values. */ var myItem = { $: self._grid[y][x].$el, /** * <small><i>This function is found in {@link module:wcLayoutTable~tableItem}.</small></i><br> * A wrapper for [jQuery's css]{@link http://api.jquery.com/css/} function. * <b>Note:</b> It is recommended that you use [stretch]{@link wcLayoutTable~stretch} if you intend to alter width or height styles. * @version 3.0.0 * @function module:wcLayoutTable#tableItem_css * @param {String} style - The style attribute to alter. * @param {String} [value] - The value of the attribute. If omitted, the current value of the attribute is returned instead of the [tableItem]{@link module:wcLayoutTable~tableItem} instance. * @returns {module:wcLayoutTable~tableItem|String} - Self, for chaining, unless the value parameter was omitted. */ css: function (style, value) { if (self._grid[y][x].$el) { if (value === undefined) { return self._grid[y][x].$el.css(style); } self._grid[y][x].$el.css(style, value); } return myItem; }, /** * <small><i>This function is found in {@link module:wcLayoutTable~tableItem}.</small></i><br> * Sets the stretch amount for the current table item. This is more reliable than * assigning width and height style attributes directly on the table item. * @version 3.0.0 * @function module:wcLayoutTable#tableItem_stretch * @param {Number|String} [sx] - The horizontal stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. * @param {Number|String} [sy] - The vertical stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. * @returns {module:wcLayoutTable~tableItem} - Self, for chaining. */ stretch: function (width, height) { self.itemStretch(x, y, width, height); return myItem; } }; return myItem; }, /** * Sets the stretch amount for a given table item. This is more reliable than * assigning width and height style attributes directly on the table item. * @version 3.0.0 * @function module:wcLayoutTable#itemStretch * @param {Number} x - The horizontal grid position. * @param {Number} y - The vertical grid position. * @param {Number|String} [sx] - The horizontal stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. * @param {Number|String} [sy] - The vertical stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. * @returns {Boolean} - Success or failure. A failure generally means your grid position was a merged grid cell. */ itemStretch: function (x, y, sx, sy) { var wasBatched = this._batchProcess; this._batchProcess = true; this.__resizeGrid(x, y); var grid = this._grid[y][x]; if (grid.x < 0 || grid.y < 0) { return false; } if (sx !== undefined) { grid.sx = sx; } if (sy !== undefined) { grid.sy = sy; } this._batchProcess = wasBatched; if (!wasBatched) { this.__resizeGrid(0, 0); } return true; }, /** * Clears the contents of the layout and squashes all rows and columns from the grid. * @function module:wcLayoutTable#clear */ clear: function () { var showGrid = this.showGrid(); var spacing = this.gridSpacing(); var alternate = this.gridAlternate(); this.$elem.remove(); this.__init(); this.showGrid(showGrid); this.gridSpacing(spacing); this.gridAlternate(alternate); this._grid = []; }, /** * Begins a batch operation. Basically it refrains from constructing * the layout grid, which causes a reflow, on each item added. Instead, * The grid is only generated at the end once [wcLayoutTable.finishBatch]{@link wcLayoutTable#finishBatch} is called. * @function module:wcLayoutTable#startBatch */ startBatch: function () { this._batchProcess = true; }, /** * Ends a batch operation. * @See module:wcLayoutTable#startBatch * @function module:wcLayoutTable#finishBatch */ finishBatch: function () { this._batchProcess = false; this.__resizeGrid(0, 0); }, /** * Gets, or Sets whether the layout grid cells should draw an outline. * @function module:wcLayoutTable#showGrid * @param {Boolean} [enabled] - If supplied, will set the grid cell border visibility. * @returns {Boolean} - The current visibility state of the grid cells. */ showGrid: function (enabled) { if (typeof enabled !== 'undefined') { this.$elem.toggleClass('wcLayoutGrid', enabled); } return this.$elem.hasClass('wcLayoutGrid'); }, /** * Gets, or Sets the spacing between cell borders. * @function module:wcLayoutTable#gridSpacing * @param {Number} [size] - If supplied, sets the pixel size of the spacing between cells. * @returns {Number} - The current cell spacing in pixels. */ gridSpacing: function (size) { if (typeof size !== 'undefined') { this.$elem.css('border-spacing', size + 'px'); } return parseInt(this.$elem.css('border-spacing')); }, /** * Gets, or Sets whether the table rows alternate in color based on the theme. * @function module:wcLayoutTable#gridAlternate * @params {Boolean} [enabled] - If supplied, will set whether the grid alternates in color. * @returns {Boolean} - Whether the grid alternates in color. */ gridAlternate: function (enabled) { if (typeof enabled !== 'undefined') { this.$elem.toggleClass('wcLayoutGridAlternate', enabled); } return this.$elem.hasClass('wcLayoutGridAlternate'); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function () { this.$elem = $('<table class="wcLayout wcWide wcTall"></table>'); this.$elem.append($('<tbody></tbody>')); this._grid = []; this.__container(this.$container); }, // Updates the size of the layout. __update: function () { }, // Resizes the grid to fit a given position. // Params: // width The width to expand to. // height The height to expand to. __resizeGrid: function (width, height) { for (var y = 0; y <= height; ++y) { if (this._grid.length <= y) { var row = []; row.$row = $('<tr>'); this._grid.push(row); } for (var x = 0; x <= width; ++x) { if (this._grid[y].length <= x) { this._grid[y].push({ $el: $('<td>'), x: 0, y: 0, sx: '', sy: '' }); } } } if (!this._batchProcess) { var $oldBody = this.$elem.find('tbody'); $('.wcDockerTransition').append($oldBody); var $newBody = $('<tbody>'); for (var y = 0; y < this._grid.length; ++y) { var $row = null; for (var x = 0; x < this._grid[y].length; ++x) { var item = this._grid[y][x]; if (item.$el) { if (!$row) { $row = this._grid[y].$row; $newBody.append($row); } item.$el.css('width', item.sx); item.$el.css('height', item.sy); $row.append(item.$el); } } } this.$elem.append($newBody); $oldBody.remove(); } }, // Merges cells in the layout. // Params: // x, y Cell position to begin merge. // w, h The width and height to merge. // Returns: // true Cells were merged succesfully. // false Merge failed, either because the grid position was out of bounds // or some of the cells were already merged. __mergeGrid: function (x, y, w, h) { // Make sure each cell to be merged is not already merged somewhere else. for (var yy = 0; yy < h; ++yy) { for (var xx = 0; xx < w; ++xx) { var item = this._grid[y + yy][x + xx]; if (!item.$el || item.x !== 0 || item.y !== 0) { return false; } } } // Now merge the cells here. var item = this._grid[y][x]; if (w > 1) { item.$el.attr('colspan', '' + w); item.x = w - 1; } if (h > 1) { item.$el.attr('rowspan', '' + h); item.y = h - 1; } for (var yy = 0; yy < h; ++yy) { for (var xx = 0; xx < w; ++xx) { if (yy !== 0 || xx !== 0) { var item = this._grid[y + yy][x + xx]; item.$el.remove(); item.$el = null; item.x = -xx; item.y = -yy; } } } return true; }, }); return Module; }); × Search results Close "},"panel.js.html":{"id":"panel.js.html","title":"Source: panel.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: panel.js /** @module wcPanel */ define([ "dcl/dcl", "./types", "./base" ], function (dcl, wcDocker, base) { /** * @class module:wcPanel * The public interface for the docking panel, it contains a number of convenience * functions and layout that manages the contents of the panel. */ var Module = dcl(base, { declaredClass: 'wcPanel', /** * @memberOf module:wcPanel * <b><i>PRIVATE</i> - Use [wcDocker.addPanel]{@link module:wcDocker#addPanel}, [wcDocker.removePanel]{@link module:wcDocker#removePanel}, and * [wcDocker.movePanel]{@link module:wcDocker#movePanel} to manage panels, <u>this should never be constructed directly * by the user.</u></b> * @param {module:wcBase} parent - The parent. * @param {String} type - The name identifier for the panel. * @param {module:wcPanel~options} [options] - An options object passed from registration of the panel. */ constructor: function (parent, type, options) { /** * An options object for the [panel]{@link module:wcPanel} constructor. * @typedef module:wcPanel~options * @property {String} [icon] - A CSS classname that represents the icon that should display on this panel's tab widget. * @property {String} [faicon] - An icon name using the [Font-Awesome]{@link http://fortawesome.github.io/Font-Awesome/} library. * @property {String|Boolean} [title] - A custom title to display for this panel, if false, title bar will not be shown. * @property {Number|String} [detachToWidth=600] - Determines the new width when the panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. * @property {Number|String} [detachToHeight=400] - Determines the new height when the panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. */ /** * The outer container element of the panel. * @member {external:jQuery~Object} */ this.$container = null; this._parent = parent; this.$icon = null; this.$title = null; this.$titleText = null; this.$loading = null; this._panelObject = null; this._initialized = false; this._collapseDirection = undefined; this._type = type; this._title = type; this._titleVisible = true; this._options = options; this._layout = null; this._buttonList = []; this._actualPos = { x: 0.5, y: 0.5 }; this._actualSize = { x: 0, y: 0 }; this._resizeData = { time: -1, timeout: false, delta: 150 }; this._pos = { x: 0.5, y: 0.5 }; this._moveData = { time: -1, timeout: false, delta: 150 }; this._size = { x: -1, y: -1 }; this._minSize = { x: 100, y: 100 }; this._maxSize = { x: Infinity, y: Infinity }; this._scroll = { x: 0, y: 0 }; this._scrollable = { x: true, y: true }; this._collapsible = true; this._overflowVisible = false; this._moveable = true; this._detachable = true; this._closeable = true; this._resizeVisible = true; this._isVisible = false; this._events = {}; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets, or Sets the title for this panel. * Titles appear in the tab widget associated with the panel. * @function module:wcPanel#title * @param {String|Boolean} title - If supplied, sets the new title (this can be html text). If false, the title bar will be removed. * @returns {String|Boolean} - The current title. */ title: function (title) { if (typeof title !== 'undefined') { if (title === false) { this._titleVisible = false; this.$titleText.html(this._type); } else { this._title = title; this.$titleText.html(title); } if (this.$icon) { this.$titleText.prepend(this.$icon); } if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__updateTabs(); } } return this._title; }, /** * Retrieves the registration info of the panel as declared from * [wcDocker.registerPanelType]{@link module:wcDocker#registerPanelType}; * @function module:wcPanel#info * @returns {module:wcDocker~registerOptions} - Registered options of the panel type. * @see [wcDocker.panelTypeInfo]{@link module:wcDocker#panelTypeInfo}. */ info: function () { return this.docker().panelTypeInfo(this._type); }, /** * Retrieves the layout instance. * @function module:wcPanel#layout * @returns {module:wcLayoutSimple|wcLayoutTable} - The layout instance. */ layout: function () { return this._layout; }, /** * Brings this panel into focus. If it is floating, it will be moved to the front of all other panels. * @function module:wcPanel#focus * @param {Boolean} [flash] - If true, in addition to bringing the panel into focus, it will also flash for the user. */ focus: function (flash) { var docker = this.docker(); if (docker) { docker.__focus(this._parent, flash); for (var i = 0; i < this._parent._panelList.length; ++i) { if (this._parent._panelList[i] === this && this._parent._curTab !== i) { this._parent.panel(i); break; } } } }, /** * @callback wcPanel~CollapseDirection * @see module:wcPanel#collapseDirection * @param {module:wcDocker~Bounds} bounds - The bounds of this panel relative to the wcDocker container. * @returns {module:wcDocker.DOCK} - A collapse direction to use, must only be LEFT, RIGHT, or BOTTOM */ /** * Gets, or Sets the collapse direction for this panel. * @function module:wcPanel#collapseDirection * @param {module:wcPanel~CollapseDirection|wcDocker.DOCK} direction - The collapse direction to use for this panel.<br>If this value is omitted, the default collapse direction will be used. */ collapseDirection: function (direction) { this._collapseDirection = direction; }, /** * Retrieves whether this panel can be seen by the user. * @function module:wcPanel#isVisible * @returns {Boolean} - Visibility state. */ isVisible: function () { return this._isVisible; }, /** * Retrieves whether this panel is floating. * @function module:wcPanel#isFloating * @returns {Boolean} */ isFloating: function () { if (this._parent && this._parent.instanceOf('wcFrame')) { return this._parent._isFloating; } return false; }, /** * Retrieves whether this panel is in focus. * @function module:wcPanel#isInFocus * @return {Boolean} */ isInFocus: function () { var docker = this.docker(); if (docker && this._parent && this._parent.instanceOf('wcFrame')) { return this._parent === docker._focusFrame; } return false; }, /** * Creates a new custom button that will appear in the title bar when the panel is active. * @function module:wcPanel#addButton * @param {String} name - The name of the button, to identify it later. * @param {String} className - A CSS class name to apply to the button. * @param {String} text - Text to apply to the button. * @param {String} tip - Tooltip text for the user. * @param {Boolean} [isTogglable] - If true, will make the button toggle on and off per click. * @param {String} [toggleClassName] - If this button is toggleable, you can designate an optional CSS class name that will replace the original class name. */ addButton: function (name, className, text, tip, isTogglable, toggleClassName) { this._buttonList.push({ name: name, className: className, toggleClassName: toggleClassName, text: text, tip: tip, isTogglable: isTogglable, isToggled: false }); if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__update(); } }, /** * Removes a custom button from the panel. * @function module:wcPanel#removeButton * @param {String} name - The name identifier for the button to remove. * @returns {Boolean} - Success or failure. */ removeButton: function (name) { for (var i = 0; i < this._buttonList.length; ++i) { if (this._buttonList[i].name === name) { this._buttonList.splice(i, 1); if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__onTabChange(); } if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__update(); } return true; } } return false; }, /** * Gets, or Sets the current toggle state of a custom button that was * added using [wcPanel.addButton]{@link module:wcPanel#addButton}. * @function module:wcPanel#buttonState * @param {String} name - The name identifier of the button. * @param {Boolean} [toggleState] - If supplied, will assign a new toggle state to the button. * @returns {Boolean} - The current toggle state of the button. */ buttonState: function (name, toggleState) { for (var i = 0; i < this._buttonList.length; ++i) { if (this._buttonList[i].name === name) { if (typeof toggleState !== 'undefined') { this._buttonList[i].isToggled = toggleState; if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__onTabChange(); } } if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__update(); } return this._buttonList[i].isToggled; } } return false; }, /** * Gets, or Sets the default position of the panel if it is floating. <b>Warning: after the panel has been initialized, this value no longer reflects the current position of the panel.</b> * @function module:wcPanel#initPos * @param {Number|String} [x] - If supplied, sets the horizontal position of the floating panel. Can be a percentage position, or a string with a 'px' or '%' suffix. * @param {Number|String} [y] - If supplied, sets the vertical position of the floating panel. Can be a percentage position, or a string with a 'px' or '%' suffix. * @returns {module:wcDocker~Coordinate} - The current default position of the panel. */ initPos: function (x, y) { if (typeof x !== 'undefined') { var docker = this.docker(); if (docker) { this._pos.x = docker.__stringToPercent(x, docker.$container.width()); } else { this._pos.x = x; } } if (typeof y !== 'undefined') { var docker = this.docker(); if (docker) { this._pos.y = docker.__stringToPercent(y, docker.$container.height()); } else { this._pos.y = y; } } return {x: this._pos.x, y: this._pos.y}; }, /** * Gets, or Sets the desired size of the panel. <b>Warning: after the panel has been initialized, this value no longer reflects the current size of the panel.</b> * @function module:wcPanel#initSize * @param {Number|String} [x] - If supplied, sets the desired initial horizontal size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @param {Number|String} [y] - If supplied, sets the desired initial vertical size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @returns {module:wcDocker~Size} - The current initial size of the panel. */ initSize: function (x, y) { if (typeof x !== 'undefined') { var docker = this.docker(); if (docker) { this._size.x = docker.__stringToPixel(x, docker.$container.width()); } else { this._size.x = x; } } if (typeof y !== 'undefined') { var docker = this.docker(); if (docker) { this._size.y = docker.__stringToPixel(y, docker.$container.height()); } else { this._size.y = y; } } return {x: this._size.x, y: this._size.y}; }, /** * Gets, or Sets the minimum size constraint of the panel. * @function module:wcPanel#minSize * @param {Number|String} [x] - If supplied, sets the desired minimum horizontal size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @param {Number|String} [y] - If supplied, sets the desired minimum vertical size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @returns {module:wcDocker~Size} - The current minimum size. */ minSize: function (x, y) { if (typeof x !== 'undefined') { var docker = this.docker(); if (docker) { this._minSize.x = docker.__stringToPixel(x, docker.$container.width()); } else { this._minSize.x = x; } } if (typeof y !== 'undefined') { var docker = this.docker(); if (docker) { this._minSize.y = docker.__stringToPixel(y, docker.$container.height()); } else { this._minSize.y = y; } } return {x: this._minSize.x, y: this._minSize.y}; }, /** * Gets, or Sets the maximum size constraint of the panel. * @function module:wcPanel#maxSize * @param {Number|String} [x] - If supplied, sets the desired maximum horizontal size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @param {Number|String} [y] - If supplied, sets the desired maximum vertical size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. * @returns {module:wcDocker~Size} - The current maximum size. */ maxSize: function (x, y) { if (typeof x !== 'undefined') { var docker = this.docker(); if (docker) { this._maxSize.x = docker.__stringToPixel(x, docker.$container.width()); } else { this._maxSize.x = x; } } if (typeof y !== 'undefined') { var docker = this.docker(); if (docker) { this._maxSize.y = docker.__stringToPixel(y, docker.$container.height()); } else { this._maxSize.y = y; } } return {x: this._maxSize.x, y: this._maxSize.y}; }, /** * Retrieves the width of the panel contents. * @function module:wcPanel#width * @returns {Number} - Panel width. */ width: function () { if (this.$container) { return this.$container.width(); } return 0.0; }, /** * Retrieves the height of the panel contents. * @function module:wcPanel#height * @returns {Number} - Panel height. */ height: function () { if (this.$container) { return this.$container.height(); } return 0.0; }, /** * Sets the icon for the panel, shown in the panels tab widget. Must be a css class name that contains the icon. * @function module:wcPanel#icon * @param {String} icon - The icon class name. */ icon: function (icon) { if (!this.$icon) { this.$icon = $('<div>'); this.$titleText.prepend(this.$icon); } this.$icon.removeClass(); this.$icon.addClass('wcTabIcon ' + icon); if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__updateTabs(); } }, /** * Sets the icon for the panel, shown in the panels tab widget, * to an icon defined from the [Font-Awesome]{@link http://fortawesome.github.io/Font-Awesome/} library. * @function module:wcPanel#faicon * @param {String} icon - The font-awesome icon name. */ faicon: function (icon) { if (!this.$icon) { this.$icon = $('<div>'); this.$titleText.prepend(this.$icon); } this.$icon.removeClass(); this.$icon.addClass('wcTabIcon fa fa-fw fa-' + icon); if (this._parent && this._parent.instanceOf('wcFrame')) { this._parent.__updateTabs(); } }, /** * Gets, or Sets whether the window is scrollable. * @function module:wcPanel#scrollable * @param {Boolean} [x] - If supplied, assigns whether the window is scrollable in the horizontal direction. * @param {Boolean} [y] - If supplied, assigns whether the window is scrollable in the vertical direction. * @returns {module:wcDocker~Scrollable} - The current scrollable status. */ scrollable: function (x, y) { if (typeof x !== 'undefined') { this._scrollable.x = x ? true : false; this._scrollable.y = y ? true : false; } return {x: this._scrollable.x, y: this._scrollable.y}; }, /** * Gets, or Sets the scroll position of the panel's contents if it is scrollable; See [wcPanel.scrollable]{@link module:wcPanel#scrollable}). * @function module:wcPanel#scroll * @param {Number} [x] - If supplied, sets the scroll horizontal position of the panel. * @param {Number} [y] - If supplied, sets the scroll vertical position of the panel. * @param {Number} [duration] - If supplied, will animate the scroll movement with the supplied duration (in milliseconds). * @returns {module:wcDocker~Coordinate} The current scroll position. */ scroll: function (x, y, duration) { if (!this.$container) { return {x: 0, y: 0}; } if (typeof x !== 'undefined') { if (duration) { this.$container.parent().stop().animate({ scrollLeft: x, scrollTop: y }, duration); } else { this.$container.parent().scrollLeft(x); this.$container.parent().scrollTop(y); } } return { x: this.$container.parent().scrollLeft(), y: this.$container.parent().scrollTop() }; }, /** * Gets, or Sets whether this panel can be collapsed to the side or bottom.<br> * This only works if the collapse feature is enabled {@link module:wcDocker~Options}. * @function module:wcPanel#collapsible * @param {Boolean} [enabled] - If supplied, assigns whether collapsing is enabled. * @returns {Boolean} - The current collapsible enabled state. */ collapsible: function (enabled) { if (typeof enabled !== 'undefined') { this._collapsible = enabled ? true : false; } return this._collapsible; }, /** * Gets, or Sets whether overflow on this panel is visible. * Use this if a child element within this panel is intended to 'popup' and be visible outside of its parent area. * @function module:wcPanel#overflowVisible * @param {Boolean} [visible] - If supplied, assigns whether overflow is visible. * @returns {Boolean} - The current overflow visibility. */ overflowVisible: function (visible) { if (typeof visible !== 'undefined') { this._overflowVisible = visible ? true : false; } return this._overflowVisible; }, /** * Gets, or Sets whether the contents of the panel are visible on resize. * Use this if the panel has extremely expensive contents which take a long time to resize. * @function module:wcPanel#resizeVisible * @param {Boolean} [visible] - If supplied, assigns whether panel contents are visible during resize. * @returns {Boolean} - The current resize visibility. */ resizeVisible: function (visible) { if (typeof visible !== 'undefined') { this._resizeVisible = visible ? true : false; } return this._resizeVisible; }, /** * Sets, or Gets the moveable status of the window. * Note: Other panels can not dock beside a non-moving panel as doing so could cause it to move. * @function module:wcPanel#moveable * @param {Boolean} [enabled] - If supplied, assigns whether this panel can be moved. * @returns {Boolean} - Whether the panel is moveable. */ moveable: function (enabled) { if (typeof enabled !== 'undefined') { this._moveable = enabled ? true : false; this.$title.toggleClass('wcNotMoveable', !this._moveable); } return this._moveable; }, /** * Sets, or Gets whether this panel can be detached into a floating panel. * @function module:wcPanel#detachable * @param {Boolean} [enabled] - If supplied, assigns whether this panel can be detached. * @returns {Boolean} - Whether this panel can detach. */ detachable: function(enabled) { if (typeof enabled !== 'undefined') { this._detachable = enabled ? true: false; } return this._detachable; }, /** * Gets, or Sets whether this dock window can be closed by the user. * Note: The panel can still be closed programmatically. * @function module:wcPanel#closeable * @param {Boolean} [enabled] - If supplied, toggles whether it can be closed. * @returns {Boolean} the current closeable status. */ closeable: function (enabled) { if (typeof enabled !== 'undefined') { this._closeable = enabled ? true : false; if (this._parent) { this._parent.__update(); } } return this._closeable; }, /** * Forces the window to close. * @function module:wcPanel#close */ close: function () { var docker = this.docker(); if (docker) { docker.__closePanel(this); } }, /** * Shows the loading screen. * @function module:wcPanel#startLoading * @param {String} [label] - An optional label to display. * @param {Number} [opacity=0.4] - If supplied, assigns a custom opacity value to the loading screen. * @param {Number} [textOpacity=1] - If supplied, assigns a custom opacity value to the loading icon and text displayed. */ startLoading: function (label, opacity, textOpacity) { if (!this.$loading) { this.$loading = $('<div class="wcLoadingContainer"></div>'); this.$container.append(this.$loading); var $background = $('<div class="wcLoadingBackground"></div>'); if (typeof opacity !== 'number') { opacity = 0.4; } this.$loading.append($background); var $icon = $('<div class="wcLoadingIconContainer"><i class="wcLoadingIcon ' + this.docker()._options.loadingClass + '"></i></div>'); this.$loading.append($icon); if (label) { var $label = $('<span class="wcLoadingLabel">' + label + '</span>'); this.$loading.append($label); } if (typeof textOpacity !== 'number') { textOpacity = 1; } // Override opacity values if the global loading screen is active. if (this.docker().$loading) { opacity = 0; textOpacity = 0; } $background.css('opacity', opacity); $icon.css('opacity', textOpacity); if ($label) { $label.css('opacity', textOpacity); } } }, /** * Hides the loading screen. * @function module:wcPanel#finishLoading * @param {Number} [fadeDuration=0] - If supplied, assigns a fade out duration for the loading screen. */ finishLoading: function (fadeDuration) { if (this.$loading) { if (fadeDuration > 0) { var self = this; this.$loading.fadeOut(fadeDuration, function () { self.$loading.remove(); self.$loading = null; self.docker().__testLoadFinished(); }); } else { this.$loading.remove(); this.$loading = null; this.docker().__testLoadFinished(); } } }, /** * Registers an [event]{@link module:wcDocker.EVENT} associated with this panel. * @function module:wcPanel#on * @param {String} eventType - The event type, can be a custom event string or a [predefined event]{@link module:wcDocker.EVENT}. * @param {module:wcDocker#onEvent} handler - An event handler function to be called when the event is fired. * @returns {Boolean} - Event registration success or failure. */ on: function (eventType, handler) { if (!eventType) { return false; } if (!this._events[eventType]) { this._events[eventType] = []; } if (this._events[eventType].indexOf(handler) !== -1) { return false; } this._events[eventType].push(handler); return true; }, /** * Unregisters an [event]{@link module:wcDocker.EVENT} associated with this panel. * @function module:wcPanel#off * @param {module:wcDocker.EVENT} eventType - The event type, can be a custom event string or a [predefined event]{@link module:wcDocker.EVENT}. * @param {module:wcDocker~event:onEvent} [handler] - The handler function registered with the event. If omitted, all events registered to the event type are unregistered. */ off: function (eventType, handler) { if (typeof eventType === 'undefined') { this._events = {}; return; } else { if (this._events[eventType]) { if (typeof handler === 'undefined') { this._events[eventType] = []; } else { for (var i = 0; i < this._events[eventType].length; ++i) { if (this._events[eventType][i] === handler) { this._events[eventType].splice(i, 1); break; } } } } } }, /** * Triggers an [event]{@link module:wcDocker.EVENT} of a given type to all panels, including itself. * @function module:wcPanel#trigger * @param {module:wcDocker.EVENT} eventType - The event type, can be a custom event string or a [predefined event]{@link module:wcDocker.EVENT}. * @param {Object} [data] - A custom data object to pass into all handlers. * @returns {Object[]} results - Returns an array with all results returned by event handlers. */ trigger: function (eventType, data) { var docker = this.docker(); if (docker) { return docker.trigger(eventType, data); } return []; }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function () { var layoutClass = (this._options && this._options.layout) || 'wcLayoutTable'; this._layout = new (this.docker().__getClass(layoutClass))(this.$container, this); this.$title = $('<div class="wcPanelTab">'); this.$titleText = $('<div>' + this._title + '</div>'); this.$title.append(this.$titleText); if (this._options.hasOwnProperty('title')) { this.title(this._options.title); } if (this._options.icon) { this.icon(this._options.icon); } if (this._options.faicon) { this.faicon(this._options.faicon); } }, // Updates the size of the layout. __update: function () { var docker = this.docker(); if (!docker) return; this._layout.__update(); if (!this.$container) { return; } if (this._resizeVisible) { this._parent.$frame.removeClass('wcHideOnResize'); } else { this._parent.$frame.addClass('wcHideOnResize'); } if (!this._initialized) { this._initialized = true; var self = this; setTimeout(function () { self.__trigger(wcDocker.EVENT.INIT); docker.__testLoadFinished(); }, 0); } else { this.__trigger(wcDocker.EVENT.UPDATED); } var width = this.$container.width(); var height = this.$container.height(); if (this._actualSize.x !== width || this._actualSize.y !== height) { this._resizeData.time = new Date(); if (!this._resizeData.timeout) { this._resizeData.timeout = true; setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); this.__trigger(wcDocker.EVENT.RESIZE_STARTED, {width: this._actualSize.x, height: this._actualSize.y}); } this._actualSize.x = width; this._actualSize.y = height; this.__trigger(wcDocker.EVENT.RESIZED, {width: this._actualSize.x, height: this._actualSize.y}); } var offset = this.$container.offset(); if (this._actualPos.x !== offset.left || this._actualPos.y !== offset.top) { this._moveData.time = new Date(); if (!this._moveData.timeout) { this._moveData.timeout = true; setTimeout(this.__moveEnd.bind(this), this._moveData.delta); this.__trigger(wcDocker.EVENT.MOVE_STARTED, {x: this._actualPos.x, y: this._actualPos.y}); } this._actualPos.x = offset.left; this._actualPos.y = offset.top; this.__trigger(wcDocker.EVENT.MOVED, {x: this._actualPos.x, y: this._actualPos.y}); } }, __resizeEnd: function () { if (new Date() - this._resizeData.time < this._resizeData.delta) { setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); } else { this._resizeData.timeout = false; this.__trigger(wcDocker.EVENT.RESIZE_ENDED, {width: this._actualSize.x, height: this._actualSize.y}); } }, __moveEnd: function () { if (new Date() - this._moveData.time < this._moveData.delta) { setTimeout(this.__moveEnd.bind(this), this._moveData.delta); } else { this._moveData.timeout = false; this.__trigger(wcDocker.EVENT.MOVE_ENDED, {x: this._actualPos.x, y: this._actualPos.y}); } }, __isVisible: function (inView) { if (this._isVisible !== inView) { this._isVisible = inView; this.__trigger(wcDocker.EVENT.VISIBILITY_CHANGED, this._isVisible); } }, // Saves the current panel configuration into a meta // object that can be used later to restore it. __save: function () { var data = {}; data.type = 'wcPanel'; data.panelType = this._type; // data.title = this._title; data.size = { x: this._size.x, y: this._size.y }; // data.minSize = { // x: this._minSize.x, // y: this._minSize.y, // }; // data.maxSize = { // x: this._maxSize.x, // y: this._maxSize.y, // }; // data.scrollable = { // x: this._scrollable.x, // y: this._scrollable.y, // }; // data.moveable = this._moveable; // data.closeable = this._closeable; // data.resizeVisible = this.resizeVisible(); data.customData = {}; this.__trigger(wcDocker.EVENT.SAVE_LAYOUT, data.customData); return data; }, // Restores a previously saved configuration. __restore: function (data, docker) { // this._title = data.title; if (data.size) { this._size.x = data.size.x; this._size.y = data.size.y; } // this._minSize.x = data.minSize.x; // this._minSize.y = data.minSize.y; // this._maxSize.x = data.maxSize.x; // this._maxSize.y = data.maxSize.y; // this._scrollable.x = data.scrollable.x; // this._scrollable.y = data.scrollable.y; // this._moveable = data.moveable; // this._closeable = data.closeable; // this.resizeVisible(data.resizeVisible); this.__trigger(wcDocker.EVENT.RESTORE_LAYOUT, data.customData); }, // Triggers an event of a given type onto this current panel. // Params: // eventType The event to trigger. // data A custom data object to pass into all handlers. __trigger: function (eventType, data) { if (!eventType) { return false; } var results = []; if (this._events[eventType]) { var events = this._events[eventType].slice(0); for (var i = 0; i < events.length; ++i) { results.push(events[i].call(this, data)); } } return results; }, // Retrieves the bounding rect for this widget. __rect: function () { var offset = this.$container.offset(); var width = this.$container.width(); var height = this.$container.height(); return { x: offset.left, y: offset.top, w: width, h: height }; }, // Gets, or Sets a new container for this layout. // Params: // $container If supplied, sets a new container for this layout. // parent If supplied, sets a new parent for this layout. // Returns: // JQuery collection The current container. __container: function ($container) { if (typeof $container === 'undefined') { return this.$container; } this.$container = $container; if (this.$container) { this._layout.__container(this.$container); if (this.$loading) { this.$container.append(this.$loading); } } else { this._layout.__container(null); this.finishLoading(); } return this.$container; }, // Destroys this panel. __destroy: function () { this._panelObject = null; this.off(); this.__container(null); this._parent = null; } }); // window['wcPanel'] = Module; return Module; }); × Search results Close "},"splitter.js.html":{"id":"splitter.js.html","title":"Source: splitter.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: splitter.js /** @module wcSplitter */ define([ "dcl/dcl", "./types", "./base" ], function (dcl, wcDocker, base) { /** * @class module:wcSplitter * Splits an area in two, dividing it with a resize-able splitter bar. This is the same class * used throughout [docker]{@link module:wcDocker} to organize the docking interface, but it can also * be used inside a panel as a custom widget. * <b>Note:</b> The container needs to be positioned in either absolute or relative coordinates in css. */ var Module = dcl(base, { declaredClass: 'wcSplitter', /** * @memberOf module:wcSplitter * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element for this splitter. * @param {wcLayout|wcSplitter|wcDocker} parent - The splitter's parent object. * @param {module:wcDocker.ORIENTATION} orientation - The orientation of the splitter bar. */ constructor:function(container, parent, orientation) { this.$container = $(container); this._parent = parent; this._orientation = orientation; this._pane = [false, false]; /** * An array of two elements representing each side of the splitter. * Index 0 is always either top or left depending on [orientation]{@link module:wcDocker.ORIENTATION}. * @member * @type {external:jQuery~Object[]} */ this.$pane = []; this.$bar = null; this._pos = 0.5; this._posTarget = 0.5; this._pixelPos = -1; this._findBestPos = false; this._anim = 0; this._boundEvents = []; this.__init(); this.docker()._splitterList.push(this); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes the two [panes]{@link module:wcSplitter#$pane} of the splitter with its own layouts.<br> * This should be used to initialize the splitter when creating one for use inside your panel. * @function module:wcSplitter#initLayouts * @param {module:wcDocker.LAYOUT} [topLeftLayout=wcDocker.LAYOUT.TABLE] - The type of layout to use for the top or left pane. * @param {module:wcDocker.LAYOUT} [bottomRightLayout=wcDocker.LAYOUT.TABLE] - The type of layout to use for the bottom or right pane. */ initLayouts: function (topLeftLayout, bottomRightLayout) { var layoutClass = topLeftLayout || 'wcLayoutTable'; var layout0 = new (this.docker().__getClass(layoutClass))(this.$pane[0], this); layoutClass = bottomRightLayout || 'wcLayoutTable'; var layout1 = new (this.docker().__getClass(layoutClass))(this.$pane[1], this); this.pane(0, layout0); this.pane(1, layout1); }, /** * Gets, or Sets the orientation of the splitter. * @function module:wcSplitter#orientation * @param {module:wcDocker.ORIENTATION} orientation - The new orientation of the splitter. */ orientation: function (orientation) { if (typeof orientation === 'undefined') { return this._orientation; } if (this._orientation != orientation) { this._orientation = orientation; if (this._orientation) { // this.$pane[0].removeClass('wcWide').addClass('wcTall'); // this.$pane[1].removeClass('wcWide').addClass('wcTall'); this.$bar.removeClass('wcWide').removeClass('wcSplitterBarH').addClass('wcTall').addClass('wcSplitterBarV'); } else { // this.$pane[0].removeClass('wcTall').addClass('wcWide'); // this.$pane[1].removeClass('wcTall').addClass('wcWide'); this.$bar.removeClass('wcTall').removeClass('wcSplitterBarV').addClass('wcWide').addClass('wcSplitterBarH'); } this.$pane[0].css('top', '').css('left', '').css('width', '').css('height', ''); this.$pane[1].css('top', '').css('left', '').css('width', '').css('height', ''); this.$bar.css('top', '').css('left', '').css('width', '').css('height', ''); this.__update(); if (this._parent && this._parent.instanceOf('wcPanel')) { this._parent.__trigger(wcDocker.EVENT.UPDATED); } } }, /** * Gets the minimum size constraint of the outer splitter area. * @function module:wcSplitter#minSize * @returns {module:wcDocker~Size} The minimum size. */ minSize: function () { var minSize1; var minSize2; if (this._pane[0] && typeof this._pane[0].minSize === 'function') { minSize1 = this._pane[0].minSize(); } if (this._pane[1] && typeof this._pane[1].minSize === 'function') { minSize2 = this._pane[1].minSize(); } if (minSize1 && minSize2) { if (this._orientation) { minSize1.x += minSize2.x; minSize1.y = Math.max(minSize1.y, minSize2.y); } else { minSize1.y += minSize2.y; minSize1.x = Math.max(minSize1.x, minSize2.x); } return minSize1; return { x: Math.min(minSize1.x, minSize2.x), y: Math.min(minSize1.y, minSize2.y) }; } else if (minSize1) { return minSize1; } else if (minSize2) { return minSize2; } return false; }, /** * Gets the maximum size constraint of the outer splitter area. * @function module:wcSplitter#maxSize * @returns {module:wcDocker~Size} - The maximum size. */ maxSize: function () { var maxSize1; var maxSize2; if (this._pane[0] && typeof this._pane[0].maxSize === 'function') { maxSize1 = this._pane[0].maxSize(); } if (this._pane[1] && typeof this._pane[1].maxSize === 'function') { maxSize2 = this._pane[1].maxSize(); } if (maxSize1 && maxSize2) { if (this._orientation) { maxSize1.x += maxSize2.x; maxSize1.y = Math.min(maxSize1.y, maxSize2.y); } else { maxSize1.y += maxSize2.y; maxSize1.x = Math.min(maxSize1.x, maxSize2.x); } return maxSize1; return { x: Math.min(maxSize1.x, maxSize2.x), y: Math.min(maxSize1.y, maxSize2.y) }; } else if (maxSize1) { return maxSize1; } else if (maxSize2) { return maxSize2; } return false; }, /** * Get, or Set the current splitter position. * @function module:wcSplitter#pos * @param {Number} [value] - If supplied, assigns a new splitter position. Value must be a percentage value between 0 and 1. * @returns {Number} - The current position. */ pos: function (value) { if (typeof value !== 'undefined') { this._pos = this._posTarget = value; this.__update(); if (this._parent && this._parent.instanceOf('wcPanel')) { this._parent.__trigger(wcDocker.EVENT.UPDATED); } } return this._posTarget; }, /** * Animates to a given splitter position. * @function module:wcSplitter#animPos * @param {Number} value - Assigns the target splitter position. Value must be a percentage between 0 and 1. * @param {module:wcSplitter~onFinished} - A finished event handler. */ animPos: function (value, callback) { this._posTarget = value; var self = this; this.$bar.queue(function (next) { if (self._anim) { clearInterval(self._anim); } self._anim = setInterval(function () { if (self._pos > self._posTarget) { self._pos -= (self._pos - self._posTarget) / 5; if (self._pos <= self._posTarget + 0.01) { self._pos = self._posTarget; } } if (self._pos < self._posTarget) { self._pos += (self._posTarget - self._pos) / 5; if (self._pos >= self._posTarget - 0.01) { self._pos = self._posTarget; } } self.__update(); if (self._pos == self._posTarget) { callback && callback(); next(); clearInterval(self._anim); self._anim = 0; } }, 5); }); this.$bar.dequeue(); }, /** * Gets, or Sets the element associated with a pane. * @function module:wcSplitter#pane * @param {Number} index - The index of the pane, only 0 and 1 are valid. * @param {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter} [item] - If supplied, the pane will be replaced with this item. * @returns {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter|Boolean} - The current object assigned to the pane, or false. */ pane: function (index, item) { if (index >= 0 && index < 2) { if (typeof item === 'undefined') { return this._pane[index]; } else { if (item) { this._pane[index] = item; item._parent = this; item.__container(this.$pane[index]); if (this._pane[0] && this._pane[1]) { this.__update(); } return item; } else if (this._pane[index]) { this._pane[index].__container(null); this._pane[index] = false; } } } // this.__update(); return false; }, /** * Gets, or Sets the element associated with the left side pane (for horizontal layouts). * @function module:wcSplitter#left * @param {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter} [item] - If supplied, the pane will be replaced with this item. * @returns {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter|Boolean} - The current object assigned to the pane, or false. */ left: function (item) { return this.pane(0, item); }, /** * Gets, or Sets the element associated with the right side pane (for horizontal layouts). * @function module:wcSplitter#right * @param {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter} [item] - If supplied, the pane will be replaced with this item. * @returns {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter|Boolean} - The current object assigned to the pane, or false. */ right: function (item) { return this.pane(1, item); }, /** * Gets, or Sets the element associated with the top pane (for vertical layouts). * @function module:wcSplitter#top * @param {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter} [item] - If supplied, the pane will be replaced with this item. * @returns {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter|Boolean} - The current object assigned to the pane, or false. */ top: function (item) { return this.pane(0, item); }, /** * Gets, or Sets the element associated with the bottom pane (for vertical layouts). * @function module:wcSplitter#bottom * @param {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter} [item] - If supplied, the pane will be replaced with this item. * @returns {module:wcLayout|module:wcPanel|module:wcFrame|wcSplitter|Boolean} - The current object assigned to the pane, or false. */ bottom: function (item) { return this.pane(1, item); }, /** * Gets, or Sets whether a pane can be scrolled via scroll bars. * By default, scrolling is enabled in both directions. * @function module:wcSplitter#scrollable * @param {Number} index - The index of the pane, only 0 and 1 are valid. * @param {Boolean} [x] - Whether to allow scrolling in the horizontal direction. * @param {Boolean} [y] - Whether to allow scrolling in the vertical direction. * @returns {module:wcDocker~Scrollable} - The current scroll state for each direction. */ scrollable: function (index, x, y) { if (typeof x !== 'undefined') { this.$pane[index].toggleClass('wcScrollableX', x); } if (typeof y !== 'undefined') { this.$pane[index].toggleClass('wcScrollableY', y); } return { x: this.$pane[index].hasClass('wcScrollableX'), y: this.$pane[index].hasClass('wcScrollableY') }; }, /** * Destroys the splitter. * @function module:wcSplitter#destroy * @param {Boolean} [destroyPanes=true] - If true, both panes attached will be destroyed as well. Use false if you plan to continue using the objects assigned to each pane, or make sure to remove them first before destruction. */ destroy: function (destroyPanes) { var docker = this.docker(); if (docker) { var index = this.docker()._splitterList.indexOf(this); if (index > -1) { this.docker()._splitterList.splice(index, 1); } } if (destroyPanes === undefined || destroyPanes) { this.__destroy(); } else { this.__container(null); } }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function () { this.$pane.push($('<div class="wcLayoutPane wcScrollableX wcScrollableY">')); this.$pane.push($('<div class="wcLayoutPane wcScrollableX wcScrollableY">')); this.$bar = $('<div class="wcSplitterBar">'); if (this._orientation) { // this.$pane[0].addClass('wcTall'); // this.$pane[1].addClass('wcTall'); this.$bar.addClass('wcTall').addClass('wcSplitterBarV'); } else { // this.$pane[0].addClass('wcWide'); // this.$pane[1].addClass('wcWide'); this.$bar.addClass('wcWide').addClass('wcSplitterBarH'); } this.__container(this.$container); if (this._parent && this._parent.instanceOf('wcPanel')) { this._boundEvents.push({event: wcDocker.EVENT.UPDATED, handler: this.__update.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.CLOSED, handler: this.destroy.bind(this)}); for (var i = 0; i < this._boundEvents.length; ++i) { this._parent.on(this._boundEvents[i].event, this._boundEvents[i].handler); } } }, // Updates the size of the splitter. __update: function (opt_dontMove) { var width = this.$container.outerWidth(); var height = this.$container.outerHeight(); var minSize = this.__minPos(); var maxSize = this.__maxPos(); if (this._findBestPos) { this._findBestPos = false; var size1; var size2; if (this._pane[0] && typeof this._pane[0].initSize === 'function') { size1 = this._pane[0].initSize(); if (size1) { if (size1.x < 0) { size1.x = width / 2; } if (size1.y < 0) { size1.y = height / 2; } } } if (this._pane[1] && typeof this._pane[1].initSize === 'function') { size2 = this._pane[1].initSize(); if (size2) { if (size2.x < 0) { size2.x = width / 2; } if (size2.y < 0) { size2.y = height / 2; } size2.x = width - size2.x; size2.y = height - size2.y; } } var size; if (size1 && size2) { size = { x: Math.min(size1.x, size2.x), y: Math.min(size1.y, size2.y) }; } else if (size1) { size = size1; } else if (size2) { size = size2; } if (size) { if (this._orientation) { this._pos = size.x / width; } else { this._pos = size.y / height; } } } this.$bar.toggleClass('wcSplitterBarStatic', this.__isStatic()); if (this._orientation === wcDocker.ORIENTATION.HORIZONTAL) { var barSize = this.$bar.outerWidth() / 2; var barBorder = parseInt(this.$bar.css('border-top-width')) + parseInt(this.$bar.css('border-bottom-width')); if (opt_dontMove) { var offset = this._pixelPos - (this.$container.offset().left + parseInt(this.$container.css('border-left-width'))) - this.$bar.outerWidth() / 2; this._pos = offset / (width - this.$bar.outerWidth()); } this._pos = Math.min(Math.max(this._pos, 0), 1); var size = (width - this.$bar.outerWidth()) * this._pos + barSize; if (minSize) { size = Math.max(minSize.x, size); } if (maxSize) { size = Math.min(maxSize.x, size); } var top = 0; var bottom = 0; if (this._parent && this._parent.declaredClass === 'wcCollapser') { var $outer = this.docker().$container; var $inner = this._parent.$container; top = $inner.offset().top - $outer.offset().top; bottom = ($outer.offset().top + $outer.outerHeight()) - ($inner.offset().top + $inner.outerHeight()); } // Bar is top to bottom this.$bar.css('left', size - barSize); this.$bar.css('top', top); this.$bar.css('height', height - barBorder - bottom); this.$pane[0].css('width', size - barSize); this.$pane[0].css('left', '0px'); this.$pane[0].css('right', ''); this.$pane[0].css('top', top); this.$pane[0].css('bottom', bottom); this.$pane[1].css('left', ''); this.$pane[1].css('right', '0px'); this.$pane[1].css('width', width - size - barSize - parseInt(this.$container.css('border-left-width')) * 2); this.$pane[1].css('top', top); this.$pane[1].css('bottom', bottom); this._pixelPos = this.$bar.offset().left + barSize; } else { var barSize = this.$bar.outerHeight() / 2; var barBorder = parseInt(this.$bar.css('border-left-width')) + parseInt(this.$bar.css('border-right-width')); if (opt_dontMove) { var offset = this._pixelPos - (this.$container.offset().top + parseInt(this.$container.css('border-top-width'))) - this.$bar.outerHeight() / 2; this._pos = offset / (height - this.$bar.outerHeight()); } this._pos = Math.min(Math.max(this._pos, 0), 1); var size = (height - this.$bar.outerHeight()) * this._pos + barSize; if (minSize) { size = Math.max(minSize.y, size); } if (maxSize) { size = Math.min(maxSize.y, size); } var left = 0; var right = 0; if (this._parent && this._parent.declaredClass === 'wcCollapser') { var $outer = this.docker().$container; var $inner = this._parent.$container; left = $inner.offset().left - $outer.offset().left; right = ($outer.offset().left + $outer.outerWidth()) - ($inner.offset().left + $inner.outerWidth()); } // Bar is left to right this.$bar.css('top', size - barSize); this.$bar.css('left', left); this.$bar.css('width', width - barBorder - bottom); this.$pane[0].css('height', size - barSize); this.$pane[0].css('top', '0px'); this.$pane[0].css('bottom', ''); this.$pane[0].css('left', left); this.$pane[0].css('right', right); this.$pane[1].css('top', ''); this.$pane[1].css('bottom', '0px'); this.$pane[1].css('height', height - size - barSize - parseInt(this.$container.css('border-top-width')) * 2); this.$pane[1].css('left', left); this.$pane[1].css('right', right); this._pixelPos = this.$bar.offset().top + barSize; } if (opt_dontMove === undefined) { opt_dontMove = true; } this._pane[0] && this._pane[0].__update(opt_dontMove); this._pane[1] && this._pane[1].__update(opt_dontMove); }, // Saves the current panel configuration into a meta // object that can be used later to restore it. __save: function () { // If this is a collapser splitter, do not save it, skip to the children. if (this._pane[0] && this._pane[0].declaredClass === 'wcCollapser') { return this._pane[1].__save(); } if (this._pane[1] && this._pane[1].declaredClass === 'wcCollapser') { return this._pane[0].__save(); } var data = {}; data.type = 'wcSplitter'; data.horizontal = this._orientation; data.isDrawer = this.$bar.hasClass('wcDrawerSplitterBar'); data.pane0 = this._pane[0] ? this._pane[0].__save() : null; data.pane1 = this._pane[1] ? this._pane[1].__save() : null; data.pos = this._pos; return data; }, // Restores a previously saved configuration. __restore: function (data, docker) { this._pos = data.pos; if (data.isDrawer) { this.$bar.addClass('wcDrawerSplitterBar'); } if (data.pane0) { this._pane[0] = docker.__create(data.pane0, this, this.$pane[0]); this._pane[0].__restore(data.pane0, docker); } if (data.pane1) { this._pane[1] = docker.__create(data.pane1, this, this.$pane[1]); this._pane[1].__restore(data.pane1, docker); } }, // Attempts to find the best splitter position based on // the contents of each pane. __findBestPos: function () { this._findBestPos = true; }, // Moves the slider bar based on a mouse position. // Params: // mouse The mouse offset position. __moveBar: function (mouse) { var offset = this.$container.offset(); mouse.x -= offset.left; mouse.y -= offset.top; if (this._orientation === wcDocker.ORIENTATION.HORIZONTAL) { var width = this.$container.outerWidth() - this.$bar.outerWidth(); mouse.x += 1 - parseInt(this.$container.css('border-left-width')) - (this.$bar.outerWidth() / 2); this.pos(mouse.x / width); } else { var height = this.$container.outerHeight() - this.$bar.outerHeight(); mouse.y += 1 - parseInt(this.$container.css('border-top-width')) - (this.$bar.outerHeight() / 2); this.pos(mouse.y / height); } }, // Gets the minimum position of the splitter divider. __minPos: function () { var width = this.$container.outerWidth(); var height = this.$container.outerHeight(); var minSize; if (this._pane[0] && typeof this._pane[0].minSize === 'function') { minSize = this._pane[0].minSize(); } else { minSize = {x: 50, y: 50}; } var maxSize; if (this._pane[1] && typeof this._pane[1].maxSize === 'function') { maxSize = this._pane[1].maxSize(); } else { maxSize = {x: width, y: height}; } if (this._orientation === wcDocker.ORIENTATION.HORIZONTAL) { var barSize = this.$bar.outerWidth() / 2; minSize.x += barSize; width -= barSize; } else { var barSize = this.$bar.outerHeight() / 2; minSize.y += barSize; height -= barSize; } maxSize.x = width - Math.min(maxSize.x, width); maxSize.y = height - Math.min(maxSize.y, height); minSize.x = Math.max(minSize.x, maxSize.x); minSize.y = Math.max(minSize.y, maxSize.y); return minSize; }, // Gets the maximum position of the splitter divider. __maxPos: function () { var width = this.$container.outerWidth(); var height = this.$container.outerHeight(); var maxSize; if (this._pane[0] && typeof this._pane[0].maxSize === 'function') { maxSize = this._pane[0].maxSize(); } else { maxSize = {x: width, y: height}; } var minSize; if (this._pane[1] && typeof this._pane[1].minSize === 'function') { minSize = this._pane[1].minSize(); } else { minSize = {x: 50, y: 50}; } if (this._orientation === wcDocker.ORIENTATION.HORIZONTAL) { var barSize = this.$bar.outerWidth() / 2; maxSize.x += barSize; width -= barSize; } else { var barSize = this.$bar.outerHeight() / 2; maxSize.y += barSize; height -= barSize; } minSize.x = width - minSize.x; minSize.y = height - minSize.y; maxSize.x = Math.min(minSize.x, maxSize.x); maxSize.y = Math.min(minSize.y, maxSize.y); return maxSize; }, // Retrieves whether the splitter is static (not moveable). __isStatic: function () { var attr = this._orientation === wcDocker.ORIENTATION.HORIZONTAL ? 'x' : 'y'; for (var i = 0; i < 2; ++i) { if (this._pane[i] && this._pane[i].minSize && this._pane[i].maxSize && this._pane[i].maxSize()[attr] - this._pane[i].minSize()[attr] === 0) { return true; } } return false; }, // Gets, or Sets a new container for this layout. // Params: // $container If supplied, sets a new container for this layout. // parent If supplied, sets a new parent for this layout. // Returns: // JQuery collection The current container. __container: function ($container) { if (typeof $container === 'undefined') { return this.$container; } this.$container = $container; if (this.$container) { this.$container.append(this.$pane[0]); this.$container.append(this.$pane[1]); this.$container.append(this.$bar); } else { this.$pane[0].remove(); this.$pane[1].remove(); this.$bar.remove(); } return this.$container; }, // Removes a child from this splitter. // Params: // child The child to remove. __removeChild: function (child) { if (this._pane[0] === child) { this._pane[0] = false; } else if (this._pane[1] === child) { this._pane[1] = false; } else { return; } if (child) { child.__container(null); child._parent = null; } }, // Disconnects and prepares this widget for destruction. __destroy: function () { // Stop any animations. if (this._anim) { clearInterval(this._anim); this._anim = 0; } this.$bar.clearQueue(); // Remove all registered events. while (this._boundEvents.length) { this._parent.off(this._boundEvents[0].event, this._boundEvents[0].handler); this._boundEvents.shift(); } if (this._pane[0]) { this._pane[0].__destroy(); this._pane[0] = null; } if (this._pane[1]) { this._pane[1].__destroy(); this._pane[1] = null; } this.__container(null); this._parent = false; } }); // window['wcSplitter'] = Module; return Module; }); /** * A callback function that is called when an action is finished. * * @callback wcSplitter~onFinished */ × Search results Close "},"tabframe.js.html":{"id":"tabframe.js.html","title":"Source: tabframe.js","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Source: tabframe.js /** @module wcTabFrame */ define([ "dcl/dcl", "./types", "./base" ], function (dcl, wcDocker, base) { /** * @class * A tab widget container, usable inside a panel to break up multiple elements into separate tabbed pages. */ var Module = dcl(base, { declaredClass: 'wcTabFrame', LEFT_TAB_BUFFER: 15, /** * @memberOf module:wcTabFrame * @param {external:jQuery~selector|external:jQuery~Object|external:domNode} container - A container element for this layout. * @param {module:wcPanel} parent - The parent panel object for this widget. */ constructor: function(container, parent) { /** * The outer container element of the widget. * @member {external:jQuery~Object} */ this.$container = $(container); this._parent = parent; this.$frame = null; this.$tabBar = null; this.$tabScroll = null; this.$center = null; this.$tabLeft = null; this.$tabRight = null; this.$close = null; this._tabOrientation = wcDocker.TAB.TOP; this._canScrollTabs = false; this._tabScrollPos = 0; this._curTab = -1; this._layoutList = []; this._moveable = true; this._boundEvents = []; this.__init(); }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Manually update the contents of this tab frame. * @function module:wcTabFrame#update */ update: function () { var scrollTop = this.$center.scrollTop(); this.__updateTabs(); this.$center.scrollTop(scrollTop); }, /** * Destroys the widget. * @function module:wcTabFrame#destroy */ destroy: function () { this.__destroy(); }, /** * Gets the total number of tabs in this frame. * @version 3.0.0 * @function module:wcTabFrame#tabCount * @returns {Number} */ tabCount: function () { return this._layoutList.length; }, /** * Gets, or Sets the tab orientation for the frame. This puts the tabbed widgets visually on any side of the tab frame. * @version 3.0.0 * @function module:wcTabFrame#tabOrientation * @param {module:wcDocker.TAB} [orientation] - Assigns the orientation of the tab items displayed. * @returns {module:wcDocker.TAB} - The current orientation. */ tabOrientation: function (orientation) { if (orientation !== undefined) { if (this._tabOrientation !== orientation && this.docker()._canOrientTabs) { this._tabOrientation = orientation; this.__updateTabs(); this.__updateTabs(); } } return this._tabOrientation }, /** * Adds a new tabbed page into the widget. * @function module:wcTabFrame#addTab * @param {String} name - The name of the new tab page. * @param {Number} [index] - If supplied and above -1, will insert the new tab page at the given tab index, otherwise the new tab is appended to the end. * @param {module:wcDocker.LAYOUT} [layout] - If supplied, will set the type of layout to use for this tab. * @returns {module:wcLayoutSimple|wcLayoutTable} - The layout of the newly created tab page. */ addTab: function (name, index, layout) { var layoutClass = layout || 'wcLayoutTable'; var newLayout = new (this.docker().__getClass(layoutClass))('.wcDockerTransition', this._parent); newLayout.name = name; newLayout._scrollable = { x: true, y: true }; newLayout._scroll = { x: 0, y: 0 }; newLayout._closeable = false; newLayout._overflowVisible = false; if (typeof index === 'undefined' || index <= -1) { this._layoutList.push(newLayout); } else { this._layoutList.splice(index, 0, newLayout); } if (this._curTab === -1 && this._layoutList.length) { this._curTab = 0; } this.__updateTabs(); return newLayout; }, /** * Removes a tab page from the widget. * @function module:wcTabFrame#removeTab * @param {Number} index - The tab page index to remove. * @returns {Boolean} - Success or failure. */ removeTab: function (index) { if (index > -1 && index < this._layoutList.length) { var name = this._layoutList[index].name; this._layoutList[index].__destroy(); this._layoutList.splice(index, 1); if (this._curTab >= index) { this._curTab--; if (this._curTab < 0) { this._curTab = 0; } } this.__updateTabs(); this._parent.__trigger(wcDocker.EVENT.CUSTOM_TAB_CLOSED, {obj: this, name: name, index: index}); return true; } return false; }, /** * Gets, or Sets the currently visible tab page. * @function module:wcTabFrame#tab * @param {Number} [index] - If supplied, sets the current tab page index. * @param {Boolean} [scrollTo] - If true, will auto scroll the tab bar until the selected tab is visible. * @returns {Number} - The index of the currently visible tab page. */ tab: function (index, scrollTo) { if (typeof index !== 'undefined') { if (index > -1 && index < this._layoutList.length) { this.$tabBar.find('> .wcTabScroller > .wcPanelTab[id="' + this._curTab + '"]').removeClass('wcPanelTabActive'); this.$center.children('.wcPanelTabContent[id="' + this._curTab + '"]').addClass('wcPanelTabContentHidden'); this._curTab = index; this.$tabBar.find('> .wcTabScroller > .wcPanelTab[id="' + index + '"]').addClass('wcPanelTabActive'); this.$center.children('.wcPanelTabContent[id="' + index + '"]').removeClass('wcPanelTabContentHidden'); this.__updateTabs(scrollTo); var name = this._layoutList[this._curTab].name; this._parent.__trigger(wcDocker.EVENT.CUSTOM_TAB_CHANGED, {obj: this, name: name, index: index}); } } return this._curTab; }, /** * Retrieves the layout for a given tab page. * @function module:wcTabFrame#layout * @param {Number} index - The tab page index to retrieve. * @returns {module:wcLayoutSimple|wcLayoutTable|Boolean} - The layout of the found tab page, or false. */ layout: function (index) { if (index > -1 && index < this._layoutList.length) { return this._layoutList[index]; } return false; }, /** * Moves a tab page from a given index to another index. * @function module:wcTabFrame#moveTab * @param {Number} fromIndex - The current tab page index to move from. * @param {Number} toIndex - The new tab page index to move to. * @returns {external:jQuery~Object} - The new element of the moved tab, or false if an error occurred. */ moveTab: function (fromIndex, toIndex) { if (fromIndex >= 0 && fromIndex < this._layoutList.length && toIndex >= 0 && toIndex < this._layoutList.length) { var panel = this._layoutList.splice(fromIndex, 1); this._layoutList.splice(toIndex, 0, panel[0]); // Preserve the currently active tab. if (this._curTab === fromIndex) { this._curTab = toIndex; } this.__updateTabs(); return this.$tabBar.find('> .wcTabScroller > .wcPanelTab[id="' + toIndex + '"]')[0]; } return false; }, /** * Gets, or Sets whether the tabs can be reordered by the user. * @function module:wcTabFrame#moveable * @param {Boolean} [moveable] - If supplied, assigns whether tab pages can be reordered. * @returns {Boolean} - Whether tab pages are currently moveable. */ moveable: function (moveable) { if (typeof moveable !== 'undefined') { this._moveable = moveable; } return this._moveable; }, /** * Gets, or Sets whether a tab can be closed (removed) by the user. * @function module:wcTabFrame#closeable * @param {Number} index - The index of the tab page. * @param {Boolean} [closeable] - If supplied, assigns whether the tab page can be closed. * @returns {Boolean} - Whether the tab page can be closed. */ closeable: function (index, closeable) { if (index > -1 && index < this._layoutList.length) { var layout = this._layoutList[index]; if (typeof closeable !== 'undefined') { layout._closeable = closeable; } return layout._closeable; } return false; }, /** * Gets, or Sets whether a tab page area is scrollable. * @function module:wcTabFrame#scrollable * @param {Number} index - The index of the tab page. * @param {Boolean} [x] - If supplied, assigns whether the tab page is scrollable in the horizontal direction. * @param {Boolean} [y] - If supplied, assigns whether the tab page is scrollable in the vertical direction. * @returns {module:wcDocker~Scrollable} - The current scrollable status of the tab page. */ scrollable: function (index, x, y) { if (index > -1 && index < this._layoutList.length) { var layout = this._layoutList[index]; var changed = false; if (typeof x !== 'undefined') { layout._scrollable.x = x; changed = true; } if (typeof y !== 'undefined') { layout._scrollable.y = y; changed = true; } if (changed) { this.__onTabChange(); } return { x: layout._scrollable.x, y: layout._scrollable.y }; } return false; }, /** * Gets, or Sets whether overflow on a tab area is visible.<br> * Use this if a child element within this panel is intended to 'popup' and be visible outside of its parent area. * @function module:wcTabFrame#overflowVisible * @param {Number} index - The index of the tab page. * @param {Boolean} [visible] - If supplied, assigns whether overflow is visible. * @returns {Boolean} - The current overflow visiblity status of the tab page. */ overflowVisible: function (index, visible) { if (index > -1 && index < this._layoutList.length) { var layout = this._layoutList[index]; if (typeof overflow !== 'undefined') { layout._overflowVisible = overflow; this.__onTabChange(); } return layout._overflowVisible; } return false; }, /** * Gets, or Sets whether the tab frame should fit to its contents. * @version 3.0.0 * @function module:wcTabFrame#fitContents * @param {Number} index - The index of the tab page. * @param {Boolean} [x] - If supplied, assigns whether the tab page is scrollable in the horizontal direction. * @param {Boolean} [y] - If supplied, assigns whether the tab page is scrollable in the vertical direction. * @returns {module:wcDocker~FitContents} - The current scrollable status of the tab page. */ fitContents: function (index, x, y) { if (index > -1 && index < this._layoutList.length) { var layout = this._layoutList[index]; if (!layout.hasOwnProperty('_fitContents')) { layout._fitContents = { x: false, y: false }; } var changed = false; if (typeof x !== 'undefined') { layout._fitContents.x = x; changed = true; } if (typeof y !== 'undefined') { layout._fitContents.y = y; changed = true; } if (changed) { this.__onTabChange(); } return { x: layout._fitContents.x, y: layout._fitContents.y }; } return false; }, /** * Sets the icon for a tab item. * @function module:wcTabFrame#icon * @param {Number} index - The index of the tab item. * @param {String} icon - A CSS class name that represents the icon. */ icon: function (index, icon) { if (index > -1 && index < this._layoutList.length) { var layout = this._layoutList[index]; if (!layout.$icon) { layout.$icon = $('<div>'); } layout.$icon.removeClass(); layout.$icon.addClass('wcTabIcon ' + icon); } }, /** * Sets the icon for a tab item using the [Font-Awesome]{@link http://fortawesome.github.io/Font-Awesome/} library. * @function module:wcTabFrame#faicon * @param {Number} index - The index of the tab item. * @param {String} icon - A [Font-Awesome]{@link http://fortawesome.github.io/Font-Awesome/} icon name (without the 'fa fa-' prefix). */ faicon: function (index, icon) { if (index > -1 && index < this._layoutList.length) { var layout = this._layoutList[index]; if (!layout.$icon) { layout.$icon = $('<div>'); } layout.$icon.removeClass(); layout.$icon.addClass('fa fa-fw fa-' + icon); } }, /////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialize __init: function () { this.$frame = $('<div class="wcCustomTab wcWide wcTall">'); this.$tabBar = $('<div class="wcFrameTitleBar wcCustomTabTitle wcWide">'); this.$tabScroll = $('<div class="wcTabScroller">'); this.$center = $('<div class="wcFrameCenter wcPanelBackground">'); this.$tabLeft = $('<div class="wcFrameButton" title="Scroll tabs to the left."><span class="fa fa-arrow-left"></span>&lt;</div>'); this.$tabRight = $('<div class="wcFrameButton" title="Scroll tabs to the right."><span class="fa fa-arrow-right"></span>&gt;</div>'); this.$close = $('<div class="wcFrameButton" title="Close the currently active panel tab"><span class="fa fa-close"></span>X</div>'); //this.$maximize = $('<div class="wcFrameButton" title="Close the currently active panel tab"><span class="fa fa-expand"></span>X</div>'); this.$buttonBar = $('<div class="wcFrameButtonBar">'); this.$tabBar.append(this.$tabScroll); this.$tabBar.append(this.$buttonBar); this.$buttonBar.append(this.$close); //this.$buttonBar.append(this.$maximize); this.$frame.append(this.$center); this.$frame.append(this.$tabBar); this.__container(this.$container); this._boundEvents.push({event: wcDocker.EVENT.UPDATED, handler: this.update.bind(this)}); this._boundEvents.push({event: wcDocker.EVENT.CLOSED, handler: this.destroy.bind(this)}); for (var i = 0; i < this._boundEvents.length; ++i) { this._parent.on(this._boundEvents[i].event, this._boundEvents[i].handler); } var docker = this.docker(); if (docker) { docker._tabList.push(this); } }, __updateTabs: function (scrollTo) { this.$tabScroll.empty(); var getOffset = function ($item) { switch (this._tabOrientation) { case wcDocker.TAB.BOTTOM: return $item.offset().left; case wcDocker.TAB.TOP: return $item.offset().left; case wcDocker.TAB.LEFT: return $item.offset().top; case wcDocker.TAB.RIGHT: return $item.offset().top; } }.bind(this); var tabPositions = []; var totalWidth = 0; var parentLeft = getOffset(this.$tabScroll); var self = this; this.$center.children('.wcPanelTabContent').each(function () { $(this).addClass('wcPanelTabContentHidden wcPanelTabUnused'); }); for (var i = 0; i < this._layoutList.length; ++i) { var $tab = $('<div id="' + i + '" class="wcPanelTab"><div>' + this._layoutList[i].name + '</div></div>'); if (this._moveable) { $tab.addClass('wcCustomTabMoveable'); } this.$tabScroll.append($tab); if (this._layoutList[i].$icon) { $tab.find('div').prepend(this._layoutList[i].$icon); } var $tabContent = this.$center.children('.wcPanelTabContent[id="' + i + '"]'); if (!$tabContent.length) { $tabContent = $('<div class="wcPanelTabContent wcPanelTabContentHidden" id="' + i + '">'); this.$center.append($tabContent); } this._layoutList[i].__container($tabContent); this._layoutList[i]._parent = this; var isVisible = this._curTab === i; $tabContent.removeClass('wcPanelTabUnused'); if (isVisible) { $tab.addClass('wcPanelTabActive'); $tabContent.removeClass('wcPanelTabContentHidden'); } totalWidth = getOffset($tab) - parentLeft; tabPositions.push(totalWidth); totalWidth += $tab.outerWidth(); } var tabWidth = 0; var titleSize = this.$tabBar.height(); switch (this._tabOrientation) { case wcDocker.TAB.TOP: this.$tabBar.addClass('wcTabTop').removeClass('wcTabLeft wcTabRight wcTabBottom'); this.$center.css('top', titleSize).css('left', 0).css('right', 0).css('bottom', 0); tabWidth = this.$center.width(); break; case wcDocker.TAB.BOTTOM: this.$tabBar.addClass('wcTabBottom').removeClass('wcTabTop wcTabLeft wcTabRight'); this.$center.css('top', 0).css('left', 0).css('right', 0).css('bottom', titleSize); tabWidth = this.$center.width(); break; case wcDocker.TAB.LEFT: this.$tabBar.addClass('wcTabLeft').removeClass('wcTabTop wcTabRight wcTabBottom'); this.$center.css('top', 0).css('left', titleSize).css('right', 0).css('bottom', 0); tabWidth = this.$center.height(); break; case wcDocker.TAB.RIGHT: this.$tabBar.addClass('wcTabRight').removeClass('wcTabTop wcTabLeft wcTabBottom'); this.$center.css('top', 0).css('left', 0).css('right', titleSize).css('bottom', 0); tabWidth = this.$center.height(); break; } // Now remove all unused panel tabs. this.$center.children('.wcPanelTabUnused').each(function () { $(this).remove(); }); var buttonSize = this.__onTabChange(); if (scrollTo) { for (var i = 0; i < tabPositions.length; ++i) { if (i === this._curTab) { var left = tabPositions[i]; var right = totalWidth; if (i + 1 < tabPositions.length) { right = tabPositions[i + 1]; } var scrollPos = -parseInt(this.$tabScroll.css('left')); var titleWidth = tabWidth - buttonSize; // If the tab is behind the current scroll position. if (left < scrollPos) { this._tabScrollPos = left - this.LEFT_TAB_BUFFER; if (this._tabScrollPos < 0) { this._tabScrollPos = 0; } } // If the tab is beyond the current scroll position. else if (right - scrollPos > titleWidth) { this._tabScrollPos = right - titleWidth + this.LEFT_TAB_BUFFER; } break; } } } this._canScrollTabs = false; if (totalWidth > tabWidth - buttonSize) { this._canScrollTabs = true; this.$buttonBar.append(this.$tabRight); this.$buttonBar.append(this.$tabLeft); buttonSize += this.$tabRight.outerWidth(); buttonSize += this.$tabLeft.outerWidth(); var scrollLimit = totalWidth - (tabWidth - buttonSize) / 2; // If we are beyond our scroll limit, clamp it. if (this._tabScrollPos > scrollLimit) { var children = this.$tabScroll.children(); for (var i = 0; i < children.length; ++i) { var $tab = $(children[i]); totalWidth = getOffset($tab) - parentLeft; if (totalWidth + $tab.outerWidth() > scrollLimit) { this._tabScrollPos = totalWidth - this.LEFT_TAB_BUFFER; if (this._tabScrollPos < 0) { this._tabScrollPos = 0; } break; } } } } else { this._tabScrollPos = 0; this.$tabLeft.remove(); this.$tabRight.remove(); } this.$tabScroll.stop().animate({left: -this._tabScrollPos + 'px'}, 'fast'); }, __onTabChange: function () { var buttonSize = 0; var layout = this.layout(this._curTab); if (layout) { this.$center.toggleClass('wcScrollableX', layout._scrollable.x); this.$center.toggleClass('wcScrollableY', layout._scrollable.y); this.$center.toggleClass('wcOverflowVisible', layout._overflowVisible); this.$tabLeft.remove(); this.$tabRight.remove(); if (layout._closeable) { this.$close.show(); buttonSize += this.$close.outerWidth(); } else { this.$close.hide(); } if (this._canScrollTabs) { this.$tabBar.append(this.$tabRight); this.$tabBar.append(this.$tabLeft); buttonSize += this.$tabRight.outerWidth() + this.$tabLeft.outerWidth(); } var fit = this.fitContents(this._curTab); if (fit.x) { var w = layout.scene().outerWidth(); if (this._tabOrientation === wcDocker.TAB.LEFT || this._tabOrientation === wcDocker.TAB.RIGHT) { w += this.$tabScroll.height(); } this.$container.css('width', w); } else { this.$container.css('width', ''); } if (fit.y) { var h = layout.scene().outerHeight(); if (this._tabOrientation === wcDocker.TAB.TOP || this._tabOrientation === wcDocker.TAB.BOTTOM) { h += this.$tabScroll.height(); } this.$container.css('height', h); } else { this.$container.css('height', ''); } switch (this._tabOrientation) { case wcDocker.TAB.RIGHT: case wcDocker.TAB.LEFT: this.$tabBar.css('width', this.$center.height() || '100%'); break; case wcDocker.TAB.TOP: case wcDocker.TAB.BOTTOM: this.$tabBar.css('width', this.$center.width() || '100%'); default: break; } this.$center.scrollLeft(layout._scroll.x); this.$center.scrollTop(layout._scroll.y); } this.$buttonBar.css('min-width', buttonSize).css('width', buttonSize); return buttonSize; }, // Handles scroll notifications. __scrolled: function () { var layout = this.layout(this._curTab); layout._scroll.x = this.$center.scrollLeft(); layout._scroll.y = this.$center.scrollTop(); }, // Gets, or Sets a new container for this layout. // Params: // $container If supplied, sets a new container for this layout. // parent If supplied, sets a new parent for this layout. // Returns: // JQuery collection The current container. __container: function ($container) { if (typeof $container === 'undefined') { return this.$container; } this.$container = $container; if (this.$container) { this.$container.append(this.$frame); } else { this.$frame.remove(); } return this.$container; }, // Disconnects and prepares this widget for destruction. __destroy: function () { var docker = this.docker(); if (docker) { var index = docker._tabList.indexOf(this); if (index > -1) { docker._tabList.splice(index, 1); } } // Remove all registered events. while (this._boundEvents.length) { this._parent.off(this._boundEvents[0].event, this._boundEvents[0].handler); this._boundEvents.shift(); } this._curTab = -1; for (var i = 0; i < this._layoutList.length; ++i) { this._layoutList[i].__destroy(); } while (this._layoutList.length) this._layoutList.pop(); this.__container(null); this._parent = null; } }); // window['wcTabFrame'] = Module; return Module; }); × Search results Close "},"modules.list.html":{"id":"modules.list.html","title":"Modules","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Modules Classes module:wcBase module:wcCollapser Events function onEvent An event handler callback. Each is registered to a event type using the wcDocker.on() or wcPanel.on() functions. Type: function Parameters: Name Type Argument Description panel module:wcPanel | NULL The panel invoking the event, or NULL if global. data Object <optional> A data object passed by the invoker. Source: docker.jsdoc, line 115 × Search results Close "},"externals.list.html":{"id":"externals.list.html","title":"Externals","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Externals Classes module:wcBase module:wcCollapser Events function onEvent An event handler callback. Each is registered to a event type using the wcDocker.on() or wcPanel.on() functions. Type: function Parameters: Name Type Argument Description panel module:wcPanel | NULL The panel invoking the event, or NULL if global. data Object <optional> A data object passed by the invoker. Source: docker.jsdoc, line 115 × Search results Close "},"tutorials.list.html":{"id":"tutorials.list.html","title":"Tutorials","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Tutorials Classes module:wcBase module:wcCollapser Events function onEvent An event handler callback. Each is registered to a event type using the wcDocker.on() or wcPanel.on() functions. Type: function Parameters: Name Type Argument Description panel module:wcPanel | NULL The panel invoking the event, or NULL if global. data Object <optional> A data object passed by the invoker. Source: docker.jsdoc, line 115 × Search results Close "},"index.html":{"id":"index.html","title":"Index","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Welcome!Welcome to WebCabin.org! Your developers cabin, on the web! Here at Web Cabin, we sincerely believe that anyone with the proper tools can become a developer! The open source community provides us with a powerful network for sharing, inspiring, and revolutionizing the world! It is awfully daunting, viewing the long road ahead through our small cabin window, but all memorable journeys must have a beginning. Will you join us? New!I've create a new theme builder panel that appears right on the demonstration front page! Build your own custom themes live within the page view! What is wcDocker?wcDocker (Web Cabin Docker) is a responsive IDE interface designed for the developer at heart! Compartmentalize your environment into smaller components, put each of those parts into a docker panel, and organize your environment however you like, whenever you like! http://docker.webcabin.org Try the front page demo. http://docker.api.webcabin.org View the API documentation. https://github.com/WebCabin/wcDocker View the source code. http://arpg.webcabin.org Try out our upcoming project (currently in alpha development), a completely web based Action RPG Maker tool! Features Extremely responsive design! Organization and duplication of panels at any time! Easily create your own themes! Comprehensive API Documentation! Easily save and restore your layout! Compatible with all major browsers, including IE8. Completely free! Getting StartedSee the Getting Started tutorial. Change LogVersion: (pre-release) 3.0.0 WARNING: Before upgrading to this version from 2.2.0, You will need to make the following changes in your implementation: Themes are no longer linked directly to the page using the <link> tag, instead use wcDocker.theme(). If your themes are not found in the "Themes" folder, you will need to assign the correct path when you construct your wcDocker instance. new wcDocker(domNode, {themePath: 'New/theme/folder'}); All wcDocker.DOCK, wcDocker.EVENT, and wcDocker.ORIENTATION enumerations have changed slightly, instead of each being one variable, they are broken into objects. // OLD format... wcDocker.DOCK_LEFT; wcDocker.EVENT_BUTTON; wcDocker.ORIENTATION_HORIZONTAL; // NEW format... wcDocker.DOCK.LEFT; wcDocker.EVENT.BUTTON; wcDocker.ORIENTATION.HORIZONTAL; // Notice how each used to be one variable name... // Now they each are an object with the same enumeration inside them, // just replace the first '_' with a '.' and they should work fine again! wcLayout's have changed in the following ways: The original layout class has been renamed to wcLayoutTable, and another type of layout now exists as wcLayoutSimple. wcLayoutTable.addItem() and wcLayoutTable.item() no longer return a jQuery object. Instead, they return a layout table item that can be used to make alterations to that cell. To use the simple layout on your panel, include the layout option when registering your panel: myDocker.registerPanelType('Simple Panel', { // Use the simple layout for the entire panel. layout: wcDocker.LAYOUT.SIMPLE, onCreate: function(myPanel) { // Create a splitter widget with simple layouts. var splitter = new wcSplitter($someContainer, myPanel, wcDocker.ORIENTATION.HORIZONTAL); splitter.initLayouts(wcDocker.LAYOUT.SIMPLE, wcDocker.LAYOUT.SIMPLE); // Create a tab frame widget with a tab that uses a simple layout. var tabFrame = new wcTabFrame($someContainer, myPanel); tabFrame.addTab('Custom Tab 1', 0, wcDocker.LAYOUT.SIMPLE).addItem($someItem); } }); The following functions are now deprecated and will be removed in an upcoming version: wcDocker.basicMenu(), renamed to wcDocker.menu(). Collapsible panels: Panels can now be collapsed to the side or bottom of the screen, where they become a slide-out drawer above the main layout. Panel creation elements: Instead of relying on the context-menu controls to add new panels, you can now add the CSS class "wcCreatePanel" to any dom element along with the data attribute "panel" and wcDocker will treat it as a panel creation control. A user will then be able to drag-drop that element into their view to create new panels of the specified type. {@lang xml}<span class="wcCreatePanel" data-panel="My Custom Panel Type">Create My Custom Panel Type</span> Tab orientation: Tab controls displayed on panels and the custom tab widget can now be oriented to the left, right, or bottom edges (browser must support css transforms). myDocker.addPanel('Some Panel', wcDocker.DOCK.STACKED, parentPanel, {tabOrientation: wcDocker.TAB.BOTTOM}); var myCustomTabFrame = new wcTabFrame(domElem, myPanel); myCustomTabFrame.tabOrientation(wcDocker.TAB.LEFT); Built in loading screens for both panels (wcPanel.startLoading() and wcPanel.finishLoading()), and the entire window (wcDocker.startLoading() and wcDocker.finishLoading()), and also included a new wcDocker.EVENT.LOADED event that is triggered once all panels have been initialized and have finished their loading screens if they've started one. Great improvements to splitter bar movement, moving one splitter no longer causes others to move (unless it explicitly pushes them). Improvements to the wcLayout object, css changes to the table cells and rows are now persistent even if the grid size changes. Tab widgets now only show on panel frames that contain more than one panel. Panels can now be registered as persistent. When the user closes a persistent panel, it is hidden instead of destroyed. When the user adds that panel back into their view, if there are any previously hidden panels of that type, it will be shown instead of creating a new panel instance.myDocker.registerPanelType('persistent panel', { isPersistent: true, onCreate: function(myPanel) { myPanel.on(wcDocker.EVENT.PERSISTENT_CLOSED, function() { // The user has closed this panel, but instead of being destroyed, it is only hidden. }); myPanel.on(wcDocker.EVENT.PERSISTENT_OPENED, function() { // The user added this panel type, but actually only re-shown this persistent version of the panel instead. }); } }); The collapse direction button on a panel can now be overridden if the built in calculation does not meet your needs. See wcPanel#collapseDirection for more information. // You can override the direction with your own calculation function callback myPanel.collapseDirection(function(bounds) { return wcDocker.DOCK.LEFT; }); // Or you can set it to a static direction myPanel.collapseDirection(wcDocker.DOCK.RIGHT); // Or you can restore it back to the default calculation myPanel.collapseDirection(false); Source code now supports DCL! Front page Theme Builder is now built into the libraries. To include it in your project, you will need to include spectrum into your project as well as register a panel to be used for the theme builder:myDocker.registerPanelType('Theme Builder', { faicon: 'map', onCreate: wcThemeBuilder }); Version: 2.2.0 Separated the default theme out of wcDocker.css (now use wcDocker.css with Themes/default.css). Added wcDocker.panelTypeInfo() and wcPanel.info() that will retrieve the registration data of a panel. Added wcDocker.panelTypes() to retrieve a list of all registered panel types. New event type wcDocker.EVENT.INIT. Panel width and height can now be retrieved. wcPanel functions initPos, initSize, minSize, and maxSize can now take a string value with a 'px' or '%' suffix. Fixed issue with using normal CSS icons in the context menu. Improved auto scrolling of tab items when clicked. Create your own wcTabFrame widget within your panels. Create your own wcIFrame widget within your panels. Floating panels can now be modal. Version: 2.1.0 wcDocker now has Bower support for easy package management. wcSplitter is now usable inside a panel. Improved performance of panel resizing. wcPanel.focus() now actually sets itself as the current active tab. wcDocker.registerPanelType() has a new option {limit: Number} that limits the total number of copies for this panel. New event type wcDocker.EVENT.VISIBILITY_CHANGED, triggered whenever the panel gains or loses visibility. Use wcPanel.isVisible() to retrieve the current state. Reduced DOM changes during tab change and resize. New event types wcDocker.EVENT.BEGIN_DOCK and wcDocker.EVENT.END_DOCK that trigger whenever the user is dragging a panel to a new location. New event types wcDocker.EVENT.GAIN_FOCUS and wcDocker.EVENT.LOST_FOCUS that trigger whenever a panel is brought it and out of focus. Floating panels no longer change size whenever a new panel is added to it as a tab. Version: 2.0.0 Layout grid can now have a spacing size. Layout grid can now be set to alternating row color. wcLayout.item() added to retrieve an already existing item in the layout. wcDocker can now send and receive events. wcLayout can now batch large numbers of elements added without page refreshing between each. wcPanel can now contain custom buttons that appear within the title bar. wcDocker.basicMenu() now has an option to include the default menu options along with your custom ones. wcDocker.basicMenu() can now accept a dynamic callback function that returns custom menu's at the time of the event. New events added for resize start, resize end, move start, and move end. Panels can now be set to hide their contents whenever they are resized. wcDocker constructor now takes an options object. wcDocker now has an option to disable the default context menu. Panel tabs are now scrollable. Icons are now supported using regular CSS or the Font-Awesome library http://fortawesome.github.io/Font-Awesome/. wcDocker.registerPanelType() can now take an options object instead of just a single callback. Fixed layout save/restore. Fixed layout clear not actually removing elements. Fixed compatibility with IE8. Fixed tabs disappearing when the panel is too small to fit them. Dependencies JQuery Library version 1.11.1 http://jquery.com/ JQuery ContextMenu Library https://github.com/swisnl/jQuery-contextMenu Font-Awesome http://fortawesome.github.io/Font-Awesome/ LicenseMIT License © 2014-2016 Jeff Houde (lochemage@webcabin.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Suggestions/Comments?Please feel free to contact me, Jeff Houde (lochemage@webcabin.org), for any information or to give feedback and suggestions. Also, if you are a web programmer, and believe you can help, please let me know! Thank you × Search results Close "},"external-domNode.html":{"id":"external-domNode.html","title":"External: domNode","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery External: domNode domNode A Document Object Model Element used by HTML. Source: ext.jsdoc, line 1 See: http://www.w3schools.com/jsref/dom_obj_all.asp × Search results Close "},"external-jQuery.html":{"id":"external-jQuery.html","title":"External: jQuery","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery External: jQuery jQuery jQuery library. Part of the listed dependencies. Source: ext.jsdoc, line 7 See: http://jquery.com/ Type Definitions typedef var contextMenu jQuery contextMenu library. Part of the listed dependencies. Type: Object Source: ext.jsdoc, line 28 See: http://medialize.github.io/jQuery-contextMenu/docs.html/ typedef var Object A jQuery object. Type: Object Source: ext.jsdoc, line 21 See: https://learn.jquery.com/using-jquery-core/jquery-object/ typedef var selector A jQuery selector string. Type: String Source: ext.jsdoc, line 14 See: http://api.jquery.com/category/selectors/ × Search results Close "},"module-wcBase.html":{"id":"module-wcBase.html","title":"Module: wcBase","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcBase new (require("wcBase"))() Base class for all docker classes Source: base.js, line 5 Methods function docker() -> module:wcDocker Retrieves the main docker instance. Source: base.js, line 43 Returns: - The top level docker object. Type module:wcDocker function getOptions() -> Object | null Returns this or the docker's options Source: base.js, line 10 Returns: Type Object | null function instanceOf(what [, who]) -> boolean Class eq function Parameters: Name Type Argument Description what string who object <optional> Source: base.js, line 31 Returns: Type boolean function option(name, _default) -> Object | null Return an option found in this or in the docker. Parameters: Name Type Description name _default Object | null Source: base.js, line 20 Returns: Type Object | null × Search results Close "},"module-wcCollapser.html":{"id":"module-wcCollapser.html","title":"Module: wcCollapser","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcCollapser new (require("wcCollapser"))() A docker container for carrying its own arrangement of docked panels as a slide out drawer. PRIVATE - Handled internally by docker and should never be constructed by the user. Version: 3.0.0 Source: collapser.js, line 10 Methods <static> function constructor(container, parent, position) Parameters: Name Type Description container external:jQuery~selector | external:jQuery~Object | external:domNode A container element for this drawer. parent module:wcSplitter | wcDocker The drawer's parent object. position module:wcDocker.DOCK A docking position to place this drawer. Source: collapser.js, line 26 function collapse() Collapses the drawer to its respective side wall. Source: collapser.js, line 43 function expand() Expands the drawer. Source: collapser.js, line 51 function isExpanded() -> Boolean Gets whether the drawer is expanded. Source: collapser.js, line 59 Returns: - The current expanded state. Type Boolean function maxSize() -> module:wcDocker~Size The maximum size constraint for the side bar area. Source: collapser.js, line 77 Returns: - The maximum size. Type module:wcDocker~Size function minSize() -> module:wcDocker~Size The minimum size constraint for the side bar area. Source: collapser.js, line 68 Returns: - The minimum size. Type module:wcDocker~Size × Search results Close "},"module-wcDocker.html":{"id":"module-wcDocker.html","title":"Module: wcDocker","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcDocker Source: docker.js, line 17 Members <static, constant> var COLLAPSED Used when adding or moving a panel to designate the target location as collapsed. Must be used with docking positions LEFT, RIGHT, or BOTTOM only. Type: String Source: types.js, line 113 <static, constant> var DOCK Enumerated Docking positions. Properties: Name Type Default Description MODAL String "modal" A floating panel that blocks input until closed FLOAT String "float" A floating panel TOP String "top" Docks to the top of a target or window LEFT String "left" Docks to the left of a target or window RIGHT String "right" Docks to the right of a target or window BOTTOM String "bottom" Docks to the bottom of a target or window STACKED String "stacked" Docks as another tabbed item along with the target Version: 3.0.0 Source: types.js, line 6 <static, constant> var EVENT Enumerated Internal events Properties: Name Type Default Description INIT String "panelInit" When the panel is initialized LOADED String "dockerLoaded" When all panels have finished loading UPDATED String "panelUpdated" When the panel is updated VISIBILITY_CHANGED String "panelVisibilityChanged" When the panel has changed its visibilityThis event is called with the current visibility state as the first parameter BEGIN_DOCK String "panelBeginDock" When the user begins moving any panel from its current docked position END_DOCK String "panelEndDock" When the user finishes moving or docking a panel GAIN_FOCUS String "panelGainFocus" When the user brings any panel within a tabbed frame into focus LOST_FOCUS String "panelLostFocus" When the user leaves focus on any panel within a tabbed frame CLOSING String "panelClosing" When the panel is about to be closed, but before it closes. If any event handler returns a falsey value, the close action will be canceled. CLOSED String "panelClosed" When the panel is being closed PERSISTENT_CLOSED String "panelPersistentClosed" When a persistent panel is being hidden PERSISTENT_OPENED String "panelPersistentOpened" When a persistent panel is being shown BUTTON String "panelButton" When a custom button is clicked, See wcPanel.addButton ATTACHED String "panelAttached" When the panel has moved from floating to a docked position DETACHED String "panelDetached" When the panel has moved from a docked position to floating MOVE_STARTED String "panelMoveStarted" 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_ENDED String "panelMoveEnded" When the user has finished moving the panelThis event is called with an object of the current {x, y} position as the first parameter MOVED String "panelMoved" When the top-left coordinates of the panel has changedThis event is called with an object of the current {x, y} position as the first parameter RESIZE_STARTED String "panelResizeStarted" 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_ENDED String "panelResizeEnded" When the user has finished resizing the panelThis event is called with an object of the current {width, height} size as the first parameter RESIZED String "panelResized" When the panels width or height has changedThis event is called with an object of the current {width, height} size as the first parameter ORDER_CHANGED String "panelOrderChanged" This only happens with floating windows when the order of the windows have changed. SCROLLED String "panelScrolled" When the contents of the panel has been scrolled SAVE_LAYOUT String "layoutSave" When the layout is being saved, See wcDocker.save RESTORE_LAYOUT String "layoutRestore" When the layout is being restored, See wcDocker.restore CUSTOM_TAB_CHANGED String "customTabChanged" When the current tab on a custom tab widget associated with this panel has changed, See module:wcTabFrame CUSTOM_TAB_CLOSED String "customTabClosed" When a tab has been closed on a custom tab widget associated with this panel, See module:wcTabFrame Version: 3.0.0 Source: types.js, line 42 <static, constant> var LAYOUT Enumerated Layout wcDocker. Properties: Name Type Default Description SIMPLE String "wcLayoutSimple" Contains a single div item without management using a module:wcLayoutSimple, it is up to you to populate it however you wish. TABLE String "wcLayoutTable" Manages a table grid layout using module:wcLayoutTable, this is the default layout used if none is specified. Version: 3.0.0 Source: types.js, line 29 <static, constant> var ORIENTATION Used for the splitter bar orientation. Properties: Name Type Default Description VERTICAL Boolean false Top and Bottom panes HORIZONTAL Boolean true Left and Right panes Version: 3.0.0 Source: types.js, line 121 <static, constant> var TAB Used to determine the position of tabbed widgets for stacked panels. Note: Not supported on IE8 or below. Properties: Name Type Default Description TOP String "top" The default, puts tabs at the top of the frame LEFT String "left" Puts tabs on the left side of the frame RIGHT String "right" Puts tabs on the right side of the frame BOTTOM String "bottom" Puts tabs on the bottom of the frame Version: 3.0.0 Source: types.js, line 133 Methods <static> function constructor(container [, options]) Parameters: Name Type Argument Description container external:jQuery~selector | external:jQuery~Object | external:domNode A container element to store the contents of wcDocker. options module:wcDocker~Options <optional> Options for constructing the instance. Source: docker.js, line 65 function addPanel(typeName, location [, targetPanel] [, options]) -> module:wcPanel | Boolean Add a new docked panel to the docker instance. Note: It is best to use wcDocker.COLLAPSED after you have added your other docked panels, as it may ensure proper placement. Parameters: Name Type Argument Description typeName String The name identifier of the panel to create. location module:wcDocker.DOCK The docking location to place this panel. targetPanel module:wcPanel | module:wcDocker.COLLAPSED <optional> A target panel to dock relative to, or use wcDocker.COLLAPSED to collapse it to the side or bottom. options module:wcDocker~PanelOptions <optional> Other options for panel placement. Source: docker.js, line 280 Returns: - The newly created panel object, or false if no panel was created. Type module:wcPanel | Boolean function basicMenu(selector, itemListOrBuildFunc, includeDefault) Assigns a basic context menu to a selector element. The context Menu is a simple list of options, no nesting or special options. If you wish to use a more complex context menu, you can use jQuery.contextMenu directly. Parameters: Name Type Description selector external:jQuery~selector A selector string that designates the elements who use this menu. itemListOrBuildFunc Array.<external:jQuery#contextMenu~item> | function An array with each context menu item in it, or a function to call that returns one. includeDefault Boolean If true, all default menu options will be included. Deprecated: Renamed to [wcDocker.menu}wcDocker#menu. Source: docker.js, line 776 function bypassMenu() Bypasses the next context menu event. Use this during a mouse up event in which you do not want the context menu to appear when it normally would have. Source: docker.js, line 1130 function clear() Clears all contents from the docker instance. Source: docker.js, line 1227 function findPanels( [typeName]) -> Array.<module:wcPanel> Finds all instances of a given panel type. Parameters: Name Type Argument Description typeName String <optional> The name identifier for the panel. If not supplied, all panels are retrieved. Source: docker.js, line 620 Returns: - A list of all panels found of the given type. Type Array.<module:wcPanel> function finishLoading( [fadeDuration]) Hides the loading screen. Parameters: Name Type Argument Default Description fadeDuration Number <optional> 0 The fade out duration for the loading screen. Source: docker.js, line 681 function isCollapseEnabled() -> Boolean Retrieves whether panel collapsers are enabled. Version: 3.0.0 Source: docker.js, line 195 Returns: - Collapsers are enabled. Type Boolean function menu(selector, itemListOrBuildFunc, includeDefault) Assigns a basic context menu to a selector element. The context Menu is a simple list of options, no nesting or special options. If you wish to use a more complex context menu, you can use jQuery.contextMenu directly. Parameters: Name Type Description selector external:jQuery~selector A selector string that designates the elements who use this menu. itemListOrBuildFunc Array.<external:jQuery#contextMenu~item> | function An array with each context menu item in it, or a function to call that returns one. includeDefault Boolean If true, all default menu options will be included. Source: docker.js, line 793 function movePanel(panel, location [, targetPanel] [, options]) -> module:wcPanel | Boolean Moves a docking panel from its current location to another. Parameters: Name Type Argument Description panel module:wcPanel The panel to move. location module:wcDocker.DOCK The new docking location of the panel. targetPanel module:wcPanel | wcDocker.COLLAPSED <optional> A target panel to dock relative to, or use wcDocker.COLLAPSED to collapse it to the side or bottom. options module:wcDocker~PanelOptions <optional> Other options for panel placement. Source: docker.js, line 464 Returns: - The panel that was created, or false on failure. Type module:wcPanel | Boolean function off(eventType [, handler]) Unregisters a global event. Parameters: Name Type Argument Description eventType module:wcDocker.EVENT The event type, can be a custom event string or a predefined event. handler module:wcDocker~event:onEvent <optional> The handler function registered with the event. If omitted, all events registered to the event type are unregistered. Source: docker.js, line 725 function on(eventType, handler) -> Boolean Registers a global event. Parameters: Name Type Description eventType module:wcDocker.EVENT The event type, can be a custom event string or a predefined event. handler module:wcDocker~event:onEvent A handler function to be called for the event. Source: docker.js, line 701 Returns: Success or failure that the event has been registered. Type Boolean function panelTypeInfo(typeName) -> module:wcDocker~registerOptions Retrieves the options data associated with a given panel type when it was registered. Parameters: Name Type Description typeName String The name identifier of the panel. Source: docker.js, line 265 Returns: - Registered options of the panel type, or false if the panel was not found. Type module:wcDocker~registerOptions function panelTypes(includePrivate) -> Array.<String> Retrieves a list of all currently registered panel types. Parameters: Name Type Description includePrivate Boolean If true, panels registered as private will also be included with this list. Source: docker.js, line 249 Returns: - A list of panel type names. Type Array.<String> function registerPanelType(name, options [, isPrivate]) -> Boolean Registers a new docking panel type to be used later. Parameters: Name Type Argument Description name String The name identifier for the new panel type. options module:wcDocker~registerOptions An options object for describing the panel type. isPrivate Boolean <optional> DEPRECATED: Use options.isPrivate instead. Version: 3.0.0 Source: docker.js, line 205 Returns: - Success or failure. Failure usually indicates the type name already exists. Type Boolean function removePanel(panel, dontDestroy) -> Boolean Removes a docked panel from the window. Parameters: Name Type Description panel module:wcPanel The panel to remove. dontDestroy Boolean If true, the panel itself will not be destroyed. Source: docker.js, line 335 Returns: - Success or failure. Type Boolean function restore(dataString) Restores a previously saved configuration. Parameters: Name Type Description dataString String A previously saved serialized string, See wcDocker.save. Source: docker.js, line 1188 function save() -> String Saves the current panel configuration into a serialized string that can be used later to restore it. Source: docker.js, line 1156 Returns: - A serialized string that describes the current panel configuration. Type String function startLoading( [label] [, opacity] [, textOpacity]) Shows the loading screen. Parameters: Name Type Argument Default Description label String <optional> An optional label to display. opacity Number <optional> 0.4 If supplied, assigns a custom opacity value to the loading screen. textOpacity Number <optional> 1 If supplied, assigns a custom opacity value to the loading icon and text displayed. Source: docker.js, line 641 function theme(themeName) -> String Gets, or Sets the current theme used by docker. Parameters: Name Type Description themeName String If supplied, will activate a theme with the given name. Source: docker.js, line 164 Returns: - The currently active theme. Type String function themePath(path) -> String Gets, or Sets the path where all theme files can be found. "Themes" is the default folder path. Parameters: Name Type Description path String If supplied, will set the path where all themes can be found. Source: docker.js, line 150 Returns: - The currently assigned path. Type String function trigger(eventType [, data]) -> Array.<Object> Trigger an event on all panels. Parameters: Name Type Argument Description eventType module:wcDocker.EVENT The event type, can be a custom event string or a predefined event. data Object <optional> A custom data object to be passed along with the event. Source: docker.js, line 750 Fires: wcDocker~event:onEvent Returns: results - Returns an array with all results returned by event handlers. Type Array.<Object> Type Definitions typedef var Anchor Anchor data. Type: Object Properties: Name Type Argument Description self Boolean Whether the anchor is hovering over the moving panel. loc module:wcDocker.DOCK The location of the anchor on the panel. item module:wcLayout The panel layout being hovered over. tab module:wcDocker.TAB The tab location. x Number <optional> X coordinate of the anchor. y Number <optional> Y coordinate of the anchor. w Number <optional> Width of the anchor. h Number <optional> Height of the anchor. Source: docker.jsdoc, line 123 typedef var AnchorRect A rectangle structure. Type: Object Properties: Name Type Argument Description x Number | String <optional> X coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. y Number | String <optional> Y coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. w Number | String <optional> Width of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. h Number | String <optional> Height of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. tabOrientation module:wcDocker.TAB <optional> Desired orientation of tab widgets. Source: docker.jsdoc, line 37 typedef var Bounds A bounding structure Type: Object Properties: Name Type Description top Number The upper, or top bound (percentage value between 0 and 1). bottom Number The lower, or bottom bound (percentage value between 0 and 1). left Number The left bound (percentage value between 0 and 1). right Number The right bound (percentage value between 0 and 1). Source: docker.jsdoc, line 47 typedef var Coordinate A coordinate structure. Type: Object Properties: Name Type Description x Number X coordinate. y Number Y coordinate. Source: docker.jsdoc, line 56 typedef var FitContents Determines whether the container should fit the size of its contents instead of scroll for each axis. Type: Object Properties: Name Type Description x Boolean Whether scrolling is enabled in the horizontal direction. y Boolean Whether scrolling is enabled in the vertical direction. Source: docker.jsdoc, line 77 typedef function onCreatePanel(panel [, options]) A function or an object constructor for the panel. This function is called using the 'new' operator. Parameters: Name Type Argument Description panel module:wcPanel The panel being constructed. options module:wcPanel~options <optional> An options object passed in from wcDocker.registerPanelType()'s options.options parameter. Source: docker.jsdoc, line 108 typedef var Options Options for a docker instance. Type: Object Properties: Name Type Argument Default Description themePath String <optional> 'Themes' A folder path where all docker theme files can be found. theme String <optional> 'default' The active docker theme. loadingClass String <optional> 'fa fa-spinner fa-pulse' Any class name to use for the loading screen icon. allowContextMenu Boolean <optional> true Overrides the default right click menu with ones that interact with docker. hideOnResize Boolean <optional> false If true, panels will hide their contents as they are being resized. allowCollapse Boolean <optional> true Allows users to collapse panels to the sides of the docker view. responseRate Number <optional> 10 This determines how often updates are performed (in milliseconds). moveStartDelay Number <optional> 300 The time delay (in milliseconds) before a panel drag operation will start. edgeAnchorSize Number | String <optional> 50 Determines the size of the anchor points when docking a panel to the outer edge of the window. Can be a pixel value, or a string with a 'px' or '%' suffix. panelAnchorSize Number | String <optional> '15%' Determines the size of the anchor points when docking a panel along the side of another panel. Can be a pixel value, or a string with a 'px' or '%' suffix. detachToWidth Number | String <optional> 600 Determines the new width when a panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. detachToHeight Number | String <optional> 400 Determines the new height when a panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. wcPanelClass Object <optional> Defines a class object to use in replacement of the default wcPanel object. wcGhostClass Object <optional> Defines a class object to use in replacement of the default wcGhost object. wcSplitterClass Object <optional> Defines a class object to use in replacement of the default wcSplitter object. wcFrameClass Object <optional> Defines a class object to use in replacement of the default wcFrame object. wcCollapserClass Object <optional> Defines a class object to use in replacement of the default wcCollapser object. wcLayoutSimpleClass Object <optional> Defines a class object to use in replacement of the default wcLayoutSimple object. wcLayoutTableClass Object <optional> Defines a class object to use in replacement of the default wcLayoutTable object. wcDrawerClass Object <optional> Defines a class object to use in replacement of the default wcDrawer object. wcTabFrameClass Object <optional> Defines a class object to use in replacement of the default wcTabFrame object. Source: docker.jsdoc, line 1 typedef var PanelOptions Options for adding a new panel. Type: Object Properties: Name Type Argument Description x Number | String <optional> X coordinate of the panel center (if floating). Can be a pixel position, or a string with a 'px' or '%' suffix. y Number | String <optional> Y coordinate of the panel center (if floating). Can be a pixel position, or a string with a 'px' or '%' suffix. w Number | String <optional> Desired width of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. h Number | String <optional> Desired height of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. tabOrientation module:wcDocker.TAB <optional> Desired position of tab widgets when using wcDocker.DOCK.STACKED. Not supported on IE8 or below. Source: docker.jsdoc, line 84 typedef var Rect A rectangle structure. Type: Object Properties: Name Type Argument Description x Number | String <optional> X coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. y Number | String <optional> Y coordinate of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. w Number | String <optional> Width of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. h Number | String <optional> Height of the rectangle. Can be a pixel position, or a string with a 'px' or '%' suffix. Source: docker.jsdoc, line 28 typedef var registerOptions Options object for registering new panel types. Properties: Name Type Argument Default Description onCreate module:wcDocker~onCreatePanel A function or an object constructor for the panel. layout module:wcDocker.LAYOUT <optional> wcDocker.LAYOUT.TABLE If supplied, overrides the default layout used for this panel. icon String <optional> A CSS class name to draw an icon in the panels tab widget. faicon String <optional> An icon name using the Font-Awesome library. You must download and link to the library first. title String | Boolean <optional> Assign a custom name to the panels tab. A false value will hide the tab entirely. isPrivate Boolean <optional> If true, the user will not be able to create this panel type. isPersistent Boolean <optional> If true, when the user closes this panel, it will only be hidden instead of completely destroyed. When the user creates an instance of this panel, it will first attempt to un-hide an already existing panel before creating a new instance. limit Number <optional> Enforces a limited number of this panel type from being created by the user. options Object <optional> A custom options object to be passed into the new panel constructor or creation function as the second parameter. Source: docker.jsdoc, line 94 typedef var Scrollable Determines whether the container will allow scroll bars to appear on each axis. Type: Object Properties: Name Type Description x Boolean Whether scrolling is enabled in the horizontal direction. y Boolean Whether scrolling is enabled in the vertical direction. Source: docker.jsdoc, line 70 typedef var Size A 2D size structure. Type: Object Properties: Name Type Description x Number Width. y Number Height. Source: docker.jsdoc, line 63 Events function onEvent An event handler callback. Each is registered to a event type using the wcDocker.on() or wcPanel.on() functions. Type: function Parameters: Name Type Argument Description panel module:wcPanel | NULL The panel invoking the event, or NULL if global. data Object <optional> A data object passed by the invoker. Source: docker.jsdoc, line 115 × Search results Close "},"module-wcDrawer.html":{"id":"module-wcDrawer.html","title":"Module: wcDrawer","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcDrawer Source: drawer.js, line 1 Methods <static> function constructor(container, parent, position) Parameters: Name Type Description container external:jQuery~selector | external:jQuery~Object | external:domNode A container element for this drawer. parent wcSplitter | wcDocker The drawer's parent object. position module:wcDocker.DOCK A docking position to place this drawer. Source: drawer.js, line 25 function collapse() Collapses the drawer to its respective side wall. Source: drawer.js, line 44 function expand() Expands the drawer. Source: drawer.js, line 104 function isExpanded() -> Boolean Gets whether the drawer is expanded. Source: drawer.js, line 139 Returns: - The current expanded state. Type Boolean function maxSize() -> module:wcDocker~Size The maximum size constraint for the drawer area. Source: drawer.js, line 165 Returns: - The maximum size. Type module:wcDocker~Size function minSize() -> module:wcDocker~Size The minimum size constraint for the drawer area. Source: drawer.js, line 148 Returns: - The minimum size. Type module:wcDocker~Size × Search results Close "},"module-wcFrame.html":{"id":"module-wcFrame.html","title":"Module: wcFrame","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcFrame Source: frame.js, line 1 Members var $container The container that holds the frame. Type: external:jQuery~Object Source: frame.js, line 30 var $frame The outer frame element. Type: external:jQuery~Object Source: frame.js, line 38 Methods <static> function constructor(container, parent, isFloating) PRIVATE - Handled internally by docker and should never be constructed by the user. Parameters: Name Type Description container external:jQuery~selector | external:jQuery~Object | external:domNode A container element for this frame. parent module:wcSplitter | wcDocker The frames parent object. isFloating Boolean If true, the frame will be a floating window. Source: frame.js, line 25 function addPanel(panel [, index]) Adds a given panel as a new tab item to the frame. Parameters: Name Type Argument Description panel module:wcPanel The panel to add. index Number <optional> Insert index. Source: frame.js, line 213 function collapse( [instant]) Collapses the frame, if it is a collapser. Parameters: Name Type Argument Description instant Boolean <optional> If true, collapses without animating. Source: frame.js, line 324 function expand() Expands the frame, if it is a collapser. Source: frame.js, line 337 function initSize() -> module:wcDocker~Size Gets the initially desired size of the panel. Source: frame.js, line 131 Returns: - The initially desired size. Type module:wcDocker~Size function isCollapser() -> Boolean Gets whether this frame is inside a collapser. Source: frame.js, line 315 Returns: - Whether this frame is inside a collapser. Type Boolean function isExpanded() -> Boolean | undefined Gets whether the frame is expanded, if it is a collapser. Source: frame.js, line 349 Returns: - The current expanded state, or undefined if it is not a collapser. Type Boolean | undefined function maxSize() -> module:wcDocker~Size Gets the maximum size of the frame. Source: frame.js, line 175 Returns: - The maximum size of the frame. Type module:wcDocker~Size function minSize() -> module:wcDocker~Size Gets the minimum size of the frame. Source: frame.js, line 157 Returns: - The minimum size of the frame. Type module:wcDocker~Size function panel( [tabIndex] [, autoFocus]) -> module:wcPanel Gets, or Sets the currently visible panel. Parameters: Name Type Argument Description tabIndex Number <optional> If supplied, sets the current panel index. autoFocus Boolean <optional> If true, this tab will be focused (brought to front). Source: frame.js, line 278 Returns: - The currently visible panel. Type module:wcPanel function pos( [x] [, y] [, pixels]) -> module:wcDocker~Coordinate Gets, or Sets the position of the frame. Parameters: Name Type Argument Description x Number <optional> If supplied, assigns a new horizontal position. y Number <optional> If supplied, assigns a new vertical position. pixels Boolean <optional> If true, the coordinates passed in will be treated as a pixel position rather than a percentage. Source: frame.js, line 102 Returns: - The current position of the frame. If the pixel parameter was true, the position will be in pixels. Type module:wcDocker~Coordinate function removePanel(panel) -> Boolean Removes a given panel from the frame. Parameters: Name Type Description panel module:wcPanel The panel to remove. Source: frame.js, line 241 Returns: - True if any panels still remain after the removal. Type Boolean function tabOrientation( [orientation]) -> module:wcDocker.TAB Gets, or Sets the tab orientation for the frame. This puts the tabbed widgets visually on any side of the frame. Parameters: Name Type Argument Description orientation module:wcDocker.TAB <optional> Assigns the orientation of the tab items displayed. Version: 3.0.0 Source: frame.js, line 193 Returns: - The current orientation. Type module:wcDocker.TAB × Search results Close "},"module-wcGhost.html":{"id":"module-wcGhost.html","title":"Module: wcGhost","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcGhost Source: ghost.js, line 1 Methods <static> function constructor(rect, mouse, docker) Parameters: Name Type Description rect module:wcDocker~Rect A rectangle area to begin the ghost highlighting. mouse module:wcDocker~Coordinate The mouse position. docker module:wcDocker The docker object. Source: ghost.js, line 20 function anchor( [mouse] [, anchor]) Get, or Sets the ghost's anchor. Parameters: Name Type Argument Description mouse module:wcDocker~Coordinate <optional> If supplied with the anchor, . anchor module:wcDocker~Anchor <optional> If supplied, assigns a new anchor. Source: ghost.js, line 81 function destroy() Destroys the instance of the ghost. Source: ghost.js, line 170 function rect() -> module:wcDocker~AnchorRect Retrieves the rectangle area of the ghost's anchor. Source: ghost.js, line 155 Returns: - The rectangle area of the anchor. Type module:wcDocker~AnchorRect function update(position [, disableFloating]) Updates the ghost based on the given screen position. Parameters: Name Type Argument Description position module:wcDocker~Coordinate The mouse position. disableFloating Boolean <optional> If true, the ghost will not float. Source: ghost.js, line 39 × Search results Close "},"module-wcIFrame.html":{"id":"module-wcIFrame.html","title":"Module: wcIFrame","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcIFrame Source: iframe.js, line 1 Members var $iFrame The iFrame element. Type: external:jQuery~Object Source: iframe.js, line 44 Methods <static> function constructor(container, parent) Parameters: Name Type Description container external:jQuery~selector | external:jQuery~Object | external:domNode A container element for this layout. parent module:wcPanel The iframes's parent panel. Source: iframe.js, line 31 function destroy() Destroys the iFrame element and clears all references. Note: This is automatically called when the owner panel is destroyed. Source: iframe.js, line 199 function hide() Forces the iFrame to be hidden, regardless of whether the panel is visible. Source: iframe.js, line 180 function onClosed(onClosedFunc) Registers an event handler when the iFrame has been closed. Parameters: Name Type Description onClosedFunc function A function to call when the iFrame has closed. Source: iframe.js, line 161 function onLoaded(onLoadedFunc) Registers an event handler when the contents of this iFrame has loaded. Parameters: Name Type Description onLoadedFunc function A function to call when the iFrame has loaded. Source: iframe.js, line 152 function openHTML(html) Populates the iFrame with the given HTML source code using the document to write data. Parameters: Name Type Description html String The HTML source code. Source: iframe.js, line 90 function openSRC(html) Populates the iFrame with the given HTML source code using the srcdoc attribute. Parameters: Name Type Description html String The HTML source code. Version: 3.0.0 Source: iframe.js, line 122 function openURL(url) Opens a given URL address into the iFrame. Parameters: Name Type Description url String The full, or relative, path to the page. Source: iframe.js, line 62 function show() Allows the iFrame to be visible when the panel is visible. Source: iframe.js, line 170 function window() -> Object Retrieves the window object from the iFrame element. Source: iframe.js, line 190 Returns: - The window object. Type Object × Search results Close "},"module-wcLayout.html":{"id":"module-wcLayout.html","title":"Module: wcLayout","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcLayout Source: layout.js, line 1 Methods function addItem(item) Adds an item into the layout, appending it to the main element. Parameters: Name Type Description item external:jQuery~selector | external:jQuery~Object | external:domNode A DOM element to add. Source: layout.js, line 44 function clear() Clears the contents of the layout and squashes all rows and columns from the grid. Source: layout.js, line 53 function scene() -> external:jQuery~Object Retrieves the main element. Source: layout.js, line 61 Returns: - The div item that makes this layout scene. Type external:jQuery~Object × Search results Close "},"module-wcLayoutSimple.html":{"id":"module-wcLayoutSimple.html","title":"Module: wcLayoutSimple","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcLayoutSimple Source: layoutsimple.js, line 1 Methods function addItem(item) Adds an item into the layout, appending it to the main element. Parameters: Name Type Description item external:jQuery~selector | external:jQuery~Object | external:domNode A DOM element to add. Source: layoutsimple.js, line 20 function clear() Clears the contents of the layout and squashes all rows and columns from the grid. Source: layoutsimple.js, line 29 × Search results Close "},"module-wcLayoutTable.html":{"id":"module-wcLayoutTable.html","title":"Module: wcLayoutTable","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcLayoutTable Source: layouttable.js, line 1 Methods function addItem(item [, x] [, y] [, w] [, h]) -> module:wcLayoutTable~tableItem | Boolean Adds an item into the layout, expanding the grid size if necessary. Parameters: Name Type Argument Default Description item external:jQuery~selector | external:jQuery~Object | external:domNode A DOM element to add. x Number <optional> 0 The horizontal grid position to place the element. y Number <optional> 0 The vertical grid position to place the element. w Number <optional> 1 The number of horizontal cells this item will take within the grid. h Number <optional> 1 The number of vertical cells this item will take within the grid. Source: layouttable.js, line 20 Returns: The table data element of the cell that contains the item, or false if there was a problem. Type module:wcLayoutTable~tableItem | Boolean function clear() Clears the contents of the layout and squashes all rows and columns from the grid. Source: layouttable.js, line 172 function finishBatch() Ends a batch operation. Source: layouttable.js, line 201 See: module:wcLayoutTable#startBatch function gridAlternate() -> Boolean Gets, or Sets whether the table rows alternate in color based on the theme. Source: layouttable.js, line 239 Returns: - Whether the grid alternates in color. Type Boolean function gridSpacing( [size]) -> Number Gets, or Sets the spacing between cell borders. Parameters: Name Type Argument Description size Number <optional> If supplied, sets the pixel size of the spacing between cells. Source: layouttable.js, line 225 Returns: - The current cell spacing in pixels. Type Number function item(x, y) -> module:wcLayoutTable~tableItem | Boolean Retrieves the table item at a given grid position, if it exists. Note, if an item spans multiple cells, only the top-left most cell will actually contain the table item. Parameters: Name Type Description x Number The horizontal grid position. y Number The vertical grid position. Source: layouttable.js, line 55 Returns: - The table item, or false if none was found. Type module:wcLayoutTable~tableItem | Boolean function itemStretch(x, y [, sx] [, sy]) -> Boolean Sets the stretch amount for a given table item. This is more reliable than assigning width and height style attributes directly on the table item. Parameters: Name Type Argument Description x Number The horizontal grid position. y Number The vertical grid position. sx Number | String <optional> The horizontal stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. sy Number | String <optional> The vertical stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. Version: 3.0.0 Source: layouttable.js, line 135 Returns: - Success or failure. A failure generally means your grid position was a merged grid cell. Type Boolean function showGrid( [enabled]) -> Boolean Gets, or Sets whether the layout grid cells should draw an outline. Parameters: Name Type Argument Description enabled Boolean <optional> If supplied, will set the grid cell border visibility. Source: layouttable.js, line 211 Returns: - The current visibility state of the grid cells. Type Boolean function startBatch() Begins a batch operation. Basically it refrains from constructing the layout grid, which causes a reflow, on each item added. Instead, The grid is only generated at the end once wcLayoutTable.finishBatch is called. Source: layouttable.js, line 191 function tableItem_css(style [, value]) -> module:wcLayoutTable~tableItem | String This function is found in module:wcLayoutTable~tableItem. A wrapper for jQuery's css function. Note: It is recommended that you use stretch if you intend to alter width or height styles. Parameters: Name Type Argument Description style String The style attribute to alter. value String <optional> The value of the attribute. If omitted, the current value of the attribute is returned instead of the tableItem instance. Version: 3.0.0 Source: layouttable.js, line 96 Returns: - Self, for chaining, unless the value parameter was omitted. Type module:wcLayoutTable~tableItem | String function tableItem_stretch( [sx] [, sy]) -> module:wcLayoutTable~tableItem This function is found in module:wcLayoutTable~tableItem. Sets the stretch amount for the current table item. This is more reliable than assigning width and height style attributes directly on the table item. Parameters: Name Type Argument Description sx Number | String <optional> The horizontal stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. sy Number | String <optional> The vertical stretch for this grid. Use empty string to clear current value. Can be a pixel position, or a string with a 'px' or '%' suffix. Version: 3.0.0 Source: layouttable.js, line 117 Returns: - Self, for chaining. Type module:wcLayoutTable~tableItem Type Definitions typedef var tableItem The table item is an object that represents one cell in the layout table, it contains convenient methods for cell alteration and supports chaining. Its purpose is to remove the need to alter <tr> and <td> elements of the table directly. Properties: Name Type Description $ jQuery~Object If you truely need the table cell jQuery object, here it is. css module:wcLayoutTable~tableItem_css Wrapper to alter jQuery's css function. stretch module:wcLayoutTable~tableItem_stretch More reliable method for setting the table item width/height values. Version: 3.0.0 Source: layouttable.js, line 82 Example myPanel.addItem(domNode).css('text-align', 'right').css('border', '1px solid black').stretch('100%', '100%'); × Search results Close "},"module-wcPanel.html":{"id":"module-wcPanel.html","title":"Module: wcPanel","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcPanel Source: panel.js, line 1 Methods function addButton(name, className, text, tip [, isTogglable] [, toggleClassName]) Creates a new custom button that will appear in the title bar when the panel is active. Parameters: Name Type Argument Description name String The name of the button, to identify it later. className String A CSS class name to apply to the button. text String Text to apply to the button. tip String Tooltip text for the user. isTogglable Boolean <optional> If true, will make the button toggle on and off per click. toggleClassName String <optional> If this button is toggleable, you can designate an optional CSS class name that will replace the original class name. Source: panel.js, line 247 function buttonState(name [, toggleState]) -> Boolean Gets, or Sets the current toggle state of a custom button that was added using wcPanel.addButton. Parameters: Name Type Argument Description name String The name identifier of the button. toggleState Boolean <optional> If supplied, will assign a new toggle state to the button. Source: panel.js, line 297 Returns: - The current toggle state of the button. Type Boolean function close() Forces the window to close. Source: panel.js, line 638 function closeable( [enabled]) -> Boolean Gets, or Sets whether this dock window can be closed by the user. Note: The panel can still be closed programmatically. Parameters: Name Type Argument Description enabled Boolean <optional> If supplied, toggles whether it can be closed. Source: panel.js, line 620 Returns: the current closeable status. Type Boolean function collapseDirection(direction) Gets, or Sets the collapse direction for this panel. Parameters: Name Type Description direction module:wcPanel~CollapseDirection | wcDocker.DOCK The collapse direction to use for this panel.If this value is omitted, the default collapse direction will be used. Source: panel.js, line 204 function collapsible( [enabled]) -> Boolean Gets, or Sets whether this panel can be collapsed to the side or bottom. This only works if the collapse feature is enabled module:wcDocker~Options. Parameters: Name Type Argument Description enabled Boolean <optional> If supplied, assigns whether collapsing is enabled. Source: panel.js, line 544 Returns: - The current collapsible enabled state. Type Boolean function detachable( [enabled]) -> Boolean Sets, or Gets whether this panel can be detached into a floating panel. Parameters: Name Type Argument Description enabled Boolean <optional> If supplied, assigns whether this panel can be detached. Source: panel.js, line 606 Returns: - Whether this panel can detach. Type Boolean function faicon(icon) Sets the icon for the panel, shown in the panels tab widget, to an icon defined from the Font-Awesome library. Parameters: Name Type Description icon String The font-awesome icon name. Source: panel.js, line 477 function finishLoading( [fadeDuration]) Hides the loading screen. Parameters: Name Type Argument Default Description fadeDuration Number <optional> 0 If supplied, assigns a fade out duration for the loading screen. Source: panel.js, line 695 function focus( [flash]) Brings this panel into focus. If it is floating, it will be moved to the front of all other panels. Parameters: Name Type Argument Description flash Boolean <optional> If true, in addition to bringing the panel into focus, it will also flash for the user. Source: panel.js, line 179 function height() -> Number Retrieves the height of the panel contents. Source: panel.js, line 446 Returns: - Panel height. Type Number function icon(icon) Sets the icon for the panel, shown in the panels tab widget. Must be a css class name that contains the icon. Parameters: Name Type Description icon String The icon class name. Source: panel.js, line 458 function info() -> module:wcDocker~registerOptions Retrieves the registration info of the panel as declared from wcDocker.registerPanelType; Source: panel.js, line 159 See: wcDocker.panelTypeInfo. Returns: - Registered options of the panel type. Type module:wcDocker~registerOptions function initPos( [x] [, y]) -> module:wcDocker~Coordinate Gets, or Sets the default position of the panel if it is floating. Warning: after the panel has been initialized, this value no longer reflects the current position of the panel. Parameters: Name Type Argument Description x Number | String <optional> If supplied, sets the horizontal position of the floating panel. Can be a percentage position, or a string with a 'px' or '%' suffix. y Number | String <optional> If supplied, sets the vertical position of the floating panel. Can be a percentage position, or a string with a 'px' or '%' suffix. Source: panel.js, line 325 Returns: - The current default position of the panel. Type module:wcDocker~Coordinate function initSize( [x] [, y]) -> module:wcDocker~Size Gets, or Sets the desired size of the panel. Warning: after the panel has been initialized, this value no longer reflects the current size of the panel. Parameters: Name Type Argument Description x Number | String <optional> If supplied, sets the desired initial horizontal size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. y Number | String <optional> If supplied, sets the desired initial vertical size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. Source: panel.js, line 353 Returns: - The current initial size of the panel. Type module:wcDocker~Size function isFloating() -> Boolean Retrieves whether this panel is floating. Source: panel.js, line 222 Returns: Type Boolean function isInFocus() -> Boolean Retrieves whether this panel is in focus. Source: panel.js, line 234 Returns: Type Boolean function isVisible() -> Boolean Retrieves whether this panel can be seen by the user. Source: panel.js, line 213 Returns: - Visibility state. Type Boolean function layout() -> module:wcLayoutSimple | wcLayoutTable Retrieves the layout instance. Source: panel.js, line 170 Returns: - The layout instance. Type module:wcLayoutSimple | wcLayoutTable function maxSize( [x] [, y]) -> module:wcDocker~Size Gets, or Sets the maximum size constraint of the panel. Parameters: Name Type Argument Description x Number | String <optional> If supplied, sets the desired maximum horizontal size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. y Number | String <optional> If supplied, sets the desired maximum vertical size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. Source: panel.js, line 407 Returns: - The current maximum size. Type module:wcDocker~Size function minSize( [x] [, y]) -> module:wcDocker~Size Gets, or Sets the minimum size constraint of the panel. Parameters: Name Type Argument Description x Number | String <optional> If supplied, sets the desired minimum horizontal size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. y Number | String <optional> If supplied, sets the desired minimum vertical size of the panel. Can be a pixel position, or a string with a 'px' or '%' suffix. Source: panel.js, line 380 Returns: - The current minimum size. Type module:wcDocker~Size function moveable( [enabled]) -> Boolean Sets, or Gets the moveable status of the window. Note: Other panels can not dock beside a non-moving panel as doing so could cause it to move. Parameters: Name Type Argument Description enabled Boolean <optional> If supplied, assigns whether this panel can be moved. Source: panel.js, line 589 Returns: - Whether the panel is moveable. Type Boolean function off(eventType [, handler]) Unregisters an event associated with this panel. Parameters: Name Type Argument Description eventType module:wcDocker.EVENT The event type, can be a custom event string or a predefined event. handler module:wcDocker~event:onEvent <optional> The handler function registered with the event. If omitted, all events registered to the event type are unregistered. Source: panel.js, line 742 function on(eventType, handler) -> Boolean Registers an event associated with this panel. Parameters: Name Type Description eventType String The event type, can be a custom event string or a predefined event. handler module:wcDocker#onEvent An event handler function to be called when the event is fired. Source: panel.js, line 718 Returns: - Event registration success or failure. Type Boolean function overflowVisible( [visible]) -> Boolean Gets, or Sets whether overflow on this panel is visible. Use this if a child element within this panel is intended to 'popup' and be visible outside of its parent area. Parameters: Name Type Argument Description visible Boolean <optional> If supplied, assigns whether overflow is visible. Source: panel.js, line 559 Returns: - The current overflow visibility. Type Boolean function removeButton(name) -> Boolean Removes a custom button from the panel. Parameters: Name Type Description name String The name identifier for the button to remove. Source: panel.js, line 273 Returns: - Success or failure. Type Boolean function resizeVisible( [visible]) -> Boolean Gets, or Sets whether the contents of the panel are visible on resize. Use this if the panel has extremely expensive contents which take a long time to resize. Parameters: Name Type Argument Description visible Boolean <optional> If supplied, assigns whether panel contents are visible during resize. Source: panel.js, line 574 Returns: - The current resize visibility. Type Boolean function scroll( [x] [, y] [, duration]) -> module:wcDocker~Coordinate Gets, or Sets the scroll position of the panel's contents if it is scrollable; See wcPanel.scrollable). Parameters: Name Type Argument Description x Number <optional> If supplied, sets the scroll horizontal position of the panel. y Number <optional> If supplied, sets the scroll vertical position of the panel. duration Number <optional> If supplied, will animate the scroll movement with the supplied duration (in milliseconds). Source: panel.js, line 513 Returns: The current scroll position. Type module:wcDocker~Coordinate function scrollable( [x] [, y]) -> module:wcDocker~Scrollable Gets, or Sets whether the window is scrollable. Parameters: Name Type Argument Description x Boolean <optional> If supplied, assigns whether the window is scrollable in the horizontal direction. y Boolean <optional> If supplied, assigns whether the window is scrollable in the vertical direction. Source: panel.js, line 497 Returns: - The current scrollable status. Type module:wcDocker~Scrollable function startLoading( [label] [, opacity] [, textOpacity]) Shows the loading screen. Parameters: Name Type Argument Default Description label String <optional> An optional label to display. opacity Number <optional> 0.4 If supplied, assigns a custom opacity value to the loading screen. textOpacity Number <optional> 1 If supplied, assigns a custom opacity value to the loading icon and text displayed. Source: panel.js, line 649 function title(title) -> String | Boolean Gets, or Sets the title for this panel. Titles appear in the tab widget associated with the panel. Parameters: Name Type Description title String | Boolean If supplied, sets the new title (this can be html text). If false, the title bar will be removed. Source: panel.js, line 130 Returns: - The current title. Type String | Boolean function trigger(eventType [, data]) -> Array.<Object> Triggers an event of a given type to all panels, including itself. Parameters: Name Type Argument Description eventType module:wcDocker.EVENT The event type, can be a custom event string or a predefined event. data Object <optional> A custom data object to pass into all handlers. Source: panel.js, line 768 Returns: results - Returns an array with all results returned by event handlers. Type Array.<Object> function width() -> Number Retrieves the width of the panel contents. Source: panel.js, line 434 Returns: - Panel width. Type Number Type Definitions typedef var options An options object for the panel constructor. Properties: Name Type Argument Default Description icon String <optional> A CSS classname that represents the icon that should display on this panel's tab widget. faicon String <optional> An icon name using the Font-Awesome library. title String | Boolean <optional> A custom title to display for this panel, if false, title bar will not be shown. detachToWidth Number | String <optional> 600 Determines the new width when the panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. detachToHeight Number | String <optional> 400 Determines the new height when the panel is detached (0 = Don't change). Can be a pixel value, or a string with a 'px' or '%' suffix. Source: panel.js, line 26 × Search results Close "},"module-wcSplitter.html":{"id":"module-wcSplitter.html","title":"Module: wcSplitter","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcSplitter Source: splitter.js, line 1 Members var $pane An array of two elements representing each side of the splitter. Index 0 is always either top or left depending on orientation. Type: Array.<external:jQuery~Object> Source: splitter.js, line 37 Methods <static> function constructor(container, parent, orientation) Parameters: Name Type Description container external:jQuery~selector | external:jQuery~Object | external:domNode A container element for this splitter. parent wcLayout | wcSplitter | wcDocker The splitter's parent object. orientation module:wcDocker.ORIENTATION The orientation of the splitter bar. Source: splitter.js, line 25 function animPos(value) Animates to a given splitter position. Parameters: Name Type Description value Number Assigns the target splitter position. Value must be a percentage between 0 and 1. module:wcSplitter~onFinished A finished event handler. Source: splitter.js, line 203 function bottom( [item]) -> module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean Gets, or Sets the element associated with the bottom pane (for vertical layouts). Parameters: Name Type Argument Description item module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter <optional> If supplied, the pane will be replaced with this item. Source: splitter.js, line 304 Returns: - The current object assigned to the pane, or false. Type module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean function destroy( [destroyPanes]) Destroys the splitter. Parameters: Name Type Argument Default Description destroyPanes Boolean <optional> true If true, both panes attached will be destroyed as well. Use false if you plan to continue using the objects assigned to each pane, or make sure to remove them first before destruction. Source: splitter.js, line 337 function initLayouts( [topLeftLayout] [, bottomRightLayout]) Initializes the two panes of the splitter with its own layouts. This should be used to initialize the splitter when creating one for use inside your panel. Parameters: Name Type Argument Default Description topLeftLayout module:wcDocker.LAYOUT <optional> wcDocker.LAYOUT.TABLE The type of layout to use for the top or left pane. bottomRightLayout module:wcDocker.LAYOUT <optional> wcDocker.LAYOUT.TABLE The type of layout to use for the bottom or right pane. Source: splitter.js, line 56 function left( [item]) -> module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean Gets, or Sets the element associated with the left side pane (for horizontal layouts). Parameters: Name Type Argument Description item module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter <optional> If supplied, the pane will be replaced with this item. Source: splitter.js, line 274 Returns: - The current object assigned to the pane, or false. Type module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean function maxSize() -> module:wcDocker~Size Gets the maximum size constraint of the outer splitter area. Source: splitter.js, line 146 Returns: - The maximum size. Type module:wcDocker~Size function minSize() -> module:wcDocker~Size Gets the minimum size constraint of the outer splitter area. Source: splitter.js, line 108 Returns: The minimum size. Type module:wcDocker~Size function orientation(orientation) Gets, or Sets the orientation of the splitter. Parameters: Name Type Description orientation module:wcDocker.ORIENTATION The new orientation of the splitter. Source: splitter.js, line 74 function pane(index [, item]) -> module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean Gets, or Sets the element associated with a pane. Parameters: Name Type Argument Description index Number The index of the pane, only 0 and 1 are valid. item module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter <optional> If supplied, the pane will be replaced with this item. Source: splitter.js, line 243 Returns: - The current object assigned to the pane, or false. Type module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean function pos( [value]) -> Number Get, or Set the current splitter position. Parameters: Name Type Argument Description value Number <optional> If supplied, assigns a new splitter position. Value must be a percentage value between 0 and 1. Source: splitter.js, line 184 Returns: - The current position. Type Number function right( [item]) -> module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean Gets, or Sets the element associated with the right side pane (for horizontal layouts). Parameters: Name Type Argument Description item module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter <optional> If supplied, the pane will be replaced with this item. Source: splitter.js, line 284 Returns: - The current object assigned to the pane, or false. Type module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean function scrollable(index [, x] [, y]) -> module:wcDocker~Scrollable Gets, or Sets whether a pane can be scrolled via scroll bars. By default, scrolling is enabled in both directions. Parameters: Name Type Argument Description index Number The index of the pane, only 0 and 1 are valid. x Boolean <optional> Whether to allow scrolling in the horizontal direction. y Boolean <optional> Whether to allow scrolling in the vertical direction. Source: splitter.js, line 314 Returns: - The current scroll state for each direction. Type module:wcDocker~Scrollable function top( [item]) -> module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean Gets, or Sets the element associated with the top pane (for vertical layouts). Parameters: Name Type Argument Description item module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter <optional> If supplied, the pane will be replaced with this item. Source: splitter.js, line 294 Returns: - The current object assigned to the pane, or false. Type module:wcLayout | module:wcPanel | module:wcFrame | wcSplitter | Boolean × Search results Close "},"module-wcTabFrame.html":{"id":"module-wcTabFrame.html","title":"Module: wcTabFrame","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Module: wcTabFrame Source: tabframe.js, line 1 Members var $container The outer container element of the widget. Type: external:jQuery~Object Source: tabframe.js, line 27 Methods <static> function constructor(container, parent) Parameters: Name Type Description container external:jQuery~selector | external:jQuery~Object | external:domNode A container element for this layout. parent module:wcPanel The parent panel object for this widget. Source: tabframe.js, line 22 function addTab(name [, index] [, layout]) -> module:wcLayoutSimple | wcLayoutTable Adds a new tabbed page into the widget. Parameters: Name Type Argument Description name String The name of the new tab page. index Number <optional> If supplied and above -1, will insert the new tab page at the given tab index, otherwise the new tab is appended to the end. layout module:wcDocker.LAYOUT <optional> If supplied, will set the type of layout to use for this tab. Source: tabframe.js, line 102 Returns: - The layout of the newly created tab page. Type module:wcLayoutSimple | wcLayoutTable function closeable(index [, closeable]) -> Boolean Gets, or Sets whether a tab can be closed (removed) by the user. Parameters: Name Type Argument Description index Number The index of the tab page. closeable Boolean <optional> If supplied, assigns whether the tab page can be closed. Source: tabframe.js, line 243 Returns: - Whether the tab page can be closed. Type Boolean function destroy() Destroys the widget. Source: tabframe.js, line 64 function faicon(index, icon) Sets the icon for a tab item using the Font-Awesome library. Parameters: Name Type Description index Number The index of the tab item. icon String A Font-Awesome icon name (without the 'fa fa-' prefix). Source: tabframe.js, line 379 function fitContents(index [, x] [, y]) -> module:wcDocker~FitContents Gets, or Sets whether the tab frame should fit to its contents. Parameters: Name Type Argument Description index Number The index of the tab page. x Boolean <optional> If supplied, assigns whether the tab page is scrollable in the horizontal direction. y Boolean <optional> If supplied, assigns whether the tab page is scrollable in the vertical direction. Version: 3.0.0 Source: tabframe.js, line 318 Returns: - The current scrollable status of the tab page. Type module:wcDocker~FitContents function icon(index, icon) Sets the icon for a tab item. Parameters: Name Type Description index Number The index of the tab item. icon String A CSS class name that represents the icon. Source: tabframe.js, line 360 function layout(index) -> module:wcLayoutSimple | wcLayoutTable | Boolean Retrieves the layout for a given tab page. Parameters: Name Type Description index Number The tab page index to retrieve. Source: tabframe.js, line 192 Returns: - The layout of the found tab page, or false. Type module:wcLayoutSimple | wcLayoutTable | Boolean function moveable( [moveable]) -> Boolean Gets, or Sets whether the tabs can be reordered by the user. Parameters: Name Type Argument Description moveable Boolean <optional> If supplied, assigns whether tab pages can be reordered. Source: tabframe.js, line 230 Returns: - Whether tab pages are currently moveable. Type Boolean function moveTab(fromIndex, toIndex) -> external:jQuery~Object Moves a tab page from a given index to another index. Parameters: Name Type Description fromIndex Number The current tab page index to move from. toIndex Number The new tab page index to move to. Source: tabframe.js, line 205 Returns: - The new element of the moved tab, or false if an error occurred. Type external:jQuery~Object function overflowVisible(index [, visible]) -> Boolean Gets, or Sets whether overflow on a tab area is visible. Use this if a child element within this panel is intended to 'popup' and be visible outside of its parent area. Parameters: Name Type Argument Description index Number The index of the tab page. visible Boolean <optional> If supplied, assigns whether overflow is visible. Source: tabframe.js, line 297 Returns: - The current overflow visiblity status of the tab page. Type Boolean function removeTab(index) -> Boolean Removes a tab page from the widget. Parameters: Name Type Description index Number The tab page index to remove. Source: tabframe.js, line 140 Returns: - Success or failure. Type Boolean function scrollable(index [, x] [, y]) -> module:wcDocker~Scrollable Gets, or Sets whether a tab page area is scrollable. Parameters: Name Type Argument Description index Number The index of the tab page. x Boolean <optional> If supplied, assigns whether the tab page is scrollable in the horizontal direction. y Boolean <optional> If supplied, assigns whether the tab page is scrollable in the vertical direction. Source: tabframe.js, line 263 Returns: - The current scrollable status of the tab page. Type module:wcDocker~Scrollable function tab( [index] [, scrollTo]) -> Number Gets, or Sets the currently visible tab page. Parameters: Name Type Argument Description index Number <optional> If supplied, sets the current tab page index. scrollTo Boolean <optional> If true, will auto scroll the tab bar until the selected tab is visible. Source: tabframe.js, line 167 Returns: - The index of the currently visible tab page. Type Number function tabCount() -> Number Gets the total number of tabs in this frame. Version: 3.0.0 Source: tabframe.js, line 72 Returns: Type Number function tabOrientation( [orientation]) -> module:wcDocker.TAB Gets, or Sets the tab orientation for the frame. This puts the tabbed widgets visually on any side of the tab frame. Parameters: Name Type Argument Description orientation module:wcDocker.TAB <optional> Assigns the orientation of the tab items displayed. Version: 3.0.0 Source: tabframe.js, line 82 Returns: - The current orientation. Type module:wcDocker.TAB function update() Manually update the contents of this tab frame. Source: tabframe.js, line 54 × Search results Close "},"tutorial-1.0-getting-started.html":{"id":"tutorial-1.0-getting-started.html","title":"Tutorial: Getting Started","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Getting Started wcDocker (Web Cabin Docker) is a page layout framework that allows users to organize an array-able list of panel types in almost any configuration. Panels can be docked beside other panels, floating on their own, resized, moved, duplicated, and removed at will by the user. It is a powerful library for use as an IDE or a visual data management interface. wcDocker is developed and maintained by Jeff Houde (lochemage@webcabin.org). DependenciesBegin by including the necessary dependencies. JQuery Library version 1.11.1 http://jquery.com/ JQuery ContextMenu Library https://github.com/swisnl/jQuery-contextMenu Font-Awesome http://fortawesome.github.io/Font-Awesome/ InstallationYou can use bower for easy installation using the Node Package Manager {@lang bash}npm install -g bower bower install wcDockerOnce installed, all of the source files will now be located in the bower_components folder and ready to link into your project. You can also download the source and link them directly. Basic Implementation{@lang xml}<link rel='stylesheet' type='text/css' href='bower_components/jQuery-contextMenu/src/jquery.contextMenu.css'/> <link rel='stylesheet' type='text/css' href='bower_components/font-awesome/css/font-awesome.css'/> <script src='bower_components/jquery/dist/jquery.min.js'></script> <script src='bower_components/jQuery-contextMenu/src/jquery.contextMenu.js'></script> <script src='bower_components/jQuery-contextMenu/src/jquery.ui.position.js'></script>Also include the wcDocker library files as well... {@lang xml}<link rel="stylesheet" type="text/css" href="bower_components/wcDocker/Build/wcDocker.min.css"/> <script src="bower_components/wcDocker/Build/wcDocker.min.js"></script> Once the dependencies have been included, start by creating an instance of the main docker and assign it a DOM container (this should be done after the document has finished loading). Typically this would be the document body element, but there is no restriction if you want to use a smaller area instead. Multiple dockers can be used, however, that feature is not currently supported and may not work properly. $(document).ready(function() { var myDocker = new wcDocker(document.body, { themePath: 'My/themes/folder' }); }); Notice the themePath, if your theme CSS files are not in the default 'Themes' folder, you will need to tell docker about the new path or it will not be able to initialize the default theme. Once the docker instance is made, you will need to register the panel types that will become the contents of your layout. A panel is an individual dockable window, generally designed to serve a single purpose. myDocker.registerPanelType('Some type name', { onCreate: function(myPanel, options) {...}, options: {'some optional object': 'that will be passed to the create function above'} }); Once a panel is registered, any time an instance of it is created, the onCreate handler will be invoked allowing you to initialize the contents of your panel. To do this, you will need to use the layout object found inside the panel. myPanel.layout().addItem(domNode, x, y, width, height); Additionally, you can assign various starting properties of the panel here, such as the desired size, or size constraints... myPanel.initSize(200, 200); myPanel.minSize(100, 100); Once you have registered the panels that you want, if they are not private, the user will be able to create them whenever they wish. However, it is recommended that you initialize docker with a default arrangement of panels, to make it easier for the users to get started. // Put Panel1 into the docking layout, since it is the first panel, // it will always fill the entire area regardless of what docking // position you request. var panel1 = myDocker.addPanel('Panel1', wcDocker.DOCK.LEFT); // Once we added a panel, we can use it as a target for another panel. myDocker.addPanel('Panel2', wcDocker.DOCK.BOTTOM, panel1); // The panel itself may have an initial size, but you may want more // control over that. myDocker.addPanel('Panel3', wcDocker.DOCK.RIGHT, null, {w:200, h:200}); See wcDocker.DOCK for a list of all available docking positions. Continue to the Tips and Tricks tutorial. × Search results Close "},"tutorial-2.0-tips-and-tricks.html":{"id":"tutorial-2.0-tips-and-tricks.html","title":"Tutorial: Tips and Tricks","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Tips and Tricks ThemesAssigning a theme to use with wcDocker is as simple as calling a function. myDocker.theme('shadow');In this case, shadow is the name of a theme shadow.css found in the themes folder. Using the Layout Table Itemthe wcLayoutTable object makes it easy to organize the contents of your wcPanel. But, sometimes you need to make some style changes to the table cells themselves! wcLayoutTable.item() and wcLayoutTable.addItem() both return you a handy tableItem object which contains convenient methods for styling! myPanel.addItem(domNode).css('text-align', 'right').css('border', '1px solid black').stretch('100%', '100%');Here we are using the tableItem.css() and tableItem.stretch() functions, which can be chained! The first provides a way to add normal style attributes to the cell while the second provides a more reliable way to set your table cell sizes. Event SystemThe event system is critical for communication between your panels. Often times you will need this to ensure all your panels integrate properly and intuitively. For example: One panel may be dedicated to showing the properties of an object, while another panel may be responsible for displaying and allowing the user to select an object. If communication did not exist between the two panels, when an object is selected, the property panel would never know to show its properties. First our property panel has to be listening for the event, in this case we have named one 'object selected' (It can be any string). propertyPanel.on('object selected', function(object) { // Registered event handler for the 'object selected' event // Here, we do something to the object that was just selected. if (object) { showProperties(object); } });Once an object is selected in the other panel, it can trigger an event to notify any panels who care otherPanel.trigger('object selected', selectedObject);All events are broadcast to all panels (including itself and docker) who have registered for the named event and will receive it. See wcDocker.on() and wcDocker.trigger() for further details. Storing User ConfigurationsEntire layout configurations can be saved and restored using wcDocker.save() and wcDocker.restore(). var savedLayout = myDocker.save(); // Any time you wish to restore a previously saved layout. myDocker.restore(savedLayout);The saved layout data is a serialized string that can be stored in cookies, or wherever you wish for later use! Additionally, any panel can register events if they need to save and restore any custom attributes. myPanel.on(wcDocker.EVENT.SAVE_LAYOUT, function(data) { // Save a custom attribute into the layout configuration data data.someValue = somePanelValueToSave; }); myPanel.on(wcDocker.EVENT.RESTORE_LAYOUT, function(data) { // When a layout is being restored, you can retrieve those custom values if they exist. somePanelValueToRestore = data.someValue; }); Batch OperationsAdding elements into the wcLayoutTable is not a problem in most cases, except when you need to add them in large quantities. Every time an item is added into the layout it causes the document to re-calculate and render. To improve performance, the layout can be put into a batch mode process, where it will queue all additions and add them all in a single operation. myPanel.layout().startBatch(); for (var i = 0; i < 1000; ++i) { myPanel.layout().addItem($('div'), 0, i); } myPanel.layout().finishBatch(); Custom Panel ButtonsAll panels can contain their own custom buttons which appear in the upper right corner of the frame (where the title bar and close button are). To add a new button, use the wcPanel.addButton() function. myPanel.addButton('Some ID Name', 'normalStateClass', 'B', 'Tooltip text', true, 'toggledStateClass');Also, you can register an event to receive notifications whenever any custom button has been pressed. myPanel.on(wcDocker.EVENT.BUTTON, function(button) { // In case we have multiple custom panel buttons, we can check the name of the activated button if (button.name === 'Some ID Name') { var toggled = button.isToggled; if (toggled) { // The button has been clicked, and its current state is depressed. } else { // The button has been clicked, and its current state is normal. } } }); Popup or Modal PanelsPopup windows are a part of almost any application, and with wcDocker, it is a very simple process. In this case, any panel can become a popup by creating them and setting them to a floating (or detached) state. myDocker.addPanel('popup', wcDocker.DOCK.FLOAT);And if you want to block all other input until the user closes or acknowledges the panel, you can set it to a modal state instead. myDocker.addPanel('popup', wcDocker.DOCK.MODAL);Just be careful that all modal panels can be closed somehow, or else you will permenantly block the application. Go back to the Getting Started tutorial.Continue to the Widgets tutorial. Panel Creation ElementsBy default, wcDocker provides a right-click context menu that allows users to create new panels into their view. However, you may want to implement panel creation a different way. wcDocker provides an easy method for doing so, in the form of a CSS class. Simply create any HTML element, give it the CSS class "wcCreatePanel" and provide it with the panel type as the data attribute "panel", and wcDocker will instantly treat it as a panel creation element. The user can then drag-drop that element directly into their layout to add the new panel. {@lang xml}<span class="wcCreatePanel" data-panel="My Custom Panel Type">Create My Custom Panel Type</span>This element can be styled to looked exactly the way you want, whether it be a simple text element, or a fancy looking button! Additionally, setting the data attribute "nofloating" to true will enforce that the user create this new panel docked within the layout rather than floating. Here is the example used in our demo page for the Creation Panel: myDocker.registerPanelType('Creation Panel', { faicon: 'plus-square', onCreate: function(myPanel) { // Retrieve a list of all panel types, that are not marked as private. var panelTypes = myDocker.panelTypes(false); for (var i = 0; i < panelTypes.length; ++i) { // Retrieve more detailed information about the panel. var info = myDocker.panelTypeInfo(panelTypes[i]); // We want to show the panel icon, if it exists. var $icon = $('<div class="wcMenuIcon" style="margin-right: 15px;">'); if (info.icon) { $icon.addClass(info.icon); } if (info.faicon) { $icon.addClass('fa fa-menu fa-' + info.faicon + ' fa-lg fa-fw'); } // Now create the item using our theme's button style, but add a few styles of our own. var $item = $('<div class="wcCreatePanel wcButton">'); $item.css('padding', 5) .css('margin-top', 5) .css('margin-bottom', 5) .css('border', '2px solid black') .css('border-radius', '10px') .css('text-align', 'center'); // Set our item content and insert the icon. $item.text(panelTypes[i]); $item.data('panel', panelTypes[i]); $item.prepend($icon); myPanel.layout().addItem($item, 0, i+1); } // Add a stretched element that will push everything to the top of the layout. myPanel.layout().addItem($('<div>'), 0, i+1).stretch(undefined, '100%'); } }); Loading ScreensSometimes panel content needs time to load, for this wcDocker comes with a built in loading screen system. The loading screen system comes in two forms, an individual panel loader and a full screen loader. When an individual panel requires some loading time, you can use wcPanel.startLoading() and wcPanel.finishLoading() to display and hide the loading screen for it. myPanel.startLoading(); // Perform some loading stuff... myPanel.finishLoading(500);Similarly, you can use wcDocker.startLoading() and wcDocker.finishLoading() to display a loading screen for the entire view. This is especially useful as an initial loading screen for the entire page. myDocker.startLoading('Loading...'); // Initialize all panels for the view. // Register our loaded event, this will be triggered after all panels have been initialized and all panel loading screens have been finished. myDocker.on(wcDocker.EVENT.LOADED, function() { myDocker.finishLoading(500); });Note that while the full screen loading screen is active, all individual panel loading screens will be invisible, so it is perfectly ok to use them together! Also note that the wcDocker.EVENT.LOADED event will only be triggered after all panels have finished their individual loading screens (if they are using it). × Search results Close "},"tutorial-3.0-widgets.html":{"id":"tutorial-3.0-widgets.html","title":"Tutorial: Widgets","body":" Web Cabin Dockerv3.0.0 (pre-release) Modules wcBasewcCollapserwcDockerwcDrawerwcFramewcGhostwcIFramewcLayoutwcLayoutSimplewcLayoutTablewcPanelwcSplitterwcTabFrame Events wcDocker#event:onEvent Tutorials Getting StartedTips and TricksWidgets Externals domNodejQuery Widgets Splitter WidgetThe splitter widget separates two elements by a moveable bar, either vertically or horizontally. It is the same one used by docker to organize the layout of all docked panels. To use it, you will need an element that will contain it. This element should be added to your layout and will mark the size and location of the splitter area.Note: Some limitations exist with iFrames. Even if the container element is partially hidden beyond the bounds of the panel layout, the iFrame itself will not be occluded.Troubleshooting: If the widget does not appear correctly, double check and make sure your container element has been positioned and sized properly according to your browser. var $container = $('<div style="position:absolute;top:0px;left:0px;right:0px;bottom:0px;"></div>'); myPanel.layout().addItem($container); var splitter = new wcSplitter($container, myPanel, wcDocker.ORIENTATION.HORIZONTAL); splitter.initLayouts();Once you have created your splitter widget, you'll want to fill each side with content. // Horizontal splitters have a pane on the left and right. var leftLayout = splitter.left(); var rightLayout = splitter.right(); // Vertical splitters have a pane on the top and bottom. var topLayout = splitter.top(); var rightLayout = splitter.bottom();Once you have the layout of the pane you want, you can add items to it like you would any panel. leftLayout.addItem(domNode);The orientation of a splitter can also be changed at any time by using the wcSplitter.orientation() function. Tab WidgetThe tab frame widget allows you to separate multiple 'pages' of content into tabbed items, much like how panels become stacked. To use it, you will need an element that will contain it. This element should be added to your layout and will mark the size and location of the tabbed area.Troubleshooting: If the widget does not appear correctly, double check and make sure your container element has been positioned and sized properly according to your browser. var $container = $('<div style="width:100%;height:100%;"></div>'); myPanel.layout().addItem($container); var tabFrame = new wcTabFrame($container, myPanel);Of course, you'll want to add tabs to your tabbed frame and fill them with content... var tabLayout = tabFrame.addTab('First Tab'); tabLayout.addItem(domNode); iFrame WidgetThe iFrame widget makes it easier to include an iFrame element into your panel. Because an iFrame's contents is cleared whenever it is moved in the DOM heirarchy (and changing a panels docking position causes DOM movement), special care must be taken when using them. To use it, you will need an element that will contain it. This element should be added to your layout and will mark the size and location of the iFrame area.Note: Some limitations exist with iFrames. Even if the container element is partially hidden beyond the bounds of the panel layout, the iFrame itself will not be occluded.Troubleshooting: If the widget does not appear correctly, double check and make sure your container element has been positioned and sized properly according to your browser. var $container = $('<div style="position:absolute;top:0px;left:0px;right:0px;bottom:0px;"></div>'); myPanel.layout().addItem($container); var iFrame = new wcIFrame($container, myPanel);And fill its contents... iFrame.openURL('http://www.example.com'); // Or... iFrame.openHTML('<span>Hello World!</span>');Or for some even more control, you can access the window object within the frame directly. var frameWindow = iFrame.window();Go back to the Tips and Tricks tutorial. × Search results Close "}}
</script>
<script type="text/javascript">
$(document).ready(function() {
Searcher.init();
});
$(window).on("message", function(msg) {
var msgData = msg.originalEvent.data;
if (msgData.msgid != "docstrap.quicksearch.start") {
return;
}
var results = Searcher.search(msgData.searchTerms);
window.parent.postMessage({"results": results, "msgid": "docstrap.quicksearch.done"}, "*");
});
</script>
</body>
</html>