From 61dcbb23cbb6ae864b0a82b046370f0e20c9a0c9 Mon Sep 17 00:00:00 2001 From: Patrick Tanner Date: Mon, 17 Jan 2022 18:46:24 +0100 Subject: [PATCH] Added busy indicator to StatusBar during activation, fixes #6 --- CHANGELOG.md | 3 + Doc/Screenshots/StatusBarBusyIndicator.png | Bin 0 -> 16666 bytes README.md | 18 +++++ src/Tools/ApiTests.ts | 27 +++++++ src/UI/StatusBar.ts | 90 +++++++++++++++++++++ src/extension.ts | 20 ++++- 6 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 Doc/Screenshots/StatusBarBusyIndicator.png create mode 100644 src/UI/StatusBar.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index d0cf6df..c043180 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ Add new but unreleased features, fixes... here during development [#31](https://github.com/br-automation-com/vscode-brautomationtools/issues/31) - A new notification is shown, if a setting which requires a reload was changed. A reload can be triggered directly in the notification. [#18](https://github.com/br-automation-com/vscode-brautomationtools/issues/18) +- A StatusBar item was added which shows that the extension is currently busy. When hovering it with the mouse, a tooltip shows which tasks are currently executed. + At the moment it is only shown during activation of the extension, but in the future other events, such as running builds etc. may be added. + [#6](https://github.com/br-automation-com/vscode-brautomationtools/issues/6) ## [0.0.5] - 2022-01-16 diff --git a/Doc/Screenshots/StatusBarBusyIndicator.png b/Doc/Screenshots/StatusBarBusyIndicator.png new file mode 100644 index 0000000000000000000000000000000000000000..dd43e84615dc1a7d5ed02e544092bc9d12f41dba GIT binary patch literal 16666 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 { logHeader('Test BrLog end'); } + +async function testStatusBar(context: vscode.ExtensionContext): Promise { + logHeader('Test StatusBar start'); + // start multiple timers + const resolveIn5 = new Promise((resolve) => setTimeout(resolve, 5000)); + const resolveIn10 = new Promise((resolve) => setTimeout(resolve, 10000)); + const resolveIn15 = new Promise((resolve) => setTimeout(resolve, 15000)); + const rejectIn20 = new Promise((resolve, reject) => setTimeout(reject, 20000)); + const resolveIn25 = new Promise((resolve) => setTimeout(resolve, 25000)); + const resolveIn30 = new Promise((resolve) => setTimeout(resolve, 30000)); + // Normal busy items + statusBar.addBusyItem(resolveIn5, 'Resolve in 5 seconds'); + statusBar.addBusyItem(resolveIn10, 'Resolve in 10 seconds'); + statusBar.addBusyItem(rejectIn20, 'Reject in 20 seconds'); + // manual remove busy item + const manualRemove = statusBar.addBusyItem(resolveIn15, 'Resolve in 15 seconds, but remove after 10'); + resolveIn10.then(() => statusBar.removeBusyItem(manualRemove)); + // empty busy item coming later + resolveIn25.then(() => statusBar.addBusyItem(resolveIn30)); + logHeader('Test StatusBar end'); +} + + function logHeader(text: string): void { const separator = ''.padEnd(100, '*'); logger.info(''); diff --git a/src/UI/StatusBar.ts b/src/UI/StatusBar.ts new file mode 100644 index 0000000..792beba --- /dev/null +++ b/src/UI/StatusBar.ts @@ -0,0 +1,90 @@ +/** + * Handles notifications in the Status Bar of VS code + * Check the guidelines for dos and donts + * https://code.visualstudio.com/api/references/extension-guidelines#status-bar + * @packageDocumentation + */ + +import * as vscode from 'vscode'; + + +export interface BusyItem { + whenDone: Promise, + text: string | undefined +} + + +/** Status bar handling */ +class StatusBar { + static #instance: StatusBar = new StatusBar(); + public static getInstance(): StatusBar { + return this.#instance; + } + + + private constructor() { + // init busy status + this.#busyStatus.name = 'B&R Tools busy indicator'; + this.#busyStatus.text = '$(sync~spin) B&R Tools'; + } + + + /** Status bar busy indicator */ + #busyStatus = vscode.window.createStatusBarItem('vscode-brautomationtools.busyStatus',vscode.StatusBarAlignment.Left); + /** Items shown in the status bar busy indicator */ + #busyItems: Set = new Set(); + + + /** + * Adds an item to the busy indicator in the status bar. Can be used for long running processes to show a feedback to the user. + * When no item has an unresolved promise left, the busy indicator will be hidden. + * @param hideWhenDone A promise which when resolved removes the item from the busy indicator + * @param text An optional text which is shown as a line in the tooltip of the busy indicator + * @returns The item which was created. It can be used to remove the item from the indicator before the promis was resolved. + */ + addBusyItem(hideWhenDone: Promise, text?: string | undefined): BusyItem { + const item = { + whenDone: hideWhenDone, + text: text + }; + this.#busyItems.add(item); + this.#updateBusyStatus(); + hideWhenDone.then(() => this.removeBusyItem(item), () => this.removeBusyItem(item)); + return item; + } + + + /** + * Removes an item from the busy indicator in the status bar. + * @param item The item to remove from the busy indicator + */ + removeBusyItem(item: BusyItem) { + this.#busyItems.delete(item); + this.#updateBusyStatus(); + } + + + /** Updates the status of the busy indicator. */ + #updateBusyStatus() { + if (this.#busyItems.size === 0) { + this.#busyStatus.hide(); + return; + } + const tooltipLines: string[] = []; + for (const item of this.#busyItems) { + if (item.text) { + tooltipLines.push(`$(sync~spin) ${item.text}`); + } + } + const toolTipRaw = tooltipLines.join('\n\n'); + this.#busyStatus.tooltip = new vscode.MarkdownString(toolTipRaw, true); + this.#busyStatus.show(); + } + + dispose() { + this.#busyStatus.dispose(); + } +} + +/** Access to the VS Code StatusBar */ +export const statusBar = StatusBar.getInstance(); \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 5c6f145..03428da 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -10,10 +10,12 @@ import {registerCppToolsConfigurationProvider} from './ExternalApi/CppToolsApi'; import {registerTaskProviders as registerBuildTaskProviders} from './BrAsBuildTaskProvider'; import {registerTaskProviders as registerTransferTaskProviders} from './BrAsTransferTaskProvider'; import {registerApiTests} from './Tools/ApiTests'; -import {registerProjectWorkspace} from './BRAsProjectWorkspace'; +import {getWorkspaceProjects, registerProjectWorkspace} from './BRAsProjectWorkspace'; import { notifications } from './UI/Notifications'; import { extensionState } from './BrExtensionState'; import { extensionConfiguration } from './BRConfiguration'; +import { getAvailableAutomationStudioVersions, getAvailablePviVersions } from './BREnvironment'; +import { statusBar } from './UI/StatusBar'; // Activation event @@ -24,7 +26,7 @@ export async function activate(context: vscode.ExtensionContext) { prettyPrintAdditionalData: extensionConfiguration.logging.prettyPrintAdditionalData }; logger.info('Start activation of B&R Automation Tools extension'); - // + // Initialize modules extensionState.initialize(context); notifications.initialize(context); notifications.newVersionMessage(); @@ -32,8 +34,22 @@ export async function activate(context: vscode.ExtensionContext) { registerCommands(context); registerBuildTaskProviders(context); registerTransferTaskProviders(context); + // get promises for long running activation events and add to status bar + const waitAsVersion = getAvailableAutomationStudioVersions(); + statusBar.addBusyItem(waitAsVersion, 'Searching for installed AS versions'); + const waitPviVersions = getAvailablePviVersions(); + statusBar.addBusyItem(waitPviVersions, 'Searching for installed PVI versions'); + const waitWorkspaceProjects = getWorkspaceProjects(); + statusBar.addBusyItem(waitWorkspaceProjects, 'Parsing AS projects in workspace'); + // TODO do we need to await these? Will probably be remove after architectural changes #5 await registerCppToolsConfigurationProvider(context); await registerProjectWorkspace(context); + // Show activation message and log entry when all is done + await Promise.all([ + waitAsVersion, + waitPviVersions, + waitWorkspaceProjects, + ]); logger.info('Activation of B&R Automation Tools extension finished'); notifications.activationMessage(); }