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

Initial run of disabling and enabling activity bar badges #158781

Merged
merged 6 commits into from Nov 18, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/vs/workbench/browser/parts/activitybar/activitybarActions.ts
Expand Up @@ -16,7 +16,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
import { IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { ActivityAction, ActivityActionViewItem, IActivityActionViewItemOptions, IActivityHoverOptions, ICompositeBar, ICompositeBarColors, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
import { ActivityAction, ActivityActionViewItem, IActivityActionViewItemOptions, IActivityHoverOptions, ICompositeBar, ICompositeBarColors, ToggleCompositeBadgeAction, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
import { IActivity } from 'vs/workbench/common/activity';
import { ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_ACTIVE_FOCUS_BORDER, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_PROFILE_BACKGROUND, ACTIVITY_BAR_PROFILE_HOVER_FOREGROUND } from 'vs/workbench/common/theme';
Expand Down Expand Up @@ -126,7 +126,7 @@ abstract class AbstractGlobalActivityActionViewItem extends ActivityActionViewIt
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
@IKeybindingService keybindingService: IKeybindingService,
) {
super(action, options, themeService, hoverService, configurationService, keybindingService);
super(action, options, () => true, themeService, hoverService, configurationService, keybindingService);
}

override render(container: HTMLElement): void {
Expand Down Expand Up @@ -419,6 +419,17 @@ export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinne
}
}

export class PlaceHolderToggleCompositeBadgeAction extends ToggleCompositeBadgeAction {

constructor(id: string, compositeBar: ICompositeBar) {
super({ id, name: id, cssClass: undefined }, compositeBar);
}

setActivity(activity: IActivity): void {
this.label = activity.name;
}
}

class SwitchSideBarViewAction extends Action2 {

constructor(
Expand Down
24 changes: 16 additions & 8 deletions src/vs/workbench/browser/parts/activitybar/activitybarPart.ts
Expand Up @@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { GLOBAL_ACTIVITY_ID, IActivity, ACCOUNTS_ACTIVITY_ID } from 'vs/workbench/common/activity';
import { Part } from 'vs/workbench/browser/part';
import { GlobalActivityActionViewItem, ViewContainerActivityAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewContainerActivityAction, AccountsActivityActionViewItem, ProfilesActivityActionViewItem, IProfileActivity } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
import { GlobalActivityActionViewItem, ViewContainerActivityAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewContainerActivityAction, AccountsActivityActionViewItem, ProfilesActivityActionViewItem, IProfileActivity, PlaceHolderToggleCompositeBadgeAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
import { IBadge, NumberBadge } from 'vs/workbench/services/activity/common/activity';
import { IWorkbenchLayoutService, Parts, Position } from 'vs/workbench/services/layout/browser/layoutService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
Expand All @@ -23,7 +23,7 @@ import { Dimension, createCSSRule, asCSSUrl, addDisposableListener, EventType, i
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ToggleCompositePinnedAction, ICompositeBarColors, ActivityAction, ICompositeActivity, IActivityHoverOptions } from 'vs/workbench/browser/parts/compositeBarActions';
import { ToggleCompositePinnedAction, ICompositeBarColors, ActivityAction, ICompositeActivity, IActivityHoverOptions, ToggleCompositeBadgeAction } from 'vs/workbench/browser/parts/compositeBarActions';
import { IViewDescriptorService, ViewContainer, IViewContainerModel, ViewContainerLocation } from 'vs/workbench/common/views';
import { getEnabledViewContainerContextKey } from 'vs/workbench/common/contextkeys';
import { IContextKeyService, ContextKeyExpr, IContextKey } from 'vs/platform/contextkey/common/contextkey';
Expand Down Expand Up @@ -58,6 +58,7 @@ interface IPlaceholderViewContainer {
interface IPinnedViewContainer {
readonly id: string;
readonly pinned: boolean;
readonly badgeEnabled: boolean;
readonly order?: number;
readonly visible: boolean;
}
Expand All @@ -67,6 +68,7 @@ interface ICachedViewContainer {
name?: string;
icon?: URI | ThemeIcon;
readonly pinned: boolean;
readonly badgeEnabled: boolean;
readonly order?: number;
visible: boolean;
isBuiltin?: boolean;
Expand Down Expand Up @@ -112,7 +114,7 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart

private readonly accountsActivity: ICompositeActivity[] = [];

private readonly compositeActions = new Map<string, { activityAction: ViewContainerActivityAction; pinnedAction: ToggleCompositePinnedAction }>();
private readonly compositeActions = new Map<string, { activityAction: ViewContainerActivityAction; pinnedAction: ToggleCompositePinnedAction; badgeAction: ToggleCompositeBadgeAction }>();
private readonly viewContainerDisposables = new Map<string, IDisposable>();

private readonly keyboardNavigationDisposables = this._register(new DisposableStore());
Expand Down Expand Up @@ -156,7 +158,8 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart
name: container.name,
visible: container.visible,
order: container.order,
pinned: container.pinned
badgeEnabled: container.badgeEnabled,
pinned: container.pinned,
}));

return this._register(this.instantiationService.createInstance(CompositeBar, cachedItems, {
Expand All @@ -169,6 +172,7 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart
},
getActivityAction: compositeId => this.getCompositeActions(compositeId).activityAction,
getCompositePinnedAction: compositeId => this.getCompositeActions(compositeId).pinnedAction,
getCompositeBadgeAction: compositeId => this.getCompositeActions(compositeId).badgeAction,
getOnCompositeClickAction: compositeId => toAction({ id: compositeId, label: '', run: async () => this.paneCompositePart.getActivePaneComposite()?.getId() === compositeId ? this.paneCompositePart.hideActivePaneComposite() : this.paneCompositePart.openPaneComposite(compositeId) }),
fillExtraContextMenuActions: (actions, e?: MouseEvent | GestureEvent) => {
// Menu
Expand Down Expand Up @@ -623,21 +627,23 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart
};
}

private getCompositeActions(compositeId: string): { activityAction: ViewContainerActivityAction; pinnedAction: ToggleCompositePinnedAction } {
private getCompositeActions(compositeId: string): { activityAction: ViewContainerActivityAction; pinnedAction: ToggleCompositePinnedAction; badgeAction: ToggleCompositeBadgeAction } {
let compositeActions = this.compositeActions.get(compositeId);
if (!compositeActions) {
const viewContainer = this.getViewContainer(compositeId);
if (viewContainer) {
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
compositeActions = {
activityAction: this.instantiationService.createInstance(ViewContainerActivityAction, this.toActivity(viewContainerModel), this.paneCompositePart),
pinnedAction: new ToggleCompositePinnedAction(this.toActivity(viewContainerModel), this.compositeBar)
pinnedAction: new ToggleCompositePinnedAction(this.toActivity(viewContainerModel), this.compositeBar),
badgeAction: new ToggleCompositeBadgeAction(this.toActivity(viewContainerModel), this.compositeBar)
};
} else {
const cachedComposite = this.cachedViewContainers.filter(c => c.id === compositeId)[0];
compositeActions = {
activityAction: this.instantiationService.createInstance(PlaceHolderViewContainerActivityAction, ActivitybarPart.toActivity(compositeId, compositeId, cachedComposite?.icon, undefined), this.paneCompositePart),
pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, this.compositeBar)
pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, this.compositeBar),
badgeAction: new PlaceHolderToggleCompositeBadgeAction(compositeId, this.compositeBar)
};
}

Expand Down Expand Up @@ -887,6 +893,7 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart
id: cachedViewContainer.id,
name: cachedViewContainer.name,
order: cachedViewContainer.order,
badgeEnabled: cachedViewContainer.badgeEnabled,
pinned: cachedViewContainer.pinned,
visible: !!compositeItems.find(({ id }) => id === cachedViewContainer.id)
});
Expand Down Expand Up @@ -934,12 +941,13 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart
icon: URI.isUri(viewContainerModel.icon) && this.environmentService.remoteAuthority ? undefined : viewContainerModel.icon, /* Donot cache uri icons with remote connection */
views,
pinned: compositeItem.pinned,
badgeEnabled: compositeItem.badgeEnabled,
order: compositeItem.order,
visible: compositeItem.visible,
isBuiltin: !viewContainer.extensionId
});
} else {
state.push({ id: compositeItem.id, pinned: compositeItem.pinned, order: compositeItem.order, visible: false, isBuiltin: false });
state.push({ id: compositeItem.id, pinned: compositeItem.pinned, badgeEnabled: compositeItem.badgeEnabled, order: compositeItem.order, visible: false, isBuiltin: false });
}
}

