@deephaven/golden-layout
Version:
A multi-screen javascript Layout manager
209 lines (195 loc) • 7.63 kB
JavaScript
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import $ from 'jquery';
import { isGLComponentConfig } from "../config/index.js";
import EventEmitter from "../utils/EventEmitter.js";
export default class ItemContainer extends EventEmitter {
constructor(config, parent, layoutManager) {
super();
_defineProperty(this, "width", void 0);
_defineProperty(this, "height", void 0);
_defineProperty(this, "title", void 0);
_defineProperty(this, "parent", void 0);
_defineProperty(this, "layoutManager", void 0);
_defineProperty(this, "tab", void 0);
// This type is to make TS happy and allow ReactComponentConfig passed to container generic
_defineProperty(this, "_config", void 0);
_defineProperty(this, "isHidden", false);
_defineProperty(this, "beforeCloseHandler", void 0);
_defineProperty(this, "_element", $(['<div class="lm_item_container">', '<div class="lm_content" tabindex="-1"></div>', '</div>'].join('')));
_defineProperty(this, "_contentElement", void 0);
this.title = isGLComponentConfig(config) ? config.componentName : '';
this.parent = parent;
this.layoutManager = layoutManager;
this._config = config;
this._contentElement = this._element.find('.lm_content');
this.beforeCloseHandler = null;
}
/**
* Get the inner DOM element the container's content
* is intended to live in
*/
getElement() {
return this._contentElement;
}
/**
* Hide the container. Notifies the containers content first
* and then hides the DOM node. If the container is already hidden
* this should have no effect
*/
hide() {
this.emit('hide');
this.isHidden = true;
this._element.hide();
}
/**
* Shows a previously hidden container. Notifies the
* containers content first and then shows the DOM element.
* If the container is already visible this has no effect.
*/
show() {
this.emit('show');
this.isHidden = false;
this._element.show();
// call shown only if the container has a valid size
if (this.height != 0 || this.width != 0) {
this.emit('shown');
}
}
/**
* Set the size from within the container. Traverses up
* the item tree until it finds a row or column element
* and resizes its items accordingly.
*
* If this container isn't a descendant of a row or column
* it returns false
* @todo Rework!!!
* @param width The new width in pixel
* @param height The new height in pixel
*
* @returns resizeSuccesful
*/
setSize(width, height) {
var _this$direction, _rowOrColumnChild$con, _rowOrColumnChild$con2;
var rowOrColumn = this.parent;
var rowOrColumnChild = null;
while (rowOrColumn && !rowOrColumn.isColumn && !rowOrColumn.isRow) {
var _rowOrColumn;
rowOrColumnChild = rowOrColumn;
rowOrColumn = rowOrColumn.parent;
/**
* No row or column has been found
*/
if ((_rowOrColumn = rowOrColumn) !== null && _rowOrColumn !== void 0 && _rowOrColumn.isRoot) {
return false;
}
}
if (!rowOrColumn || !rowOrColumnChild) {
return false;
}
var direction = rowOrColumn.isColumn ? 'height' : 'width';
var newSize = direction === 'height' ? height : width;
var totalPixel = ((_this$direction = this[direction]) !== null && _this$direction !== void 0 ? _this$direction : 0) * (1 / (((_rowOrColumnChild$con = rowOrColumnChild.config[direction]) !== null && _rowOrColumnChild$con !== void 0 ? _rowOrColumnChild$con : 0) / 100));
var percentage = newSize / totalPixel * 100;
var delta = (((_rowOrColumnChild$con2 = rowOrColumnChild.config[direction]) !== null && _rowOrColumnChild$con2 !== void 0 ? _rowOrColumnChild$con2 : 0) - percentage) / (rowOrColumn.contentItems.length - 1);
for (var i = 0; i < rowOrColumn.contentItems.length; i++) {
if (rowOrColumn.contentItems[i] === rowOrColumnChild) {
rowOrColumn.contentItems[i].config[direction] = percentage;
} else {
var _rowOrColumn$contentI;
rowOrColumn.contentItems[i].config[direction] = ((_rowOrColumn$contentI = rowOrColumn.contentItems[i].config[direction]) !== null && _rowOrColumn$contentI !== void 0 ? _rowOrColumn$contentI : 0) + delta;
}
}
rowOrColumn.callDownwards('setSize');
return true;
}
/**
* Closes the container if it is closable. Can be called by
* both the component within at as well as the contentItem containing
* it. Emits a close event before the container itself is closed.
* @param options Options to pass into the beforeClose handler
*/
close(options) {
var _this$beforeCloseHand, _this$beforeCloseHand2;
// Not closable, don't do anything
if (!this._config.isClosable) return;
// If beforeCloseHandler returns true or if the handler doesn't exist, close
if ((_this$beforeCloseHand = (_this$beforeCloseHand2 = this.beforeCloseHandler) === null || _this$beforeCloseHand2 === void 0 ? void 0 : _this$beforeCloseHand2.call(this, options)) !== null && _this$beforeCloseHand !== void 0 ? _this$beforeCloseHand : true) {
this.emit('close');
this.parent.close();
}
}
/**
* Sets the beforeCloseHandler to callback
* @param callback Callback function to call before closing
*/
beforeClose(callback) {
this.beforeCloseHandler = callback;
}
/**
* Returns the current state object
*
* @returns state
*/
getState() {
return this._config.componentState;
}
/**
* Returns the object's config
*
* @returns id
*/
getConfig() {
return this._config;
}
/**
* Notifies the layout manager of a stateupdate
*
* @param state
*/
setState(state) {
this._config.componentState = state;
this.parent.emitBubblingEvent('stateChanged');
}
/**
* Sets persisted state for functional components
* which do not have lifecycle methods to hook into.
*
* @param state The state to persist
*/
setPersistedState(state) {
this._config.persistedState = state;
this.parent.emitBubblingEvent('stateChanged');
}
/**
* Set's the components title
*
* @param title
*/
setTitle(title) {
this.parent.setTitle(title);
}
/**
* Set's the containers size. Called by the container's component.
* To set the size programmatically from within the container please
* use the public setSize method
*
* @param width in px
* @param height in px
*/
_$setSize() {
var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var height = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (width !== this.width || height !== this.height) {
this.width = width;
this.height = height;
var cl = this._contentElement[0];
var hdelta = cl.offsetWidth - cl.clientWidth;
var vdelta = cl.offsetHeight - cl.clientHeight;
this._contentElement.width(this.width - hdelta).height(this.height - vdelta);
this.emit('resize');
}
}
}
//# sourceMappingURL=ItemContainer.js.map