feat: add support for multi-themes (#210)

* chore: update deps

* wip

* add themes

* add matrix theme

* add flexoki and spaceduck themes

* .

* simple theme change function

* .

* respect shadow and radius settings

* add rose pine themes

* toggle theme
This commit is contained in:
reya
2025-12-26 08:20:18 +07:00
committed by GitHub
parent 5b7780ec9b
commit 34e026751b
49 changed files with 4349 additions and 2743 deletions

View File

@@ -9,18 +9,20 @@ use gpui::{
WindowControlArea,
};
use smallvec::{smallvec, SmallVec};
use theme::platform_kind::PlatformKind;
use theme::{ActiveTheme, CLIENT_SIDE_DECORATION_ROUNDING};
use ui::h_flex;
use crate::platform_kind::PlatformKind;
#[cfg(target_os = "linux")]
use crate::platforms::linux::LinuxWindowControls;
use crate::platforms::windows::WindowsWindowControls;
mod platform_kind;
mod platforms;
pub struct TitleBar {
children: SmallVec<[AnyElement; 2]>,
platform_kind: PlatformKind,
should_move: bool,
}
@@ -34,6 +36,7 @@ impl TitleBar {
pub fn new() -> Self {
Self {
children: smallvec![],
platform_kind: PlatformKind::platform(),
should_move: false,
}
}
@@ -90,7 +93,7 @@ impl Render for TitleBar {
.map(|this| {
if window.is_fullscreen() {
this.px_2()
} else if cx.theme().platform_kind.is_mac() {
} else if self.platform_kind.is_mac() {
this.pl(px(platforms::mac::TRAFFIC_LIGHT_PADDING))
.pr_2()
.when(children.len() <= 1, |this| {
@@ -120,14 +123,14 @@ impl Render for TitleBar {
.items_center()
.justify_between()
.w_full()
.when(cx.theme().platform_kind.is_mac(), |this| {
.when(self.platform_kind.is_mac(), |this| {
this.on_click(|event, window, _| {
if event.click_count() == 2 {
window.titlebar_double_click();
}
})
})
.when(cx.theme().platform_kind.is_linux(), |this| {
.when(self.platform_kind.is_linux(), |this| {
this.on_click(|event, window, _| {
if event.click_count() == 2 {
window.zoom_window();
@@ -136,47 +139,45 @@ impl Render for TitleBar {
})
.children(children),
)
.when(!window.is_fullscreen(), |this| {
match cx.theme().platform_kind {
PlatformKind::Linux => {
#[cfg(target_os = "linux")]
if matches!(decorations, Decorations::Client { .. }) {
this.child(LinuxWindowControls::new(None))
.when(supported_controls.window_menu, |this| {
this.on_mouse_down(MouseButton::Right, move |ev, window, _| {
window.show_window_menu(ev.position)
})
.when(!window.is_fullscreen(), |this| match self.platform_kind {
PlatformKind::Linux => {
#[cfg(target_os = "linux")]
if matches!(decorations, Decorations::Client { .. }) {
this.child(LinuxWindowControls::new(None))
.when(supported_controls.window_menu, |this| {
this.on_mouse_down(MouseButton::Right, move |ev, window, _| {
window.show_window_menu(ev.position)
})
.on_mouse_move(cx.listener(move |this, _ev, window, _| {
if this.should_move {
this.should_move = false;
window.start_window_move();
}
}))
.on_mouse_down_out(cx.listener(move |this, _ev, _window, _cx| {
})
.on_mouse_move(cx.listener(move |this, _ev, window, _| {
if this.should_move {
this.should_move = false;
}))
.on_mouse_up(
MouseButton::Left,
cx.listener(move |this, _ev, _window, _cx| {
this.should_move = false;
}),
)
.on_mouse_down(
MouseButton::Left,
cx.listener(move |this, _ev, _window, _cx| {
this.should_move = true;
}),
)
} else {
this
}
#[cfg(not(target_os = "linux"))]
window.start_window_move();
}
}))
.on_mouse_down_out(cx.listener(move |this, _ev, _window, _cx| {
this.should_move = false;
}))
.on_mouse_up(
MouseButton::Left,
cx.listener(move |this, _ev, _window, _cx| {
this.should_move = false;
}),
)
.on_mouse_down(
MouseButton::Left,
cx.listener(move |this, _ev, _window, _cx| {
this.should_move = true;
}),
)
} else {
this
}
PlatformKind::Windows => this.child(WindowsWindowControls::new(height)),
PlatformKind::Mac => this,
#[cfg(not(target_os = "linux"))]
this
}
PlatformKind::Windows => this.child(WindowsWindowControls::new(height)),
PlatformKind::Mac => this,
})
}
}

View File

@@ -0,0 +1,33 @@
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
pub enum PlatformKind {
Mac,
Linux,
Windows,
}
impl PlatformKind {
pub const fn platform() -> Self {
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
Self::Linux
} else if cfg!(target_os = "windows") {
Self::Windows
} else {
Self::Mac
}
}
#[allow(dead_code)]
pub fn is_linux(&self) -> bool {
matches!(self, Self::Linux)
}
#[allow(dead_code)]
pub fn is_windows(&self) -> bool {
matches!(self, Self::Windows)
}
#[allow(dead_code)]
pub fn is_mac(&self) -> bool {
matches!(self, Self::Mac)
}
}