Skip to content

Commit

Permalink
Use ThemeIcon & IconRegistry for custom icons
Browse files Browse the repository at this point in the history
  • Loading branch information
aeschli committed Nov 25, 2020
1 parent c59ddc6 commit 2ecb47d
Show file tree
Hide file tree
Showing 43 changed files with 231 additions and 179 deletions.
4 changes: 2 additions & 2 deletions src/vs/base/browser/ui/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { Codicon } from 'vs/base/common/codicons';
import { Codicon, CSSIcon } from 'vs/base/common/codicons';
import { BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';

export interface ICheckboxOpts extends ICheckboxStyles {
readonly actionClassName?: string;
readonly icon?: Codicon;
readonly icon?: CSSIcon;
readonly title: string;
readonly isChecked: boolean;
}
Expand Down
8 changes: 6 additions & 2 deletions src/vs/base/common/codicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,22 @@ export function registerIcon(id: string, def: Codicon, description?: string) {
return new Codicon(id, def, description);
}

export class Codicon {
export class Codicon implements CSSIcon {
constructor(public readonly id: string, public readonly definition: Codicon | IconDefinition, public description?: string) {
_registry.add(this);
}
public get classNames() { return 'codicon codicon-' + this.id; }
// classNamesArray is useful for migrating to ES6 classlist
public get classNamesArray() { return ['codicon', 'codicon-' + this.id]; }
public get cssSelector() { return '.codicon.codicon-' + this.id; }
}

public get classNameIdentifier() { return 'codicon-' + this.id; }
export interface CSSIcon {
readonly classNames: string;
}



interface IconDefinition {
character: string;
}
Expand Down
2 changes: 1 addition & 1 deletion src/vs/base/parts/quickinput/browser/quickInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const $ = dom.$;
type Writeable<T> = { -readonly [P in keyof T]: T[P] };


const backButtonIcon = registerIcon('quick-input-back', Codicon.arrowLeft);
const backButtonIcon = registerIcon('quick-input-back', Codicon.arrowLeft, localize('backButtonIcon', 'Icon for the back button in the quick input dialog.'));

const backButton = {
iconClass: backButtonIcon.classNames,
Expand Down
15 changes: 8 additions & 7 deletions src/vs/editor/browser/widget/diffEditorWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { defaultInsertColor, defaultRemoveColor, diffBorder, diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, scrollbarShadow, scrollbarSliderBackground, scrollbarSliderHoverBackground, scrollbarSliderActiveBackground, diffDiagonalFill } from 'vs/platform/theme/common/colorRegistry';
import { IColorTheme, IThemeService, getThemeTypeSelector, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { IColorTheme, IThemeService, getThemeTypeSelector, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IDiffLinesChange, InlineDiffMargin } from 'vs/editor/browser/widget/inlineDiffMargin';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
Expand All @@ -48,10 +48,11 @@ import { EditorExtensionsRegistry, IDiffEditorContributionDescription } from 'vs
import { onUnexpectedError } from 'vs/base/common/errors';
import { IEditorProgressService, IProgressRunner } from 'vs/platform/progress/common/progress';
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
import { Codicon, registerIcon } from 'vs/base/common/codicons';
import { Codicon } from 'vs/base/common/codicons';
import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor/mouseCursor';
import { IViewLineTokens } from 'vs/editor/common/core/lineTokens';
import { FontInfo } from 'vs/editor/common/config/fontInfo';
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';

interface IEditorDiffDecorations {
decorations: IModelDeltaDecoration[];
Expand Down Expand Up @@ -154,8 +155,8 @@ class VisualEditorState {
let DIFF_EDITOR_ID = 0;


const diffInsertIcon = registerIcon('diff-insert', Codicon.add);
const diffRemoveIcon = registerIcon('diff-remove', Codicon.remove);
const diffInsertIcon = registerIcon('diff-insert', Codicon.add, nls.localize('diffInsertIcon', 'Line decoration for inserts in the diff editor'));
const diffRemoveIcon = registerIcon('diff-remove', Codicon.remove, nls.localize('diffRemoveIcon', 'Line decoration for removals in the diff editor'));
const ttPolicy = window.trustedTypes?.createPolicy('diffEditorWidget', { createHTML: value => value });

export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffEditor {
Expand Down Expand Up @@ -1760,7 +1761,7 @@ const DECORATIONS = {
}),
lineInsertWithSign: ModelDecorationOptions.register({
className: 'line-insert',
linesDecorationsClassName: 'insert-sign ' + diffInsertIcon.classNames,
linesDecorationsClassName: 'insert-sign ' + ThemeIcon.asClassName(diffInsertIcon),
marginClassName: 'line-insert',
isWholeLine: true
}),
Expand All @@ -1772,7 +1773,7 @@ const DECORATIONS = {
}),
lineDeleteWithSign: ModelDecorationOptions.register({
className: 'line-delete',
linesDecorationsClassName: 'delete-sign ' + diffRemoveIcon.classNames,
linesDecorationsClassName: 'delete-sign ' + ThemeIcon.asClassName(diffRemoveIcon),
marginClassName: 'line-delete',
isWholeLine: true

Expand Down Expand Up @@ -2462,7 +2463,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {

if (this._renderIndicators) {
const marginElement = document.createElement('div');
marginElement.className = `delete-sign ${diffRemoveIcon.classNames}`;
marginElement.className = `delete-sign ${ThemeIcon.asClassName(diffRemoveIcon)}`;
marginElement.setAttribute('style', `position:absolute;top:${renderedLineCount * lineHeight}px;width:${lineDecorationsWidth}px;height:${lineHeight}px;right:0;`);
marginDomNode.appendChild(marginElement);
}
Expand Down
17 changes: 9 additions & 8 deletions src/vs/editor/browser/widget/diffReview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ import { ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
import { Constants } from 'vs/base/common/uint';
import { registerIcon, Codicon } from 'vs/base/common/codicons';
import { Codicon } from 'vs/base/common/codicons';
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';

const DIFF_LINES_PADDING = 3;

Expand Down Expand Up @@ -73,9 +74,9 @@ class Diff {
}
}

const diffReviewInsertIcon = registerIcon('diff-review-insert', Codicon.add);
const diffReviewRemoveIcon = registerIcon('diff-review-remove', Codicon.remove);
const diffReviewCloseIcon = registerIcon('diff-review-close', Codicon.close);
const diffReviewInsertIcon = registerIcon('diff-review-insert', Codicon.add, nls.localize('diffReviewInsertIcon', 'Icon for \'Insert\' in diff review.'));
const diffReviewRemoveIcon = registerIcon('diff-review-remove', Codicon.remove, nls.localize('diffReviewRemoveIcon', 'Icon for \'Remove\' in diff review.'));
const diffReviewCloseIcon = registerIcon('diff-review-close', Codicon.close, nls.localize('diffReviewCloseIcon', 'Icon for \'Close\' in diff review.'));

export class DiffReview extends Disposable {

Expand Down Expand Up @@ -104,7 +105,7 @@ export class DiffReview extends Disposable {
this.actionBarContainer.domNode
));

this._actionBar.push(new Action('diffreview.close', nls.localize('label.close', "Close"), 'close-diff-review ' + diffReviewCloseIcon.classNames, true, () => {
this._actionBar.push(new Action('diffreview.close', nls.localize('label.close', "Close"), 'close-diff-review ' + ThemeIcon.asClassName(diffReviewCloseIcon), true, () => {
this.hide();
return Promise.resolve(null);
}), { label: false, icon: true });
Expand Down Expand Up @@ -647,7 +648,7 @@ export class DiffReview extends Disposable {
let rowClassName: string = 'diff-review-row';
let lineNumbersExtraClassName: string = '';
const spacerClassName: string = 'diff-review-spacer';
let spacerIcon: Codicon | null = null;
let spacerIcon: ThemeIcon | null = null;
switch (type) {
case DiffEntryType.Insert:
rowClassName = 'diff-review-row line-insert';
Expand Down Expand Up @@ -723,7 +724,7 @@ export class DiffReview extends Disposable {

if (spacerIcon) {
const spacerCodicon = document.createElement('span');
spacerCodicon.className = spacerIcon.classNames;
spacerCodicon.className = ThemeIcon.asClassName(spacerIcon);
spacerCodicon.innerText = '\u00a0\u00a0';
spacer.appendChild(spacerCodicon);
} else {
Expand Down
53 changes: 31 additions & 22 deletions src/vs/editor/contrib/find/findWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contri
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { contrastBorder, editorFindMatch, editorFindMatchBorder, editorFindMatchHighlight, editorFindMatchHighlightBorder, editorFindRangeHighlight, editorFindRangeHighlightBorder, editorWidgetBackground, editorWidgetBorder, editorWidgetResizeBorder, errorForeground, inputActiveOptionBorder, inputActiveOptionBackground, inputActiveOptionForeground, inputBackground, inputBorder, inputForeground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationInfoForeground, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationWarningForeground, widgetShadow, editorWidgetForeground, focusBorder } from 'vs/platform/theme/common/colorRegistry';
import { IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { IColorTheme, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
import { ContextScopedFindInput, ContextScopedReplaceInput } from 'vs/platform/browser/contextScopedHistoryWidget';
import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { Codicon, registerIcon } from 'vs/base/common/codicons';
import { Codicon } from 'vs/base/common/codicons';
import { registerIcon, widgetClose } from 'vs/platform/theme/common/iconRegistry';

const findSelectionIcon = registerIcon('find-selection', Codicon.selection);
const findCollapsedIcon = registerIcon('find-collapsed', Codicon.chevronRight);
const findExpandedIcon = registerIcon('find-expanded', Codicon.chevronDown);
const findSelectionIcon = registerIcon('find-selection', Codicon.selection, nls.localize('findSelectionIcon', 'Icon for \'Find in Selection\' in the editor find widget.'));
const findCollapsedIcon = registerIcon('find-collapsed', Codicon.chevronRight, nls.localize('findCollapsedIcon', 'Icon to indicate that the editor find widget is collapsed.'));
const findExpandedIcon = registerIcon('find-expanded', Codicon.chevronDown, nls.localize('findExpandedIcon', 'Icon to indicate that the editor find widget is expanded.'));

export const findCloseIcon = registerIcon('find-close', Codicon.close);
export const findReplaceIcon = registerIcon('find-replace', Codicon.replace);
export const findReplaceAllIcon = registerIcon('find-replace-all', Codicon.replaceAll);
export const findPreviousMatchIcon = registerIcon('find-previous-match', Codicon.arrowUp);
export const findNextMatchIcon = registerIcon('find-next-match', Codicon.arrowDown);
export const findReplaceIcon = registerIcon('find-replace', Codicon.replace, nls.localize('findReplaceIcon', 'Icon for \'Replace\' in the editor find widget.'));
export const findReplaceAllIcon = registerIcon('find-replace-all', Codicon.replaceAll, nls.localize('findReplaceAllIcon', 'Icon for \'Replace All\' in the editor find widget.'));
export const findPreviousMatchIcon = registerIcon('find-previous-match', Codicon.arrowUp, nls.localize('findPreviousMatchIcon', 'Icon for \'Find Previous\' in the editor find widget.'));
export const findNextMatchIcon = registerIcon('find-next-match', Codicon.arrowDown, nls.localize('findNextMatchIcon', 'Icon for \'Find Next\' in the editor find widget.'));

export interface IFindController {
replace(): void;
Expand Down Expand Up @@ -1017,7 +1017,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
// Previous button
this._prevBtn = this._register(new SimpleButton({
label: NLS_PREVIOUS_MATCH_BTN_LABEL + this._keybindingLabelFor(FIND_IDS.PreviousMatchFindAction),
className: findPreviousMatchIcon.classNames,
icon: findPreviousMatchIcon,
onTrigger: () => {
this._codeEditor.getAction(FIND_IDS.PreviousMatchFindAction).run().then(undefined, onUnexpectedError);
}
Expand All @@ -1026,7 +1026,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
// Next button
this._nextBtn = this._register(new SimpleButton({
label: NLS_NEXT_MATCH_BTN_LABEL + this._keybindingLabelFor(FIND_IDS.NextMatchFindAction),
className: findNextMatchIcon.classNames,
icon: findNextMatchIcon,
onTrigger: () => {
this._codeEditor.getAction(FIND_IDS.NextMatchFindAction).run().then(undefined, onUnexpectedError);
}
Expand All @@ -1044,7 +1044,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL

// Toggle selection button
this._toggleSelectionFind = this._register(new Checkbox({
icon: findSelectionIcon,
icon: ThemeIcon.asCSSIcon(findSelectionIcon),
title: NLS_TOGGLE_SELECTION_FIND_TITLE + this._keybindingLabelFor(FIND_IDS.ToggleSearchScopeCommand),
isChecked: false
}));
Expand Down Expand Up @@ -1077,7 +1077,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
// Close button
this._closeBtn = this._register(new SimpleButton({
label: NLS_CLOSE_BTN_LABEL + this._keybindingLabelFor(FIND_IDS.CloseFindWidgetCommand),
className: findCloseIcon.classNames,
icon: widgetClose,
onTrigger: () => {
this._state.change({ isRevealed: false, searchScope: null }, false);
},
Expand Down Expand Up @@ -1141,7 +1141,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
// Replace one button
this._replaceBtn = this._register(new SimpleButton({
label: NLS_REPLACE_BTN_LABEL + this._keybindingLabelFor(FIND_IDS.ReplaceOneAction),
className: findReplaceIcon.classNames,
icon: findReplaceIcon,
onTrigger: () => {
this._controller.replace();
},
Expand All @@ -1156,7 +1156,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
// Replace all button
this._replaceAllBtn = this._register(new SimpleButton({
label: NLS_REPLACE_ALL_BTN_LABEL + this._keybindingLabelFor(FIND_IDS.ReplaceAllAction),
className: findReplaceAllIcon.classNames,
icon: findReplaceAllIcon,
onTrigger: () => {
this._controller.replaceAll();
}
Expand Down Expand Up @@ -1293,7 +1293,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL

export interface ISimpleButtonOpts {
readonly label: string;
readonly className: string;
readonly className?: string;
readonly icon?: ThemeIcon;
readonly onTrigger: () => void;
readonly onKeyDown?: (e: IKeyboardEvent) => void;
}
Expand All @@ -1307,10 +1308,18 @@ export class SimpleButton extends Widget {
super();
this._opts = opts;

let className = 'button';
if (this._opts.className) {
className = className + ' ' + this._opts.className;
}
if (this._opts.icon) {
className = className + ' ' + ThemeIcon.asClassName(this._opts.icon);
}

this._domNode = document.createElement('div');
this._domNode.title = this._opts.label;
this._domNode.tabIndex = 0;
this._domNode.className = 'button ' + this._opts.className;
this._domNode.className = className;
this._domNode.setAttribute('role', 'button');
this._domNode.setAttribute('aria-label', this._opts.label);

Expand Down Expand Up @@ -1352,11 +1361,11 @@ export class SimpleButton extends Widget {
public setExpanded(expanded: boolean): void {
this._domNode.setAttribute('aria-expanded', String(!!expanded));
if (expanded) {
this._domNode.classList.remove(...findCollapsedIcon.classNames.split(' '));
this._domNode.classList.add(...findExpandedIcon.classNames.split(' '));
this._domNode.classList.remove(...ThemeIcon.asClassNameArray(findCollapsedIcon));
this._domNode.classList.add(...ThemeIcon.asClassNameArray(findExpandedIcon));
} else {
this._domNode.classList.remove(...findExpandedIcon.classNames.split(' '));
this._domNode.classList.add(...findCollapsedIcon.classNames.split(' '));
this._domNode.classList.remove(...ThemeIcon.asClassNameArray(findExpandedIcon));
this._domNode.classList.add(...ThemeIcon.asClassNameArray(findCollapsedIcon));
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/vs/editor/contrib/folding/folding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { InitializingRangeProvider, ID_INIT_PROVIDER } from 'vs/editor/contrib/f
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { onUnexpectedError } from 'vs/base/common/errors';
import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
import { registerColor, editorSelectionBackground, transparent, iconForeground } from 'vs/platform/theme/common/colorRegistry';

const CONTEXT_FOLDING_ENABLED = new RawContextKey<boolean>('foldingEnabled', false);
Expand Down Expand Up @@ -916,8 +916,8 @@ registerThemingParticipant((theme, collector) => {
const editorFoldColor = theme.getColor(editorFoldForeground);
if (editorFoldColor) {
collector.addRule(`
.monaco-editor .cldr${foldingExpandedIcon.cssSelector},
.monaco-editor .cldr${foldingCollapsedIcon.cssSelector} {
.monaco-editor .cldr${ThemeIcon.asCSSSelector(foldingExpandedIcon)},
.monaco-editor .cldr${ThemeIcon.asCSSSelector(foldingCollapsedIcon)} {
color: ${editorFoldColor} !important;
}
`);
Expand Down
Loading

0 comments on commit 2ecb47d

Please sign in to comment.