This PR adds the supporting infrastructure to support loading icon
themes defined by extensions.
Here's an example icon theme:
```json
{
"name": "My Icon Theme",
"author": "Me <me@example.com>",
"themes": [
{
"name": "My Icon Theme",
"appearance": "dark",
"file_icons": {
"gleam": { "path": "./icons/file_type_gleam.svg" },
"toml": { "path": "./icons/file_type_toml.svg" }
}
}
]
}
```
The icon paths are resolved relative to the root of the extension
directory.
Release Notes:
- N/A
81 lines
2.4 KiB
Rust
81 lines
2.4 KiB
Rust
use std::path::PathBuf;
|
|
use std::sync::Arc;
|
|
|
|
use anyhow::Result;
|
|
use extension::{ExtensionHostProxy, ExtensionThemeProxy};
|
|
use fs::Fs;
|
|
use gpui::{AppContext, BackgroundExecutor, SharedString, Task};
|
|
use theme::{ThemeRegistry, ThemeSettings};
|
|
|
|
pub fn init(
|
|
extension_host_proxy: Arc<ExtensionHostProxy>,
|
|
theme_registry: Arc<ThemeRegistry>,
|
|
executor: BackgroundExecutor,
|
|
) {
|
|
extension_host_proxy.register_theme_proxy(ThemeRegistryProxy {
|
|
theme_registry,
|
|
executor,
|
|
});
|
|
}
|
|
|
|
struct ThemeRegistryProxy {
|
|
theme_registry: Arc<ThemeRegistry>,
|
|
executor: BackgroundExecutor,
|
|
}
|
|
|
|
impl ExtensionThemeProxy for ThemeRegistryProxy {
|
|
fn list_theme_names(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<Vec<String>>> {
|
|
self.executor.spawn(async move {
|
|
let themes = theme::read_user_theme(&theme_path, fs).await?;
|
|
Ok(themes.themes.into_iter().map(|theme| theme.name).collect())
|
|
})
|
|
}
|
|
|
|
fn remove_user_themes(&self, themes: Vec<SharedString>) {
|
|
self.theme_registry.remove_user_themes(&themes);
|
|
}
|
|
|
|
fn load_user_theme(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<()>> {
|
|
let theme_registry = self.theme_registry.clone();
|
|
self.executor
|
|
.spawn(async move { theme_registry.load_user_theme(&theme_path, fs).await })
|
|
}
|
|
|
|
fn reload_current_theme(&self, cx: &mut AppContext) {
|
|
ThemeSettings::reload_current_theme(cx)
|
|
}
|
|
|
|
fn list_icon_theme_names(
|
|
&self,
|
|
icon_theme_path: PathBuf,
|
|
fs: Arc<dyn Fs>,
|
|
) -> Task<Result<Vec<String>>> {
|
|
self.executor.spawn(async move {
|
|
let icon_theme_family = theme::read_icon_theme(&icon_theme_path, fs).await?;
|
|
Ok(icon_theme_family
|
|
.themes
|
|
.into_iter()
|
|
.map(|theme| theme.name)
|
|
.collect())
|
|
})
|
|
}
|
|
|
|
fn remove_icon_themes(&self, icon_themes: Vec<SharedString>) {
|
|
self.theme_registry.remove_icon_themes(&icon_themes);
|
|
}
|
|
|
|
fn load_icon_theme(
|
|
&self,
|
|
icon_theme_path: PathBuf,
|
|
icons_root_dir: PathBuf,
|
|
fs: Arc<dyn Fs>,
|
|
) -> Task<Result<()>> {
|
|
let theme_registry = self.theme_registry.clone();
|
|
self.executor.spawn(async move {
|
|
theme_registry
|
|
.load_icon_theme(&icon_theme_path, &icons_root_dir, fs)
|
|
.await
|
|
})
|
|
}
|
|
}
|