All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scout.desktop.bench.DesktopBench.js Maven / Gradle / Ivy

There is a newer version: 25.1.0-beta.0
Show newest version
/*******************************************************************************
 * Copyright (c) 2014-2015 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
scout.DesktopBench = function() {
  scout.DesktopBench.parent.call(this);
  this.htmlComp;
  this.VIEW_AREA_COLUMN_INDEX = {
    LEFT: 0,
    CENTER: 1,
    RIGHT: 2
  };
  this.columns = [];
  this.components;
  this.tabBoxMap = {}; // [key=viewId, value=SimpleTabBox instance]
  this._desktopOutlineChangedHandler = this._onDesktopOutlineChanged.bind(this);
  this._desktopPropertyChangeHandler = this._onDesktopPropertyChange.bind(this);
  this._outlineNodesSelectedHandler = this._onOutlineNodesSelected.bind(this);
  this._outlinePageChangedHandler = this._onOutlinePageChanged.bind(this);
  this._outlinePropertyChangeHandler = this._onOutlinePropertyChange.bind(this);

  // event listener functions
  this._viewAddedHandler = this._onViewAdded.bind(this);
  this._viewRemovedHandler = this._onViewRemoved.bind(this);
  this._viewActivatedHandler = this._onViewActivated.bind(this);
  this._viewDeactivatedHandler = this._onViewDeactivated.bind(this);

  this._desktopAnimationEndHandler = this._onDesktopAnimationEnd.bind(this);

  this._addEventSupport();
};
scout.inherits(scout.DesktopBench, scout.Widget);

scout.DesktopBench.VIEW_MIN_HEIGHT; // Configured in sizes.css
scout.DesktopBench.VIEW_MIN_WIDTH; // Configured in sizes.css

scout.DesktopBench.prototype._init = function(model) {
  scout.DesktopBench.parent.prototype._init.call(this, model);

  scout.DesktopBench.VIEW_MIN_HEIGHT = $.pxToNumber(scout.styles.get('view-tab-box', 'min-height').minHeight);
  scout.DesktopBench.VIEW_MIN_WIDTH = $.pxToNumber(scout.styles.get('view-tab-box', 'min-width').minWidth);

  this._createColumns();
  this.desktop = this.session.desktop;
  this.headerTabArea = model.headerTabArea;
  // controller for headerTabArea
  if (this.headerTabArea) {
    this.headerTabAreaController = new scout.HeaderTabBoxController(this, this.headerTabArea);
  }
  this.outlineContentVisible = scout.nvl(model.outlineContentVisible, true);
  this.setOutline(this.desktop.outline);
  this.updateNavigationHandleVisibility();
};

scout.DesktopBench.prototype._createColumns = function() {
  for (var i = 0; i < 3; i++) {
    var column = scout.create('BenchColumn', {
      parent: this
    });
    column.on('viewAdded', this._viewAddedHandler);
    column.on('viewRemoved', this._viewRemovedHandler);
    column.on('viewActivated', this._viewActivatedHandler);
    column.on('viewDeactivated', this._viewDeactivatedHandler);
    this.columns.push(column);
  }
};

scout.DesktopBench.prototype._initKeyStrokeContext = function(keyStrokeContext) {
  scout.DesktopBench.parent.prototype._initKeyStrokeContext.call(this, keyStrokeContext);

  // Bound to desktop
  this.desktopKeyStrokeContext = new scout.KeyStrokeContext();
  this.desktopKeyStrokeContext.invokeAcceptInputOnActiveValueField = true;
  this.desktopKeyStrokeContext.$bindTarget = this.desktop.$container;
  this.desktopKeyStrokeContext.$scopeTarget = this.$container;
  this.desktopKeyStrokeContext.registerKeyStroke(this.desktop.keyStrokes);
};

scout.DesktopBench.prototype._render = function($parent) {
  this.$container = $parent.appendDiv('desktop-bench');
  this.htmlComp = new scout.HtmlComponent(this.$container, this.session);

  this.htmlComp.setLayout(new scout.DesktopBenchLayout(this));

  this._renderColumns();
  this._revalidateSplitters();
  this._renderNavigationHandleVisible();

  this.session.keyStrokeManager.installKeyStrokeContext(this.desktopKeyStrokeContext);
  this.desktop.on('propertyChange', this._desktopPropertyChangeHandler);
  this.desktop.on('outlineChanged', this._desktopOutlineChangedHandler);
  this.desktop.on('animationEnd', this._desktopAnimationEndHandler);
};

scout.DesktopBench.prototype._renderColumns = function() {
  this.columns.forEach(function(column) {
    if (column.viewCount() > 0) {
      this._renderColumn(column);

    }
  }.bind(this));
};

scout.DesktopBench.prototype._renderColumn = function(column) {
  if (!column || column.rendered) {
    return;
  }

  column.render(this.$container);
};

scout.DesktopBench.prototype._remove = function() {

  this.desktop.off('propertyChange', this._desktopPropertyChangeHandler);
  this.desktop.off('outlineChanged', this._desktopOutlineChangedHandler);
  this.desktop.off('animationEnd', this._desktopAnimationEndHandler);
  this.session.keyStrokeManager.uninstallKeyStrokeContext(this.desktopKeyStrokeContext);
  scout.DesktopBench.parent.prototype._remove.call(this);

};

scout.DesktopBench.prototype._renderOutlineContent = function() {
  if (!this.outlineContent || this.desktop.inBackground) {
    return;
  }

  this.addView(this.outlineContent);

  if (this.desktop.rendered) {

    // Request focus on first element in outline content
    this.session.focusManager.validateFocus();
  }
  if (this.outlineContent instanceof scout.Table) {
    this.outlineContent.restoreScrollPosition();
  }
};

scout.DesktopBench.prototype._removeOutlineContent = function() {
  if (!this.outlineContent) {
    return;
  }
  if (this.outlineContent instanceof scout.Table) {
    this.outlineContent.storeScrollPosition();
  }
  this.removeView(this.outlineContent, false);

};

scout.DesktopBench.prototype._renderNavigationHandle = function() {
  if (this.navigationHandle) {
    return;
  }
  this.navigationHandle = scout.create('DesktopNavigationHandle', {
    parent: this,
    leftVisible: false
  });
  this.navigationHandle.render(this.$container);
  this.navigationHandle.$container.addClass('navigation-closed');
  this.navigationHandle.on('action', this._onNavigationHandleAction.bind(this));
};

scout.DesktopBench.prototype._removeNavigationHandle = function() {
  if (!this.navigationHandle) {
    return;
  }
  this.navigationHandle.remove();
  this.navigationHandle = null;
};

scout.DesktopBench.prototype._renderNavigationHandleVisible = function() {
  if (this.navigationHandleVisible) {
    this._renderNavigationHandle();
  } else {
    this._removeNavigationHandle();
  }
};

/**
 * is called in post render of desktop used to initialize the ui state. E.g. show default views
 */
