上一篇文章我介紹了vscode從入口文件開始一直到渲染進程的運行流程。今天咱們經過實現 dark mode 來了解一下workbench.node
先看一下效果圖鎮場子, 本篇文章只介紹邏輯實現. 具體UI不探討.git
我我的的話實現dark mode實際上是使用了兩套主題. 其實vscode有提供dark mode api. 不過比較麻煩。 由於我我的遇到的實際場景是不須要讓用戶切換主題的。因此我就選了兩套主題作切換來實現 僞dark modegithub
咱們從workbench.ts裏的startup
開始。這裏開始vscode會渲染咱們看到的UI. 因此咱們能夠給 workbench.ts 加倆函數分別是 startupDarkModeButton
和 changeThemeHandle
分別負責button的渲染和切換主題邏輯json
private startupDarkModeButton(instantiationService: IInstantiationService) { const node = document.createElement("input"); node.id = "dark-mode-button"; node.style.backgroundColor = "blue"; node.value = "dark mode"; node.type = "checkbox"; node.style.height = "26px"; node.style.width = "100px"; node.style.color = "#ffffff"; // 這裏我就隨便加入到body裏面了...本文章只討論實現方式 document.body.insertBefore(node, document.getElementById('monaco-parts-splash')) node.onchange = async () => { this.changeThemeHandle(instantiationService, node); } }
private changeThemeHandle(instantiationService: IInstantiationService, checkbox: HTMLInputElement) { const themeIDs: string[] = [ // 正常主題 "vs thenikso-github-plus-theme-themes-github-plus-theme-json", // dark mode 主題 "vs-dark vscode-theme-defaults-themes-dark_vs-json" ]; // invokeFunction 主要是獲取ServicesAccessor instantiationService.invokeFunction((accessor: ServicesAccessor) => { const workbenchThemeService: IWorkbenchThemeService = accessor.get(IWorkbenchThemeService); // 切換主題 workbenchThemeService.setColorTheme(BELLCODE_THEMES[Number(el.checked)], undefined) }) }
而後在 startup
函數內調用咱們的startupDarkModeButton
函數來掛載咱們的小按鈕segmentfault
startup(): IInstantiationService { try { // Configure emitter leak warning threshold setGlobalLeakWarningThreshold(175); // ARIA setARIAContainer(document.body); // Services const instantiationService = this.initServices(this.serviceCollection); instantiationService.invokeFunction(async accessor => { const lifecycleService = accessor.get(ILifecycleService); const storageService = accessor.get(IStorageService); const configurationService = accessor.get(IConfigurationService); // Layout this.initLayout(accessor); // Registries this.startRegistries(accessor); // Context Keys this._register(instantiationService.createInstance(WorkbenchContextKeysHandler)); // Register Listeners this.registerListeners(lifecycleService, storageService, configurationService); // Render Workbench this.renderWorkbench(instantiationService, accessor.get(INotificationService) as NotificationService, storageService, configurationService); // Workbench Layout this.createWorkbenchLayout(); // Layout this.layout(); // mount dark mode button this.startupDarkModeButton(); // Restore try { await this.restoreWorkbench(accessor.get(IEditorService), accessor.get(IEditorGroupsService), accessor.get(IViewletService), accessor.get(IPanelService), accessor.get(ILogService), lifecycleService); } catch (error) { onUnexpectedError(error); } }); return instantiationService; } catch (error) { onUnexpectedError(error); throw error; // rethrow because this is a critical issue we cannot handle properly here } }
簡單的兩個函數咱們就基本實現了主題切換。若是像個人效果圖同樣本身寫了一些組件怎麼辦呢? 明天咱們就講講如何擴展vscode UI。若是你以爲天天的文章內容過於簡單有問題能夠私信我。 天天進步一點點.api