#22289 Show files exclude filter inside inputbox

This commit is contained in:
Sandeep Somavarapu
2018-04-11 23:39:22 +02:00
parent 93582ce6de
commit c1b9138a23
3 changed files with 95 additions and 80 deletions

View File

@@ -20,7 +20,7 @@ import { Marker, ResourceMarkers, RelatedInformation } from 'vs/workbench/parts/
import { Controller } from 'vs/workbench/parts/markers/electron-browser/markersTreeController';
import * as Viewer from 'vs/workbench/parts/markers/electron-browser/markersTreeViewer';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { CollapseAllAction, FilterInputActionItem, FilterByFilesExcludeAction, FilterAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions';
import { CollapseAllAction, MarkersFilterActionItem, MarkersFilterAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import Messages from 'vs/workbench/parts/markers/electron-browser/messages';
import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations';
@@ -47,8 +47,7 @@ export class MarkersPanel extends Panel {
private actions: IAction[];
private collapseAllAction: IAction;
private filterInputActionItem: FilterInputActionItem;
private filterByFilesExcludeAction: FilterByFilesExcludeAction;
private filterInputActionItem: MarkersFilterActionItem;
private treeContainer: HTMLElement;
private messageBoxContainer: HTMLElement;
@@ -183,7 +182,7 @@ export class MarkersPanel extends Panel {
private updateFilter() {
this.autoExpanded = new Set<string>();
this.markersWorkbenchService.filter({ filterText: this.filterInputActionItem.getFilterText(), useFilesExclude: this.filterByFilesExcludeAction.checked });
this.markersWorkbenchService.filter({ filterText: this.filterInputActionItem.getFilterText(), useFilesExclude: this.filterInputActionItem.useFilesExclude });
}
private createMessageBox(parent: HTMLElement): void {
@@ -228,10 +227,9 @@ export class MarkersPanel extends Panel {
private createActions(): void {
this.collapseAllAction = this.instantiationService.createInstance(CollapseAllAction, this.tree, true);
const filterAction = this.instantiationService.createInstance(FilterAction);
this.filterInputActionItem = this.instantiationService.createInstance(FilterInputActionItem, this.panelSettings['filter'] || '', this.panelSettings['filterHistory'] || [], filterAction);
this.filterByFilesExcludeAction = new FilterByFilesExcludeAction(this.panelSettings['useFilesExclude']);
this.actions = [filterAction, this.filterByFilesExcludeAction, this.collapseAllAction];
const filterAction = this.instantiationService.createInstance(MarkersFilterAction);
this.filterInputActionItem = this.instantiationService.createInstance(MarkersFilterActionItem, { filterText: this.panelSettings['filter'] || '', filterHistory: this.panelSettings['filterHistory'] || [], useFilesExclude: !!this.panelSettings['useFilesExclude'] }, filterAction);
this.actions = [filterAction, this.collapseAllAction];
}
private createListeners(): void {
@@ -239,7 +237,6 @@ export class MarkersPanel extends Panel {
this.toUnbind.push(this.editorGroupService.onEditorsChanged(this.onEditorsChanged, this));
this.toUnbind.push(this.tree.onDidChangeSelection(() => this.onSelected()));
this.toUnbind.push(this.filterInputActionItem.onDidChange(() => this.updateFilter()));
this.toUnbind.push(this.filterByFilesExcludeAction.onDidCheck(() => this.updateFilter()));
this.actions.forEach(a => this.toUnbind.push(a));
}
@@ -321,7 +318,7 @@ export class MarkersPanel extends Panel {
const link = dom.append(container, dom.$('a.messageAction'));
link.textContent = localize('disableFilesExclude', "Disable Files Exclude.");
link.setAttribute('tabIndex', '0');
dom.addDisposableListener(link, dom.EventType.CLICK, () => this.filterByFilesExcludeAction.checked = false);
dom.addDisposableListener(link, dom.EventType.CLICK, () => this.filterInputActionItem.useFilesExclude = false);
}
private renderFilteredByFilterMessage(container: HTMLElement) {
@@ -419,7 +416,7 @@ export class MarkersPanel extends Panel {
}
public getActionItem(action: IAction): IActionItem {
if (action.id === FilterAction.ID) {
if (action.id === MarkersFilterAction.ID) {
return this.filterInputActionItem;
}
return super.getActionItem(action);
@@ -429,7 +426,7 @@ export class MarkersPanel extends Panel {
// store memento
this.panelSettings['filter'] = this.filterInputActionItem.getFilterText();
this.panelSettings['filterHistory'] = this.filterInputActionItem.getFilterHistory();
this.panelSettings['useFilesExclude'] = this.filterByFilesExcludeAction.checked;
this.panelSettings['useFilesExclude'] = this.filterInputActionItem.useFilesExclude;
super.shutdown();
}

View File

@@ -20,15 +20,15 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { CollapseAllAction as TreeCollapseAction } from 'vs/base/parts/tree/browser/treeDefaults';
import * as Tree from 'vs/base/parts/tree/browser/tree';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { attachInputBoxStyler, attachStylerCallback, attachCheckboxStyler } from 'vs/platform/theme/common/styler';
import { IMarkersWorkbenchService } from 'vs/workbench/parts/markers/electron-browser/markers';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable } from 'vs/base/common/lifecycle';
import { HistoryNavigator } from 'vs/base/common/history';
import { BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { badgeBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { localize } from 'vs/nls';
import { isUndefined } from 'vs/base/common/types';
import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
export class ToggleMarkersPanelAction extends TogglePanelAction {
@@ -68,50 +68,24 @@ export class CollapseAllAction extends TreeCollapseAction {
}
}
export class FilterByFilesExcludeAction extends Action {
public static readonly ID: string = 'workbench.actions.problems.useFilesExclude';
private readonly _onDidCheck: Emitter<boolean> = new Emitter<boolean>();
readonly onDidCheck: Event<boolean> = this._onDidCheck.event;
private toDispose: IDisposable[] = [];
constructor(checked: boolean) {
super(FilterByFilesExcludeAction.ID, checked ? Messages.MARKERS_PANEL_ACTION_TOOLTIP_DO_NOT_USE_FILES_EXCLUDE : Messages.MARKERS_PANEL_ACTION_TOOLTIP_USE_FILES_EXCLUDE, 'markers-panel-action-files-exclude', true);
this.toDispose.push(this._onDidCheck);
this.checked = checked;
this.toDispose.push(this.onDidChange(e => {
if (e && !isUndefined(e.checked)) {
this._onDidCheck.fire(this.checked);
}
}));
}
public run(): TPromise<any> {
this.checked = !this.checked;
this.tooltip = this.checked ? Messages.MARKERS_PANEL_ACTION_TOOLTIP_DO_NOT_USE_FILES_EXCLUDE : Messages.MARKERS_PANEL_ACTION_TOOLTIP_USE_FILES_EXCLUDE;
return TPromise.as(null);
}
dispose(): void {
this.toDispose = dispose(this.toDispose);
super.dispose();
}
}
export class FilterAction extends Action {
export class MarkersFilterAction extends Action {
public static readonly ID: string = 'workbench.actions.problems.filter';
constructor() {
super(FilterAction.ID, Messages.MARKERS_PANEL_ACTION_TOOLTIP_FILTER, 'markers-panel-action-filter', true);
super(MarkersFilterAction.ID, Messages.MARKERS_PANEL_ACTION_TOOLTIP_FILTER, 'markers-panel-action-filter', true);
}
}
export class FilterInputActionItem extends BaseActionItem {
export interface IMarkersFilterActionItemOptions {
filterText: string;
filterHistory: string[];
useFilesExclude: boolean;
}
export class MarkersFilterActionItem extends BaseActionItem {
private _toDispose: IDisposable[] = [];
@@ -122,11 +96,12 @@ export class FilterInputActionItem extends BaseActionItem {
private container: HTMLElement;
private filterInputBox: InputBox;
private filterHistory: HistoryNavigator<string>;
private controlsContainer: HTMLInputElement;
private filterBadge: HTMLInputElement;
private filesExcludeFilter: Checkbox;
constructor(
private filterText: string,
filterHistory: string[],
private itemOptions: IMarkersFilterActionItemOptions,
action: IAction,
@IContextViewService private contextViewService: IContextViewService,
@IThemeService private themeService: IThemeService,
@@ -135,14 +110,15 @@ export class FilterInputActionItem extends BaseActionItem {
) {
super(null, action);
this.delayedFilterUpdate = new Delayer<void>(500);
this.filterHistory = new HistoryNavigator<string>(filterHistory);
this.filterHistory = new HistoryNavigator<string>(itemOptions.filterHistory || []);
}
render(container: HTMLElement): void {
this.container = container;
DOM.addClass(this.container, 'markers-panel-action-filter');
this.createInput(this.container);
this.createBadge(this.container);
this.createControls(this.container);
this.adjustInputBox();
}
clear(): void {
@@ -150,13 +126,26 @@ export class FilterInputActionItem extends BaseActionItem {
}
getFilterText(): string {
return this.filterText;
return this.filterInputBox ? this.filterInputBox.value : this.itemOptions.filterText;
}
getFilterHistory(): string[] {
return this.filterHistory.getHistory();
}
get useFilesExclude(): boolean {
return this.filesExcludeFilter ? this.filesExcludeFilter.checked : this.itemOptions.useFilesExclude;
}
set useFilesExclude(useFilesExclude: boolean) {
if (this.filesExcludeFilter) {
if (this.filesExcludeFilter.checked !== useFilesExclude) {
this.filesExcludeFilter.checked = useFilesExclude;
this._onDidChange.fire();
}
}
}
toggleLayout(small: boolean) {
if (this.container) {
DOM.toggleClass(this.container, 'small', small);
@@ -170,13 +159,19 @@ export class FilterInputActionItem extends BaseActionItem {
ariaLabel: Messages.MARKERS_PANEL_FILTER_ARIA_LABEL
});
this._register(attachInputBoxStyler(this.filterInputBox, this.themeService));
this.filterInputBox.value = this.filterText;
this.filterInputBox.value = this.itemOptions.filterText;
this._register(this.filterInputBox.onDidChange(filter => this.delayedFilterUpdate.trigger(() => this.onDidInputChange())));
this._register(DOM.addStandardDisposableListener(this.filterInputBox.inputElement, 'keydown', (keyboardEvent) => this.onInputKeyDown(keyboardEvent, this.filterInputBox)));
this._register(DOM.addStandardDisposableListener(container, 'keydown', this.handleKeyboardEvent));
this._register(DOM.addStandardDisposableListener(container, 'keyup', this.handleKeyboardEvent));
}
private createControls(container: HTMLElement): void {
this.controlsContainer = DOM.append(container, DOM.$('.markers-panel-filter-controls'));
this.createBadge(this.controlsContainer);
this.createFilesExcludeCheckbox(this.controlsContainer);
}
private createBadge(container: HTMLElement): void {
this.filterBadge = DOM.append(container, DOM.$('.markers-panel-filter-badge'));
this._register(attachStylerCallback(this.themeService, { badgeBackground, contrastBorder }, colors => {
@@ -189,12 +184,27 @@ export class FilterInputActionItem extends BaseActionItem {
this.filterBadge.style.borderStyle = border ? 'solid' : null;
this.filterBadge.style.borderColor = border;
}));
this.updateBadge();
this._register(this.markersWorkbenchService.onDidChange(() => this.updateBadge()));
}
private createFilesExcludeCheckbox(container: HTMLElement): void {
this.filesExcludeFilter = new Checkbox({
actionClassName: 'markers-panel-filter-filesExclude',
title: this.itemOptions.useFilesExclude ? Messages.MARKERS_PANEL_ACTION_TOOLTIP_DO_NOT_USE_FILES_EXCLUDE : Messages.MARKERS_PANEL_ACTION_TOOLTIP_USE_FILES_EXCLUDE,
isChecked: this.itemOptions.useFilesExclude,
onChange: () => {
this.filesExcludeFilter.domNode.title = this.filesExcludeFilter.checked ? Messages.MARKERS_PANEL_ACTION_TOOLTIP_DO_NOT_USE_FILES_EXCLUDE : Messages.MARKERS_PANEL_ACTION_TOOLTIP_USE_FILES_EXCLUDE;
this._onDidChange.fire();
}
});
this._register(attachCheckboxStyler(this.filesExcludeFilter, this.themeService));
container.appendChild(this.filesExcludeFilter.domNode);
}
private onDidInputChange() {
this.filterText = this.filterInputBox.value;
if (this.filterText && this.filterText !== this.filterHistory.current()) {
const filterText = this.filterInputBox.value;
if (filterText && filterText !== this.filterHistory.current()) {
this.filterHistory.add(this.getFilterText());
}
this._onDidChange.fire();
@@ -205,7 +215,11 @@ export class FilterInputActionItem extends BaseActionItem {
const { total, filtered } = this.markersWorkbenchService.markersModel.stats();
DOM.toggleClass(this.filterBadge, 'hidden', total === filtered || filtered === 0);
this.filterBadge.textContent = localize('showing filtered problems', "Showing {0} of {1}", filtered, total);
this.filterInputBox.inputElement.style.paddingRight = DOM.getTotalWidth(this.filterBadge) + 'px';
this.adjustInputBox();
}
private adjustInputBox(): void {
this.filterInputBox.inputElement.style.paddingRight = (DOM.getTotalWidth(this.controlsContainer) || 20) + 'px';
}
// Action toolbar is swallowing some keys for action items which should not be for an input box

View File

@@ -7,7 +7,7 @@
cursor: default;
margin: 4px 10px 0 0;
min-width: 150px;
max-width: 800px;
max-width: 1000px;
}
.monaco-action-bar .action-item.markers-panel-action-filter {
@@ -27,20 +27,37 @@
border: 1px solid #ddd;
}
.markers-panel-action-filter > .markers-panel-filter-badge {
margin: 4px 0px;
padding: 0px 8px;
border-radius: 2px;
.markers-panel-action-filter > .markers-panel-filter-controls {
position: absolute;
top: 0px;
right: 4px;
display: flex;
}
.markers-panel-action-filter > .markers-panel-filter-badge.hidden,
.markers-panel-action-filter > .markers-panel-filter-badge.small {
.markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-badge {
margin: 4px 0px;
padding: 0px 8px;
border-radius: 2px;
}
.markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-badge.hidden,
.markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-badge.small {
display: none;
}
.markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude {
margin: 3px 0 0 3px;
}
.vs .markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude {
background: url('excludeSettings.svg') center center no-repeat;
}
.vs-dark .markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude,
.hc-black .markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude {
background: url('excludeSettings-dark.svg') center center no-repeat;
}
.markers-panel .markers-panel-container {
height: 100%;
}
@@ -141,17 +158,4 @@
.vs-dark .markers-panel .icon.info {
background: url('status-info-inverse.svg') center center no-repeat;
}
.vs .monaco-action-bar .action-item .icon.markers-panel-action-files-exclude {
background: url('excludeSettings.svg') center center no-repeat;
}
.vs-dark .monaco-action-bar .action-item .icon.markers-panel-action-files-exclude,
.hc-black .monaco-action-bar .action-item .icon.markers-panel-action-files-exclude {
background: url('excludeSettings-dark.svg') center center no-repeat;
}
.monaco-action-bar .action-item .icon.markers-panel-action-files-exclude:not(.checked) {
opacity: 0.5;
}
}