From 4dee0c5d4bc3834c2ff0e85ec82002a756546cee Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 8 Oct 2022 12:15:21 -0700 Subject: [PATCH] Build out theme service more --- src/browser/Terminal.ts | 1 - src/browser/renderer/shared/Types.d.ts | 4 ++-- src/browser/services/RenderService.ts | 12 ++++++++---- src/browser/services/Services.ts | 5 +++-- src/browser/services/ThemeService.ts | 13 ++++++++++--- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index c641a544..a2f1aad9 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -241,7 +241,6 @@ export class Terminal extends CoreTerminal implements ITerminal { } } // TODO: Have these listen to theme change - this._renderService?.setColors(this._themeService.colors); this.viewport?.handleThemeChange(this._themeService.colors); } diff --git a/src/browser/renderer/shared/Types.d.ts b/src/browser/renderer/shared/Types.d.ts index 5704f312..d5dd378b 100644 --- a/src/browser/renderer/shared/Types.d.ts +++ b/src/browser/renderer/shared/Types.d.ts @@ -4,7 +4,7 @@ */ import { FontWeight, Terminal } from 'xterm'; -import { IColorSet } from 'browser/Types'; +import { IColorSet, ReadonlyColorSet } from 'browser/Types'; import { IDisposable } from 'common/Types'; import { IEvent } from 'common/EventEmitter'; @@ -61,7 +61,7 @@ export interface IRenderer extends IDisposable { readonly onRequestRedraw: IEvent; dispose(): void; - setColors(colors: IColorSet): void; + setColors(colors: ReadonlyColorSet): void; handleDevicePixelRatioChange(): void; handleResize(cols: number, rows: number): void; handleCharSizeChanged(): void; diff --git a/src/browser/services/RenderService.ts b/src/browser/services/RenderService.ts index a51fe722..585344f9 100644 --- a/src/browser/services/RenderService.ts +++ b/src/browser/services/RenderService.ts @@ -9,10 +9,11 @@ import { EventEmitter, IEvent } from 'common/EventEmitter'; import { Disposable } from 'common/Lifecycle'; import { ScreenDprMonitor } from 'browser/ScreenDprMonitor'; import { addDisposableDomListener } from 'browser/Lifecycle'; -import { IColorSet, IRenderDebouncerWithCallback } from 'browser/Types'; +import { IColorSet, IRenderDebouncerWithCallback, ReadonlyColorSet } from 'browser/Types'; import { IOptionsService, IBufferService, IDecorationService } from 'common/services/Services'; -import { ICharSizeService, ICoreBrowserService, IRenderService } from 'browser/services/Services'; +import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services'; import { DebouncedIdleTask } from 'common/TaskQueue'; +import { ThemeService } from 'browser/services/ThemeService'; interface ISelectionState { start: [number, number] | undefined; @@ -58,7 +59,8 @@ export class RenderService extends Disposable implements IRenderService { @ICharSizeService private readonly _charSizeService: ICharSizeService, @IDecorationService decorationService: IDecorationService, @IBufferService bufferService: IBufferService, - @ICoreBrowserService coreBrowserService: ICoreBrowserService + @ICoreBrowserService coreBrowserService: ICoreBrowserService, + @IThemeService themeService: IThemeService ) { super(); @@ -89,6 +91,8 @@ export class RenderService extends Disposable implements IRenderService { // matchMedia query. this.register(addDisposableDomListener(coreBrowserService.window, 'resize', () => this.handleDevicePixelRatioChange())); + this.register(themeService.onChangeColors(e => this._handleChangeColors(e))); + // Detect whether IntersectionObserver is detected and enable renderer pause // and resume based on terminal visibility if so if ('IntersectionObserver' in coreBrowserService.window) { @@ -204,7 +208,7 @@ export class RenderService extends Disposable implements IRenderService { this._fullRefresh(); } - public setColors(colors: IColorSet): void { + private _handleChangeColors(colors: ReadonlyColorSet): void { if (!this._renderer) { return; } diff --git a/src/browser/services/Services.ts b/src/browser/services/Services.ts index 6132c3ea..76a0f7df 100644 --- a/src/browser/services/Services.ts +++ b/src/browser/services/Services.ts @@ -74,7 +74,6 @@ export interface IRenderService extends IDisposable { resize(cols: number, rows: number): void; hasRenderer(): boolean; setRenderer(renderer: IRenderer): void; - setColors(colors: ReadonlyColorSet): void; handleDevicePixelRatioChange(): void; handleResize(cols: number, rows: number): void; handleCharSizeChanged(): void; @@ -128,7 +127,9 @@ export interface IThemeService { serviceBrand: undefined; readonly colors: ReadonlyColorSet; - setTheme(theme?: ITheme): void; + + readonly onChangeColors: IEvent; + restoreColor(slot?: ColorIndex): void; /** * Allows external modifying of colors in the theme, this is used instead of {@link colors} to diff --git a/src/browser/services/ThemeService.ts b/src/browser/services/ThemeService.ts index 72f2163e..7765eca6 100644 --- a/src/browser/services/ThemeService.ts +++ b/src/browser/services/ThemeService.ts @@ -6,6 +6,7 @@ import { ColorManager } from 'browser/ColorManager'; import { IThemeService } from 'browser/services/Services'; import { IColorSet, ReadonlyColorSet } from 'browser/Types'; +import { EventEmitter } from 'common/EventEmitter'; import { Disposable } from 'common/Lifecycle'; import { IOptionsService, ITheme } from 'common/services/Services'; import { ColorIndex } from 'common/Types'; @@ -18,29 +19,35 @@ export class ThemeService extends Disposable implements IThemeService { public get colors(): ReadonlyColorSet { return this._colorManager.colors; } + private readonly _onChangeColors = this.register(new EventEmitter()); + public readonly onChangeColors = this._onChangeColors.event; + constructor( @IOptionsService private readonly _optionsService: IOptionsService ) { super(); this.register(this._optionsService.onOptionChange(key => { if (key === 'theme') { - this.setTheme(this._optionsService.rawOptions.theme); + this._setTheme(this._optionsService.rawOptions.theme); } this._colorManager.handleOptionsChange(key, this._optionsService.rawOptions[key]); })); this._colorManager.setTheme(this._optionsService.rawOptions.theme); } - public setTheme(theme: ITheme = {}): void { + private _setTheme(theme: ITheme = {}): void { this._colorManager.setTheme(theme); + this._onChangeColors.fire(this.colors); } public restoreColor(slot?: ColorIndex): void { this._colorManager.restoreColor(slot); + this._onChangeColors.fire(this.colors); } public modifyColors(callback: (colors: IColorSet) => void): void { callback(this._colorManager.colors); - // TODO: Fire event + // Assume the change happened + this._onChangeColors.fire(this.colors); } }