scout.DesktopBench.prototype.postRender = function() {
  this.columns.forEach(function(column) {
    column.postRender();
  });
};

scout.DesktopBench.prototype.setNavigationHandleVisible = function(visible) {
  if (this.navigationHandleVisible === visible) {
    return;
  }
  this.navigationHandleVisible = visible;
  if (this.rendered) {
    this._renderNavigationHandleVisible();
  }
};

scout.DesktopBench.prototype.setOutline = function(outline) {
  if (this.outline) {
    this.outline.off('nodesSelected', this._outlineNodesSelectedHandler);
    this.outline.off('pageChanged', this._outlinePageChangedHandler);
    this.outline.off('propertyChange', this._outlinePropertyChangeHandler);
  }
  this.outline = outline;
  if (this.outline) {
    this.outline.on('nodesSelected', this._outlineNodesSelectedHandler);
    this.outline.on('pageChanged', this._outlinePageChangedHandler);
    this.outline.on('propertyChange', this._outlinePropertyChangeHandler);
  }
  this.updateOutlineContent();
};

scout.DesktopBench.prototype.setOutlineContent = function(content) {
  var oldContent = this.outlineContent;
  if (this.outlineContent === content) {
    return;
  }

  if (this.rendered) {
    this._removeOutlineContent();
  }
  this._setProperty('outlineContent', content);
  // Inform header that outline content has changed
  // (having a listener in the header is quite complex due to initialization phase, a direct call here is much easier to implement)
  if (this.desktop.header) {
    this.desktop.header.onBenchOutlineContentChange(content, oldContent);
  }
  this._showOutlineContent();
};

