@eclipse-scout/core
Version:
Eclipse Scout runtime
388 lines (332 loc) • 12 kB
text/typescript
/*
* Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
import {
aria, Desktop, DesktopHeaderEventMap, DesktopHeaderLayout, DesktopHeaderModel, DesktopLogo, DesktopTabArea, DesktopToolBox, Event, EventHandler, Form, HtmlComponent, InitModelOf, Menu, MenuBar, ObjectIdProvider, ObjectOrChildModel,
OutlineContent, PropertyChangeEvent, scout, ViewButtonBox, Widget
} from '../../index';
export class DesktopHeader extends Widget implements DesktopHeaderModel {
declare model: DesktopHeaderModel;
declare eventMap: DesktopHeaderEventMap;
declare self: DesktopHeader;
desktop: Desktop;
tabArea: DesktopTabArea;
logoUrl: string;
logo: DesktopLogo;
toolBoxVisible: boolean;
toolBox: DesktopToolBox;
viewButtonBoxVisible: boolean;
viewButtonBox: ViewButtonBox;
outlineContent: OutlineContent;
protected _desktopPropertyChangeHandler: EventHandler<PropertyChangeEvent<any, Desktop>>;
protected _desktopAnimationEndHandler: EventHandler<Event<Desktop>>;
protected _outlineContentMenuBarVisibleChangeHandler: EventHandler<PropertyChangeEvent<boolean, MenuBar>>;
protected _outlineContentCssClassChangeHandler: EventHandler<PropertyChangeEvent<string, OutlineContent>>;
protected _viewButtonBoxPropertyChangeHandler: EventHandler<PropertyChangeEvent<any, ViewButtonBox>>;
constructor() {
super();
this.tabArea = null;
this.toolBoxVisible = true;
this.viewButtonBox = null;
this.viewButtonBoxVisible = false;
this.outlineContent = null;
this._desktopPropertyChangeHandler = this._onDesktopPropertyChange.bind(this);
this._desktopAnimationEndHandler = this._onDesktopAnimationEnd.bind(this);
this._outlineContentMenuBarVisibleChangeHandler = this._onOutlineContentMenuBarVisibleChange.bind(this);
this._outlineContentCssClassChangeHandler = this._onOutlineContentCssClassChange.bind(this);
this._viewButtonBoxPropertyChangeHandler = this._onViewButtonBoxPropertyChange.bind(this);
}
protected override _init(model: InitModelOf<this>) {
super._init(model);
this.desktop = this.session.desktop;
this.updateViewButtonBoxVisibility();
this.tabArea = this._createTabArea();
}
protected _createTabArea(): DesktopTabArea {
return scout.create(DesktopTabArea, $.extend({
parent: this
}, this.tabArea));
}
protected override _render() {
this.$container = this.$parent.appendDiv('desktop-header');
aria.role(this.$container, 'banner');
aria.label(this.$container, this.session.text('ui.HeaderArea'));
this.htmlComp = HtmlComponent.install(this.$container, this.session);
this.htmlComp.setLayout(new DesktopHeaderLayout(this));
this.desktop.on('propertyChange', this._desktopPropertyChangeHandler);
this.desktop.on('animationEnd', this._desktopAnimationEndHandler);
if (this.desktop.bench) {
this._setOutlineContent(this.desktop.bench.outlineContent);
}
}
protected override _renderProperties() {
super._renderProperties();
this._renderViewButtonBoxVisible();
this._renderViewTabs();
this._renderToolBoxVisible();
this._renderLogoUrl();
this._renderInBackground();
}
protected override _remove() {
this.desktop.off('propertyChange', this._desktopPropertyChangeHandler);
this.desktop.off('animationEnd', this._desktopAnimationEndHandler);
this._setOutlineContent(null);
super._remove();
}
protected _renderViewTabs() {
this.tabArea.render();
}
protected _renderToolBox() {
if (this.toolBox) {
return;
}
this.toolBox = this._createToolBox();
this.toolBox.render();
}
protected _createToolBox(): DesktopToolBox {
return scout.create(DesktopToolBox, {
parent: this,
menus: this.desktop.menus
});
}
protected _removeToolBox() {
if (!this.toolBox) {
return;
}
this.toolBox.destroy();
this.toolBox = null;
}
protected _renderToolBoxVisible() {
if (this.toolBoxVisible) {
this._renderToolBox();
} else {
this._removeToolBox();
}
this.invalidateLayoutTree();
}
protected _renderLogoUrl() {
if (this.logoUrl) {
this._renderLogo();
} else {
this._removeLogo();
}
this.invalidateLayoutTree();
}
protected _renderLogo() {
if (this.desktop.displayStyle === Desktop.DisplayStyle.COMPACT) {
// Do not render logo in compact mode (wastes space)
return;
}
if (!this.logo) {
this.logo = this._createLogo();
this.logo.render();
} else {
this.logo.setUrl(this.logoUrl);
}
}
protected _createLogo(): DesktopLogo {
return scout.create(DesktopLogo, {
parent: this,
url: this.logoUrl
});
}
protected _removeLogo() {
if (!this.logo) {
return;
}
this.logo.destroy();
this.logo = null;
}
protected _renderViewButtonBox() {
if (this.viewButtonBox) {
return;
}
this.viewButtonBox = this._createViewButtonBox();
this.viewButtonBox.on('propertyChange', this._viewButtonBoxPropertyChangeHandler);
this.viewButtonBox.render();
this.viewButtonBox.$container.prependTo(this.$container);
this.updateViewButtonStyling();
}
protected _createViewButtonBox(): ViewButtonBox {
return scout.create(ViewButtonBox, {
parent: this,
viewButtons: this.desktop.viewButtons,
selectedMenuButtonAlwaysVisible: true
});
}
protected _removeViewButtonBox() {
if (!this.viewButtonBox) {
return;
}
this.viewButtonBox.off('propertyChange', this._viewButtonBoxPropertyChangeHandler);
this.viewButtonBox.destroy();
this.viewButtonBox = null;
}
protected _renderViewButtonBoxVisible() {
if (this.viewButtonBoxVisible) {
this._renderViewButtonBox();
} else {
this._removeViewButtonBox();
}
this.$container.toggleClass('has-view-button-box', this.viewButtonBoxVisible);
this.invalidateLayoutTree();
}
sendToBack() {
if (this.rendered) {
this._renderInBackground();
}
}
bringToFront() {
if (this.rendered) {
this._renderInBackground();
}
}
protected _renderInBackground() {
this.$container.toggleClass('in-background', this.desktop.inBackground);
}
setLogoUrl(logoUrl: string) {
this.setProperty('logoUrl', logoUrl);
}
setToolBoxVisible(visible: boolean) {
this.setProperty('toolBoxVisible', visible);
}
setViewButtonBoxVisible(visible: boolean) {
this.setProperty('viewButtonBoxVisible', visible);
}
setMenus(menus: ObjectOrChildModel<Menu>[]) {
if (this.toolBox) {
this.toolBox.setMenus(menus);
}
}
protected _setOutlineContent(outlineContent: OutlineContent) {
if (this.outlineContent === outlineContent) {
return;
}
this._detachOutlineContentHandlers();
this._setProperty('outlineContent', outlineContent);
this._attachOutlineContentHandlers();
this.updateViewButtonStyling();
}
updateViewButtonBoxVisibility() {
// View buttons are visible in the header if the navigation is not visible
// If there are no view buttons at all, don't show the box
// With displayStyle is set to compact, the view buttons should never be visible in the header
this.setViewButtonBoxVisible(this.desktop.viewButtons.some(button => button.visible) && !this.desktop.navigationVisible && this.desktop.displayStyle !== Desktop.DisplayStyle.COMPACT);
}
protected _attachOutlineContentHandlers() {
this._attachOutlineContentMenuBarHandler();
this._attachOutlineContentCssClassHandler();
}
protected _attachOutlineContentMenuBarHandler() {
if (!this.outlineContent) {
return;
}
let menuBar = this._outlineContentMenuBar(this.outlineContent);
if (menuBar) {
menuBar.on('propertyChange:visible', this._outlineContentMenuBarVisibleChangeHandler);
}
}
protected _attachOutlineContentCssClassHandler() {
if (!this.outlineContent) {
return;
}
this.outlineContent.on('propertyChange:cssClass', this._outlineContentCssClassChangeHandler);
}
protected _detachOutlineContentHandlers() {
this._detachOutlineContentMenuBarHandler();
this._detachOutlineContentCssClassHandler();
}
protected _detachOutlineContentMenuBarHandler() {
if (!this.outlineContent) {
return;
}
let menuBar = this._outlineContentMenuBar(this.outlineContent);
if (menuBar) {
menuBar.off('propertyChange:visible', this._outlineContentMenuBarVisibleChangeHandler);
}
}
protected _detachOutlineContentCssClassHandler() {
if (!this.outlineContent) {
return;
}
this.outlineContent.off('propertyChange:cssClass', this._outlineContentCssClassChangeHandler);
}
protected _outlineContentMenuBar(outlineContent: OutlineContent): MenuBar {
if (outlineContent instanceof Form) {
return outlineContent.rootGroupBox.menuBar;
}
return (outlineContent as { menuBar?: MenuBar }).menuBar;
}
updateViewButtonStyling() {
this._updateOutlineContentHasMenuBar();
this._updateOutlineContentHasDimmedBackground();
}
protected _getOutlineContentForViewButtonStyling(): OutlineContent {
if (!this.viewButtonBoxVisible || !this.outlineContent || !this.outlineContent.visible) {
return;
}
return this.outlineContent;
}
protected _updateOutlineContentHasMenuBar() {
let outlineContent = this._getOutlineContentForViewButtonStyling();
if (!outlineContent) {
return;
}
let hasMenuBar = false;
if (outlineContent instanceof Form && outlineContent.detailForm) {
let rootGroupBox = outlineContent.rootGroupBox;
hasMenuBar = rootGroupBox.menuBar && rootGroupBox.menuBarVisible && rootGroupBox.menuBar.visible;
} else {
let outlineTable = outlineContent as { menuBar?: MenuBar };
hasMenuBar = outlineTable.menuBar && outlineTable.menuBar.visible;
}
this.$container.toggleClass('outline-content-has-menubar', !!hasMenuBar);
}
protected _updateOutlineContentHasDimmedBackground() {
let outlineContent = this._getOutlineContentForViewButtonStyling();
if (!outlineContent) {
return;
}
let hasDimmedBackground = false;
if (outlineContent.cssClass) {
hasDimmedBackground = outlineContent.cssClass.indexOf('dimmed-background') > -1;
}
this.$container.toggleClass('outline-content-has-dimmed-background', hasDimmedBackground);
}
protected _onDesktopNavigationVisibleChange() {
// If navigation gets visible: Hide view buttons immediately
// If navigation gets hidden using animation: Show view buttons when animation ends
if (this.desktop.navigationVisible) {
this.updateViewButtonBoxVisibility();
}
}
protected _onDesktopAnimationEnd(event: Event<Desktop>) {
this.updateViewButtonBoxVisibility();
}
onBenchOutlineContentChange(content: OutlineContent, oldContent: OutlineContent) {
this._setOutlineContent(content);
}
protected _onDesktopPropertyChange(event: PropertyChangeEvent<any, Desktop>) {
if (event.propertyName === 'navigationVisible') {
this._onDesktopNavigationVisibleChange();
}
}
protected _onOutlineContentMenuBarVisibleChange(event: PropertyChangeEvent<boolean, MenuBar>) {
this._updateOutlineContentHasMenuBar();
}
protected _onOutlineContentCssClassChange(event: PropertyChangeEvent<string, OutlineContent>) {
this._updateOutlineContentHasDimmedBackground();
}
protected _onViewButtonBoxPropertyChange(event: PropertyChangeEvent<any, ViewButtonBox>) {
if (event.propertyName === 'menuButtons' || event.propertyName === 'tabButtons') {
this.invalidateLayoutTree();
}
}
}
ObjectIdProvider.uuidPathSkipWidgets.add(DesktopHeader);