Expand Down
51 changes: 46 additions & 5 deletions src/vs/workbench/browser/parts/compositeBar.ts
Expand Up @@ -30,6 +30,7 @@ export interface ICompositeBarItem {

name?: string;
pinned: boolean;
badgeEnabled: boolean;
order?: number;
visible: boolean;
}
Expand Down Expand Up @@ -152,6 +153,7 @@ export interface ICompositeBarOptions {

readonly getActivityAction: (compositeId: string) => ActivityAction;
readonly getCompositePinnedAction: (compositeId: string) => IAction;
readonly getCompositeBadgeAction: (compositeId: string) => IAction;
readonly getOnCompositeClickAction: (compositeId: string) => IAction;
readonly fillExtraContextMenuActions: (actions: IAction[], e?: MouseEvent | GestureEvent) => void;
readonly getContextMenuActionsForComposite: (compositeId: string) => IAction[];
Expand Down Expand Up @@ -222,6 +224,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
{ draggable: true, colors: this.options.colors, icon: this.options.icon, hoverOptions: this.options.activityHoverOptions },
action as ActivityAction,
item.pinnedAction,
item.toggleBadgeAction,
compositeId => this.options.getContextMenuActionsForComposite(compositeId),
() => this.getContextMenuActions(),
this.options.dndHandler,
Expand Down Expand Up @@ -410,6 +413,27 @@ export class CompositeBar extends Widget implements ICompositeBar {
}
}

