Skip to content

Commit

Permalink
Add global toolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
kenneth-marut-work committed Feb 9, 2022
1 parent a552c06 commit 617f64e
Show file tree
Hide file tree
Showing 31 changed files with 2,765 additions and 30 deletions.
1 change: 1 addition & 0 deletions examples/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@theia/task": "1.22.1",
"@theia/terminal": "1.22.1",
"@theia/timeline": "1.22.1",
"@theia/toolbar": "1.22.1",
"@theia/typehierarchy": "1.22.1",
"@theia/userstorage": "1.22.1",
"@theia/variable-resolver": "1.22.1",
Expand Down
3 changes: 3 additions & 0 deletions examples/browser/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@
{
"path": "../../packages/timeline"
},
{
"path": "../../packages/toolbar"
},
{
"path": "../../packages/typehierarchy"
},
Expand Down
1 change: 1 addition & 0 deletions examples/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@theia/task": "1.22.1",
"@theia/terminal": "1.22.1",
"@theia/timeline": "1.22.1",
"@theia/toolbar": "1.22.1",
"@theia/typehierarchy": "1.22.1",
"@theia/userstorage": "1.22.1",
"@theia/variable-resolver": "1.22.1",
Expand Down
3 changes: 3 additions & 0 deletions examples/electron/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@
{
"path": "../../packages/timeline"
},
{
"path": "../../packages/toolbar"
},
{
"path": "../../packages/typehierarchy"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class QuickCommandService implements QuickAccessContribution, QuickAccess
return items;
}

