src/vs/platform/theme/common/themeService.ts

261 LOC · 223 covered · 38 uncovered · 14 ranges · 1739 concepts · 2 introducers · 875 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- colorUtils.ts ×16
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { Codicon } from '../../../base/common/codicons.js';
7 > import { Color } from '../../../base/common/color.js';
8 > import { Emitter, Event } from '../../../base/common/event.js';
9 > import { Disposable, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
10 > import { IEnvironmentService } from '../../environment/common/environment.js';
11 > import { createDecorator } from '../../instantiation/common/instantiation.js';
12 > import * as platform from '../../registry/common/platform.js';
13 > import { ColorIdentifier } from './colorRegistry.js';
14 > import { IconContribution, IconDefinition } from './iconRegistry.js';
15 > import { ColorScheme, ThemeTypeSelector } from './theme.js';
16 >
17 > export const IThemeService = createDecorator<IThemeService>('themeService');
18 >
19 > export function themeColorFromId(id: ColorIdentifier) {
20 return { id };
21 }
23 > export const FileThemeIcon = Codicon.file;
24 > export const FolderThemeIcon = Codicon.folder;
25 >
26 > export function getThemeTypeSelector(type: ColorScheme): ThemeTypeSelector {
27 switch (type) {
28 case ColorScheme.DARK: return ThemeTypeSelector.VS_DARK;
29 case ColorScheme.HIGH_CONTRAST_DARK: return ThemeTypeSelector.HC_BLACK;
30 case ColorScheme.HIGH_CONTRAST_LIGHT: return ThemeTypeSelector.HC_LIGHT;
31 default: return ThemeTypeSelector.VS;
32 }
33 }
35 > export interface ITokenStyle {
36 > readonly foreground: number | undefined;
37 > readonly bold: boolean | undefined;
38 > readonly underline: boolean | undefined;
39 > readonly strikethrough: boolean | undefined;
40 > readonly italic: boolean | undefined;
41 > }
42 >
43 > export interface IColorTheme {
44 >
45 > readonly type: ColorScheme;
46 >
47 > readonly label: string;
48 >
49 > /**
50 > * Resolves the color of the given color identifier. If the theme does not
51 > * specify the color, the default color is returned unless <code>useDefault</code> is set to false.
52 > * @param color the id of the color
53 > * @param useDefault specifies if the default color should be used. If not set, the default is used.
54 > */
55 > getColor(color: ColorIdentifier, useDefault?: boolean): Color | undefined;
56 >
57 > /**
58 > * Returns whether the theme defines a value for the color. If not, that means the
59 > * default color will be used.
60 > */
61 > defines(color: ColorIdentifier): boolean;
62 >
63 > /**
64 > * Returns the token style for a given classification. The result uses the <code>MetadataConsts</code> format
65 > */
66 > getTokenStyleMetadata(type: string, modifiers: string[], modelLanguage: string): ITokenStyle | undefined;
67 >
68 > /**
69 > * List of all colors used with tokens. <code>getTokenStyleMetadata</code> references the colors by index into this list.
70 > */
71 > readonly tokenColorMap: string[];
72 >
73 > /**
74 > * List of all the fonts used with tokens.
75 > */
76 > readonly tokenFontMap: IFontTokenOptions[];
77 >
78 > /**
79 > * Defines whether semantic highlighting should be enabled for the theme.
80 > */
81 > readonly semanticHighlighting: boolean;
82 > }
83 >
84 > export class IFontTokenOptions {
85 > fontFamily?: string;
86 > fontSizeMultiplier?: number;
87 > lineHeightMultiplier?: number;
88 > }
89 >
90 > export interface IFileIconTheme {
91 > readonly hasFileIcons: boolean;
92 > readonly hasFolderIcons: boolean;
93 > readonly hidesExplorerArrows: boolean;
94 > }
95 >
96 > export interface IProductIconTheme {
97 > /**
98 > * Resolves the definition for the given icon as defined by the theme.
99 > *
100 > * @param iconContribution The icon
101 > */
102 > getIcon(iconContribution: IconContribution): IconDefinition | undefined;
103 > }
104 >
105 >
106 > export interface ICssStyleCollector {
107 > addRule(rule: string): void;
108 > }
109 >
110 > export interface IThemingParticipant {
111 > (theme: IColorTheme, collector: ICssStyleCollector, environment: IEnvironmentService): void;
112 > }
113 >
114 > export interface IThemeService {
115 > readonly _serviceBrand: undefined;
116 >
117 > getColorTheme(): IColorTheme;
118 >
119 > readonly onDidColorThemeChange: Event<IColorTheme>;
120 >
121 > getFileIconTheme(): IFileIconTheme;
122 >
123 > readonly onDidFileIconThemeChange: Event<IFileIconTheme>;
124 >
125 > getProductIconTheme(): IProductIconTheme;
126 >
127 > readonly onDidProductIconThemeChange: Event<IProductIconTheme>;
128 >
129 > }
130 >
131 > // static theming participant
132 > export const Extensions = {
133 > ThemingContribution: 'base.contributions.theming'
134 > };
135 >
136 > export interface IThemingRegistry {
137 >
138 > /**
139 > * Register a theming participant that is invoked on every theme change.
140 > */
141 > onColorThemeChange(participant: IThemingParticipant): IDisposable;
142 >
143 > getThemingParticipants(): IThemingParticipant[];
144 >
145 > readonly onThemingParticipantAdded: Event<IThemingParticipant>;
146 > }
147 >
148 > class ThemingRegistry extends Disposable implements IThemingRegistry {
149 > private themingParticipants: IThemingParticipant[] = [];
150 > private readonly onThemingParticipantAddedEmitter: Emitter<IThemingParticipant>;
151 >
152 > constructor() {
153 > super();
154 > this.themingParticipants = [];
155 > this.onThemingParticipantAddedEmitter = this._register(new Emitter<IThemingParticipant>());
156 > }
157 >
158 > public onColorThemeChange(participant: IThemingParticipant): IDisposable {
159 > this.themingParticipants.push(participant); themeService.ts ×3
160 > this.onThemingParticipantAddedEmitter.fire(participant);
161 > return toDisposable(() => {
162 const idx = this.themingParticipants.indexOf(participant);
163 this.themingParticipants.splice(idx, 1);
165 > }
167 > public get onThemingParticipantAdded(): Event<IThemingParticipant> {
168 return this.onThemingParticipantAddedEmitter.event;
169 }
171 > public getThemingParticipants(): IThemingParticipant[] {
172 return this.themingParticipants;
173 }
175 >
176 > const themingRegistry = new ThemingRegistry();
177 > platform.Registry.add(Extensions.ThemingContribution, themingRegistry);
178 >
179 > export function registerThemingParticipant(participant: IThemingParticipant): IDisposable {
180 > return themingRegistry.onColorThemeChange(participant); themeService.ts ×3
181 > }
183 > /**
184 > * Utility base class for all themable components.
185 > */
186 > export class Themable extends Disposable {
187 > protected theme: IColorTheme;
188 >
189 > constructor(
190 protected themeService: IThemeService
191 ) {
192 super();
193
194 this.theme = themeService.getColorTheme();
195
196 // Hook up to theme changes
197 this._register(this.themeService.onDidColorThemeChange(theme => this.onThemeChange(theme)));
198 }
200 > protected onThemeChange(theme: IColorTheme): void {
201 this.theme = theme;
202
203 this.updateStyles();
204 }
206 > updateStyles(): void {
207 // Subclasses to override
208 }
210 > protected getColor(id: string, modify?: (color: Color, theme: IColorTheme) => Color): string | null {
211 let color = this.theme.getColor(id);
212
213 if (color && modify) {
214 color = modify(color, this.theme);
215 }
216
217 return color ? color.toString() : null;
218 }
220 >
221 > export interface IPartsSplash {
222 > zoomLevel: number | undefined;
223 > baseTheme: ThemeTypeSelector;
224 > colorInfo: {
225 > background: string;
226 > foreground: string | undefined;
227 > editorBackground: string | undefined;
228 > titleBarBackground: string | undefined;
229 > titleBarBorder: string | undefined;
230 > activityBarBackground: string | undefined;
231 > activityBarBorder: string | undefined;
232 > sideBarBackground: string | undefined;
233 > sideBarBorder: string | undefined;
234 > panelBackground: string | undefined;
235 > editorGroupBorder: string | undefined;
236 > agentsPanelBackground: string | undefined;
237 > agentsPanelBorder: string | undefined;
238 > statusBarBackground: string | undefined;
239 > statusBarBorder: string | undefined;
240 > statusBarNoFolderBackground: string | undefined;
241 > windowBorder: string | undefined;
242 > };
243 > layoutInfo: {
244 > sideBarSide: string;
245 > editorPartMinWidth: number;
246 > titleBarHeight: number;
247 > activityBarWidth: number;
248 > sideBarWidth: number;
249 > auxiliaryBarWidth: number;
250 > statusBarHeight: number;
251 > windowBorder: boolean;
252 > windowBorderRadius: string | undefined;
253 > modernUI: boolean;
254 > partBounds: {
255 > sideBar: { top: number; left: number; width: number; height: number } | undefined;
256 > auxiliaryBar: { top: number; left: number; width: number; height: number } | undefined;
257 > panel: { top: number; left: number; width: number; height: number } | undefined;
258 > editor: { top: number; left: number; width: number; height: number } | undefined;
259 > } | undefined;
260 > } | undefined;
261 > }