@theia/core 1.61.0 → 1.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/i18n/nls.cs.json +158 -13
- package/i18n/nls.de.json +158 -13
- package/i18n/nls.es.json +158 -13
- package/i18n/nls.fr.json +158 -13
- package/i18n/nls.hu.json +158 -13
- package/i18n/nls.it.json +158 -13
- package/i18n/nls.ja.json +158 -13
- package/i18n/nls.json +159 -14
- package/i18n/nls.ko.json +158 -13
- package/i18n/nls.pl.json +158 -13
- package/i18n/nls.pt-br.json +158 -13
- package/i18n/nls.ru.json +158 -13
- package/i18n/nls.tr.json +158 -13
- package/i18n/nls.zh-cn.json +158 -13
- package/i18n/nls.zh-tw.json +158 -13
- package/lib/browser/catalog.json +197 -33
- package/lib/browser/common-frontend-contribution.d.ts +1 -1
- package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
- package/lib/browser/common-frontend-contribution.js +13 -11
- package/lib/browser/common-frontend-contribution.js.map +1 -1
- package/lib/browser/context-menu-renderer.d.ts +14 -3
- package/lib/browser/context-menu-renderer.d.ts.map +1 -1
- package/lib/browser/context-menu-renderer.js +23 -1
- package/lib/browser/context-menu-renderer.js.map +1 -1
- package/lib/browser/frontend-application-module.d.ts.map +1 -1
- package/lib/browser/frontend-application-module.js +1 -3
- package/lib/browser/frontend-application-module.js.map +1 -1
- package/lib/browser/hover-service.d.ts.map +1 -1
- package/lib/browser/hover-service.js +7 -0
- package/lib/browser/hover-service.js.map +1 -1
- package/lib/browser/menu/action-menu-node.d.ts +36 -0
- package/lib/browser/menu/action-menu-node.d.ts.map +1 -0
- package/lib/browser/menu/action-menu-node.js +113 -0
- package/lib/browser/menu/action-menu-node.js.map +1 -0
- package/lib/browser/menu/browser-context-menu-renderer.d.ts +12 -4
- package/lib/browser/menu/browser-context-menu-renderer.d.ts.map +1 -1
- package/lib/browser/menu/browser-context-menu-renderer.js +12 -13
- package/lib/browser/menu/browser-context-menu-renderer.js.map +1 -1
- package/lib/browser/menu/browser-menu-module.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-module.js +4 -0
- package/lib/browser/menu/browser-menu-module.js.map +1 -1
- package/lib/browser/menu/browser-menu-node-factory.d.ts +13 -0
- package/lib/browser/menu/browser-menu-node-factory.d.ts.map +1 -0
- package/lib/browser/menu/browser-menu-node-factory.js +54 -0
- package/lib/browser/menu/browser-menu-node-factory.js.map +1 -0
- package/lib/browser/menu/browser-menu-plugin.d.ts +12 -30
- package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.js +78 -159
- package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
- package/lib/browser/menu/composite-menu-node.d.ts +49 -0
- package/lib/browser/menu/composite-menu-node.d.ts.map +1 -0
- package/lib/browser/menu/composite-menu-node.js +127 -0
- package/lib/browser/menu/composite-menu-node.js.map +1 -0
- package/lib/browser/menu/menu.spec.d.ts.map +1 -0
- package/lib/{common → browser}/menu/menu.spec.js +38 -13
- package/lib/browser/menu/menu.spec.js.map +1 -0
- package/lib/browser/open-with-service.d.ts +1 -1
- package/lib/browser/saveable-service.d.ts.map +1 -1
- package/lib/browser/saveable-service.js +6 -1
- package/lib/browser/saveable-service.js.map +1 -1
- package/lib/browser/shell/application-shell.d.ts +7 -5
- package/lib/browser/shell/application-shell.d.ts.map +1 -1
- package/lib/browser/shell/application-shell.js +82 -28
- package/lib/browser/shell/application-shell.js.map +1 -1
- package/lib/browser/shell/index.d.ts +1 -0
- package/lib/browser/shell/index.d.ts.map +1 -1
- package/lib/browser/shell/index.js +1 -0
- package/lib/browser/shell/index.js.map +1 -1
- package/lib/browser/shell/sidebar-bottom-menu-widget.d.ts.map +1 -1
- package/lib/browser/shell/sidebar-bottom-menu-widget.js +2 -1
- package/lib/browser/shell/sidebar-bottom-menu-widget.js.map +1 -1
- package/lib/browser/shell/sidebar-menu-widget.d.ts +4 -1
- package/lib/browser/shell/sidebar-menu-widget.d.ts.map +1 -1
- package/lib/browser/shell/sidebar-menu-widget.js +14 -1
- package/lib/browser/shell/sidebar-menu-widget.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts +66 -8
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js +161 -8
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts +18 -32
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js +52 -88
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts +17 -21
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js +9 -9
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts +7 -39
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js +30 -238
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.js +13 -13
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts +56 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.js +208 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.js.map +1 -0
- package/lib/browser/shell/tab-bars.d.ts.map +1 -1
- package/lib/browser/shell/tab-bars.js +2 -1
- package/lib/browser/shell/tab-bars.js.map +1 -1
- package/lib/browser/shell/theia-dock-panel.d.ts +4 -10
- package/lib/browser/shell/theia-dock-panel.d.ts.map +1 -1
- package/lib/browser/shell/theia-dock-panel.js +7 -84
- package/lib/browser/shell/theia-dock-panel.js.map +1 -1
- package/lib/browser/shell/theia-split-panel.d.ts +6 -0
- package/lib/browser/shell/theia-split-panel.d.ts.map +1 -0
- package/lib/browser/shell/theia-split-panel.js +56 -0
- package/lib/browser/shell/theia-split-panel.js.map +1 -0
- package/lib/browser/tree/tree-widget.d.ts +1 -0
- package/lib/browser/tree/tree-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-widget.js +6 -0
- package/lib/browser/tree/tree-widget.js.map +1 -1
- package/lib/browser/view-container.d.ts +6 -3
- package/lib/browser/view-container.d.ts.map +1 -1
- package/lib/browser/view-container.js +36 -26
- package/lib/browser/view-container.js.map +1 -1
- package/lib/browser/window/default-secondary-window-service.d.ts +1 -0
- package/lib/browser/window/default-secondary-window-service.d.ts.map +1 -1
- package/lib/browser/window/default-secondary-window-service.js +3 -0
- package/lib/browser/window/default-secondary-window-service.js.map +1 -1
- package/lib/common/listener.d.ts +21 -0
- package/lib/common/listener.d.ts.map +1 -0
- package/lib/common/listener.js +81 -0
- package/lib/common/listener.js.map +1 -0
- package/lib/common/listener.spec.d.ts +2 -0
- package/lib/common/listener.spec.d.ts.map +1 -0
- package/lib/common/listener.spec.js +255 -0
- package/lib/common/listener.spec.js.map +1 -0
- package/lib/common/menu/index.d.ts +2 -3
- package/lib/common/menu/index.d.ts.map +1 -1
- package/lib/common/menu/index.js +2 -3
- package/lib/common/menu/index.js.map +1 -1
- package/lib/common/menu/menu-model-registry.d.ts +37 -50
- package/lib/common/menu/menu-model-registry.d.ts.map +1 -1
- package/lib/common/menu/menu-model-registry.js +176 -225
- package/lib/common/menu/menu-model-registry.js.map +1 -1
- package/lib/common/menu/menu-types.d.ts +58 -96
- package/lib/common/menu/menu-types.d.ts.map +1 -1
- package/lib/common/menu/menu-types.js +43 -39
- package/lib/common/menu/menu-types.js.map +1 -1
- package/lib/common/messaging/proxy-factory.d.ts.map +1 -1
- package/lib/common/messaging/proxy-factory.js +4 -0
- package/lib/common/messaging/proxy-factory.js.map +1 -1
- package/lib/electron-browser/menu/electron-context-menu-renderer.d.ts +15 -5
- package/lib/electron-browser/menu/electron-context-menu-renderer.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-context-menu-renderer.js +21 -14
- package/lib/electron-browser/menu/electron-context-menu-renderer.js.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +4 -16
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.js +84 -104
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.js +1 -4
- package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
- package/lib/electron-browser/menu/electron-menu-module.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-menu-module.js +5 -0
- package/lib/electron-browser/menu/electron-menu-module.js.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts +1 -0
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.js +20 -0
- package/lib/electron-browser/window/electron-secondary-window-service.js.map +1 -1
- package/lib/electron-browser/window/electron-window-service.d.ts +3 -0
- package/lib/electron-browser/window/electron-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-window-service.js +10 -1
- package/lib/electron-browser/window/electron-window-service.js.map +1 -1
- package/lib/electron-main/theia-electron-window.d.ts.map +1 -1
- package/lib/electron-main/theia-electron-window.js +2 -0
- package/lib/electron-main/theia-electron-window.js.map +1 -1
- package/package.json +7 -8
- package/src/browser/common-frontend-contribution.ts +14 -14
- package/src/browser/context-menu-renderer.ts +33 -5
- package/src/browser/frontend-application-module.ts +1 -7
- package/src/browser/hover-service.ts +7 -0
- package/src/browser/menu/action-menu-node.ts +128 -0
- package/src/browser/menu/browser-context-menu-renderer.ts +18 -11
- package/src/browser/menu/browser-menu-module.ts +4 -0
- package/src/browser/menu/browser-menu-node-factory.ts +48 -0
- package/src/browser/menu/browser-menu-plugin.ts +80 -168
- package/src/browser/menu/composite-menu-node.ts +140 -0
- package/src/{common → browser}/menu/menu.spec.ts +47 -15
- package/src/browser/open-with-service.ts +1 -1
- package/src/browser/saveable-service.ts +6 -1
- package/src/browser/shell/application-shell.ts +91 -29
- package/src/browser/shell/index.ts +1 -0
- package/src/browser/shell/sidebar-bottom-menu-widget.tsx +2 -1
- package/src/browser/shell/sidebar-menu-widget.tsx +12 -2
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.tsx +239 -0
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +59 -102
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.ts +14 -23
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.ts +14 -14
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.tsx +34 -261
- package/src/browser/shell/tab-bar-toolbar/tab-toolbar-item.tsx +251 -0
- package/src/browser/shell/tab-bars.ts +2 -1
- package/src/browser/shell/theia-dock-panel.ts +10 -91
- package/src/browser/shell/theia-split-panel.ts +56 -0
- package/src/browser/style/hover-service.css +6 -1
- package/src/browser/style/index.css +3 -11
- package/src/browser/style/view-container.css +17 -31
- package/src/browser/tree/tree-widget.tsx +7 -0
- package/src/browser/view-container.ts +51 -30
- package/src/browser/window/default-secondary-window-service.ts +4 -0
- package/src/common/listener.spec.ts +315 -0
- package/src/common/listener.ts +88 -0
- package/src/common/menu/index.ts +2 -3
- package/src/common/menu/menu-model-registry.ts +187 -230
- package/src/common/menu/menu-types.ts +82 -128
- package/src/common/messaging/proxy-factory.ts +4 -1
- package/src/electron-browser/menu/electron-context-menu-renderer.ts +29 -13
- package/src/electron-browser/menu/electron-main-menu-factory.ts +92 -116
- package/src/electron-browser/menu/electron-menu-contribution.ts +1 -4
- package/src/electron-browser/menu/electron-menu-module.ts +6 -1
- package/src/electron-browser/window/electron-secondary-window-service.ts +22 -0
- package/src/electron-browser/window/electron-window-service.ts +11 -1
- package/src/electron-main/theia-electron-window.ts +2 -0
- package/lib/common/menu/action-menu-node.d.ts +0 -20
- package/lib/common/menu/action-menu-node.d.ts.map +0 -1
- package/lib/common/menu/action-menu-node.js +0 -57
- package/lib/common/menu/action-menu-node.js.map +0 -1
- package/lib/common/menu/composite-menu-node.d.ts +0 -47
- package/lib/common/menu/composite-menu-node.d.ts.map +0 -1
- package/lib/common/menu/composite-menu-node.js +0 -96
- package/lib/common/menu/composite-menu-node.js.map +0 -1
- package/lib/common/menu/composite-menu-node.spec.d.ts +0 -2
- package/lib/common/menu/composite-menu-node.spec.d.ts.map +0 -1
- package/lib/common/menu/composite-menu-node.spec.js +0 -68
- package/lib/common/menu/composite-menu-node.spec.js.map +0 -1
- package/lib/common/menu/menu-adapter.d.ts +0 -36
- package/lib/common/menu/menu-adapter.d.ts.map +0 -1
- package/lib/common/menu/menu-adapter.js +0 -93
- package/lib/common/menu/menu-adapter.js.map +0 -1
- package/lib/common/menu/menu.spec.d.ts.map +0 -1
- package/lib/common/menu/menu.spec.js.map +0 -1
- package/lib/common/test/mock-menu.d.ts +0 -8
- package/lib/common/test/mock-menu.d.ts.map +0 -1
- package/lib/common/test/mock-menu.js +0 -35
- package/lib/common/test/mock-menu.js.map +0 -1
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.ts +0 -31
- package/src/common/menu/action-menu-node.ts +0 -65
- package/src/common/menu/composite-menu-node.spec.ts +0 -67
- package/src/common/menu/composite-menu-node.ts +0 -116
- package/src/common/menu/menu-adapter.ts +0 -103
- package/src/common/test/mock-menu.ts +0 -35
- /package/lib/{common → browser}/menu/menu.spec.d.ts +0 -0
|
@@ -16,14 +16,16 @@
|
|
|
16
16
|
|
|
17
17
|
import { inject, injectable, postConstruct } from 'inversify';
|
|
18
18
|
import * as React from 'react';
|
|
19
|
-
import { ContextKeyService
|
|
20
|
-
import { CommandRegistry, Disposable, DisposableCollection,
|
|
19
|
+
import { ContextKeyService } from '../../context-key-service';
|
|
20
|
+
import { CommandRegistry, Disposable, DisposableCollection, nls } from '../../../common';
|
|
21
21
|
import { Anchor, ContextMenuAccess, ContextMenuRenderer } from '../../context-menu-renderer';
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
22
|
+
import { LabelParser } from '../../label-parser';
|
|
23
|
+
import { codicon, ReactWidget, Widget } from '../../widgets';
|
|
24
24
|
import { TabBarToolbarRegistry } from './tab-bar-toolbar-registry';
|
|
25
|
-
import {
|
|
25
|
+
import { TabBarDelegator, TabBarToolbarAction } from './tab-bar-toolbar-types';
|
|
26
26
|
import { KeybindingRegistry } from '../..//keybinding';
|
|
27
|
+
import { TabBarToolbarItem } from './tab-toolbar-item';
|
|
28
|
+
import { GroupImpl, MenuModelRegistry } from '../../../common/menu';
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
* Factory for instantiating tab-bar toolbars.
|
|
@@ -33,10 +35,10 @@ export interface TabBarToolbarFactory {
|
|
|
33
35
|
(): TabBarToolbar;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
export function toAnchor(event: React.MouseEvent): Anchor {
|
|
39
|
+
const itemBox = event.currentTarget.closest('.' + TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM)?.getBoundingClientRect();
|
|
40
|
+
return itemBox ? { y: itemBox.bottom, x: itemBox.left } : event.nativeEvent;
|
|
41
|
+
}
|
|
40
42
|
|
|
41
43
|
/**
|
|
42
44
|
* Tab-bar toolbar widget representing the active [tab-bar toolbar items](TabBarToolbarItem).
|
|
@@ -45,7 +47,7 @@ const NO_ICON_CLASS = 'no-icon';
|
|
|
45
47
|
export class TabBarToolbar extends ReactWidget {
|
|
46
48
|
|
|
47
49
|
protected current: Widget | undefined;
|
|
48
|
-
protected inline = new Map<string, TabBarToolbarItem
|
|
50
|
+
protected inline = new Map<string, TabBarToolbarItem>();
|
|
49
51
|
protected more = new Map<string, TabBarToolbarItem>();
|
|
50
52
|
|
|
51
53
|
protected contextKeyListener: Disposable | undefined;
|
|
@@ -56,7 +58,6 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
56
58
|
@inject(CommandRegistry) protected readonly commands: CommandRegistry;
|
|
57
59
|
@inject(LabelParser) protected readonly labelParser: LabelParser;
|
|
58
60
|
@inject(MenuModelRegistry) protected readonly menus: MenuModelRegistry;
|
|
59
|
-
@inject(MenuCommandExecutor) protected readonly menuCommandExecutor: MenuCommandExecutor;
|
|
60
61
|
@inject(ContextMenuRenderer) protected readonly contextMenuRenderer: ContextMenuRenderer;
|
|
61
62
|
@inject(TabBarToolbarRegistry) protected readonly toolbarRegistry: TabBarToolbarRegistry;
|
|
62
63
|
@inject(ContextKeyService) protected readonly contextKeyService: ContextKeyService;
|
|
@@ -79,34 +80,25 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
79
80
|
}));
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
updateItems(items: Array<TabBarToolbarItem
|
|
83
|
+
updateItems(items: Array<TabBarToolbarItem>, current: Widget | undefined): void {
|
|
83
84
|
this.toDisposeOnUpdateItems.dispose();
|
|
84
85
|
this.toDisposeOnUpdateItems = new DisposableCollection();
|
|
85
86
|
this.inline.clear();
|
|
86
87
|
this.more.clear();
|
|
87
88
|
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
if (item.
|
|
91
|
-
this.commands.getAllHandlers(item.command).forEach(handler => {
|
|
92
|
-
if (handler.onDidChangeEnabled) {
|
|
93
|
-
this.toDisposeOnUpdateItems.push(handler.onDidChangeEnabled(() => this.maybeUpdate()));
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
if ('render' in item || item.group === undefined || item.group === 'navigation') {
|
|
89
|
+
for (const item of items.sort(TabBarToolbarAction.PRIORITY_COMPARATOR).reverse()) {
|
|
90
|
+
|
|
91
|
+
if (!('toMenuNode' in item) || item.group === undefined || item.group === 'navigation') {
|
|
98
92
|
this.inline.set(item.id, item);
|
|
99
93
|
} else {
|
|
100
94
|
this.more.set(item.id, item);
|
|
101
95
|
}
|
|
102
96
|
|
|
103
|
-
if (item.
|
|
104
|
-
this.
|
|
97
|
+
if (item.onDidChange) {
|
|
98
|
+
this.toDisposeOnUpdateItems.push(item.onDidChange(() => this.maybeUpdate()));
|
|
105
99
|
}
|
|
106
100
|
}
|
|
107
101
|
|
|
108
|
-
this.updateContextKeyListener(contextKeys);
|
|
109
|
-
|
|
110
102
|
this.setCurrent(current);
|
|
111
103
|
if (items.length) {
|
|
112
104
|
this.show();
|
|
@@ -139,124 +131,14 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
139
131
|
}
|
|
140
132
|
}
|
|
141
133
|
|
|
142
|
-
protected updateContextKeyListener(contextKeys: Set<string>): void {
|
|
143
|
-
this.contextKeyListener?.dispose();
|
|
144
|
-
if (contextKeys.size > 0) {
|
|
145
|
-
this.contextKeyListener = this.contextKeyService.onDidChange(event => {
|
|
146
|
-
if (event.affects(contextKeys)) {
|
|
147
|
-
this.maybeUpdate();
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
134
|
protected render(): React.ReactNode {
|
|
154
135
|
this.keybindingContextKeys.clear();
|
|
155
136
|
return <React.Fragment>
|
|
156
137
|
{this.renderMore()}
|
|
157
|
-
{[...this.inline.values()].map(item =>
|
|
158
|
-
if (ReactTabBarToolbarItem.is(item)) {
|
|
159
|
-
return item.render(this.current);
|
|
160
|
-
} else {
|
|
161
|
-
return (item.menuPath && this.toolbarRegistry.isNonEmptyMenu(item, this.current) ? this.renderMenuItem(item) : this.renderItem(item));
|
|
162
|
-
}
|
|
163
|
-
})}
|
|
138
|
+
{[...this.inline.values()].map(item => item.render(this.current))}
|
|
164
139
|
</React.Fragment>;
|
|
165
140
|
}
|
|
166
141
|
|
|
167
|
-
protected resolveKeybindingForCommand(command: string | undefined): string {
|
|
168
|
-
let result = '';
|
|
169
|
-
if (command) {
|
|
170
|
-
const bindings = this.keybindings.getKeybindingsForCommand(command);
|
|
171
|
-
let found = false;
|
|
172
|
-
if (bindings && bindings.length > 0) {
|
|
173
|
-
bindings.forEach(binding => {
|
|
174
|
-
if (binding.when) {
|
|
175
|
-
this.contextKeyService.parseKeys(binding.when)?.forEach(key => this.keybindingContextKeys.add(key));
|
|
176
|
-
}
|
|
177
|
-
if (!found && this.keybindings.isEnabledInScope(binding, this.current?.node)) {
|
|
178
|
-
found = true;
|
|
179
|
-
result = ` (${this.keybindings.acceleratorFor(binding, '+')})`;
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return result;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
protected renderItem(item: RenderedToolbarItem): React.ReactNode {
|
|
188
|
-
let innerText = '';
|
|
189
|
-
const classNames = [];
|
|
190
|
-
const command = item.command ? this.commands.getCommand(item.command) : undefined;
|
|
191
|
-
// Fall back to the item ID in extremis so there is _something_ to render in the
|
|
192
|
-
// case that there is neither an icon nor a title
|
|
193
|
-
const itemText = item.text || command?.label || command?.id || item.id;
|
|
194
|
-
if (itemText) {
|
|
195
|
-
for (const labelPart of this.labelParser.parse(itemText)) {
|
|
196
|
-
if (LabelIcon.is(labelPart)) {
|
|
197
|
-
const className = `fa fa-${labelPart.name}${labelPart.animation ? ' fa-' + labelPart.animation : ''}`;
|
|
198
|
-
classNames.push(...className.split(' '));
|
|
199
|
-
} else {
|
|
200
|
-
innerText = labelPart;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
const iconClass = (typeof item.icon === 'function' && item.icon()) || item.icon as string || (command && command.iconClass);
|
|
205
|
-
if (iconClass) {
|
|
206
|
-
classNames.push(iconClass);
|
|
207
|
-
}
|
|
208
|
-
const tooltipText = item.tooltip || (command && command.label) || '';
|
|
209
|
-
const tooltip = `${this.labelParser.stripIcons(tooltipText)}${this.resolveKeybindingForCommand(command?.id)}`;
|
|
210
|
-
|
|
211
|
-
// Only present text if there is no icon
|
|
212
|
-
if (classNames.length) {
|
|
213
|
-
innerText = '';
|
|
214
|
-
} else if (innerText) {
|
|
215
|
-
// Make room for the label text
|
|
216
|
-
classNames.push(NO_ICON_CLASS);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// In any case, this is an action item, with or without icon.
|
|
220
|
-
classNames.push(ACTION_ITEM);
|
|
221
|
-
|
|
222
|
-
const toolbarItemClassNames = this.getToolbarItemClassNames(item);
|
|
223
|
-
return <div key={item.id}
|
|
224
|
-
className={toolbarItemClassNames.join(' ')}
|
|
225
|
-
onMouseDown={this.onMouseDownEvent}
|
|
226
|
-
onMouseUp={this.onMouseUpEvent}
|
|
227
|
-
onMouseOut={this.onMouseUpEvent} >
|
|
228
|
-
<div id={item.id} className={classNames.join(' ')}
|
|
229
|
-
onClick={e => this.executeCommand(e, item)}
|
|
230
|
-
title={tooltip}>{innerText}
|
|
231
|
-
</div>
|
|
232
|
-
</div>;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
protected isEnabled(item: TabBarToolbarItem): boolean {
|
|
236
|
-
if (!!item.command) {
|
|
237
|
-
return this.commandIsEnabled(item.command) && this.evaluateWhenClause(item.when);
|
|
238
|
-
} else {
|
|
239
|
-
return !!item.menuPath;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
protected getToolbarItemClassNames(item: TabBarToolbarItem): string[] {
|
|
244
|
-
const classNames = [TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM];
|
|
245
|
-
if (item.command) {
|
|
246
|
-
if (this.isEnabled(item)) {
|
|
247
|
-
classNames.push('enabled');
|
|
248
|
-
}
|
|
249
|
-
if (this.commandIsToggled(item.command)) {
|
|
250
|
-
classNames.push('toggled');
|
|
251
|
-
}
|
|
252
|
-
} else {
|
|
253
|
-
if (this.isEnabled(item)) {
|
|
254
|
-
classNames.push('enabled');
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return classNames;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
142
|
protected renderMore(): React.ReactNode {
|
|
261
143
|
return !!this.more.size && <div key='__more__' className={TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM + ' enabled'}>
|
|
262
144
|
<div id='__more__' className={codicon('ellipsis', true)} onClick={this.showMoreContextMenu}
|
|
@@ -267,116 +149,35 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
267
149
|
protected showMoreContextMenu = (event: React.MouseEvent) => {
|
|
268
150
|
event.stopPropagation();
|
|
269
151
|
event.preventDefault();
|
|
270
|
-
const anchor =
|
|
152
|
+
const anchor = toAnchor(event);
|
|
271
153
|
this.renderMoreContextMenu(anchor);
|
|
272
154
|
};
|
|
273
155
|
|
|
274
|
-
|
|
275
|
-
const itemBox = event.currentTarget.closest('.' + TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM)?.getBoundingClientRect();
|
|
276
|
-
return itemBox ? { y: itemBox.bottom, x: itemBox.left } : event.nativeEvent;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
renderMoreContextMenu(anchor: Anchor, subpath?: MenuPath): ContextMenuAccess {
|
|
156
|
+
renderMoreContextMenu(anchor: Anchor): ContextMenuAccess {
|
|
280
157
|
const toDisposeOnHide = new DisposableCollection();
|
|
281
158
|
this.addClass('menu-open');
|
|
282
159
|
toDisposeOnHide.push(Disposable.create(() => this.removeClass('menu-open')));
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
const paths: string[] = [];
|
|
294
|
-
for (let i = 0; i < split.length - 1; i += 2) {
|
|
295
|
-
paths.push(split[i], split[i + 1]);
|
|
296
|
-
toDisposeOnHide.push(this.menus.registerSubmenu([...TAB_BAR_TOOLBAR_CONTEXT_MENU, ...paths], split[i + 1], { order: item.order }));
|
|
297
|
-
}
|
|
160
|
+
|
|
161
|
+
const menu = new GroupImpl('contextMenu');
|
|
162
|
+
for (const item of this.more.values()) {
|
|
163
|
+
if (item.toMenuNode) {
|
|
164
|
+
const node = item.toMenuNode();
|
|
165
|
+
if (node) {
|
|
166
|
+
if (item.group) {
|
|
167
|
+
menu.getOrCreate([item.group], 0, 1).addNode(node);
|
|
168
|
+
} else {
|
|
169
|
+
menu.addNode(node);
|
|
298
170
|
}
|
|
299
|
-
toDisposeOnHide.push(this.menus.registerMenuAction([...TAB_BAR_TOOLBAR_CONTEXT_MENU, ...item.group!.split('/')], {
|
|
300
|
-
label: (item as RenderedToolbarItem).tooltip,
|
|
301
|
-
commandId: item.command,
|
|
302
|
-
when: item.when,
|
|
303
|
-
order: item.order
|
|
304
|
-
}));
|
|
305
171
|
}
|
|
306
172
|
}
|
|
307
173
|
}
|
|
308
174
|
return this.contextMenuRenderer.render({
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
anchor,
|
|
312
|
-
context: this.current?.node || this.node,
|
|
313
|
-
onHide: () => toDisposeOnHide.dispose(),
|
|
314
|
-
skipSingleRootNode: true,
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* Renders a toolbar item that is a menu, presenting it as a button with a little
|
|
320
|
-
* chevron decoration that pops up a floating menu when clicked.
|
|
321
|
-
*
|
|
322
|
-
* @param item a toolbar item that is a menu item
|
|
323
|
-
* @returns the rendered toolbar item
|
|
324
|
-
*/
|
|
325
|
-
protected renderMenuItem(item: RenderedToolbarItem): React.ReactNode {
|
|
326
|
-
const command = item.command ? this.commands.getCommand(item.command) : undefined;
|
|
327
|
-
const icon = (typeof item.icon === 'function' && item.icon()) || item.icon as string || (command && command.iconClass) || 'ellipsis';
|
|
328
|
-
|
|
329
|
-
let contextMatcher: ContextMatcher = this.contextKeyService;
|
|
330
|
-
if (item.contextKeyOverlays) {
|
|
331
|
-
contextMatcher = this.contextKeyService.createOverlay(Object.keys(item.contextKeyOverlays).map(key => [key, item.contextKeyOverlays![key]]));
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
return <div key={item.id}
|
|
335
|
-
className={TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM + ' enabled menu'}
|
|
336
|
-
>
|
|
337
|
-
<div className={codicon(icon, true)}
|
|
338
|
-
title={item.text}
|
|
339
|
-
onClick={e => this.executeCommand(e, item)}
|
|
340
|
-
/>
|
|
341
|
-
<div className={ACTION_ITEM} onClick={event => this.showPopupMenu(item.menuPath!, event, contextMatcher)}>
|
|
342
|
-
<div className={codicon('chevron-down') + ' chevron'} />
|
|
343
|
-
</div>
|
|
344
|
-
|
|
345
|
-
</div >;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Presents the menu to popup on the `event` that is the clicking of
|
|
350
|
-
* a menu toolbar item.
|
|
351
|
-
*
|
|
352
|
-
* @param menuPath the path of the registered menu to show
|
|
353
|
-
* @param event the mouse event triggering the menu
|
|
354
|
-
*/
|
|
355
|
-
protected showPopupMenu = (menuPath: MenuPath, event: React.MouseEvent, contextMatcher: ContextMatcher) => {
|
|
356
|
-
event.stopPropagation();
|
|
357
|
-
event.preventDefault();
|
|
358
|
-
const anchor = this.toAnchor(event);
|
|
359
|
-
this.renderPopupMenu(menuPath, anchor, contextMatcher);
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Renders the menu popped up on a menu toolbar item.
|
|
364
|
-
*
|
|
365
|
-
* @param menuPath the path of the registered menu to render
|
|
366
|
-
* @param anchor a description of where to render the menu
|
|
367
|
-
* @returns platform-specific access to the rendered context menu
|
|
368
|
-
*/
|
|
369
|
-
protected renderPopupMenu(menuPath: MenuPath, anchor: Anchor, contextMatcher: ContextMatcher): ContextMenuAccess {
|
|
370
|
-
const toDisposeOnHide = new DisposableCollection();
|
|
371
|
-
this.addClass('menu-open');
|
|
372
|
-
toDisposeOnHide.push(Disposable.create(() => this.removeClass('menu-open')));
|
|
373
|
-
|
|
374
|
-
return this.contextMenuRenderer.render({
|
|
375
|
-
menuPath,
|
|
175
|
+
menu: MenuModelRegistry.removeSingleRootNodes(menu),
|
|
176
|
+
menuPath: ['contextMenu'],
|
|
376
177
|
args: [this.current],
|
|
377
178
|
anchor,
|
|
378
179
|
context: this.current?.node || this.node,
|
|
379
|
-
contextKeyService:
|
|
180
|
+
contextKeyService: this.contextKeyService,
|
|
380
181
|
onHide: () => toDisposeOnHide.dispose()
|
|
381
182
|
});
|
|
382
183
|
}
|
|
@@ -397,39 +198,11 @@ export class TabBarToolbar extends ReactWidget {
|
|
|
397
198
|
return whenClause ? this.contextKeyService.match(whenClause, this.current?.node) : true;
|
|
398
199
|
}
|
|
399
200
|
|
|
400
|
-
protected executeCommand(e: React.MouseEvent<HTMLElement>, item: TabBarToolbarItem): void {
|
|
401
|
-
e.preventDefault();
|
|
402
|
-
e.stopPropagation();
|
|
403
|
-
|
|
404
|
-
if (!item || !this.isEnabled(item)) {
|
|
405
|
-
return;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (item.command && item.delegateMenuPath) {
|
|
409
|
-
this.menuCommandExecutor.executeCommand(item.delegateMenuPath, item.command, this.current);
|
|
410
|
-
} else if (item.command) {
|
|
411
|
-
this.commands.executeCommand(item.command, this.current);
|
|
412
|
-
} else if (item.menuPath) {
|
|
413
|
-
this.renderMoreContextMenu(this.toAnchor(e), item.menuPath);
|
|
414
|
-
}
|
|
415
|
-
this.maybeUpdate();
|
|
416
|
-
};
|
|
417
|
-
|
|
418
201
|
protected maybeUpdate(): void {
|
|
419
202
|
if (!this.isDisposed) {
|
|
420
203
|
this.update();
|
|
421
204
|
}
|
|
422
205
|
}
|
|
423
|
-
|
|
424
|
-
protected onMouseDownEvent = (e: React.MouseEvent<HTMLElement>) => {
|
|
425
|
-
if (e.button === 0) {
|
|
426
|
-
e.currentTarget.classList.add('active');
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
protected onMouseUpEvent = (e: React.MouseEvent<HTMLElement>) => {
|
|
431
|
-
e.currentTarget.classList.remove('active');
|
|
432
|
-
};
|
|
433
206
|
}
|
|
434
207
|
|
|
435
208
|
export namespace TabBarToolbar {
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 STMicroelectronics and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { ContextKeyService } from '../../context-key-service';
|
|
18
|
+
import { ReactTabBarToolbarAction, RenderedToolbarAction, TabBarToolbarActionBase } from './tab-bar-toolbar-types';
|
|
19
|
+
import { Widget } from '@lumino/widgets';
|
|
20
|
+
import { LabelIcon, LabelParser } from '../../label-parser';
|
|
21
|
+
import { CommandRegistry, Event, Disposable, Emitter, DisposableCollection } from '../../../common';
|
|
22
|
+
import { KeybindingRegistry } from '../../keybinding';
|
|
23
|
+
import { ACTION_ITEM } from '../../widgets';
|
|
24
|
+
import { TabBarToolbar } from './tab-bar-toolbar';
|
|
25
|
+
import * as React from 'react';
|
|
26
|
+
import { ActionMenuNode, GroupImpl, MenuNode } from '../../../common/menu';
|
|
27
|
+
|
|
28
|
+
export interface TabBarToolbarItem {
|
|
29
|
+
id: string;
|
|
30
|
+
isVisible(widget: Widget): boolean;
|
|
31
|
+
isEnabled(widget?: Widget): boolean;
|
|
32
|
+
isToggled(): boolean;
|
|
33
|
+
render(widget?: Widget): React.ReactNode;
|
|
34
|
+
onDidChange?: Event<void>;
|
|
35
|
+
group?: string;
|
|
36
|
+
priority?: number;
|
|
37
|
+
toMenuNode?(): MenuNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Class name indicating rendering of a toolbar item without an icon but instead with a text label.
|
|
42
|
+
*/
|
|
43
|
+
const NO_ICON_CLASS = 'no-icon';
|
|
44
|
+
|
|
45
|
+
class AbstractToolbarItemImpl<T extends TabBarToolbarActionBase> {
|
|
46
|
+
constructor(
|
|
47
|
+
protected readonly commandRegistry: CommandRegistry,
|
|
48
|
+
protected readonly contextKeyService: ContextKeyService,
|
|
49
|
+
protected readonly action: T) {
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get id(): string {
|
|
53
|
+
return this.action.id;
|
|
54
|
+
}
|
|
55
|
+
get group(): string | undefined {
|
|
56
|
+
return this.action.group;
|
|
57
|
+
}
|
|
58
|
+
get priority(): number | undefined {
|
|
59
|
+
return this.action.priority;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get onDidChange(): Event<void> | undefined {
|
|
63
|
+
return this.action.onDidChange;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
isVisible(widget: Widget): boolean {
|
|
67
|
+
if (this.action.isVisible) {
|
|
68
|
+
return this.action.isVisible(widget);
|
|
69
|
+
}
|
|
70
|
+
const actionVisible = !this.action.command || this.commandRegistry.isVisible(this.action.command, widget);
|
|
71
|
+
const contextMatches = !this.action.when || this.contextKeyService.match(this.action.when);
|
|
72
|
+
|
|
73
|
+
return actionVisible && contextMatches;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
isEnabled(widget?: Widget): boolean {
|
|
77
|
+
return this.action.command ? this.commandRegistry.isEnabled(this.action.command, widget) : !!this.action.menuPath;
|
|
78
|
+
}
|
|
79
|
+
isToggled(): boolean {
|
|
80
|
+
return this.action.command ? this.commandRegistry.isToggled(this.action.command) : true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class RenderedToolbarItemImpl extends AbstractToolbarItemImpl<RenderedToolbarAction> implements TabBarToolbarItem {
|
|
85
|
+
protected contextKeyListener: Disposable | undefined;
|
|
86
|
+
protected disposables = new DisposableCollection();
|
|
87
|
+
|
|
88
|
+
constructor(
|
|
89
|
+
commandRegistry: CommandRegistry,
|
|
90
|
+
contextKeyService: ContextKeyService,
|
|
91
|
+
protected readonly keybindingRegistry: KeybindingRegistry,
|
|
92
|
+
protected readonly labelParser: LabelParser,
|
|
93
|
+
action: RenderedToolbarAction) {
|
|
94
|
+
super(commandRegistry, contextKeyService, action);
|
|
95
|
+
if (action.onDidChange) {
|
|
96
|
+
this.disposables.push(action.onDidChange(() => this.onDidChangeEmitter.fire()));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
dispose(): void {
|
|
101
|
+
this.disposables.dispose();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
updateContextKeyListener(when: string): void {
|
|
105
|
+
const contextKeys = new Set<string>();
|
|
106
|
+
this.contextKeyService.parseKeys(when)?.forEach(key => contextKeys.add(key));
|
|
107
|
+
if (contextKeys.size > 0) {
|
|
108
|
+
this.contextKeyListener = this.contextKeyService.onDidChange(change => {
|
|
109
|
+
if (change.affects(contextKeys)) {
|
|
110
|
+
this.onDidChangeEmitter.fire();
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
render(widget?: Widget | undefined): React.ReactNode {
|
|
117
|
+
return this.renderItem(widget);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected getToolbarItemClassNames(widget?: Widget): string[] {
|
|
121
|
+
const classNames = [TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM];
|
|
122
|
+
if (this.isEnabled(widget)) {
|
|
123
|
+
classNames.push('enabled');
|
|
124
|
+
}
|
|
125
|
+
if (this.isToggled()) {
|
|
126
|
+
classNames.push('toggled');
|
|
127
|
+
}
|
|
128
|
+
return classNames;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
protected resolveKeybindingForCommand(widget: Widget | undefined, command: string | undefined): string {
|
|
132
|
+
let result = '';
|
|
133
|
+
if (this.action.command) {
|
|
134
|
+
const bindings = this.keybindingRegistry.getKeybindingsForCommand(this.action.command);
|
|
135
|
+
let found = false;
|
|
136
|
+
if (bindings && bindings.length > 0) {
|
|
137
|
+
bindings.forEach(binding => {
|
|
138
|
+
if (binding.when) {
|
|
139
|
+
this.updateContextKeyListener(binding.when);
|
|
140
|
+
}
|
|
141
|
+
if (!found && this.keybindingRegistry.isEnabledInScope(binding, widget?.node)) {
|
|
142
|
+
found = true;
|
|
143
|
+
result = ` (${this.keybindingRegistry.acceleratorFor(binding, '+')})`;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
protected readonly onDidChangeEmitter = new Emitter<void>;
|
|
152
|
+
override get onDidChange(): Event<void> | undefined {
|
|
153
|
+
return this.onDidChangeEmitter.event;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
toMenuNode?(): MenuNode {
|
|
157
|
+
const action = new ActionMenuNode({
|
|
158
|
+
label: this.action.tooltip,
|
|
159
|
+
commandId: this.action.command!,
|
|
160
|
+
when: this.action.when,
|
|
161
|
+
order: this.action.order
|
|
162
|
+
}, this.commandRegistry, this.keybindingRegistry, this.contextKeyService);
|
|
163
|
+
|
|
164
|
+
// Register a submenu for the item, if the group is in format `<submenu group>/<submenu name>/.../<item group>`
|
|
165
|
+
const menuPath = this.action.group?.split('/') || [];
|
|
166
|
+
if (menuPath.length > 1) {
|
|
167
|
+
let menu = new GroupImpl(menuPath[0], this.action.order);
|
|
168
|
+
menu = menu.getOrCreate(menuPath, 1, menuPath.length);
|
|
169
|
+
menu.addNode(action);
|
|
170
|
+
return menu;
|
|
171
|
+
}
|
|
172
|
+
return action;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
protected onMouseDownEvent = (e: React.MouseEvent<HTMLElement>) => {
|
|
176
|
+
if (e.button === 0) {
|
|
177
|
+
e.currentTarget.classList.add('active');
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
protected onMouseUpEvent = (e: React.MouseEvent<HTMLElement>) => {
|
|
182
|
+
e.currentTarget.classList.remove('active');
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
protected executeCommand(e: React.MouseEvent<HTMLElement>, widget?: Widget): void {
|
|
186
|
+
e.preventDefault();
|
|
187
|
+
e.stopPropagation();
|
|
188
|
+
|
|
189
|
+
if (!this.isEnabled(widget)) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (this.action.command) {
|
|
194
|
+
this.commandRegistry.executeCommand(this.action.command, widget);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
protected renderItem(widget?: Widget): React.ReactNode {
|
|
199
|
+
let innerText = '';
|
|
200
|
+
const classNames = [];
|
|
201
|
+
const command = this.action.command ? this.commandRegistry.getCommand(this.action.command) : undefined;
|
|
202
|
+
// Fall back to the item ID in extremis so there is _something_ to render in the
|
|
203
|
+
// case that there is neither an icon nor a title
|
|
204
|
+
const itemText = this.action.text || command?.label || command?.id || this.action.id;
|
|
205
|
+
if (itemText) {
|
|
206
|
+
for (const labelPart of this.labelParser.parse(itemText)) {
|
|
207
|
+
if (LabelIcon.is(labelPart)) {
|
|
208
|
+
const className = `fa fa-${labelPart.name}${labelPart.animation ? ' fa-' + labelPart.animation : ''}`;
|
|
209
|
+
classNames.push(...className.split(' '));
|
|
210
|
+
} else {
|
|
211
|
+
innerText = labelPart;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const iconClass = (typeof this.action.icon === 'function' && this.action.icon()) || this.action.icon as string || (command && command.iconClass);
|
|
216
|
+
if (iconClass) {
|
|
217
|
+
classNames.push(iconClass);
|
|
218
|
+
}
|
|
219
|
+
const tooltipText = this.action.tooltip || (command && command.label) || '';
|
|
220
|
+
const tooltip = `${this.labelParser.stripIcons(tooltipText)}${this.resolveKeybindingForCommand(widget, command?.id)}`;
|
|
221
|
+
|
|
222
|
+
// Only present text if there is no icon
|
|
223
|
+
if (classNames.length) {
|
|
224
|
+
innerText = '';
|
|
225
|
+
} else if (innerText) {
|
|
226
|
+
// Make room for the label text
|
|
227
|
+
classNames.push(NO_ICON_CLASS);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// In any case, this is an action item, with or without icon.
|
|
231
|
+
classNames.push(ACTION_ITEM);
|
|
232
|
+
|
|
233
|
+
const toolbarItemClassNames = this.getToolbarItemClassNames(widget);
|
|
234
|
+
return <div key={this.action.id}
|
|
235
|
+
className={toolbarItemClassNames.join(' ')}
|
|
236
|
+
onMouseDown={this.onMouseDownEvent}
|
|
237
|
+
onMouseUp={this.onMouseUpEvent}
|
|
238
|
+
onMouseOut={this.onMouseUpEvent} >
|
|
239
|
+
<div id={this.action.id} className={classNames.join(' ')}
|
|
240
|
+
onClick={e => this.executeCommand(e, widget)}
|
|
241
|
+
title={tooltip} > {innerText}
|
|
242
|
+
</div>
|
|
243
|
+
</div>;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export class ReactToolbarItemImpl extends AbstractToolbarItemImpl<ReactTabBarToolbarAction> implements TabBarToolbarItem {
|
|
248
|
+
render(widget?: Widget | undefined): React.ReactNode {
|
|
249
|
+
return this.action.render(widget);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -958,6 +958,7 @@ export class ToolbarAwareTabBar extends ScrollableTabBar {
|
|
|
958
958
|
this.node.appendChild(this.breadcrumbsContainer);
|
|
959
959
|
|
|
960
960
|
this.toolbar = this.tabBarToolbarFactory();
|
|
961
|
+
this.toDispose.push(this.toolbar);
|
|
961
962
|
this.toDispose.push(this.tabBarToolbarRegistry.onDidChange(() => this.update()));
|
|
962
963
|
this.toDispose.push(this.breadcrumbsRenderer);
|
|
963
964
|
|
|
@@ -1009,7 +1010,7 @@ export class ToolbarAwareTabBar extends ScrollableTabBar {
|
|
|
1009
1010
|
|
|
1010
1011
|
protected override onBeforeDetach(msg: Message): void {
|
|
1011
1012
|
if (this.toolbar && this.toolbar.isAttached) {
|
|
1012
|
-
this.toolbar
|
|
1013
|
+
Widget.detach(this.toolbar);
|
|
1013
1014
|
}
|
|
1014
1015
|
super.onBeforeDetach(msg);
|
|
1015
1016
|
}
|