Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 417c2b7

Browse files
author
Akos Kitta
committed
feat: removed the non official themes from the UI
Closes #1283 Ref eclipse-theia/theia#11151 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent 3676960 commit 417c2b7

File tree

6 files changed

+642
-34
lines changed

6 files changed

+642
-34
lines changed

‎arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ import {
238238
UploadFirmwareDialog,
239239
UploadFirmwareDialogProps,
240240
} from './dialogs/firmware-uploader/firmware-uploader-dialog';
241-
242241
import { UploadCertificate } from './contributions/upload-certificate';
243242
import {
244243
ArduinoFirmwareUploader,
@@ -328,9 +327,13 @@ import { NewCloudSketch } from './contributions/new-cloud-sketch';
328327
import { SketchbookCompositeWidget } from './widgets/sketchbook/sketchbook-composite-widget';
329328
import { WindowTitleUpdater } from './theia/core/window-title-updater';
330329
import { WindowTitleUpdater as TheiaWindowTitleUpdater } from '@theia/core/lib/browser/window/window-title-updater';
331-
import { ThemeServiceWithDB } from './theia/core/theming';
332-
import { ThemeServiceWithDB as TheiaThemeServiceWithDB } from '@theia/monaco/lib/browser/monaco-indexed-db';
333-
import { MonacoThemingService } from './theia/monaco/monaco-theming-service';
330+
import {
331+
MonacoThemingService,
332+
CleanupObsoleteThemes,
333+
ThemesRegistrationSummary,
334+
MonacoThemeRegistry,
335+
} from './theia/monaco/monaco-theming-service';
336+
import { MonacoThemeRegistry as TheiaMonacoThemeRegistry } from '@theia/monaco/lib/browser/textmate/monaco-theme-registry';
334337
import { MonacoThemingService as TheiaMonacoThemingService } from '@theia/monaco/lib/browser/monaco-theming-service';
335338
import { TypeHierarchyServiceProvider } from './theia/typehierarchy/type-hierarchy-service';
336339
import { TypeHierarchyServiceProvider as TheiaTypeHierarchyServiceProvider } from '@theia/typehierarchy/lib/browser/typehierarchy-service';
@@ -973,11 +976,19 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
973976
rebind(TheiaWindowTitleUpdater).toService(WindowTitleUpdater);
974977

975978
// register Arduino themes
976-
bind(ThemeServiceWithDB).toSelf().inSingletonScope();
977-
rebind(TheiaThemeServiceWithDB).toService(ThemeServiceWithDB);
978979
bind(MonacoThemingService).toSelf().inSingletonScope();
979980
rebind(TheiaMonacoThemingService).toService(MonacoThemingService);
980981

982+
// workaround for themes cannot be removed after registration
983+
// https://github.com/eclipse-theia/theia/issues/11151
984+
bind(CleanupObsoleteThemes).toSelf().inSingletonScope();
985+
bind(FrontendApplicationContribution).toService(
986+
CleanupObsoleteThemes
987+
);
988+
bind(ThemesRegistrationSummary).toSelf().inSingletonScope();
989+
bind(MonacoThemeRegistry).toSelf().inSingletonScope();
990+
rebind(TheiaMonacoThemeRegistry).toService(MonacoThemeRegistry);
991+
981992
// disable type-hierarchy support
982993
// https://github.com/eclipse-theia/theia/commit/16c88a584bac37f5cf3cc5eb92ffdaa541bda5be
983994
bind(TypeHierarchyServiceProvider).toSelf().inSingletonScope();

‎arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx‎

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ import {
2424
} from '@theia/core/lib/common/i18n/localization';
2525
import SettingsStepInput from './settings-step-input';
2626
import { InterfaceScale } from '../../contributions/interface-scale';
27+
import {
28+
userConfigurableThemes,
29+
themeLabelForSettings,
30+
arduinoThemeTypeOf,
31+
} from '../../theia/core/theming';
32+
import { Theme } from '@theia/core/lib/common/theme';
2733

2834
const maxScale = InterfaceScale.ZoomLevel.toPercentage(
2935
InterfaceScale.ZoomLevel.MAX
@@ -218,14 +224,10 @@ export class SettingsComponent extends React.Component<
218224
<div className="flex-line">
219225
<select
220226
className="theia-select"
221-
value={this.props.themeService.getCurrentTheme().label}
227+
value={this.currentThemeLabel}
222228
onChange={this.themeDidChange}
223229
>
224-
{this.props.themeService.getThemes().map(({ id, label }) => (
225-
<option key={id} value={label}>
226-
{label}
227-
</option>
228-
))}
230+
{this.themeSelectOptions}
229231
</select>
230232
</div>
231233
<div className="flex-line">
@@ -333,6 +335,46 @@ export class SettingsComponent extends React.Component<
333335
);
334336
}
335337

