UNPKG

webgme

Version:

Web-based Generic Modeling Environment

401 lines (325 loc) 13.7 kB
/*globals define, $*/ /*jshint browser: true*/ /** * @author rkereskenyi / https://github.com/rkereskenyi */ define([ 'js/Toolbar/ToolbarButton', 'js/Toolbar/ToolbarDropDownButton' ], function (ToolbarButton, ToolbarDropDownButton) { 'use strict'; var DiagramDesignerWidgetTabs, TABS_CONTAINER = 'diagram-designer-tabs-container', ADD_TAB_CONTAINER_CLASS = 'add-tab-container', TAB_LIST_CONTAINER_CLASS = 'tab-list-container', TAB_SCROLL = 200, TAB_ID = 'TAB_ID', TAB_RENAME = 'TAB_RENAME', WITH_TABS_CLASS = 'w-tabs', SELECTED_ICON = 'icon-ok', DDL_SELECTED_TAB_ICON_BASE = $('<i class="' + SELECTED_ICON + ' glyphicon glyphicon-ok" />'), TAB_LI_BASE = $('<li class=""><a href="#" data-toggle="tab"><div class="tab-title"></div></a></li>'), TAB_DELETE_ICON_BASE = $('<i class="glyphicon glyphicon-remove-circle delete-tab-btn hidden"/>'); DiagramDesignerWidgetTabs = function () { }; DiagramDesignerWidgetTabs.prototype._initializeTabs = function () { var self = this; this.$tabsContainer = $('<div/>', {class: TABS_CONTAINER + ' no-print'}); this.$el.parent().append(this.$tabsContainer); this.$el.parent().addClass(WITH_TABS_CLASS); this._tabCounter = 0; this._selectedTab = undefined; this.$divAddTab = $('<div/>', {class: ADD_TAB_CONTAINER_CLASS}); if (this._addTabs === true) { this.$btnAddTab = new ToolbarButton({ title: 'Add new tab...', icon: 'glyphicon glyphicon-plus', clickFn: function (/*data*/) { if (self.getIsReadOnlyMode() !== true) { self.onTabAddClicked(); } } }); this.$divAddTab.append(this.$btnAddTab.el); } this.$ddlTabsList = new ToolbarDropDownButton({ title: 'Tab list', icon: 'glyphicon glyphicon-list' }); this.$divAddTab.append(this.$ddlTabsList.el); this.$btnScrollLeft = new ToolbarButton({ title: 'Scroll left', icon: 'glyphicon glyphicon-chevron-left', clickFn: function (/*data*/) { self._tabsScrollLeft(); } }); this.$divAddTab.append(this.$btnScrollLeft.el); this.$btnScrollRight = new ToolbarButton({ title: 'Scroll right', icon: 'glyphicon glyphicon-chevron-right', clickFn: function (/*data*/) { self._tabsScrollRight(); } }); this.$divAddTab.append(this.$btnScrollRight.el); this.$divTabList = $('<div/>', {class: TAB_LIST_CONTAINER_CLASS}); this.$ulTabTab = $('<ul/>', {class: 'nav nav-tabs'}); this.$divTabList.append(this.$ulTabTab); this._makeTabsSortable(); this.$tabsContainer.append(this.$divAddTab); this.$tabsContainer.append(this.$divTabList); this._tabScrollValue = 0; //hook up tab rename // set title editable on double-click this.$ulTabTab.on('dblclick.editOnDblClick', '.tab-title', function (event) { if (self.getIsReadOnlyMode() !== true) { var li = $(this).parentsUntil('li').parent(); if (li.data(TAB_RENAME) === true) { $(this).editInPlace({ class: '', onChange: function (oldValue, newValue) { var li = $(this).parent().parent(); self.onTabTitleChanged(li.data(TAB_ID), oldValue, newValue); } }); } } event.stopPropagation(); event.preventDefault(); }); //tab delete handler this.$ulTabTab.on('click.deleteTabClick', 'a > i', function (event) { var tabEl = $(this).parent().parent(); if (self.getIsReadOnlyMode() !== true && tabEl.hasClass('active')) { self.onTabDeleteClicked(tabEl.data(TAB_ID)); } event.stopPropagation(); event.preventDefault(); }); //tab selection handler this.$ulTabTab.on('click.selectTabClick', 'li', function (event) { self.selectTab($(this).data(TAB_ID)); event.stopPropagation(); event.preventDefault(); }); }; DiagramDesignerWidgetTabs.prototype._addTabsButtonEnabled = function (enabled) { if (this.$btnAddTab) { this.$btnAddTab.enabled(enabled); } }; DiagramDesignerWidgetTabs.prototype.clearTabs = function () { this._destroyTabsSortable(); this.$ulTabTab.empty(); this._makeTabsSortable(); this.$ddlTabsList.clear(); this._tabCounter = 0; this._selectedTab = undefined; this._scrollTabListBy(0 - this._tabScrollValue); }; DiagramDesignerWidgetTabs.prototype._makeTabsSortable = function () { var self = this; if (this.getIsReadOnlyMode() !== true) { if (this._reorderTabs === true) { if (!this.$ulTabTab.hasClass('ui-sortable')) { this.$ulTabTab.sortable({ dropBehaviour: true, stop: function () { self._onTabsSortStop(); } }); } } } }; DiagramDesignerWidgetTabs.prototype._destroyTabsSortable = function () { if (this.$ulTabTab && this.$ulTabTab.hasClass('ui-sortable')) { this.$ulTabTab.sortable('destroy'); } }; DiagramDesignerWidgetTabs.prototype._addTabDeleteBtn = function (li) { var deleteBtn = TAB_DELETE_ICON_BASE.clone(); deleteBtn.attr('title', 'Delete tab'); li.find('a').append(deleteBtn); }; DiagramDesignerWidgetTabs.prototype.addTab = function (titleOrDesc, deletable, renamable) { var self = this, li = TAB_LI_BASE.clone(); let title = ''; let backgroundText = ''; if (typeof titleOrDesc === 'string') { title = titleOrDesc; } else { title = titleOrDesc.title; backgroundText = titleOrDesc.backgroundText; } li.find('.tab-title').attr('title', title).text(title); if (backgroundText) { li.find('.tab-title').data('backgroundText', backgroundText); } li.data(TAB_ID, this._tabCounter + ''); this._tabCounter += 1; if (this._deleteTabs === true && deletable === true) { this._addTabDeleteBtn(li); } //store renamable info in LI li.data(TAB_RENAME, renamable); this.$ulTabTab.append(li); this.$ddlTabsList.addButton({ title: title, text: title, data: {TAB_ID: li.data(TAB_ID)}, clickFn: function (data) { self.selectTab(data.TAB_ID); } }); if (this._addingMultipleTabs !== true) { this._refreshTabScrollButtons(); } return li.data(TAB_ID); }; DiagramDesignerWidgetTabs.prototype.addMultipleTabsBegin = function () { this._addingMultipleTabs = true; this.$ulTabTab.hide(); }; DiagramDesignerWidgetTabs.prototype.addMultipleTabsEnd = function () { this.$ulTabTab.show(); this._refreshTabScrollButtons(); this._addingMultipleTabs = false; }; DiagramDesignerWidgetTabs.prototype._tabsScrollLeft = function () { if (this._tabScrollValue < 0) { this._scrollTabListBy(Math.min(Math.abs(this._tabScrollValue), TAB_SCROLL)); } }; DiagramDesignerWidgetTabs.prototype._tabsScrollRight = function () { var overflowRightBy = this.$ulTabTab.width() - this.$tabsContainer.width() + this.$divAddTab.outerWidth(true) + this._tabScrollValue; if (overflowRightBy > 0) { overflowRightBy = Math.min(overflowRightBy, TAB_SCROLL); this._scrollTabListBy(-overflowRightBy); } }; DiagramDesignerWidgetTabs.prototype._scrollTabListBy = function (value) { this._tabScrollValue += value; this.$ulTabTab.css('left', this._tabScrollValue); this._refreshTabScrollButtons(); }; DiagramDesignerWidgetTabs.prototype.selectTab = function (tabID) { var liToSelect, allLi = this.$ulTabTab.find('li'), allDropDownLi = this.$ddlTabsList.el.find('li'), prevActiveTab, i, li; if (this._selectedTab !== tabID) { //select tab for (i = 0; i < allLi.length; i += 1) { li = $(allLi[i]); if (li && li.data(TAB_ID) === tabID) { liToSelect = li; break; } } if (liToSelect) { prevActiveTab = this.$ulTabTab.find('li.active'); prevActiveTab.removeClass('active'); prevActiveTab.find('.delete-tab-btn').addClass('hidden'); liToSelect.addClass('active'); liToSelect.find('.delete-tab-btn').removeClass('hidden'); this._selectedTab = liToSelect.data(TAB_ID); const activeTabTitleEl = this.$ulTabTab.find('li.active').first().find('.tab-title'); const backgroundText = activeTabTitleEl.data('backgroundText') || activeTabTitleEl.text(); this.setBackgroundText(backgroundText.toUpperCase()); } //select in DropDown liToSelect = undefined; for (i = 0; i < allDropDownLi.length; i += 1) { li = $(allDropDownLi[i]).find('a').first(); if (li && li.data(TAB_ID) === tabID) { liToSelect = $(allDropDownLi[i]); break; } } if (liToSelect) { this.$ddlTabsList.el.find('i.' + SELECTED_ICON).remove(); liToSelect.find('a').prepend(DDL_SELECTED_TAB_ICON_BASE.clone()); } this._scrollSelectedTabIntoView(); //fire event... this.onSelectedTabChanged(this._selectedTab); } }; DiagramDesignerWidgetTabs.prototype._scrollSelectedTabIntoView = function () { //scroll selected tab's tab into view var li = this.$ulTabTab.find('li.active').first(); var liPos = li.position(); var visibleWidth = this.$tabsContainer.width() - this.$divAddTab.outerWidth(true); var visibleMin = -this._tabScrollValue; var visibleMax = -this._tabScrollValue + visibleWidth; if (liPos) { if (liPos.left < visibleMin) { this._scrollTabListBy(visibleMin - liPos.left); } else if (liPos.left + li.width() > visibleMax) { this._scrollTabListBy(visibleMax - (liPos.left + li.width())); } } }; DiagramDesignerWidgetTabs.prototype._refreshTabScrollButtons = function () { var overflowRightBy = this.$ulTabTab.width() - this.$tabsContainer.width() + this.$divAddTab.outerWidth(true) + this._tabScrollValue; this.$btnScrollLeft.enabled(this._tabScrollValue < 0); this.$btnScrollRight.enabled(overflowRightBy > 0); }; DiagramDesignerWidgetTabs.prototype._onTabsSortStop = function () { var ul = this.$ulTabTab, orderChanged = false, allLi = ul.find('li'), i, li, order = []; for (i = 0; i < allLi.length; i += 1) { li = $(allLi[i]); order.push(li.data(TAB_ID)); } for (i = 0; i < order.length; i += 1) { if (i + '' !== order[i]) { orderChanged = true; break; } } if (orderChanged) { this.onTabsSorted(order); } }; DiagramDesignerWidgetTabs.prototype._refreshTabTabsScrollOnResize = function () { if (this._tabsEnabled === true) { var overflowRightBy = this.$ulTabTab.width() - this.$tabsContainer.width() + this.$divAddTab.outerWidth(true) + this._tabScrollValue; if (overflowRightBy < 0) { this._scrollTabListBy(-overflowRightBy); } this._scrollSelectedTabIntoView(); this._refreshTabScrollButtons(); } }; DiagramDesignerWidgetTabs.prototype.onTabDeleteClicked = function (tabID) { this.logger.warn('onTabDeleteClicked not implemented: "' + tabID + '"'); }; DiagramDesignerWidgetTabs.prototype.onTabAddClicked = function () { var tabID = this.addTab('New tab', true); this.logger.warn('onTabAddClicked not implemented: "' + tabID + '"'); }; DiagramDesignerWidgetTabs.prototype.onTabTitleChanged = function (tabID, oldValue, newValue) { this.logger.warn('onTabTitleChanged not implemented: ID: ' + tabID + ' "' + oldValue + '" --> "' + newValue + '"'); }; DiagramDesignerWidgetTabs.prototype.onSelectedTabChanged = function (tabID) { this.logger.warn('onSelectedTabChanged not implemented: "' + tabID + '"'); }; DiagramDesignerWidgetTabs.prototype.onTabsSorted = function (newTabIDOrder) { this.logger.warn('onTabsSorted not implemented: "' + newTabIDOrder + '"'); }; return DiagramDesignerWidgetTabs; });