123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
"use strict";
modulum('HBoxSplitViewWidget', ['HBoxWidget', 'WidgetFactory'],
function(context, cls) {
cls.HBoxSplitViewWidget = context.oo.Class(cls.HBoxWidget, function($super) {
return {
__name: "HBoxSplitViewWidget",
_currentDisplayedGroupIndex: 0,
_currentGroupWidget: null,
_displayGroupActiveHandlers: null,
_swipeHandler: null,
_screenSizeHandler: null,
_resizeHandle: null,
_uiWidget: null,
_isSplitView: false,
_isSwiping: false,
_previewedIndex: -1,
_isScrolling: false,
_currentGroupOverflowing: false,
_splitViewContent: null,
_leftArrow: null,
_rightArrow: null,
_dots: null,
_arrowsStyle: "no",
_withDots: false,
_focusRestoredHandler: null,
constructor: function(opts) {
opts = opts || {};
this._uiWidget = opts.uiWidget;
$super.constructor.call(this, opts);
},
_initContainerElement: function() {
$super._initContainerElement.call(this);
this._displayGroupActiveHandlers = new Map();
this._splitViewContent = this.getElement().getElementsByClassName("splitViewContent")[0];
this._leftArrow = this.getElement().getElementsByClassName("left_arrow")[0];
this._rightArrow = this.getElement().getElementsByClassName("right_arrow")[0];
this._dots = this.getElement().getElementsByClassName("dots")[0];
this._screenSizeHandler = context.HostService.onScreenResize(function() {
if (this._resizeHandle) {
this._clearTimeout(this._resizeHandle);
}
this._resizeHandle = this._registerTimeout(this._initSplitView.bind(this), 100);
}.bind(this));
this._leftArrow.on("click.SplitViewLeftArrow", function() {
var newIndex = this._currentDisplayedGroupIndex - 1;
if (newIndex >= 0) {
this._displayGroupByIndex(newIndex);
}
}.bind(this));
this._rightArrow.on("click.SplitViewRightArrow", function() {
var newIndex = this._currentDisplayedGroupIndex + 1;
if (newIndex < this.getGroupsLength()) {
this._displayGroupByIndex(newIndex);
}
}.bind(this));
},
destroy: function() {
if (this._resizeHandle) {
this._clearTimeout(this._resizeHandle);
this._resizeHandle = null;
}
if (this._screenSizeHandler) {
this._screenSizeHandler();
this._screenSizeHandler = null;
}
if (this._focusRestoredHandler) {
this._focusRestoredHandler();
this._focusRestoredHandler = null;
}
this._uiWidget = null;
this._releaseSplitViewHandlers();
for (var i = 0; i < this._dots.children.length; i++) {
this._dots.children[i].off("click.SplitViewDot");
}
this._leftArrow.off("click.SplitViewLeftArrow");
this._rightArrow.off("click.SplitViewRightArrow");
this._leftArrow = null;
this._rightArrow = null;
this._dots = null;
this._currentDisplayedGroupIndex = 0;
this._currentGroupWidget = null;
this._splitViewContent = null;
this._displayGroupActiveHandlers = null;
$super.destroy.call(this);
},
_initLayout: function() {
this._layoutInformation = new cls.LayoutInformation(this);
if (this.isSplitView()) {
this._layoutEngine = new cls.SplitViewLayoutEngine(this);
this._layoutInformation.getStretched().setDefaultX(true);
this._layoutInformation.getStretched().setDefaultY(true);
if (this.areArrowsSolid()) {
this.enableSolidArrows();
}
} else {
this._layoutEngine = new cls.HBoxLayoutEngine(this);
}
this._initSplitView();
},
addChildWidget: function(widget, options) {
$super.addChildWidget.call(this, widget, options);
if (this.isSplitView()) {
this._prepareGroup(widget, true);
this._listenToGroupVisibilityChange(widget);
}
},
isSplitView: function() {
return window.innerWidth <= context.ThemeService.getValue("mt-responsive-screen-width-breakpoint");
},
_initSplitView: function() {
this._resizeHandle = null;
if (this.isSplitView()) {
this._enableSplitView();
this._isSplitView = true;
} else {
this._disableSplitView();
this._isSplitView = false;
}
},
_enableSplitView: function() {
if (!this._isSplitView) {
this._displayGroupActiveHandlers.clear();
var oldEngine = this._layoutEngine;
this._layoutEngine = new cls.SplitViewLayoutEngine(this);
this._layoutInformation.getStretched().setDefaultX(true);
this._layoutInformation.getStretched().setDefaultY(true);
if (this.areArrowsSolid()) {
this.enableSolidArrows();
}
for (var i = 0; i < this.getChildren().length; i++) {
var child = this.getChildren()[i];
this._prepareGroup(child);
if (!child.isHidden()) {
oldEngine.unregisterChild(child);
this._layoutEngine.registerChild(child);
}
this._listenToGroupVisibilityChange(child);
}
context.SessionService.getCurrent().getCurrentApplication().layout.refreshLayout();
if (this._uiWidget) {
this._displayGroupActiveHandlers.set(this._uiWidget.getUniqueIdentifier() + "_focus", this._uiWidget.when(context
.constants
.widgetEvents.splitViewChange,
this._displayFocusedGroup.bind(this)));
}
this._swipeHandler = this._displayGroupByDirection.bind(this);
this._splitViewContent.onSwipe("HBoxSplitViewWidget", this._swipeHandler, {
direction: ["left", "right"],
velocity: 0.6,
distance: 0.45,
startCallback: this._beforeSwipe.bind(this),
moveCallback: this._duringSwipe.bind(this),
endCallback: this._afterSwipe.bind(this),
});
this._moveGroup(this._currentDisplayedGroupIndex);
this.getElement().addClass("isSplitView");
this._showArrowsDots();
if (!this._focusRestoredHandler) {
this._focusRestoredHandler = context.SessionService.getCurrent().getCurrentApplication().focus.when(context.constants
.widgetEvents.focusRestored,
function() {
this._focusRestoredHandler = null;
this._layoutEngine.refreshLayout();
}.bind(this), true);
}
}
},
_disableSplitView: function() {
if (this._isSplitView) {
this._hideArrowsDots();
if (this._focusRestoredHandler) {
this._focusRestoredHandler();
this._focusRestoredHandler = null;
}
this.getElement().removeClass("isSplitView");
this._removeSplitViewStyles();
var oldEngine = this._layoutEngine;
this._layoutEngine = new cls.HBoxLayoutEngine(this);
this._layoutInformation.getStretched().setDefaultX(false);
this._layoutInformation.getStretched().setDefaultY(false);
this.disableSolidArrows();
for (var i = this.getChildren().length - 1; i >= 0; i--) {
var child = this.getChildren()[i];
if (child instanceof cls.SplitterWidget) {
child.setHidden(false);
}
oldEngine.unregisterChild(child);
this._layoutEngine.registerChild(child);
if (child.getElement().parentNode.hasClass("hidden")) {
child.getElement().parentNode.removeClass("hidden");
}
}
this.initSplitterLayoutEngine();
context.SessionService.getCurrent().getCurrentApplication().layout.refreshLayout();
this._releaseSplitViewHandlers();
}
},
_releaseSplitViewHandlers: function() {
if (this._swipeHandler) {
this._splitViewContent.offSwipe("HBoxSplitViewWidget");
this._swipeHandler = null;
}
if (this._displayGroupActiveHandlers) {
this._displayGroupActiveHandlers.forEach(function(handler) {
handler();
handler = null;
});
this._displayGroupActiveHandlers.clear();
}
},
_removeSplitViewStyles: function() {
this.getContainerElement().style.removeProperty("transform");
this.getContainerElement().style.removeProperty("transition-duration");
},
_prepareGroup: function(widget, firstCreation) {
if (widget instanceof cls.SplitterWidget) {
widget.setHidden(true);
} else if (!widget.isHidden()) {
this._displayGroupActiveHandlers.set(widget.getUniqueIdentifier() + "_focus", widget.when(context.constants.widgetEvents
.splitViewChange, this
._displayFocusedGroup
.bind(this)));
if (firstCreation) {
this._addDot();
}
}
if (widget.isHidden()) {
if (widget.getElement().parentNode) {
widget.getElement().parentNode.addClass("hidden");
}
}
},
_listenToGroupVisibilityChange: function(widget) {
if (!(widget instanceof cls.SplitterWidget)) {
this._displayGroupActiveHandlers.set(widget.getUniqueIdentifier() + "_visibility", widget.when(context.constants
.widgetEvents.visibilityChange, this._addRemoveGroup.bind(this, widget)));
}
},
_addRemoveGroup: function(widget) {
if (widget.isHidden()) {
this._removeGroup(widget);
} else {
this._addGroup(widget);
}
},
_addGroup: function(widget) {
this._prepareGroup(widget);
this._layoutEngine.registerChild(widget);
widget.getElement().parentNode.removeClass("hidden");
},
_removeGroup: function(widget) {
if (this._currentDisplayedGroupIndex === this.getGroupsLength() - 1 && this._currentDisplayedGroupIndex > 0) {
this._displayGroupByIndex(this._currentDisplayedGroupIndex - 1);
}
var handler = this._displayGroupActiveHandlers.get(widget.getUniqueIdentifier() + "_focus");
if (handler) {
handler();
}
this._displayGroupActiveHandlers.delete(widget.getUniqueIdentifier() + "_focus");
this._layoutEngine.unregisterChild(widget);
widget.getElement().parentNode.addClass("hidden");
},
_displayFocusedGroup: function(data, caller, focusedWidget) {
var newGroupIndex = this._currentDisplayedGroupIndex;
var newVmFocusWidget = focusedWidget ? focusedWidget : this.getUserInterfaceWidget().getVMFocusedWidget();
if (newVmFocusWidget) {
var i = 0;
var child = null;
for (i = 0; i < this.getLayoutEngine().getRegisteredWidgets().length; i++) {
child = this.getLayoutEngine().getRegisteredWidgets()[i];
if (newVmFocusWidget === child || newVmFocusWidget.isChildOf(child)) {
newGroupIndex = i;
break;
}
}
}
this._displayGroupByIndex(newGroupIndex);
},
_displayGroupByIndex: function(groupIndex) {
if (this._currentDisplayedGroupIndex !== groupIndex) {
this._currentDisplayedGroupIndex = groupIndex;
this._currentGroupWidget = this.getLayoutEngine().getRegisteredWidgets()[groupIndex];
this._moveGroup(groupIndex, 0.5);
}
},
_beforeSwipe: function(evt) {
this.getContainerElement().addClass('disableAnimation');
this._previewedIndex = -1;
this._splitViewWidth = this.getLayoutInformation().getAllocated().getWidth();
this._currentGroupOverflowing = false;
if (evt.touches) {
var clickedElement = evt.target;
if (clickedElement && clickedElement.parentNode && !clickedElement.parentNode.hasClass("isSplitView")) {
this._currentGroupOverflowing = this._currentGroupWidget && this._currentGroupWidget.getLayoutInformation()
.getAllocated()
.getWidth() > (this._splitViewWidth +
2);
}
}
},
_duringSwipe: function(evt, startX) {
if (evt) {
var clientX = evt.changedTouches ? evt.changedTouches[0].clientX : evt.clientX;
var distance = Math.round(clientX - startX);
var directionSign = Math.sign(distance);
this._isScrolling = false;
if (this
._currentGroupOverflowing) {
var rect = this._currentGroupWidget.getElement().getBoundingClientRect();
if ((directionSign < 0 && rect.right > window.innerWidth) || (directionSign >= 0 && rect.left <
0)) {
this._isScrolling = true;
}
}
this._previewedIndex = this._currentDisplayedGroupIndex - directionSign;
this._isSwiping = !this._isScrolling && this._previewedIndex >= 0 && this._previewedIndex < this.getGroupsLength();
if (this._isSwiping) {
evt.stopPropagation();
this._previewGroup(this._currentDisplayedGroupIndex, distance);
}
}
},
getGroupsLength: function() {
return this.getLayoutEngine().getRegisteredWidgets().length;
},
_displayGroupByDirection: function(direction) {
if (this._isSwiping && this._previewedIndex >= 0 && (direction === "left" || direction === "right")) {
this._currentDisplayedGroupIndex = this._previewedIndex;
this._currentGroupWidget = this.getLayoutEngine().getRegisteredWidgets()[this._previewedIndex];
}
},
_afterSwipe: function(evt, swipedVelocity, swipedFraction) {
this._isSwiping = false;
if (this._previewedIndex !== -1) {
this._previewedIndex = -1;
var duration = (swipedVelocity > 0 ? swipedFraction : "1") * 0.5;
this._moveGroup(this._currentDisplayedGroupIndex, duration);
}
this.getContainerElement().removeClass('disableAnimation');
},
_moveGroup: function(index, duration) {
var current = index * -100;
this._updateCurrentDot();
if (this.areArrowsVisible()) {
this._showArrows();
}
if (duration) {
this.getContainerElement().style.transitionDuration = duration + "s";
} else {
this.getContainerElement().style.removeProperty("transition-duration");
}
this.getContainerElement().style.transform = "translate(" + current + "%)";
},
_previewGroup: function(index, previewDistance) {
var preview = -(index * this._splitViewWidth) + previewDistance;
this.getContainerElement().style.transform = "translate(" + preview + "px)";
},
_addDot: function() {
var div = document.createElement("div");
div.addClass("dot");
div.on("click.SplitViewDot", this._displayGroupByIndex.bind(this, this._dots.children.length));
this._dots.appendChild(div);
},
_updateCurrentDot: function() {
for (var i = 0; i < this._dots.children.length; i++) {
var dot = this._dots.children[i];
if (i === this._currentDisplayedGroupIndex) {
if (!dot.hasClass("current")) {
dot.addClass("current");
}
} else {
dot.removeClass("current");
}
}
},
areArrowsVisible: function() {
return this.isSplitView() && (this.areArrowsOverlay() || this.areArrowsSolid());
},
areArrowsOverlay: function() {
return this._arrowsStyle === "overlay";
},
areArrowsSolid: function() {
return this._arrowsStyle === "solid";
},
enableSolidArrows: function() {
this._layoutInformation.setDecorating(60, 0);
this._layoutInformation.setDecoratingOffset(30, 0);
if (!this._leftArrow.hasClass("solid")) {
this._leftArrow.addClass("solid");
}
if (!this._rightArrow.hasClass("solid")) {
this._rightArrow.addClass("solid");
}
},
disableSolidArrows: function() {
this._layoutInformation.setDecorating(0, 0);
this._layoutInformation.setDecoratingOffset(0, 0);
this._leftArrow.removeClass("solid");
this._rightArrow.removeClass("solid");
},
areDotsVisible: function() {
return this.isSplitView() && this._withDots;
},
_showArrowsDots: function() {
if (this.areArrowsVisible()) {
this._showArrows();
}
if (this.areDotsVisible()) {
this._showDots();
}
},
_hideArrowsDots: function() {
this._hideArrows();
this._hideDots();
},
_showArrows: function() {
if (this._currentDisplayedGroupIndex > 0) {
this._leftArrow.removeClass("disabled");
} else {
if (!this._leftArrow.hasClass("disabled")) {
this._leftArrow.addClass("disabled");
}
}
if (this._currentDisplayedGroupIndex < this.getGroupsLength() - 1) {
this._rightArrow.removeClass("disabled");
} else {
if (!this._rightArrow.hasClass("disabled")) {
this._rightArrow.addClass("disabled");
}
}
},
_showDots: function() {
this._dots.removeClass("disabled");
this._updateCurrentDot();
},
_hideArrows: function() {
if (!this._leftArrow.hasClass("disabled")) {
this._leftArrow.addClass("disabled");
}
if (!this._rightArrow.hasClass("disabled")) {
this._rightArrow.addClass("disabled");
}
},
_hideDots: function() {
if (!this._dots.hasClass("disabled")) {
this._dots.addClass("disabled");
}
},
setArrowsStyle: function(style) {
this._arrowsStyle = style;
if (this.areArrowsVisible()) {
this._showArrows();
} else {
this._hideArrows();
}
if (this.areArrowsSolid()) {
this.enableSolidArrows();
} else {
this.disableSolidArrows();
}
},
setWithDots: function(style) {
this._withDots = style === 'yes';
if (this.areDotsVisible()) {
this._showDots();
} else {
this._hideDots();
}
}
};
});
cls.WidgetFactory.registerBuilder("HBoxSplitView", cls.HBoxSplitViewWidget);
});