338+
private get currentThemeLabel(): string {
339+
const currentTheme = this.props.themeService.getCurrentTheme();
340+
return themeLabelForSettings(currentTheme);
341+
}
342+
343+
private get separatedThemes(): (Theme | string)[] {
344+
const separatedThemes: (Theme | string)[] = [];
345+
const groupedThemes = userConfigurableThemes(this.props.themeService);
346+
for (const group of groupedThemes) {
347+
for (let i = 0; i < group.length; i++) {
348+
const theme = group[i];
349+
if (i === 0 && separatedThemes.length) {
350+
const arduinoThemeType = arduinoThemeTypeOf(theme);
351+
separatedThemes.push(`separator-${arduinoThemeType}`);
352+
}
353+
separatedThemes.push(theme);
354+
}
355+
}
356+
return separatedThemes;
357+
}
358+
359+
private get themeSelectOptions(): React.ReactNode[] {
360+
return this.separatedThemes.map((item) => {
361+
if (typeof item === 'string') {
362+
return (
363+
// &#9472; -> BOX DRAWINGS LIGHT HORIZONTAL
364+
<option key={item} disabled>
365+
&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;
366+
</option>
367+
);
368+
}
369+
const label = themeLabelForSettings(item);
370+
return (
371+
<option key={item.id} value={label}>
372+
{label}
373+
</option>
374+
);
375+
});
376+
}
377+
336378
private toSelectOptions(language: string | LanguageInfo): JSX.Element {
337379
const plain = typeof language === 'string';
338380
const key = plain ? language : language.languageId;
@@ -610,8 +652,8 @@ export class SettingsComponent extends React.Component<
610652
event: React.ChangeEvent<HTMLSelectElement>
611653
): void => {
612654
const { selectedIndex } = event.target.options;
613-
const theme = this.props.themeService.getThemes()[selectedIndex];
614-
if (theme) {
655+
const theme = this.separatedThemes[selectedIndex];
656+
if (theme&&typeoftheme!=='string') {
615657
this.setState({ themeId: theme.id });
616658
if (this.props.themeService.getCurrentTheme().id !== theme.id) {
617659
this.props.themeService.setCurrentTheme(theme.id);
Lines changed: 170 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,186 @@
1-
import type { Theme } from '@theia/core/lib/common/theme';
2-
import { injectable } from '@theia/core/shared/inversify';
3-
import { ThemeServiceWithDB as TheiaThemeServiceWithDB } from '@theia/monaco/lib/browser/monaco-indexed-db';
1+
import {
2+
BuiltinThemeProvider,
3+
ThemeService,
4+
} from '@theia/core/lib/browser/theming';
5+
import { nls } from '@theia/core/lib/common/nls';
6+
import type { Theme, ThemeType } from '@theia/core/lib/common/theme';
7+
import { assertUnreachable } from '../../../common/utils';
48

59
export namespace ArduinoThemes {
6-
export const Light: Theme = {
10+
export const light: Theme = {
711
id: 'arduino-theme',
812
type: 'light',
913
label: 'Light (Arduino)',
1014
editorTheme: 'arduino-theme',
1115
};
12-
export const Dark: Theme = {
16+
export const dark: Theme = {
1317
id: 'arduino-theme-dark',
1418
type: 'dark',
1519
label: 'Dark (Arduino)',
1620
editorTheme: 'arduino-theme-dark',
1721
};
1822
}
1923

20-
@injectable()
21-
export class ThemeServiceWithDB extends TheiaThemeServiceWithDB {
22-
protected override init(): void {
23-
this.register(ArduinoThemes.Light, ArduinoThemes.Dark);
24-
super.init();
24+
const builtInThemeIds = new Set(
25+
[
26+
ArduinoThemes.light,
27+
ArduinoThemes.dark,
28+
BuiltinThemeProvider.hcTheme,
29+
// TODO: add the HC light theme after Theia 1.36
30+
].map(({ id }) => id)
31+
);
32+
const deprecatedThemeIds = new Set(
33+
[BuiltinThemeProvider.lightTheme, BuiltinThemeProvider.darkTheme].map(
34+
({ id }) => id
35+
)
36+
);
37+
38+
export const lightThemeLabel = nls.localize('arduino/theme/light', 'Light');
39+
export const darkThemeLabel = nls.localize('arduino/theme/dark', 'Dark');
40+
export const hcThemeLabel = nls.localize('arduino/theme/hc', 'High Contrast');
41+
export function userThemeLabel(theme: Theme): string {
42+
return nls.localize('arduino/theme/user', '{0} (user)', theme.label);
43+
}
44+
export function deprecatedThemeLabel(theme: Theme): string {
45+
return nls.localize(
46+
'arduino/theme/deprecated',
47+
'{0} (deprecated)',
48+
theme.label
49+
);
50+
}
51+
52+
export function themeLabelForSettings(theme: Theme): string {
53+
switch (theme.id) {
54+
case ArduinoThemes.light.id:
55+
return lightThemeLabel;
56+
case ArduinoThemes.dark.id:
57+
return darkThemeLabel;
58+
case BuiltinThemeProvider.hcTheme.id:
59+
return hcThemeLabel;
60+
case BuiltinThemeProvider.lightTheme.id: // fall-through
61+
case BuiltinThemeProvider.darkTheme.id:
62+
return deprecatedThemeLabel(theme);
63+
default:
64+
return userThemeLabel(theme);
65+
}
66+
}
67+
68+
export function compatibleBuiltInTheme(theme: Theme): Theme {
69+
switch (theme.type) {
70+
case 'light':
71+
return ArduinoThemes.light;
72+
case 'dark':
73+
return ArduinoThemes.dark;
74+
case 'hc':
75+
return BuiltinThemeProvider.hcTheme;
76+
default: {
77+
console.warn(
78+
`Unhandled theme type: ${theme.type}. Theme ID: ${theme.id}, label: ${theme.label}`
79+
);
80+
return ArduinoThemes.light;
81+
}
82+
}
83+
}
84+
85+
// For tests without DI
86+
interface ThemeProvider {
87+
themes(): Theme[];
88+
currentTheme(): Theme;
89+
}
90+
91+
/**
92+
* Returns with a list of built-in themes officially supported by IDE2 (https://github.com/arduino/arduino-ide/issues/1283).
93+
* The themes in the array follow the following order:
94+
* - built-in themes first (in `Light`, `Dark`, `High Contrast`), // TODO -> High Contrast will be split up to HC Dark and HC Light after the Theia version uplift
95+
* - followed by user installed (VSIX) themes grouped by theme type, then alphabetical order,
96+
* - if the `currentTheme` is either Light (Theia) or Dark (Theia), the last item of the array will be the selected theme with `(deprecated)` suffix.
97+
*/
98+
export function userConfigurableThemes(service: ThemeService): Theme[][];
99+
export function userConfigurableThemes(provider: ThemeProvider): Theme[][];
100+
export function userConfigurableThemes(
101+
serviceOrProvider: ThemeService | ThemeProvider
102+
): Theme[][] {
103+
const provider =
104+
serviceOrProvider instanceof ThemeService
105+
? {
106+
currentTheme: () => serviceOrProvider.getCurrentTheme(),
107+
themes: () => serviceOrProvider.getThemes(),
108+
}
109+
: serviceOrProvider;
110+
const currentTheme = provider.currentTheme();
111+
const allThemes = provider
112+
.themes()
113+
.map((theme) => ({ ...theme, arduinoThemeType: arduinoThemeTypeOf(theme) }))
114+
.filter(
115+
(theme) =>
116+
theme.arduinoThemeType !== 'deprecated' || currentTheme.id === theme.id
117+
)
118+
.sort((left, right) => {
119+
const leftArduinoThemeType = left.arduinoThemeType;
120+
const rightArduinoThemeType = right.arduinoThemeType;
121+
if (leftArduinoThemeType === rightArduinoThemeType) {
122+
const result = themeTypeOrder[left.type] - themeTypeOrder[right.type];
123+
if (result) {
124+
return result;
125+
}
126+
return left.label.localeCompare(right.label); // alphabetical order
127+
}
128+
return (
129+
arduinoThemeTypeOrder[leftArduinoThemeType] -
130+
arduinoThemeTypeOrder[rightArduinoThemeType]
131+
);
132+
});
133+
const builtInThemes: Theme[] = [];
134+
const userThemes: Theme[] = [];
135+
const deprecatedThemes: Theme[] = [];
136+
allThemes.forEach((theme) => {
137+
const { arduinoThemeType } = theme;
138+
switch (arduinoThemeType) {
139+
case 'built-in':
140+
builtInThemes.push(theme);
141+
break;
142+
case 'user':
143+
userThemes.push(theme);
144+
break;
145+
case 'deprecated':
146+
deprecatedThemes.push(theme);
147+
break;
148+
default:
149+
assertUnreachable(arduinoThemeType);
150+
}
151+
});
152+
const groupedThemes: Theme[][] = [];
153+
if (builtInThemes.length) {
154+
groupedThemes.push(builtInThemes);
155+
}
156+
if (userThemes.length) {
157+
groupedThemes.push(userThemes);
158+
}
159+
if (deprecatedThemes.length) {
160+
groupedThemes.push(deprecatedThemes);
161+
}
162+
return groupedThemes;
163+
}
164+
165+
export type ArduinoThemeType = 'built-in' | 'user' | 'deprecated';
166+
const arduinoThemeTypeOrder: Record<ArduinoThemeType, number> = {
167+
'built-in': 0,
168+
user: 1,
169+
deprecated: 2,
170+
};
171+
const themeTypeOrder: Record<ThemeType, number> = {
172+
light: 0,
173+
dark: 1,
174+
hc: 2,
175+
};
176+
177+
export function arduinoThemeTypeOf(theme: Theme | string): ArduinoThemeType {
178+
const themeId = typeof theme === 'string' ? theme : theme.id;
179+
if (builtInThemeIds.has(themeId)) {
180+
return 'built-in';
181+
}
182+
if (deprecatedThemeIds.has(themeId)) {
183+
return 'deprecated';
25184
}
185+
return 'user';
26186
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /