提交 1dc65e06 编写于 作者: R Rob Lourens

Use new tree for settings TOC tree

上级 39237394
......@@ -17,7 +17,7 @@ import { ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selec
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IObjectTreeOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { ITreeModel, ITreeNode, ITreeRenderer, ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree';
import { ITreeFilter, ITreeModel, ITreeNode, ITreeRenderer, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
import { Action, IAction } from 'vs/base/common/actions';
import * as arrays from 'vs/base/common/arrays';
import { Color, RGBA } from 'vs/base/common/color';
......@@ -28,7 +28,7 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { ISpliceable } from 'vs/base/common/sequence';
import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
import { ITree, IFilter, IAccessibilityProvider } from 'vs/base/parts/tree/browser/tree';
import { IAccessibilityProvider, ITree } from 'vs/base/parts/tree/browser/tree';
import { localize } from 'vs/nls';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ICommandService } from 'vs/platform/commands/common/commands';
......@@ -1139,66 +1139,7 @@ function escapeInvisibleChars(enumValue: string): string {
.replace(/\r/g, '\\r');
}
export class SettingsTreeFilter implements IFilter {
constructor(
private viewState: ISettingsEditorViewState,
) { }
isVisible(tree: ITree, element: SettingsTreeElement): boolean {
// Filter during search
if (this.viewState.filterToCategory && element instanceof SettingsTreeSettingElement) {
if (!this.settingContainedInGroup(element.setting, this.viewState.filterToCategory)) {
return false;
}
}
// Non-user scope selected
if (element instanceof SettingsTreeSettingElement && this.viewState.settingsTarget !== ConfigurationTarget.USER) {
if (!element.matchesScope(this.viewState.settingsTarget)) {
return false;
}
}
// @modified or tag
if (element instanceof SettingsTreeSettingElement && this.viewState.tagFilters) {
if (!element.matchesAllTags(this.viewState.tagFilters)) {
return false;
}
}
// Group with no visible children
if (element instanceof SettingsTreeGroupElement) {
if (typeof element.count === 'number') {
return element.count > 0;
}
return element.children.some(child => this.isVisible(tree, child));
}
// Filtered "new extensions" button
if (element instanceof SettingsTreeNewExtensionsElement) {
if ((this.viewState.tagFilters && this.viewState.tagFilters.size) || this.viewState.filterToCategory) {
return false;
}
}
return true;
}
private settingContainedInGroup(setting: ISetting, group: SettingsTreeGroupElement): boolean {
return group.children.some(child => {
if (child instanceof SettingsTreeGroupElement) {
return this.settingContainedInGroup(setting, child);
} else if (child instanceof SettingsTreeSettingElement) {
return child.setting.key === setting.key;
} else {
return false;
}
});
}
}
export class SettingsTreeFilter2 implements ITreeFilter<SettingsTreeElement> {
export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
constructor(
private viewState: ISettingsEditorViewState,
) { }
......@@ -1362,7 +1303,7 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
return e.id;
}
},
filter: new SettingsTreeFilter2(viewState)
filter: new SettingsTreeFilter(viewState)
});
this.disposables = [];
......@@ -1370,7 +1311,7 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
const activeBorderColor = theme.getColor(focusBorder);
if (activeBorderColor) {
// TODO@rob - why isn't this applied when added to the stylesheet from tocTree.ts? Seems like a chromium glitch.
collector.addRule(`.settings-editor > .settings-body > .settings-toc-container .monaco-tree:focus .monaco-tree-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`);
collector.addRule(`.settings-editor > .settings-body > .settings-toc-container .monaco-list:focus .monaco-list-row.focused {outline: solid 1px ${activeBorderColor}; outline-offset: -1px; }`);
}
const foregroundColor = theme.getColor(foreground);
......
......@@ -4,17 +4,15 @@
*--------------------------------------------------------------------------------------------*/
import * as DOM from 'vs/base/browser/dom';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { IDataSource, IRenderer, ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree';
import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { IObjectTreeOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ITreeElement, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { Iterator } from 'vs/base/common/iterator';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IListService, WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService';
import { editorBackground } from 'vs/platform/theme/common/colorRegistry';
import { attachStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { SettingsAccessibilityProvider, SettingsTreeFilter } from 'vs/workbench/parts/preferences/browser/settingsTree';
import { SettingsTreeFilter } from 'vs/workbench/parts/preferences/browser/settingsTree';
import { ISettingsEditorViewState, SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels';
import { settingsHeaderForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets';
......@@ -82,43 +80,6 @@ export class TOCTreeModel {
}
}
export type TOCTreeElement = SettingsTreeGroupElement | TOCTreeModel;
export class TOCDataSource implements IDataSource {
constructor(private _treeFilter: SettingsTreeFilter) {
}
getId(tree: ITree, element: SettingsTreeGroupElement): string {
return element.id;
}
hasChildren(tree: ITree, element: TOCTreeElement): boolean {
if (element instanceof TOCTreeModel) {
return true;
}
if (element instanceof SettingsTreeGroupElement) {
// Should have child which won't be filtered out
return element.children && element.children.some(child => child instanceof SettingsTreeGroupElement && this._treeFilter.isVisible(tree, child));
}
return false;
}
getChildren(tree: ITree, element: TOCTreeElement): Promise<SettingsTreeElement[]> {
return Promise.resolve(this._getChildren(element));
}
private _getChildren(element: TOCTreeElement): SettingsTreeElement[] {
return (<SettingsTreeElement[]>element.children)
.filter(child => child instanceof SettingsTreeGroupElement);
}
getParent(tree: ITree, element: TOCTreeElement): Promise<any> {
return Promise.resolve(element instanceof SettingsTreeGroupElement && element.parent);
}
}
const TOC_ENTRY_TEMPLATE_ID = 'settings.toc.entry';
interface ITOCEntryTemplate {
......@@ -126,23 +87,19 @@ interface ITOCEntryTemplate {
countElement: HTMLElement;
}
export class TOCRenderer implements IRenderer {
getHeight(tree: ITree, element: SettingsTreeElement): number {
return 22;
}
export class TOCRenderer implements ITreeRenderer<SettingsTreeGroupElement, never, ITOCEntryTemplate> {
getTemplateId(tree: ITree, element: SettingsTreeElement): string {
return TOC_ENTRY_TEMPLATE_ID;
}
templateId = TOC_ENTRY_TEMPLATE_ID;
renderTemplate(tree: ITree, templateId: string, container: HTMLElement): ITOCEntryTemplate {
renderTemplate(container: HTMLElement): ITOCEntryTemplate {
return {
labelElement: DOM.append(container, $('.settings-toc-entry')),
countElement: DOM.append(container, $('.settings-toc-count'))
};
}
renderElement(tree: ITree, element: SettingsTreeGroupElement, templateId: string, template: ITOCEntryTemplate): void {
renderElement(node: ITreeNode<SettingsTreeGroupElement>, index: number, template: ITOCEntryTemplate): void {
const element = node.element;
const count = element.count;
const label = element.label;
......@@ -156,49 +113,59 @@ export class TOCRenderer implements IRenderer {
}
}
disposeTemplate(tree: ITree, templateId: string, templateData: any): void {
disposeTemplate(templateData: ITOCEntryTemplate): void {
}
}
class TOCTreeDelegate implements IListVirtualDelegate<SettingsTreeElement> {
getTemplateId(element: SettingsTreeElement): string {
return TOC_ENTRY_TEMPLATE_ID;
}
getHeight(element: SettingsTreeElement): number {
return 22;
}
}
export class TOCTree extends WorkbenchTree {
export function createTOCIterator(model: TOCTreeModel | SettingsTreeGroupElement): Iterator<ITreeElement<SettingsTreeGroupElement>> {
const groupChildren = <SettingsTreeGroupElement[]>model.children.filter(c => c instanceof SettingsTreeGroupElement);
const groupsIt = Iterator.fromArray(groupChildren);
return Iterator.map(groupsIt, g => {
return {
element: g,
children: g instanceof SettingsTreeGroupElement ?
createTOCIterator(g) :
undefined
};
});
}
export class TOCTree extends ObjectTree<SettingsTreeGroupElement> {
constructor(
container: HTMLElement,
viewState: ISettingsEditorViewState,
configuration: Partial<ITreeConfiguration>,
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService
@IInstantiationService instantiationService: IInstantiationService
) {
const treeClass = 'settings-toc-tree';
// test open mode
const filter = instantiationService.createInstance(SettingsTreeFilter, viewState);
const fullConfiguration = <ITreeConfiguration>{
controller: instantiationService.createInstance(WorkbenchTreeController, {}),
const options: IObjectTreeOptions<SettingsTreeGroupElement> = {
filter,
styler: new DefaultTreestyler(DOM.createStyleSheet(container), treeClass),
dataSource: instantiationService.createInstance(TOCDataSource, filter),
accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider),
...configuration
};
const options: ITreeOptions = {
showLoading: false,
twistiePixels: 15,
horizontalScrollMode: ScrollbarVisibility.Hidden
identityProvider: {
getId(e) {
return e.id;
}
}
};
super(container,
fullConfiguration,
options,
contextKeyService,
listService,
themeService,
instantiationService,
configurationService);
new TOCTreeDelegate(),
[new TOCRenderer()],
options);
const treeClass = 'settings-toc-tree';
this.getHTMLElement().classList.add(treeClass);
this.disposables.push(attachStyler(themeService, {
......
......@@ -199,7 +199,7 @@
position: absolute;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree {
.settings-editor > .settings-body .settings-toc-container .monaco-list {
width: 160px;
pointer-events: initial;
}
......@@ -213,11 +213,11 @@
display: none;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .content {
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .monaco-tl-contents {
display: flex;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-entry {
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .settings-toc-entry {
overflow: hidden;
text-overflow: ellipsis;
line-height: 22px;
......@@ -225,30 +225,30 @@
flex-shrink: 1;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-count {
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count {
display: none;
line-height: 22px;
opacity: 0.7;
margin-left: 3px;
}
.settings-editor.search-mode > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-count {
.settings-editor.search-mode > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count {
display: block;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children > .content::before {
.settings-editor > .settings-body .settings-toc-container .monaco-list-row.has-children > .content::before {
opacity: 0.9;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.has-children.selected > .content::before {
.settings-editor > .settings-body .settings-toc-container .monaco-list-row.has-children.selected > .content::before {
opacity: 1;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-entry.no-results {
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .settings-toc-entry.no-results {
opacity: 0.5;
}
.settings-editor > .settings-body .settings-toc-container .monaco-tree-row.selected .settings-toc-entry {
.settings-editor > .settings-body .settings-toc-container .monaco-list-row.selected .settings-toc-entry {
font-weight: bold;
opacity: 1;
}
......@@ -535,6 +535,6 @@
padding-top: 7px;
}
.settings-editor.search-mode > .settings-body .settings-toc-container .monaco-tree-row .settings-toc-count {
.settings-editor.search-mode > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count {
display: block;
}
\ No newline at end of file
......@@ -13,14 +13,12 @@ import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors';
import { Iterator } from 'vs/base/common/iterator';
import { isArray } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { collapseAll, expandAll } from 'vs/base/parts/tree/browser/treeUtils';
import 'vs/css!./media/settingsEditor2';
import { localize } from 'vs/nls';
import { ConfigurationTarget, ConfigurationTargetToString, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { WorkbenchTree } from 'vs/platform/list/browser/listService';
import { ILogService } from 'vs/platform/log/common/log';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
......@@ -36,7 +34,7 @@ import { commonlyUsedData, tocData } from 'vs/workbench/parts/preferences/browse
import { AbstractSettingRenderer, ISettingLinkClickEvent, ISettingOverrideClickEvent, resolveExtensionsSettings, resolveSettingsTree, SettingsTree, SettingTreeRenderers } from 'vs/workbench/parts/preferences/browser/settingsTree';
import { ISettingsEditorViewState, parseQuery, SearchResultIdx, SearchResultModel, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeModel } from 'vs/workbench/parts/preferences/browser/settingsTreeModels';
import { settingsTextInputBorder } from 'vs/workbench/parts/preferences/browser/settingsWidgets';
import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree';
import { createTOCIterator, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree';
import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider, MODIFIED_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/parts/preferences/common/preferences';
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
import { IPreferencesService, ISearchResult, ISettingsEditorModel, ISettingsEditorOptions, SettingsEditorOptions, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
......@@ -98,7 +96,7 @@ export class SettingsEditor2 extends BaseEditor {
private clearFilterLinkContainer: HTMLElement;
private tocTreeContainer: HTMLElement;
private tocTree: WorkbenchTree;
private tocTree: TOCTree;
private settingsAriaExtraLabelsContainer: HTMLElement;
......@@ -552,24 +550,26 @@ export class SettingsEditor2 extends BaseEditor {
this.tocTreeModel = new TOCTreeModel(this.viewState);
this.tocTreeContainer = DOM.append(parent, $('.settings-toc-container'));
const tocRenderer = this.instantiationService.createInstance(TOCRenderer);
this.tocTree = this._register(this.instantiationService.createInstance(TOCTree,
DOM.append(this.tocTreeContainer, $('.settings-toc-wrapper')),
this.viewState,
{
renderer: tocRenderer
}));
this.viewState));
this._register(this.tocTree.onDidChangeFocus(e => {
const element: SettingsTreeGroupElement = e.focus;
this.tocTree.setSelection(e.elements);
const element: SettingsTreeGroupElement = e.elements[0];
if (this.searchResultModel) {
this.viewState.filterToCategory = element;
this.renderTree();
this.settingsTree.scrollTop = 0;
} else if (element && (!e.payload || !e.payload.fromScroll)) {
if (this.viewState.filterToCategory !== element) {
this.viewState.filterToCategory = element;
this.renderTree();
this.settingsTree.scrollTop = 0;
}
} else if (element) {
this.settingsTree.reveal(element, 0);
}
// else if (element && (!e.payload || !e.payload.fromScroll)) {
// this.settingsTree.reveal(element, 0);
// }
}));
this._register(this.tocTree.onDidFocus(() => {
......@@ -655,7 +655,7 @@ export class SettingsEditor2 extends BaseEditor {
return;
}
if (!this.tocTree.getInput()) {
if (!this.tocTreeModel) {
return;
}
......@@ -679,8 +679,8 @@ export class SettingsEditor2 extends BaseEditor {
// this.tocTree.expand(element);
this.tocTree.setSelection([element]);
this.tocTree.setFocus(element, { fromScroll: true });
// this.tocTree.setSelection([element]);
// this.tocTree.setFocus(element, { fromScroll: true });
}
}
......@@ -870,11 +870,8 @@ export class SettingsEditor2 extends BaseEditor {
this.refreshTree();
this.tocTreeModel.settingsTreeRoot = this.settingsTreeModel.root as SettingsTreeGroupElement;
if (this.tocTree.getInput()) {
this.tocTree.refresh();
} else {
this.tocTree.setInput(this.tocTreeModel);
}
this.refreshTOCTree();
this.tocTree.collapseAll();
}
return Promise.resolve(void 0);
......@@ -943,13 +940,18 @@ export class SettingsEditor2 extends BaseEditor {
}
this.tocTreeModel.update();
return this.tocTree.refresh();
this.refreshTOCTree();
return Promise.resolve(undefined);
}
private refreshTree(): void {
this.settingsTree.setChildren(null, createGroupIterator(this.currentSettingsModel.root));
}
private refreshTOCTree(): void {
this.tocTree.setChildren(null, createTOCIterator(this.tocTreeModel));
}
private updateModifiedLabelForKey(key: string): void {
const dataElements = this.currentSettingsModel.getElementsByName(key);
const isModified = dataElements && dataElements[0] && dataElements[0].isConfigured; // all elements are either configured or not
......@@ -1002,18 +1004,18 @@ export class SettingsEditor2 extends BaseEditor {
this.viewState.filterToCategory = null;
this.tocTreeModel.currentSearchModel = this.searchResultModel;
this.tocTree.refresh();
this.refreshTOCTree();
this.onSearchModeToggled();
if (this.searchResultModel) {
// Added a filter model
this.tocTree.setSelection([]);
expandAll(this.tocTree);
this.tocTree.expandAll();
this.refreshTree();
this.renderResultCountMessages();
} else {
// Leaving search mode
collapseAll(this.tocTree);
this.tocTree.collapseAll();
this.refreshTree();
this.renderResultCountMessages();
}
......@@ -1145,7 +1147,7 @@ export class SettingsEditor2 extends BaseEditor {
this.tocTree.setSelection([]);
this.viewState.filterToCategory = null;
expandAll(this.tocTree);
this.tocTree.expandAll();
return this.renderTree().then(() => result);
});
......@@ -1205,7 +1207,7 @@ export class SettingsEditor2 extends BaseEditor {
const tocTreeHeight = listHeight - 16;
this.tocTreeContainer.style.height = `${tocTreeHeight}px`;
this.tocTree.layout(tocTreeHeight, 175);
this.tocTree.layout(tocTreeHeight);
}
protected saveState(): void {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册