UNPKG

@eclipse-scout/core

Version:
388 lines (332 loc) 12 kB
/* * 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);