Skip to content

Commit fe68282

Browse files
committed
scm view improvements
1 parent 1713bd7 commit fe68282

5 files changed

Lines changed: 47 additions & 25 deletions

File tree

src/vs/base/browser/ui/dropdown/dropdown.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
1111
import { IContextViewProvider, IAnchor, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
1212
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
1313
import { ResolvedKeybinding, KeyCode } from 'vs/base/common/keyCodes';
14-
import { EventHelper, EventType, removeClass, addClass, append, $, addDisposableListener, addClasses } from 'vs/base/browser/dom';
14+
import { EventHelper, EventType, removeClass, addClass, append, $, addDisposableListener, addClasses, DOMEvent } from 'vs/base/browser/dom';
1515
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
1616
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
1717
import { Emitter } from 'vs/base/common/event';
@@ -122,7 +122,7 @@ export class BaseDropdown extends ActionRunner {
122122
return !!this.visible;
123123
}
124124

125-
protected onEvent(e: Event, activeElement: HTMLElement): void {
125+
protected onEvent(e: DOMEvent, activeElement: HTMLElement): void {
126126
this.hide();
127127
}
128128

@@ -294,6 +294,9 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
294294
private anchorAlignmentProvider: (() => AnchorAlignment) | undefined;
295295
private menuAsChild?: boolean;
296296

297+
private _onDidChangeVisibility = this._register(new Emitter<boolean>());
298+
readonly onDidChangeVisibility = this._onDidChangeVisibility.event;
299+
297300
constructor(action: IAction, menuActions: ReadonlyArray<IAction>, contextMenuProvider: IContextMenuProvider, actionViewItemProvider: IActionViewItemProvider | undefined, actionRunner: IActionRunner, keybindings: ((action: IAction) => ResolvedKeybinding | undefined) | undefined, clazz: string | undefined, anchorAlignmentProvider?: () => AnchorAlignment, menuAsChild?: boolean);
298301
constructor(action: IAction, actionProvider: IActionProvider, contextMenuProvider: IContextMenuProvider, actionViewItemProvider: IActionViewItemProvider | undefined, actionRunner: IActionRunner, keybindings: ((action: IAction) => ResolvedKeybinding) | undefined, clazz: string | undefined, anchorAlignmentProvider?: () => AnchorAlignment, menuAsChild?: boolean);
299302
constructor(action: IAction, menuActionsOrProvider: ReadonlyArray<IAction> | IActionProvider, contextMenuProvider: IContextMenuProvider, actionViewItemProvider: IActionViewItemProvider | undefined, actionRunner: IActionRunner, keybindings: ((action: IAction) => ResolvedKeybinding | undefined) | undefined, clazz: string | undefined, anchorAlignmentProvider?: () => AnchorAlignment, menuAsChild?: boolean) {
@@ -339,7 +342,10 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
339342
}
340343

341344
this.dropdownMenu = this._register(new DropdownMenu(container, options));
342-
this._register(this.dropdownMenu.onDidChangeVisibility(visible => this.element?.setAttribute('aria-expanded', `${visible}`)));
345+
this._register(this.dropdownMenu.onDidChangeVisibility(visible => {
346+
this.element?.setAttribute('aria-expanded', `${visible}`);
347+
this._onDidChangeVisibility.fire(visible);
348+
}));
343349

344350
this.dropdownMenu.menuOptions = {
345351
actionViewItemProvider: this.actionViewItemProvider,

src/vs/base/browser/ui/toolbar/toolbar.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import { Action, IActionRunner, IAction } from 'vs/base/common/actions';
99
import { ActionBar, ActionsOrientation, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
1010
import { IContextMenuProvider, DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdown';
1111
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
12-
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
12+
import { Disposable, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
1313
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
1414
import { withNullAsUndefined } from 'vs/base/common/types';
1515
import { Codicon, registerIcon } from 'vs/base/common/codicons';
16+
import { Emitter } from 'vs/base/common/event';
1617

1718
export const CONTEXT = 'context.toolbar';
1819

@@ -35,17 +36,21 @@ export class ToolBar extends Disposable {
3536
private options: IToolBarOptions;
3637
private actionBar: ActionBar;
3738
private toggleMenuAction: ToggleMenuAction;
38-
private toggleMenuActionViewItem = this._register(new MutableDisposable<DropdownMenuActionViewItem>());
39+
private toggleMenuActionViewItem: DropdownMenuActionViewItem | undefined;
40+
private toggleMenuActionViewItemDisposable: IDisposable = Disposable.None;
3941
private hasSecondaryActions: boolean = false;
4042
private lookupKeybindings: boolean;
4143

44+
private _onDidChangeDropdownVisibility = this._register(new Emitter<boolean>());
45+
readonly onDidChangeDropdownVisibility = this._onDidChangeDropdownVisibility.event;
46+
4247
constructor(container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) {
4348
super();
4449

4550
this.options = options;
4651
this.lookupKeybindings = typeof this.options.getKeyBinding === 'function';
4752

48-
this.toggleMenuAction = this._register(new ToggleMenuAction(() => this.toggleMenuActionViewItem.value && this.toggleMenuActionViewItem.value.show(), options.toggleMenuTitle));
53+
this.toggleMenuAction = this._register(new ToggleMenuAction(() => this.toggleMenuActionViewItem?.show(), options.toggleMenuTitle));
4954

5055
let element = document.createElement('div');
5156
element.className = 'monaco-toolbar';
@@ -60,8 +65,10 @@ export class ToolBar extends Disposable {
6065
// Return special action item for the toggle menu action
6166
if (action.id === ToggleMenuAction.ID) {
6267

68+
this.toggleMenuActionViewItemDisposable.dispose();
69+
6370
// Create new
64-
this.toggleMenuActionViewItem.value = new DropdownMenuActionViewItem(
71+
this.toggleMenuActionViewItem = new DropdownMenuActionViewItem(
6572
action,
6673
(<ToggleMenuAction>action).menuActions,
6774
contextMenuProvider,
@@ -72,9 +79,14 @@ export class ToolBar extends Disposable {
7279
this.options.anchorAlignmentProvider,
7380
true
7481
);
75-
this.toggleMenuActionViewItem.value.setActionContext(this.actionBar.context);
82+
this.toggleMenuActionViewItem.setActionContext(this.actionBar.context);
83+
84+
this.toggleMenuActionViewItemDisposable = combinedDisposable(
85+
this.toggleMenuActionViewItem,
86+
this.toggleMenuActionViewItem.onDidChangeVisibility(e => this._onDidChangeDropdownVisibility.fire(e))
87+
);
7688

77-
return this.toggleMenuActionViewItem.value;
89+
return this.toggleMenuActionViewItem;
7890
}
7991

8092
return options.actionViewItemProvider ? options.actionViewItemProvider(action) : undefined;
@@ -92,8 +104,8 @@ export class ToolBar extends Disposable {
92104

93105
set context(context: unknown) {
94106
this.actionBar.context = context;
95-
if (this.toggleMenuActionViewItem.value) {
96-
this.toggleMenuActionViewItem.value.setActionContext(context);
107+
if (this.toggleMenuActionViewItem) {
108+
this.toggleMenuActionViewItem.setActionContext(context);
97109
}
98110
}
99111

@@ -151,6 +163,11 @@ export class ToolBar extends Disposable {
151163
}
152164
};
153165
}
166+
167+
dispose(): void {
168+
super.dispose();
169+
this.toggleMenuActionViewItemDisposable.dispose();
170+
}
154171
}
155172

156173
class ToggleMenuAction extends Action {

src/vs/workbench/contrib/scm/browser/media/scm.css

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,12 @@
3838
flex-flow: nowrap;
3939
}
4040

41-
.scm-viewlet .scm-provider > .icon {
42-
margin-right: 4px;
43-
}
44-
4541
.scm-viewlet .scm-provider > .label {
4642
display: flex;
4743
flex-shrink: 1;
4844
overflow: hidden;
4945
}
5046

51-
.scm-viewlet .scm-provider > .label > .name {
52-
text-decoration: underline;
53-
}
54-
5547
.scm-viewlet .scm-provider > .status {
5648
flex: 1;
5749
display: flex;
@@ -105,7 +97,6 @@
10597
flex: 1;
10698
overflow: hidden;
10799
text-overflow: ellipsis;
108-
text-decoration: underline;
109100
}
110101

111102
.scm-viewlet .monaco-list-row .resource {
@@ -149,10 +140,13 @@
149140
}
150141

151142
.scm-viewlet .monaco-list .monaco-list-row:hover .scm-provider > .actions,
143+
.scm-viewlet .monaco-list .monaco-list-row .scm-provider.active > .actions,
144+
.scm-viewlet .monaco-list .monaco-list-row.selected .scm-provider > .actions,
145+
.scm-viewlet .monaco-list .monaco-list-row.focused .scm-provider > .actions,
152146
.scm-viewlet .monaco-list .monaco-list-row:hover .resource-group > .actions,
153-
.scm-viewlet .monaco-list .monaco-list-row:hover .resource > .name > .monaco-icon-label > .actions,
154147
.scm-viewlet .monaco-list .monaco-list-row.selected .resource-group > .actions,
155148
.scm-viewlet .monaco-list .monaco-list-row.focused .resource-group > .actions,
149+
.scm-viewlet .monaco-list .monaco-list-row:hover .resource > .name > .monaco-icon-label > .actions,
156150
.scm-viewlet .monaco-list .monaco-list-row.selected .resource > .name > .monaco-icon-label > .actions,
157151
.scm-viewlet .monaco-list .monaco-list-row.focused .resource > .name > .monaco-icon-label > .actions,
158152
.scm-viewlet .monaco-list:not(.selection-multiple) .monaco-list-row .resource:hover > .actions {
@@ -179,7 +173,7 @@
179173

180174
.scm-viewlet .scm-input {
181175
height: 100%;
182-
margin-left: 6px;
176+
margin-left: 9px;
183177
}
184178

185179
.scm-viewlet .scm-editor {

src/vs/workbench/contrib/scm/browser/scmViewPane.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ class RepositoryRenderer implements ICompressibleTreeRenderer<ISCMRepository, Fu
176176
addClass(container.parentElement!.parentElement!.querySelector('.monaco-tl-twistie')! as HTMLElement, 'force-twistie');
177177

178178
const provider = append(container, $('.scm-provider'));
179-
append(provider, $('span.icon.codicon.codicon-repo'));
180179
const label = append(provider, $('.label'));
181180
const name = append(label, $('span.name'));
182181
const status = append(provider, $('.status'));
@@ -186,8 +185,10 @@ class RepositoryRenderer implements ICompressibleTreeRenderer<ISCMRepository, Fu
186185
const countContainer = append(provider, $('.count'));
187186
const count = new CountBadge(countContainer);
188187
const badgeStyler = attachBadgeStyler(count, this.themeService);
188+
const visibilityDisposable = toolBar.onDidChangeDropdownVisibility(e => toggleClass(provider, 'active', e));
189+
189190
const disposable = Disposable.None;
190-
const templateDisposable = combinedDisposable(statusActionBar, toolBar, badgeStyler);
191+
const templateDisposable = combinedDisposable(statusActionBar, visibilityDisposable, toolBar, badgeStyler);
191192

192193
return { name, countContainer, count, statusActionBar, toolBar, disposable, templateDisposable };
193194
}
@@ -265,6 +266,9 @@ class InputRenderer implements ICompressibleTreeRenderer<ISCMInput, FuzzyScore,
265266
) { }
266267

267268
renderTemplate(container: HTMLElement): InputTemplate {
269+
// hack
270+
addClass(container.parentElement!.parentElement!.querySelector('.monaco-tl-twistie')! as HTMLElement, 'force-no-twistie');
271+
268272
const inputElement = append(container, $('.scm-input'));
269273
const inputWidget = this.instantiationService.createInstance(SCMInputWidget, inputElement);
270274

src/vs/workbench/contrib/views/browser/media/views.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
.file-icon-themable-tree.align-icons-and-twisties .monaco-tl-twistie:not(.force-twistie):not(.collapsible),
99
.file-icon-themable-tree .align-icon-with-twisty .monaco-tl-twistie:not(.force-twistie):not(.collapsible),
10-
.file-icon-themable-tree.hide-arrows .monaco-tl-twistie:not(.force-twistie) {
10+
.file-icon-themable-tree.hide-arrows .monaco-tl-twistie:not(.force-twistie),
11+
.file-icon-themable-tree .monaco-tl-twistie.force-no-twistie {
1112
background-image: none !important;
1213
width: 0 !important;
1314
padding-right: 0 !important;

0 commit comments

Comments
 (0)