Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use composition to improve tab switch #231

Merged
merged 16 commits into from
Nov 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions packages/widgets/src/docklayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export class DockLayout extends Layout {
if (options.spacing !== undefined) {
this._spacing = Utils.clampDimension(options.spacing);
}
this._hiddenMode =
options.hiddenMode !== undefined
? options.hiddenMode
: Widget.HiddenMode.Display;
}

/**
Expand Down Expand Up @@ -89,6 +93,30 @@ export class DockLayout extends Layout {
*/
readonly renderer: DockLayout.IRenderer;

/**
* The method for hiding child widgets.
*
* #### Notes
* If there is only one child widget, `Display` hiding mode will be used
* regardless of this setting.
*/
get hiddenMode(): Widget.HiddenMode {
return this._hiddenMode;
}
set hiddenMode(v: Widget.HiddenMode) {
if (this._hiddenMode === v) {
return;
}
this._hiddenMode = v;
each(this.tabBars(), bar => {
if (bar.titles.length > 1) {
bar.titles.forEach(title => {
title.owner.hiddenMode = this._hiddenMode;
});
}
});
}

/**
* Get the inter-element spacing for the dock layout.
*/
Expand Down Expand Up @@ -651,6 +679,13 @@ export class DockLayout extends Layout {
// If there are multiple tabs, just remove the widget's tab.
if (tabNode.tabBar.titles.length > 1) {
tabNode.tabBar.removeTab(widget.title);
if (
this._hiddenMode === Widget.HiddenMode.Scale &&
tabNode.tabBar.titles.length == 1
) {
const existingWidget = tabNode.tabBar.titles[0].owner;
existingWidget.hiddenMode = Widget.HiddenMode.Display;
}
return;
}

Expand Down Expand Up @@ -808,6 +843,22 @@ export class DockLayout extends Layout {
index = refNode.tabBar.currentIndex;
}

// Using transform create an additional layer in the pixel pipeline
// to limit the number of layer, it is set only if there is more than one widget.
if (
this._hiddenMode === Widget.HiddenMode.Scale &&
refNode.tabBar.titles.length > 0
) {
if (refNode.tabBar.titles.length == 1) {
const existingWidget = refNode.tabBar.titles[0].owner;
existingWidget.hiddenMode = Widget.HiddenMode.Scale;
}

widget.hiddenMode = Widget.HiddenMode.Scale;
} else {
widget.hiddenMode = Widget.HiddenMode.Display;
}

// Insert the widget's tab relative to the target index.
refNode.tabBar.insertTab(index + (after ? 1 : 0), widget.title);
Private.addAria(widget, refNode.tabBar);
Expand Down Expand Up @@ -1089,6 +1140,7 @@ export class DockLayout extends Layout {
private _dirty = false;
private _root: Private.LayoutNode | null = null;
private _box: ElementExt.IBoxSizing | null = null;
private _hiddenMode: Widget.HiddenMode;
private _items: Private.ItemMap = new Map<Widget, LayoutItem>();
}

Expand All @@ -1100,6 +1152,13 @@ export namespace DockLayout {
* An options object for creating a dock layout.
*/
export interface IOptions {
/**
* The method for hiding widgets.
*
* The default is `Widget.HiddenMode.Display`.
*/
hiddenMode?: Widget.HiddenMode;

/**
* The renderer to use for the dock layout.
*/
Expand Down
27 changes: 26 additions & 1 deletion packages/widgets/src/dockpanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ export class DockPanel extends Widget {
};

// Set up the dock layout for the panel.
this.layout = new DockLayout({ renderer, spacing: options.spacing });
this.layout = new DockLayout({
renderer,
spacing: options.spacing,
hiddenMode: options.hiddenMode
});

// Set up the overlay drop indicator.
this.overlay = options.overlay || new DockPanel.Overlay();
Expand All @@ -93,6 +97,20 @@ export class DockPanel extends Widget {
super.dispose();
}

/**
* The method for hiding widgets.
*/
get hiddenMode(): Widget.HiddenMode {
return (this.layout as DockLayout).hiddenMode;
}

/**
* Set the method for hiding widgets.
*/
set hiddenMode(v: Widget.HiddenMode) {
(this.layout as DockLayout).hiddenMode = v;
}

/**
* A signal emitted when the layout configuration is modified.
*
Expand Down Expand Up @@ -1094,6 +1112,13 @@ export namespace DockPanel {
*/
edges?: IEdges;

/**
* The method for hiding widgets.
*
* The default is `Widget.HiddenMode.Display`.
*/
hiddenMode?: Widget.HiddenMode;

/**
* Allow tabs to be draggable / movable by user.
*
Expand Down
82 changes: 81 additions & 1 deletion packages/widgets/src/stackedlayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { ElementExt } from '@lumino/domutils';

import { Message, MessageLoop } from '@lumino/messaging';

import { LayoutItem } from './layout';
import { Layout, LayoutItem } from './layout';

import { PanelLayout } from './panellayout';

Expand All @@ -26,6 +26,44 @@ import { Widget } from './widget';
* The Z-order of the visible widgets follows their layout order.
*/
export class StackedLayout extends PanelLayout {
constructor(options: StackedLayout.IOptions = {}) {
super(options);
this._hiddenMode =
options.hiddenMode !== undefined
? options.hiddenMode
: Widget.HiddenMode.Display;
}

/**
* The method for hiding widgets.
*
* #### Notes
* If there is only one child widget, `Display` hiding mode will be used
* regardless of this setting.
*/
get hiddenMode(): Widget.HiddenMode {
return this._hiddenMode;
}

/**
* Set the method for hiding widgets.
*
* #### Notes
* If there is only one child widget, `Display` hiding mode will be used
* regardless of this setting.
*/
set hiddenMode(v: Widget.HiddenMode) {
if (this._hiddenMode === v) {
return;
}
this._hiddenMode = v;
if (this.widgets.length > 1) {
this.widgets.forEach(w => {
w.hiddenMode = this._hiddenMode;
});
}
}

/**
* Dispose of the resources held by the layout.
*/
Expand Down Expand Up @@ -54,6 +92,20 @@ export class StackedLayout extends PanelLayout {
* This is a reimplementation of the superclass method.
*/
protected attachWidget(index: number, widget: Widget): void {
// Using transform create an additional layer in the pixel pipeline
// to limit the number of layer, it is set only if there is more than one widget.
if (
this._hiddenMode === Widget.HiddenMode.Scale &&
this._items.length > 0
) {
if (this._items.length === 1) {
fcollonval marked this conversation as resolved.
Show resolved Hide resolved
this.widgets[0].hiddenMode = Widget.HiddenMode.Scale;
}
widget.hiddenMode = Widget.HiddenMode.Scale;
} else {
widget.hiddenMode = Widget.HiddenMode.Display;
}

// Create and add a new layout item for the widget.
ArrayExt.insert(this._items, index, new LayoutItem(widget));

Expand Down Expand Up @@ -128,6 +180,16 @@ export class StackedLayout extends PanelLayout {
// Reset the z-index for the widget.
item!.widget.node.style.zIndex = '';

// Reset the hidden mode for the widget.
if (this._hiddenMode === Widget.HiddenMode.Scale) {
widget.hiddenMode = Widget.HiddenMode.Display;

// Reset the hidden mode for the first widget if necessary.
if (this._items.length === 1) {
this._items[0].widget.hiddenMode = Widget.HiddenMode.Display;
}
}

// Dispose of the layout item.
item!.dispose();

Expand Down Expand Up @@ -304,4 +366,22 @@ export class StackedLayout extends PanelLayout {
private _dirty = false;
private _items: LayoutItem[] = [];
private _box: ElementExt.IBoxSizing | null = null;
private _hiddenMode: Widget.HiddenMode;
}

/**
* The namespace for the `StackedLayout` class statics.
*/
export namespace StackedLayout {
/**
* An options object for initializing a stacked layout.
*/
export interface IOptions extends Layout.IOptions {
/**
* The method for hiding widgets.
*
* The default is `Widget.HiddenMode.Display`.
*/
hiddenMode?: Widget.HiddenMode;
}
}
22 changes: 22 additions & 0 deletions packages/widgets/src/stackedpanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ export class StackedPanel extends Panel {
/* </DEPRECATED> */
}

/**
* The method for hiding widgets.
*
* #### Notes
* If there is only one child widget, `Display` hiding mode will be used
* regardless of this setting.
*/
get hiddenMode(): Widget.HiddenMode {
return (this.layout as StackedLayout).hiddenMode;
}

/**
* Set the method for hiding widgets.
*
* #### Notes
* If there is only one child widget, `Display` hiding mode will be used
* regardless of this setting.
*/
set hiddenMode(v: Widget.HiddenMode) {
(this.layout as StackedLayout).hiddenMode = v;
}

/**
* A signal emitted when a widget is removed from a stacked panel.
*/
Expand Down
Loading