areBadgesEnabled(compositeId: string): boolean {
const item = this.model?.findItem(compositeId);
// Old restored views can have undefined badge enablement
if (item && item.badgeEnabled === undefined) {
item.badgeEnabled = true;
}
return item?.badgeEnabled;
}

toggleBadgeEnablement(compositeId: string): void {
if (this.model.setBadgeEnablement(compositeId, !this.areBadgesEnabled(compositeId))) {
this.updateCompositeSwitcher();
const item = this.model.findItem(compositeId);
if (item) {
// TODO @lramos15 how do we tell the activity to re-render the badge? This triggers an onDidChange but isn't the right way to do it.
// I could add another specific function like `activity.updateBadgeEnablement` would then the activity store the sate?
item.activityAction.setBadge(item.activityAction.getBadge(), item.activityAction.getClass());
}
}
}

private resetActiveComposite(compositeId: string) {
const defaultCompositeId = this.options.getDefaultCompositeId();

Expand Down Expand Up @@ -668,6 +692,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
interface ICompositeBarModelItem extends ICompositeBarItem {
readonly activityAction: ActivityAction;
readonly pinnedAction: IAction;
readonly toggleBadgeAction: IAction;
readonly activity: ICompositeActivity[];
}

Expand All @@ -692,7 +717,7 @@ class CompositeBarModel {
const result: ICompositeBarModelItem[] = [];
let hasChanges: boolean = false;
if (!this.items || this.items.length === 0) {
this._items = items.map(i => this.createCompositeBarItem(i.id, i.name, i.order, i.pinned, i.visible));
this._items = items.map(i => this.createCompositeBarItem(i.id, i.name, i.order, i.pinned, i.badgeEnabled, i.visible));
hasChanges = true;
} else {
const existingItems = this.items;
Expand All @@ -711,7 +736,7 @@ class CompositeBarModel {
result.push(existingItem);
}
} else {
result.push(this.createCompositeBarItem(newItem.id, newItem.name, newItem.order, newItem.pinned, newItem.visible));
result.push(this.createCompositeBarItem(newItem.id, newItem.name, newItem.order, newItem.pinned, newItem.badgeEnabled, newItem.visible));
hasChanges = true;
}
}
Expand All @@ -729,16 +754,19 @@ class CompositeBarModel {
return this.items.filter(item => item.visible && item.pinned);
}

private createCompositeBarItem(id: string, name: string | undefined, order: number | undefined, pinned: boolean, visible: boolean): ICompositeBarModelItem {
private createCompositeBarItem(id: string, name: string | undefined, order: number | undefined, pinned: boolean, badgeEnabled: boolean, visible: boolean): ICompositeBarModelItem {
const options = this.options;
return {
id, name, pinned, order, visible,
id, name, pinned, order, visible, badgeEnabled,
activity: [],
get activityAction() {
return options.getActivityAction(id);
},
get pinnedAction() {
return options.getCompositePinnedAction(id);
},
get toggleBadgeAction() {
return options.getCompositeBadgeAction(id);
}
};
}
Expand All @@ -759,7 +787,7 @@ class CompositeBarModel {

return changed;
} else {
const item = this.createCompositeBarItem(id, name, order, true, true);
const item = this.createCompositeBarItem(id, name, order, true, true, true);
if (!isUndefinedOrNull(requestedIndex)) {
let index = 0;
let rIndex = requestedIndex;
Expand Down Expand Up @@ -839,6 +867,19 @@ class CompositeBarModel {
return false;
}

setBadgeEnablement(id: string, isEnabled: boolean): boolean {
for (const item of this.items) {
if (item.id === id) {
if (item.badgeEnabled !== isEnabled) {
item.badgeEnabled = isEnabled;
return true;
}
return false;
}
}
return false;
}

addActivity(id: string, activity: ICompositeActivity): boolean {
const item = this.findItem(id);
if (item) {
Expand Down
55 changes: 51 additions & 4 deletions src/vs/workbench/browser/parts/compositeBarActions.ts
Expand Up @@ -49,6 +49,18 @@ export interface ICompositeBar {
*/
isPinned(compositeId: string): boolean;

/**
* Returns if badges are enabled for that specified composite.
* @param compositeId The id of the composite to check
*/
areBadgesEnabled(compositeId: string): boolean;

/**
* Toggles whether or not badges are shown on that particular composite.
* @param compositeId The composite to toggle badge enablement for
*/
toggleBadgeEnablement(compositeId: string): void;

/**
* Reorder composite ordering by moving a composite to the location of another composite.
*/
Expand Down Expand Up @@ -160,6 +172,7 @@ export class ActivityActionViewItem extends BaseActionViewItem {
constructor(
action: ActivityAction,
options: IActivityActionViewItemOptions,
private readonly badgesEnabled: (compositeId: string) => boolean,
@IThemeService protected readonly themeService: IThemeService,
@IHoverService private readonly hoverService: IHoverService,
@IConfigurationService protected readonly configurationService: IConfigurationService,
Expand Down Expand Up @@ -293,7 +306,9 @@ export class ActivityActionViewItem extends BaseActionViewItem {
clearNode(this.badgeContent);
hide(this.badge);

if (badge) {
const shouldRenderBadges = this.badgesEnabled(this.activity.id);

if (badge && shouldRenderBadges) {

// Number
if (badge instanceof NumberBadge) {
Expand Down Expand Up @@ -475,7 +490,7 @@ export class CompositeOverflowActivityActionViewItem extends ActivityActionViewI
@IConfigurationService configurationService: IConfigurationService,
@IKeybindingService keybindingService: IKeybindingService,
) {
super(action, { icon: true, colors, hasPopup: true, hoverOptions }, themeService, hoverService, configurationService, keybindingService);
super(action, { icon: true, colors, hasPopup: true, hoverOptions }, () => true, themeService, hoverService, configurationService, keybindingService);
}

showMenu(): void {
Expand Down Expand Up @@ -546,6 +561,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
options: IActivityActionViewItemOptions,
private readonly compositeActivityAction: ActivityAction,
private readonly toggleCompositePinnedAction: IAction,
private readonly toggleCompositeBadgeAction: IAction,
private readonly compositeContextMenuActionsProvider: (compositeId: string) => IAction[],
private readonly contextMenuActionsProvider: () => IAction[],
private readonly dndHandler: ICompositeDragAndDrop,
Expand All @@ -557,7 +573,15 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
@IHoverService hoverService: IHoverService,
@IConfigurationService configurationService: IConfigurationService,
) {
super(compositeActivityAction, options, themeService, hoverService, configurationService, keybindingService);
super(
compositeActivityAction,
options,
compositeBar.areBadgesEnabled.bind(compositeBar),
themeService,
hoverService,
configurationService,
keybindingService
);

if (!CompositeActionViewItem.manageExtensionAction) {
CompositeActionViewItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
Expand Down Expand Up @@ -657,7 +681,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
}

private showContextMenu(container: HTMLElement): void {
const actions: IAction[] = [this.toggleCompositePinnedAction];
const actions: IAction[] = [this.toggleCompositePinnedAction, this.toggleCompositeBadgeAction];

const compositeContextMenuActions = this.compositeContextMenuActionsProvider(this.activity.id);
if (compositeContextMenuActions.length) {
Expand All @@ -677,6 +701,13 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
this.toggleCompositePinnedAction.label = localize('keep', "Keep '{0}'", this.activity.name);
}

const isBadgeEnabled = this.compositeBar.areBadgesEnabled(this.activity.id);
if (isBadgeEnabled) {
this.toggleCompositeBadgeAction.label = localize('hideBadge', "Hide Badge");
} else {
this.toggleCompositeBadgeAction.label = localize('showBadge', "Show Badge");
}

const otherActions = this.contextMenuActionsProvider();
if (otherActions.length) {
actions.push(new Separator());
Expand Down Expand Up @@ -752,3 +783,19 @@ export class ToggleCompositePinnedAction extends Action {
}
}
}

export class ToggleCompositeBadgeAction extends Action {
constructor(
private activity: IActivity | undefined,
private compositeBar: ICompositeBar
) {
super('show.toggleCompositeBadge', activity ? activity.name : localize('toggleBadge', "Toggle View Badge"));

this.checked = false;
}

override async run(context: string): Promise<void> {
const id = this.activity ? this.activity.id : context;
this.compositeBar.toggleBadgeEnablement(id);
}
}