提交 0da60730 编写于 作者: J Joao Moreno

markers: filter with highlights

上级 e9809b3c
......@@ -11,7 +11,7 @@ import { append, $ } from 'vs/base/browser/dom';
import { Event, Relay, chain, mapEvent } from 'vs/base/common/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence';
import { IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
import { memoize } from 'vs/base/common/decorators';
......@@ -72,11 +72,6 @@ function renderDefaultTwistie<T>(node: ITreeNode<T, any>, twistie: HTMLElement):
}
}
export interface ITreeRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
renderTwistie?(element: TElement, twistieElement: HTMLElement): boolean;
onDidChangeTwistieState?: Event<TElement>;
}
class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {
readonly templateId: string;
......@@ -85,7 +80,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
private disposables: IDisposable[] = [];
constructor(
private renderer: ITreeRenderer<T, TTemplateData>,
private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>
) {
this.templateId = renderer.templateId;
......@@ -113,11 +108,11 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
templateData.twistie.style.width = `${10 + node.depth * 10}px`;
this.renderTwistie(node, templateData.twistie);
this.renderer.renderElement(node.element, index, templateData.templateData);
this.renderer.renderElement(node, index, templateData.templateData);
}
disposeElement(node: ITreeNode<T, TFilterData>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(node.element, index, templateData.templateData);
this.renderer.disposeElement(node, index, templateData.templateData);
this.renderedNodes.delete(node);
this.renderedElements.set(node.element);
}
......@@ -190,7 +185,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
constructor(
container: HTMLElement,
delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[],
renderers: ITreeRenderer<T, TFilterData, any>[],
options?: ITreeOptions<T, TFilterData>
) {
const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);
......
......@@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions, ITreeRenderer } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { IVirtualDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { IVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeRenderElement } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { timeout } from 'vs/base/common/async';
......@@ -39,14 +39,21 @@ interface IDataTreeListTemplateData<T> {
templateData: T;
}
class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>> {
function unpack<T, TFilterData>(node: ITreeRenderElement<IDataTreeNode<T>, TFilterData>): ITreeRenderElement<T, TFilterData> {
return {
get element() { return node.element.element; },
get filterData() { return node.filterData; }
};
}
class DataTreeRenderer<T, TFilterData, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, TFilterData, IDataTreeListTemplateData<TTemplateData>> {
readonly templateId: string;
private renderedNodes = new Map<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>>();
private disposables: IDisposable[] = [];
constructor(
private renderer: IRenderer<T, TTemplateData>,
private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
readonly onDidChangeTwistieState: Event<IDataTreeNode<T>>
) {
this.templateId = renderer.templateId;
......@@ -57,8 +64,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
return { templateData };
}
renderElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.renderElement(node.element, index, templateData.templateData);
renderElement(element: ITreeRenderElement<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.renderElement(unpack(element), index, templateData.templateData);
}
renderTwistie(element: IDataTreeNode<T>, twistieElement: HTMLElement): boolean {
......@@ -70,8 +77,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
return false;
}
disposeElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(node.element, index, templateData.templateData);
disposeElement(element: ITreeRenderElement<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(unpack(element), index, templateData.templateData);
}
disposeTemplate(templateData: IDataTreeListTemplateData<TTemplateData>): void {
......@@ -97,7 +104,7 @@ export class DataTree<T extends NonNullable<any>, TFilterData = void> implements
constructor(
container: HTMLElement,
delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[],
renderers: ITreeRenderer<T, TFilterData, any>[],
private dataSource: IDataSource<T>,
options?: ITreeOptions<T, TFilterData>
) {
......
......@@ -5,6 +5,7 @@
import { Event } from 'vs/base/common/event';
import { Iterator } from 'vs/base/common/iterator';
import { IRenderer } from 'vs/base/browser/ui/list/list';
export const enum TreeVisibility {
Hidden,
......@@ -60,4 +61,14 @@ export interface ITreeModel<T, TFilterData, TRef> {
getParentElement(location: TRef): T | null;
getFirstElementChild(location: TRef): T | null;
getLastElementAncestor(location: TRef): T | null;
}
export interface ITreeRenderElement<T, TFilterData> {
readonly element: T;
readonly filterData: TFilterData | undefined;
}
export interface ITreeRenderer<T, TFilterData, TTemplateData> extends IRenderer<ITreeRenderElement<T, TFilterData>, TTemplateData> {
renderTwistie?(element: T, twistieElement: HTMLElement): boolean;
onDidChangeTwistieState?: Event<T>;
}
\ No newline at end of file
......@@ -33,7 +33,8 @@ import { attachInputBoxStyler, attachListStyler, computeStyles, defaultListStyle
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { InputFocusedContextKey } from 'vs/platform/workbench/common/contextkeys';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ITreeRenderer, ITreeOptions as ITreeOptions2 } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeOptions as ITreeOptions2 } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
export type ListWidget = List<any> | PagedList<any> | ITree | ObjectTree<any, any>;
......@@ -814,7 +815,7 @@ export class WorkbenchObjectTree<T extends NonNullable<any>, TFilterData = void>
constructor(
container: HTMLElement,
delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[],
renderers: ITreeRenderer<T, TFilterData, any>[],
options: ITreeOptions2<T, TFilterData>,
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
......
......@@ -22,8 +22,7 @@ import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/mark
import { ILabelService } from 'vs/platform/label/common/label';
import { dirname } from 'vs/base/common/resources';
import { IVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeRenderer } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree';
import { ITreeFilter, TreeVisibility, TreeFilterResult, ITreeRenderer, ITreeRenderElement } from 'vs/base/browser/ui/tree/tree';
import { FilterOptions } from 'vs/workbench/parts/markers/electron-browser/markersFilterOptions';
import { IMatch } from 'vs/base/common/filters';
......@@ -99,7 +98,33 @@ export class VirtualDelegate implements IVirtualDelegate<ResourceMarkers | Marke
}
}
export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, IResourceMarkersTemplateData> {
const enum FilterDataType {
ResourceMarkers,
Marker,
RelatedInformation
}
interface ResourceMarkersFilterData {
type: FilterDataType.ResourceMarkers;
uriMatches: IMatch[];
}
interface MarkerFilterData {
type: FilterDataType.Marker;
messageMatches: IMatch[];
sourceMatches: IMatch[];
codeMatches: IMatch[];
}
interface RelatedInformationFilterData {
type: FilterDataType.RelatedInformation;
uriMatches: IMatch[];
messageMatches: IMatch[];
}
type FilterData = ResourceMarkersFilterData | MarkerFilterData | RelatedInformationFilterData;
export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, ResourceMarkersFilterData, IResourceMarkersTemplateData> {
constructor(
@IInstantiationService protected instantiationService: IInstantiationService,
......@@ -123,14 +148,17 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, I
}
// TODO@joao
renderElement(element: ResourceMarkers, _: number, templateData: IResourceMarkersTemplateData): void {
renderElement(element: ITreeRenderElement<ResourceMarkers, ResourceMarkersFilterData>, _: number, templateData: IResourceMarkersTemplateData): void {
const resourceMarkers = element.element;
const uriMatches = element.filterData && element.filterData.uriMatches || [];
if (templateData.resourceLabel instanceof FileLabel) {
templateData.resourceLabel.setFile(element.resource/* , { matches: element.uriMatches } */);
templateData.resourceLabel.setFile(resourceMarkers.resource, { matches: uriMatches });
} else {
templateData.resourceLabel.setLabel({ name: element.name, description: this.labelService.getUriLabel(dirname(element.resource), { relative: true }), resource: element.resource }/* , { matches: element.uriMatches } */);
templateData.resourceLabel.setLabel({ name: resourceMarkers.name, description: this.labelService.getUriLabel(dirname(resourceMarkers.resource), { relative: true }), resource: resourceMarkers.resource }, { matches: uriMatches });
}
templateData.count.setCount(element.markers.length/* filteredCount */);
// templateData.count.setCount(element.markers.length/* filteredCount */);
}
disposeElement(): void {
......@@ -156,7 +184,7 @@ export class FileResourceMarkersRenderer extends ResourceMarkersRenderer {
}
}
export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData> {
export class MarkerRenderer implements ITreeRenderer<Marker, MarkerFilterData, IMarkerTemplateData> {
constructor(
private actionItemProvider: IActionItemProvider,
......@@ -177,24 +205,26 @@ export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData
return data;
}
// TODO@joao
renderElement(element: Marker, _: number, templateData: IMarkerTemplateData): void {
let marker = element.marker;
renderElement(element: ITreeRenderElement<Marker, MarkerFilterData>, _: number, templateData: IMarkerTemplateData): void {
const marker = element.element.marker;
const sourceMatches = element.filterData && element.filterData.sourceMatches || [];
const messageMatches = element.filterData && element.filterData.messageMatches || [];
const codeMatches = element.filterData && element.filterData.codeMatches || [];
templateData.icon.className = 'icon ' + MarkerRenderer.iconClassNameFor(marker);
templateData.source.set(marker.source/* , element.sourceMatches */);
templateData.source.set(marker.source, sourceMatches);
dom.toggleClass(templateData.source.element, 'marker-source', !!marker.source);
templateData.actionBar.clear();
const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element);
const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element.element);
templateData.actionBar.push([quickFixAction], { icon: true, label: false });
templateData.description.set(marker.message/* , element.messageMatches */);
templateData.description.set(marker.message, messageMatches);
templateData.description.element.title = marker.message;
dom.toggleClass(templateData.code.element, 'marker-code', !!marker.code);
templateData.code.set(marker.code || ''/* , element.codeMatches */);
templateData.code.set(marker.code || '', codeMatches);
templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(marker.startLineNumber, marker.startColumn);
}
......@@ -224,7 +254,7 @@ export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData
}
}
export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformation, IRelatedInformationTemplateData> {
export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformation, RelatedInformationFilterData, IRelatedInformationTemplateData> {
constructor(
@ILabelService private labelService: ILabelService
......@@ -250,12 +280,16 @@ export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformat
}
// TODO@joao
renderElement(element: RelatedInformation, _: number, templateData: IRelatedInformationTemplateData): void {
templateData.resourceLabel.set(paths.basename(element.raw.resource.fsPath)/* , element.uriMatches */);
templateData.resourceLabel.element.title = this.labelService.getUriLabel(element.raw.resource, { relative: true });
templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(element.raw.startLineNumber, element.raw.startColumn);
templateData.description.set(element.raw.message/* , element.messageMatches */);
templateData.description.element.title = element.raw.message;
renderElement(element: ITreeRenderElement<RelatedInformation, RelatedInformationFilterData>, _: number, templateData: IRelatedInformationTemplateData): void {
const relatedInformation = element.element.raw;
const uriMatches = element.filterData && element.filterData.uriMatches || [];
const messageMatches = element.filterData && element.filterData.messageMatches || [];
templateData.resourceLabel.set(paths.basename(relatedInformation.resource.fsPath), uriMatches);
templateData.resourceLabel.element.title = this.labelService.getUriLabel(relatedInformation.resource, { relative: true });
templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(relatedInformation.startLineNumber, relatedInformation.startColumn);
templateData.description.set(relatedInformation.message, messageMatches);
templateData.description.element.title = relatedInformation.message;
}
disposeElement(): void {
......@@ -268,30 +302,6 @@ export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformat
}
}
const enum FilterDataType {
ResourceMarkers,
Marker,
RelatedInformation
}
interface ResourceMarkersFilterData {
type: FilterDataType.ResourceMarkers;
uriMatches: IMatch[];
}
interface MarkerFilterData {
type: FilterDataType.Marker;
messageMatches: IMatch[];
sourceMatches: IMatch[];
codeMatches: IMatch[];
}
interface RelatedInformationFilterData {
type: FilterDataType.RelatedInformation;
}
type FilterData = ResourceMarkersFilterData | MarkerFilterData | RelatedInformationFilterData;
export class Filter implements ITreeFilter<ResourceMarkers | Marker | RelatedInformation, FilterData> {
options = new FilterOptions();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册