scout.DesktopBench.prototype._showOutlineContent = function() {
  if (this.outlineContent) {
    // Reset view tab relevant properties to make sure no tab is visible for the outline content
    delete this.outlineContent.title;
    delete this.outlineContent.subTitle;
    delete this.outlineContent.iconId;

    this.addView(this.outlineContent);

    if (this.desktop.rendered) {
      // Request focus on first element in outline content
      this.session.focusManager.validateFocus();
    }
    if (this.outlineContent instanceof scout.Table) {
      this.outlineContent.restoreScrollPosition();
    }
  }
};

scout.DesktopBench.prototype.setOutlineContentVisible = function(visible) {
  if (visible === this.outlineContentVisible) {
    return;
  }
  this.outlineContentVisible = visible;
  this.updateOutlineContent();
};

scout.DesktopBench.prototype.bringToFront = function() {
  if (!this.outlineContent) {
    return;
  }
  this._showOutlineContent();
};

scout.DesktopBench.prototype.sendToBack = function() {
  // nop
};

scout.DesktopBench.prototype._computeDefaultDetailForm = function() {
  return this.outline.defaultDetailForm;
};

scout.DesktopBench.prototype._computeOutlineOverview = function() {
  return this.outline.outlineOverview;
};

scout.DesktopBench.prototype._computeDetailContentForPage = function(node) {
  if (!node) {
    throw new Error('called _showDetailContentForPage without node');
  }

  var content;
  if (node.detailForm && node.detailFormVisible && node.detailFormVisibleByUi) {
    content = node.detailForm;
    content.uiCssClasses = ['detail-form'];
  } else if (node.detailTable && node.detailTableVisible) {
    content = node.detailTable;
    content.uiCssClasses = ['detail-table'];
  }

  return content;
};

scout.DesktopBench.prototype.updateOutlineContent = function() {
  if (!this.outlineContentVisible || !this.outline) {
    return;
  }
  var content;
  var selectedPages = this.outline.selectedNodes;
  if (selectedPages.length === 0) {
    if (this.outline.defaultDetailForm) {
      content = this._computeDefaultDetailForm();
    } else if (this.outline.outlineOverview) {
      content = this._computeOutlineOverview();
    }
  } else {
    // Outline does not support multi selection -> [0]
    var selectedPage = selectedPages[0];
    content = this._computeDetailContentForPage(selectedPage);

  }
  if (content) {
    if (content instanceof scout.Table) {
      content.menuBar.top();
      content.menuBar.large();
    }
    content.displayViewId = 'C';
  }
  this.setOutlineContent(content);
};

scout.DesktopBench.prototype.updateOutlineContentDebounced = function() {
  clearTimeout(this._updateOutlineContentTimeout);
  this._updateOutlineContentTimeout = setTimeout(function() {
    this.updateOutlineContent();
  }.bind(this), 300);
};

scout.DesktopBench.prototype.updateNavigationHandleVisibility = function() {
  // Don't show handle if desktop says handle must not be visible
  // Only show handle if navigation is invisible
  this.setNavigationHandleVisible(this.desktop.navigationHandleVisible && !this.desktop.navigationVisible);
};

scout.DesktopBench.prototype._onDesktopOutlineChanged = function(event) {
  this.setOutline(this.desktop.outline);
  this.updateNavigationHandleVisibility();
};

scout.DesktopBench.prototype._onOutlineNodesSelected = function(event) {
  if (event.debounce) {
    this.updateOutlineContentDebounced();
  } else {
    this.updateOutlineContent();
  }
};

scout.DesktopBench.prototype._onOutlinePageChanged = function(event) {
  var selectedPage = this.outline.selectedNodes[0];
  if (!event.page && !selectedPage || event.page === selectedPage) {
    this.updateOutlineContent();
  }
};

scout.DesktopBench.prototype._onOutlinePropertyChange = function(event) {
  if (event.changedProperties.indexOf('defaultDetailForm') !== -1) {
    this.updateOutlineContent();
  }
};

scout.DesktopBench.prototype._onDesktopNavigationVisibleChange = function(event) {
  // If navigation gets visible: Hide handle immediately
  // If navigation gets hidden using animation: Show handle when animation ends
  if (this.desktop.navigationVisible) {
    this.updateNavigationHandleVisibility();
  }
};

scout.DesktopBench.prototype._onDesktopNavigationHandleVisibleChange = function(event) {
  this.updateNavigationHandleVisibility();
};

scout.DesktopBench.prototype._onDesktopAnimationEnd = function(event) {
  if (!this.desktop.navigationVisible) {
    this.updateNavigationHandleVisibility();
  }
};

scout.DesktopBench.prototype._onDesktopPropertyChange = function(event) {
  if (event.changedProperties.indexOf('navigationVisible') !== -1) {
    this._onDesktopNavigationVisibleChange();
  } else if (event.changedProperties.indexOf('navigationHandleVisible') !== -1) {
    this._onDesktopNavigationHandleVisibleChange();
  }
};

scout.DesktopBench.prototype._onNavigationHandleAction = function(event) {
  this.desktop.enlargeNavigation();
};

scout.DesktopBench.prototype._revalidateSplitters = function() {
  // remove old splitters
  if (this.components) {
    this.components.forEach(function(comp) {
      if (comp instanceof scout.Splitter) {
        comp.remove();
      }
    });
  }
  var splitterParent = this;
  this.components = this.columns.filter(function(column) {
    return column.hasViews();
  }).reduce(function(arr, col) {
    if (arr.length > 0) {
      // add sep
      var splitter = scout.create('Splitter', {
        parent: splitterParent,
        $anchor: arr[arr.length - 1].$container,
        $root: splitterParent.$container,
        maxRatio: 1
      });
      splitter.render(splitterParent.$container);
      splitter.$container.addClass('line');
      splitter.on('move', splitterParent._onSplitterMove.bind(splitterParent));
      splitter.on('positionChanged', splitterParent._onSplitterPositionChanged.bind(splitterParent));
      arr.push(splitter);
    }
    arr.push(col);
    return arr;
  }, []);
  // well order the dom elements (reduce is used for simple code reasons, the result of reduce is not of interest).
  this.components.filter(function(comp) {
      return comp instanceof scout.BenchColumn;
    })
    .reduce(function(c1, c2, index) {
      if (index > 0) {
        c2.$container.insertAfter(c1.$container);
      }
      return c2;
    }, undefined);

};

scout.DesktopBench.prototype._onSplitterMove = function(event) {
  var splitterIndex = this.components.indexOf(event.source);
  if (splitterIndex > 0 /*cannot be 0 since first element is a BenchColumn*/ ) {
    var $before = this.components[splitterIndex - 1].$container,
      $after = this.components[splitterIndex + 1].$container,
      diff = event.position - event.source.position;

    if (($before.width() + diff) < scout.DesktopBench.VIEW_MIN_WIDTH) {
      // set to min
      event.setPosition($before.position().left + scout.DesktopBench.VIEW_MIN_WIDTH);
    }
    if (($after.position().left + $after.width() - event.position) < scout.DesktopBench.VIEW_MIN_WIDTH) {
      event.setPosition($after.position().left + $after.width() - scout.DesktopBench.VIEW_MIN_WIDTH);
    }
  }
};

scout.DesktopBench.prototype._onSplitterPositionChanged = function(event) {
  this.revalidateLayout();
};

scout.DesktopBench.prototype._onViewAdded = function(event) {
  this.trigger('viewAdded', {
    view: event.view
  });
};

scout.DesktopBench.prototype._onViewRemoved = function(event) {
  this.trigger('viewRemoved', {
    view: event.view
  });
};

scout.DesktopBench.prototype._onViewActivated = function(event) {
  var view = event.view;
  if (this.outlineContent === view) {
    this.desktop.bringOutlineToFront(this.desktop.outline);
  }
  this.trigger('viewActivated', {
    view: view
  });
};

scout.DesktopBench.prototype._onViewDeactivated = function(event) {
  if (this.outlineContent === event.view) {
    this.desktop.sendOutlineToBack();
  }
  this.trigger('viewDeactivated', {
    view: event.view
  });
};

scout.DesktopBench.prototype.addView = function(view, activate) {
  // normalize displayViewId
  switch (view.displayViewId) {
    case 'NW':
    case 'W':
    case 'SW':
    case 'N':
    case 'C':
    case 'S':
    case 'NE':
    case 'E':
    case 'SE':
      break;
    default:
      // map all other displayViewIds to center
      view.displayViewId = 'C';
      break;
  }
  var column = this._getColumn(view.displayViewId);
  this.tabBoxMap[view.id] = column;
  column.addView(view, activate);

  if (this.rendered) {
    if (column.viewCount() === 1) {
      this._renderColumn(column);
      this._revalidateSplitters();
      this.htmlComp.invalidateLayoutTree();
      // Layout immediate to prevent 'laggy' form visualization,
      // but not initially while desktop gets rendered because it will be done at the end anyway
      this.htmlComp.validateLayoutTree();
    }
  }
};

scout.DesktopBench.prototype.activateView = function(view) {
  var column = this._getColumn(view.displayViewId);
  if (column) {
    column.activateView(view);
  }
};

scout.DesktopBench.prototype._getColumn = function(displayViewId) {
  var column;

  switch (displayViewId) {
    case 'NW':
    case 'W':
    case 'SW':
      column = this.columns[this.VIEW_AREA_COLUMN_INDEX.LEFT];
      break;
    case 'NE':
    case 'E':
    case 'SE':
      column = this.columns[this.VIEW_AREA_COLUMN_INDEX.RIGHT];
      break;
    default:
      column = this.columns[this.VIEW_AREA_COLUMN_INDEX.CENTER];
      break;
  }
  return column;
};

scout.DesktopBench.prototype.removeView = function(view, showSiblingView) {
  var column = this.tabBoxMap[view.id];
  if (column) {
    column.removeView(view, showSiblingView);
    delete this.tabBoxMap[view.id];
    // remove if empty
    if (this.rendered && column.viewCount() === 0) {
      column.remove();
      this._revalidateSplitters(true);
      this.htmlComp.invalidateLayoutTree();
      // Layout immediate to prevent 'laggy' form visualization,
      // but not initially while desktop gets rendered because it will be done at the end anyway
      this.htmlComp.validateLayoutTree();
    }
  }
};

scout.DesktopBench.prototype.getComponents = function() {
  return this.components;
};

scout.DesktopBench.prototype.getTabBox = function(displayViewId) {
  var viewColumn = this._getColumn(displayViewId);
  if (!viewColumn) {
    return;
  }
  return viewColumn.getTabBox(displayViewId);
};

scout.DesktopBench.prototype.getViews = function(displayViewId) {
  return this.columns.reduce(function(arr, column) {
    scout.arrays.pushAll(arr, column.getViews(displayViewId));
    return arr;
  }, []);
};

scout.DesktopBench.prototype.getViewTab = function(view) {
  var viewTab;
  this.getTabs().some(function(vt) {
    if (vt.view === view) {
      viewTab = vt;
      return true;
    }
    return false;
  });
  return viewTab;
};

scout.DesktopBench.prototype.getTabs = function() {
  var tabs = [];
  // consider right order
  tabs = tabs.concat(this.getTabBox('NW').getController().getTabs());
  tabs = tabs.concat(this.getTabBox('W').getController().getTabs());
  tabs = tabs.concat(this.getTabBox('SW').getController().getTabs());
  tabs = tabs.concat(this.getTabBox('N').getController().getTabs());
  if (this.headerTabAreaController) {
    tabs = tabs.concat(this.headerTabAreaController.getTabs());
  } else {
    tabs = tabs.concat(this.getTabBox('C').getController().getTabs());
  }
  tabs = tabs.concat(this.getTabBox('S').getController().getTabs());
  tabs = tabs.concat(this.getTabBox('NE').getController().getTabs());
  tabs = tabs.concat(this.getTabBox('E').getController().getTabs());
  tabs = tabs.concat(this.getTabBox('SE').getController().getTabs());
  return tabs;
};




© 2015 - 2025 Weber Informatics LLC | Privacy Policy