提交 423da148 编写于 作者: R Rob Lourens

files.exclude control - focus/keyboard behavior

上级 e58c103e
......@@ -37,8 +37,12 @@
position: relative;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:focus {
outline: none;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover .monaco-action-bar,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.focused .monaco-action-bar {
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected .monaco-action-bar {
display: block;
}
......
......@@ -15,7 +15,7 @@ import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import 'vs/css!./media/settingsWidgets';
import { localize } from 'vs/nls';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry';
import { foreground, inputBackground, inputBorder, inputForeground, listHoverBackground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, listHoverForeground, listActiveSelectionBackground, listActiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry';
import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
......@@ -76,27 +76,47 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; }`);
}
// Exclude control
const listHoverBackgroundColor = theme.getColor(listHoverBackground);
if (listHoverBackgroundColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover { background-color: ${listHoverBackgroundColor}; }`);
}
const listHoverForegroundColor = theme.getColor(listHoverForeground);
if (listHoverForegroundColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover { color: ${listHoverForegroundColor}; }`);
}
const listSelectBackgroundColor = theme.getColor(listActiveSelectionBackground);
if (listSelectBackgroundColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { background-color: ${listSelectBackgroundColor}; }`);
}
const listSelectForegroundColor = theme.getColor(listActiveSelectionForeground);
if (listSelectForegroundColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected { color: ${listSelectForegroundColor}; }`);
}
});
export class ExcludeSettingListModel {
private _dataItems: IExcludeDataItem[] = [];
private _editKey: string;
private _editKey: string | null;
private _selectedIdx: number | null;
get items(): IExcludeViewItem[] {
const items = this._dataItems.map(item => {
const items = this._dataItems.map((item, i) => {
const editing = item.pattern === this._editKey;
return <IExcludeViewItem>{
...item,
editing: item.pattern === this._editKey
editing,
selected: i === this._selectedIdx || editing
};
});
if (this._editKey === '') {
items.push({
editing: true,
selected: true,
pattern: '',
sibling: ''
});
......@@ -112,6 +132,26 @@ export class ExcludeSettingListModel {
setValue(excludeData: IExcludeDataItem[]): void {
this._dataItems = excludeData;
}
select(idx: number): void {
this._selectedIdx = idx;
}
selectNext(): void {
if (typeof this._selectedIdx === 'number') {
this._selectedIdx = Math.min(this._selectedIdx + 1, this._dataItems.length - 1);
} else {
this._selectedIdx = 0;
}
}
selectPrevious(): void {
if (typeof this._selectedIdx === 'number') {
this._selectedIdx = Math.max(this._selectedIdx - 1, 0);
} else {
this._selectedIdx = 0;
}
}
}
interface IExcludeChangeEvent {
......@@ -137,8 +177,41 @@ export class ExcludeSettingWidget extends Disposable {
super();
this.listElement = DOM.append(container, $('.setting-exclude-widget'));
this.listElement.setAttribute('tabindex', '0');
DOM.append(container, this.renderAddButton());
this.renderList();
this._register(DOM.addDisposableListener(this.listElement, 'click', (e: MouseEvent) => {
if (!e.target) {
return;
}
const element = DOM.findParentWithClass((<any>e.target), 'setting-exclude-row');
if (!element) {
return;
}
const targetIdx = element.getAttribute('data-index');
if (!targetIdx) {
return;
}
this.model.select(parseInt(targetIdx));
this.renderList();
e.preventDefault();
e.stopPropagation();
}));
this._register(DOM.addStandardDisposableListener(this.listElement, 'keydown', (e: KeyboardEvent) => {
if (e.keyCode === KeyCode.UpArrow) {
this.model.selectPrevious();
this.renderList();
} else if (e.keyCode === KeyCode.DownArrow) {
this.model.selectNext();
this.renderList();
}
}));
}
setValue(excludeData: IExcludeDataItem[]): void {
......@@ -154,7 +227,7 @@ export class ExcludeSettingWidget extends Disposable {
DOM.toggleClass(this.container, 'setting-exclude-new-mode', newMode);
this.model.items
.map(item => this.renderItem(item))
.map((item, i) => this.renderItem(item, i))
.forEach(itemElement => this.listElement.appendChild(itemElement));
const listHeight = 22 * this.model.items.length;
......@@ -184,14 +257,18 @@ export class ExcludeSettingWidget extends Disposable {
};
}
private renderItem(item: IExcludeViewItem): HTMLElement {
private renderItem(item: IExcludeViewItem, idx: number): HTMLElement {
return item.editing ?
this.renderEditItem(item) :
this.renderDataItem(item);
this.renderDataItem(item, idx);
}
private renderDataItem(item: IExcludeDataItem): HTMLElement {
private renderDataItem(item: IExcludeViewItem, idx: number): HTMLElement {
const rowElement = $('.setting-exclude-row');
rowElement.setAttribute('data-index', idx + '');
rowElement.setAttribute('tabindex', item.selected ? '0' : '-1');
DOM.toggleClass(rowElement, 'selected', item.selected);
const actionBar = new ActionBar(rowElement);
this.listDisposables.push(actionBar);
......@@ -209,6 +286,12 @@ export class ExcludeSettingWidget extends Disposable {
localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", item.pattern, item.sibling) :
localize('excludePatternHintLabel', "Exclude files matching `{0}`", item.pattern);
if (item.selected) {
setTimeout(() => {
rowElement.focus();
}, 10);
}
return rowElement;
}
......@@ -312,4 +395,5 @@ export interface IExcludeDataItem {
interface IExcludeViewItem extends IExcludeDataItem {
editing?: boolean;
selected?: boolean;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册