private toItem(command: Command): QuickPickItem {
toItem(command: Command): QuickPickItem {
const label = (command.category) ? `${command.category}: ` + command.label! : command.label!;
const iconClasses = this.getItemIconClasses(command);
const activeElement = window.document.activeElement as HTMLElement;
Expand Down
61 changes: 32 additions & 29 deletions packages/core/src/browser/shell/application-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,25 @@ export class ApplicationShell extends Widget {
/**
* The dock panel in the main shell area. This is where editors usually go to.
*/
readonly mainPanel: TheiaDockPanel;
mainPanel: TheiaDockPanel;

/**
* The dock panel in the bottom shell area. In contrast to the main panel, the bottom panel
* can be collapsed and expanded.
*/
readonly bottomPanel: TheiaDockPanel;
bottomPanel: TheiaDockPanel;

/**
* Handler for the left side panel. The primary application views go here, such as the
* file explorer and the git view.
*/
readonly leftPanelHandler: SidePanelHandler;
leftPanelHandler: SidePanelHandler;

/**
* Handler for the right side panel. The secondary application views go here, such as the
* outline view.
*/
readonly rightPanelHandler: SidePanelHandler;
rightPanelHandler: SidePanelHandler;

/**
* General options for the application shell.
Expand All @@ -171,7 +171,7 @@ export class ApplicationShell extends Widget {
/**
* The fixed-size panel shown on top. This one usually holds the main menu.
*/
readonly topPanel: Panel;
topPanel: Panel;

/**
* The current state of the bottom panel.
Expand Down Expand Up @@ -212,42 +212,62 @@ export class ApplicationShell extends Widget {
constructor(
@inject(DockPanelRendererFactory) protected dockPanelRendererFactory: () => DockPanelRenderer,
@inject(StatusBarImpl) protected readonly statusBar: StatusBarImpl,
@inject(SidePanelHandlerFactory) sidePanelHandlerFactory: () => SidePanelHandler,
@inject(SidePanelHandlerFactory) protected readonly sidePanelHandlerFactory: () => SidePanelHandler,
@inject(SplitPositionHandler) protected splitPositionHandler: SplitPositionHandler,
@inject(FrontendApplicationStateService) protected readonly applicationStateService: FrontendApplicationStateService,
@inject(ApplicationShellOptions) @optional() options: RecursivePartial<ApplicationShell.Options> = {},
@inject(CorePreferences) protected readonly corePreferences: CorePreferences
) {
super(options as Widget.IOptions);
}

@postConstruct()
protected init(): void {
this.initializeShell();
this.initSidebarVisibleKeyContext();
this.initFocusKeyContexts();

if (!environment.electron.is()) {
this.corePreferences.ready.then(() => {
this.setTopPanelVisibility(this.corePreferences['window.menuBarVisibility']);
});
this.corePreferences.onPreferenceChanged(preference => {
if (preference.preferenceName === 'window.menuBarVisibility') {
this.setTopPanelVisibility(preference.newValue);
}
});
}
}

protected initializeShell(): void {
this.addClass(APPLICATION_SHELL_CLASS);
this.id = 'theia-app-shell';

// Merge the user-defined application options with the default options
this.options = {
bottomPanel: {
...ApplicationShell.DEFAULT_OPTIONS.bottomPanel,
...options.bottomPanel || {}
...this.options?.bottomPanel || {}
},
leftPanel: {
...ApplicationShell.DEFAULT_OPTIONS.leftPanel,
...options.leftPanel || {}
...this.options?.leftPanel || {}
},
rightPanel: {
...ApplicationShell.DEFAULT_OPTIONS.rightPanel,
...options.rightPanel || {}
...this.options?.rightPanel || {}
}
};

this.mainPanel = this.createMainPanel();
this.topPanel = this.createTopPanel();
this.bottomPanel = this.createBottomPanel();

this.leftPanelHandler = sidePanelHandlerFactory();
this.leftPanelHandler = this.sidePanelHandlerFactory();
this.leftPanelHandler.create('left', this.options.leftPanel);
this.leftPanelHandler.dockPanel.widgetAdded.connect((_, widget) => this.fireDidAddWidget(widget));
this.leftPanelHandler.dockPanel.widgetRemoved.connect((_, widget) => this.fireDidRemoveWidget(widget));

this.rightPanelHandler = sidePanelHandlerFactory();
this.rightPanelHandler = this.sidePanelHandlerFactory();
this.rightPanelHandler.create('right', this.options.rightPanel);
this.rightPanelHandler.dockPanel.widgetAdded.connect((_, widget) => this.fireDidAddWidget(widget));
this.rightPanelHandler.dockPanel.widgetRemoved.connect((_, widget) => this.fireDidRemoveWidget(widget));
Expand All @@ -258,23 +278,6 @@ export class ApplicationShell extends Widget {
this.tracker.activeChanged.connect(this.onActiveChanged, this);
}

@postConstruct()
protected init(): void {
this.initSidebarVisibleKeyContext();
this.initFocusKeyContexts();

if (!environment.electron.is()) {
this.corePreferences.ready.then(() => {
this.setTopPanelVisibility(this.corePreferences['window.menuBarVisibility']);
});
this.corePreferences.onPreferenceChanged(preference => {
if (preference.preferenceName === 'window.menuBarVisibility') {
this.setTopPanelVisibility(preference.newValue);
}
});
}
}

protected initSidebarVisibleKeyContext(): void {
const leftSideBarPanel = this.leftPanelHandler.dockPanel;
const sidebarVisibleKey = this.contextKeyService.createKey('sidebarVisible', leftSideBarPanel.isVisible);
Expand Down
10 changes: 10 additions & 0 deletions packages/toolbar/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: [
'../../configs/build.eslintrc.json'
],
parserOptions: {
tsconfigRootDir: __dirname,
project: 'tsconfig.json'
}
};
42 changes: 42 additions & 0 deletions packages/toolbar/fetch-icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (C) 2022 Ericsson 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
********************************************************************************/

const fs = require('fs');
const path = require('path');

// This script generates an JSON array of font-awesome classnames from the font-awesome.css files
const fontAwesomeCSSPath = path.resolve(__dirname, '../../node_modules/font-awesome/css/font-awesome.css');
const fontAwesomeDestination = path.resolve(__dirname, './src/browser/font-awesome.json');

const codiconCSSPath = path.resolve(__dirname, '../../node_modules/@vscode/codicons/dist/codicon.css')
const codiconDestination = path.resolve(__dirname, './src/browser/codicon.json')

const faContent = fs.readFileSync(fontAwesomeCSSPath, 'utf-8');
const regexp = /([\w,-]*):before/gm;
let faArray;
const faMatches = [];
while (faArray = regexp.exec(faContent)) {
faMatches.push(faArray[1]);
}
fs.writeFileSync(fontAwesomeDestination, JSON.stringify(faMatches));

const codiconContent = fs.readFileSync(codiconCSSPath, 'utf-8');
let codiconArray;
const codiconMatches = [];
while (codiconArray = regexp.exec(codiconContent)) {
codiconMatches.push(codiconArray[1]);
}
fs.writeFileSync(codiconDestination, JSON.stringify(codiconMatches));
50 changes: 50 additions & 0 deletions packages/toolbar/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "@theia/toolbar",
"version": "1.22.1",
"description": "Theia - Toolbar",
"keywords": [
"theia-extension"
],
"homepage": "https://github.com/eclipse-theia/theia",
"license": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0",
"repository": {
"type": "git",
"url": "https://github.com/eclipse-theia/theia.git"
},
"bugs": {
"url": "https://github.com/eclipse-theia/theia/issues"
},
"files": [
"lib",
"src"
],
"scripts": {
"build": "theiaext build",
"clean": "theiaext clean",
"compile": "theiaext compile",
"lint": "theiaext lint",
"test": "theiaext test",
"watch": "theiaext watch"
},
"dependencies": {
"@theia/core": "1.22.1",
"@theia/editor": "1.22.1",
"@theia/file-search": "1.22.1",
"@theia/filesystem": "1.22.1",
"@theia/monaco": "1.22.1",
"@theia/search-in-workspace": "1.22.1",
"@theia/userstorage": "1.22.1",
"@theia/workspace": "1.22.1",
"ajv": "^6.5.3",
"jsonc-parser": "^2.2.0",
"perfect-scrollbar": "^1.3.0"
},
"theiaExtensions": [
{
"frontend": "lib/browser/main-toolbar-frontend-module"
}
],
"publishConfig": {
"access": "public"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/********************************************************************************
* Copyright (C) 2022 Ericsson 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 * as React from '@theia/core/shared/react';
import { CommandService, Emitter } from '@theia/core';
import { injectable, inject } from '@theia/core/shared/inversify';
import { ContextMenuRenderer, KeybindingRegistry } from '@theia/core/lib/browser';
import { ReactTabBarToolbarContribution, ToolbarAlignment } from './main-toolbar-interfaces';

@injectable()
export abstract class AbstractMainToolbarContribution implements ReactTabBarToolbarContribution {
abstract id: string;
abstract column: ToolbarAlignment;
abstract priority: number;
newGroup = true;

protected didChangeEmitter = new Emitter<void>();
readonly onDidChange = this.didChangeEmitter.event;

@inject(KeybindingRegistry) protected readonly keybindingRegistry: KeybindingRegistry;
@inject(ContextMenuRenderer) protected readonly contextMenuRenderer: ContextMenuRenderer;
@inject(CommandService) protected readonly commandService: CommandService;

abstract render(): React.ReactNode;

toJSON(): { id: string; group: string } {
return { id: this.id, group: 'contributed' };
}

protected resolveKeybindingForCommand(commandID: string | undefined): string {
if (!commandID) {
return '';
}
const keybindings = this.keybindingRegistry.getKeybindingsForCommand(commandID);
if (keybindings.length > 0) {
const binding = keybindings[0];
const bindingKeySequence = this.keybindingRegistry.resolveKeybinding(binding);
const keyCode = bindingKeySequence[0];
return ` (${this.keybindingRegistry.acceleratorForKeyCode(keyCode, '+')})`;
}
return '';
}
}
Loading

0 comments on commit 617f64e

Please sign in to comment.