Skip to content

Commit

Permalink
[#7268] Adjust behavior of all close tab commands so that they respec…
Browse files Browse the repository at this point in the history
…t the widget.title.closable propertySigned-off-by: Vivien Jovet <vivien.jovet@gmail.com>
  • Loading branch information
Hanksha authored and Vivien Jovet committed Mar 5, 2020
1 parent 3d5e4f9 commit bcc53aa
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 14 deletions.
16 changes: 15 additions & 1 deletion examples/api-samples/src/browser/api-samples-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

import { injectable, inject } from 'inversify';
import { Command, CommandContribution, CommandRegistry, CommandHandler } from '@theia/core';
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { AbstractViewContribution, FrontendApplicationContribution } from '@theia/core/lib/browser';
import { SampleDynamicLabelProviderContribution } from './sample-dynamic-label-provider-contribution';
import { SampleView } from '@theia/api-samples/lib/browser/sample-view';

export namespace ExampleLabelProviderCommands {
const EXAMPLE_CATEGORY = 'Examples';
Expand Down Expand Up @@ -53,3 +54,16 @@ export class ExampleLabelProviderCommandHandler implements CommandHandler {
}

}

@injectable()
export class SampleViewContribution extends AbstractViewContribution<SampleView> {
constructor() {
super({
widgetId: SampleView.ID,
widgetName: 'Sample',
defaultWidgetOptions: {
area: 'main'
}
});
}
}
10 changes: 9 additions & 1 deletion examples/api-samples/src/browser/api-samples-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@
import { ContainerModule } from 'inversify';
import { CommandContribution } from '@theia/core';
import { LabelProviderContribution } from '@theia/core/lib/browser/label-provider';
import { ApiSamplesContribution } from './api-samples-contribution';
import { ApiSamplesContribution, SampleViewContribution } from './api-samples-contribution';
import { SampleDynamicLabelProviderContribution } from './sample-dynamic-label-provider-contribution';
import { bindViewContribution, WidgetFactory } from '@theia/core/lib/browser';
import { SampleView } from './sample-view';

export default new ContainerModule(bind => {
bind(CommandContribution).to(ApiSamplesContribution).inSingletonScope();

bind(SampleDynamicLabelProviderContribution).toSelf().inSingletonScope();
bind(LabelProviderContribution).toService(SampleDynamicLabelProviderContribution);
bindViewContribution(bind, SampleViewContribution);
bind(SampleView).toSelf();
bind(WidgetFactory).toDynamicValue(ctx => ({
id: SampleView.ID,
createWidget: () => ctx.container.get<SampleView>(SampleView)
}));
});
43 changes: 43 additions & 0 deletions examples/api-samples/src/browser/sample-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/********************************************************************************
* Copyright (C) 2019 Arm and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { ReactWidget } from '@theia/core/lib/browser';
import { injectable, postConstruct } from 'inversify';
import * as React from 'react';

@injectable()
export class SampleView extends ReactWidget {
static readonly ID = 'sampleView';

@postConstruct()
init(): void {
this.id = SampleView.ID;
this.title.caption = 'Sample';
this.title.label = 'Sample';
this.title.iconClass = 'fa fa-window-maximize';
this.title.closable = true;
this.update();
}

protected render(): React.ReactNode {
return (
<div>
Closeable
<input type="checkbox" defaultChecked={this.title.closable} onChange={e => this.title.closable = e.target.checked} />
</div>
);
}
}
41 changes: 29 additions & 12 deletions packages/core/src/browser/common-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,14 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
execute: () => this.shell.activatePreviousTab()
});
commandRegistry.registerCommand(CommonCommands.CLOSE_TAB, {
isEnabled: (event?: Event) => this.findTabBar(event) !== undefined,
isEnabled: (event?: Event) => {
const tabBar = this.findTabBar(event);
if (!tabBar) {
return false;
}
const currentTitle = this.findTitle(tabBar, event);
return currentTitle !== undefined && currentTitle.closable;
},
execute: (event?: Event) => {
const tabBar = this.findTabBar(event)!;
const currentTitle = this.findTitle(tabBar, event);
Expand All @@ -530,19 +537,23 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
commandRegistry.registerCommand(CommonCommands.CLOSE_OTHER_TABS, {
isEnabled: (event?: Event) => {
const tabBar = this.findTabBar(event);
return tabBar !== undefined && tabBar.titles.length > 1;
if (!tabBar) {
return false;
}
const currentTitle = this.findTitle(tabBar, event);
return tabBar.titles.some(title => title !== currentTitle && title.closable);
},
execute: (event?: Event) => {
const tabBar = this.findTabBar(event)!;
const currentTitle = this.findTitle(tabBar, event);
const area = this.shell.getAreaFor(tabBar)!;
this.shell.closeTabs(area, title => title !== currentTitle);
this.shell.closeTabs(area, title => title !== currentTitle && title.closable);
}
});
commandRegistry.registerCommand(CommonCommands.CLOSE_RIGHT_TABS, {
isEnabled: (event?: Event) => {
const tabBar = this.findTabBar(event);
return tabBar !== undefined && tabBar.currentIndex < tabBar.titles.length - 1;
return tabBar !== undefined && tabBar.titles.some((title, index) => index > tabBar.currentIndex && title.closable);
},
isVisible: (event?: Event) => {
const area = this.findTabArea(event);
Expand All @@ -551,32 +562,38 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
execute: (event?: Event) => {
const tabBar = this.findTabBar(event)!;
const currentIndex = tabBar.currentIndex;
this.shell.closeTabs(tabBar, (_, index) => index > currentIndex);
this.shell.closeTabs(tabBar, (title, index) => index > currentIndex && title.closable);
}
});
commandRegistry.registerCommand(CommonCommands.CLOSE_ALL_TABS, {
isEnabled: (event?: Event) => this.findTabBar(event) !== undefined,
execute: (event?: Event) => this.shell.closeTabs(this.findTabArea(event)!)
isEnabled: (event?: Event) => {
const tabBar = this.findTabBar(event);
return tabBar !== undefined && tabBar.titles.some(title => title.closable);
},
execute: (event?: Event) => this.shell.closeTabs(this.findTabArea(event)!, title => title.closable)
});
commandRegistry.registerCommand(CommonCommands.CLOSE_MAIN_TAB, {
isEnabled: () => this.shell.getCurrentWidget('main') !== undefined,
isEnabled: () => {
const currentWidget = this.shell.getCurrentWidget('main');
return currentWidget !== undefined && currentWidget.title.closable;
},
execute: () => this.shell.getCurrentWidget('main')!.close()
});
commandRegistry.registerCommand(CommonCommands.CLOSE_OTHER_MAIN_TABS, {
isEnabled: () => {
const tabBars = this.shell.mainAreaTabBars;
return tabBars.length > 1 || tabBars.length === 1 && tabBars[0].titles.length > 1;
return tabBars.length > 1 || tabBars.length === 1 && tabBars[0].titles.some(title => title.closable);
},
execute: () => {
const currentWidget = this.shell.getCurrentWidget('main');
if (currentWidget !== undefined) {
this.shell.closeTabs('main', title => title.owner !== currentWidget);
this.shell.closeTabs('main', title => title.owner !== currentWidget && title.closable);
}
}
});
commandRegistry.registerCommand(CommonCommands.CLOSE_ALL_MAIN_TABS, {
isEnabled: () => this.shell.mainAreaTabBars.find(tb => tb.titles.length > 0) !== undefined,
execute: () => this.shell.closeTabs('main')
isEnabled: () => this.shell.mainAreaTabBars.some(tb => tb.titles.some(title => title.closable)),
execute: () => this.shell.closeTabs('main', title => title.closable)
});
commandRegistry.registerCommand(CommonCommands.COLLAPSE_PANEL, {
isEnabled: (event?: Event) => ApplicationShell.isSideArea(this.findTabArea(event)),
Expand Down

0 comments on commit bcc53aa

Please sign in to comment.