认识vscode(三)

上一篇文章我介绍了vscode从入口文件开始一直到渲染进程的运行流程。今天我们通过实现 dark mode 来了解一下workbench.

先看一下效果图镇场子, 本篇文章只介绍逻辑实现. 具体UI不探讨.

我个人的话实现dark mode其实是使用了两套主题. 其实vscode有提供dark mode api. 不过比较麻烦。 因为我个人遇到的实际场景是不需要让用户切换主题的。所以我就选了两套主题做切换来实现 伪dark mode

我们从workbench.ts里的startup开始。这里开始vscode会渲染我们看到的UI. 所以我们可以给 workbench.ts 加俩函数分别是 startupDarkModeButtonchangeThemeHandle 分别负责button的渲染和切换主题逻辑

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函数来挂载我们的小按钮

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。如果你觉得每天的文章内容过于简单有问题可以私信我。 每天进步一点点.

你可能感兴趣的:(typescript)