migrate to gpui-component

This commit is contained in:
2026-06-02 18:15:54 +07:00
parent 5d4c8634ef
commit bac04ab4da
116 changed files with 1165 additions and 24445 deletions

View File

@@ -6,11 +6,11 @@ publish.workspace = true
[dependencies]
common = { path = "../common" }
theme = { path = "../theme" }
ui = { path = "../ui" }
gpui.workspace = true
gpui-component.workspace = true
nostr-sdk.workspace = true
gpui.workspace = true
smol.workspace = true
smallvec.workspace = true
anyhow.workspace = true

View File

@@ -5,10 +5,10 @@ use gpui::{
AnyElement, Context, Decorations, Hsla, InteractiveElement as _, IntoElement, ParentElement,
Pixels, Render, StatefulInteractiveElement as _, Styled, Window, WindowControlArea, px,
};
use gpui_component::{ActiveTheme, h_flex};
use smallvec::{SmallVec, smallvec};
use theme::{ActiveTheme, CLIENT_SIDE_DECORATION_ROUNDING, PlatformKind};
use ui::h_flex;
use crate::platforms::PlatformKind;
#[cfg(target_os = "linux")]
use crate::platforms::linux::LinuxWindowControls;
use crate::platforms::mac::TRAFFIC_LIGHT_PADDING;
@@ -16,6 +16,18 @@ use crate::platforms::windows::WindowsWindowControls;
mod platforms;
/// Defines window border radius for platforms that use client side decorations.
pub const CLIENT_SIDE_DECORATION_ROUNDING: Pixels = px(10.0);
/// Defines window shadow size for platforms that use client side decorations.
pub const CLIENT_SIDE_DECORATION_SHADOW: Pixels = px(10.0);
/// Defines window border size for platforms that use client side decorations.
pub const CLIENT_SIDE_DECORATION_BORDER: Pixels = px(1.0);
/// Defines window titlebar height
pub const TITLEBAR_HEIGHT: Pixels = px(36.0);
/// Titlebar
pub struct TitleBar {
/// Children elements of the title bar.
@@ -23,6 +35,9 @@ pub struct TitleBar {
/// Whether the title bar is currently being moved.
should_move: bool,
/// Current user platform.
platform: PlatformKind,
}
impl TitleBar {
@@ -30,6 +45,7 @@ impl TitleBar {
Self {
children: smallvec![],
should_move: false,
platform: PlatformKind::platform(),
}
}
@@ -48,7 +64,7 @@ impl TitleBar {
if window.is_window_active() && !self.should_move {
cx.theme().title_bar
} else {
cx.theme().title_bar_inactive
cx.theme().title_bar.alpha(0.75)
}
} else {
cx.theme().title_bar
@@ -86,7 +102,7 @@ impl Render for TitleBar {
.map(|this| {
if window.is_fullscreen() {
this.px_2()
} else if cx.theme().platform.is_mac() {
} else if self.platform.is_mac() {
this.pr_2().pl(px(TRAFFIC_LIGHT_PADDING))
} else {
this.px_2()
@@ -111,24 +127,24 @@ impl Render for TitleBar {
.id("title-bar")
.justify_between()
.w_full()
.when(cx.theme().platform.is_mac(), |this| {
.when(self.platform.is_mac(), |this| {
this.on_click(|event, window, _| {
if event.click_count() == 2 {
window.titlebar_double_click();
}
})
})
.when(cx.theme().platform.is_linux(), |this| {
.when(self.platform.is_linux(), |this| {
this.on_click(|event, window, _| {
if event.click_count() == 2 {
window.zoom_window();
}
})
})
.when(!cx.theme().platform.is_mac(), |this| this.pr_2())
.when(!self.platform.is_mac(), |this| this.pr_2())
.children(children),
)
.when(!window.is_fullscreen(), |this| match cx.theme().platform {
.when(!window.is_fullscreen(), |this| match self.platform {
PlatformKind::Linux => {
#[cfg(target_os = "linux")]
if matches!(decorations, Decorations::Client { .. }) {

View File

@@ -3,12 +3,12 @@ use std::sync::OnceLock;
use gpui::prelude::FluentBuilder;
use gpui::{
svg, Action, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce,
SharedString, StatefulInteractiveElement, Styled, Window,
Action, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce,
SharedString, StatefulInteractiveElement, Styled, Window, svg,
};
use linicon::{lookup_icon, IconType};
use linicon::{IconType, lookup_icon};
use theme::ActiveTheme;
use ui::{h_flex, Icon, IconName, Sizable};
use ui::{Icon, IconName, Sizable, h_flex};
#[derive(IntoElement)]
pub struct LinuxWindowControls {
@@ -34,20 +34,20 @@ impl RenderOnce for LinuxWindowControls {
.when(supported_controls.minimize, |this| {
this.child(WindowControl::new(
LinuxControl::Minimize,
IconName::WindowMinimize,
CoopIcon::WindowMinimize,
))
})
.when(supported_controls.maximize, |this| {
this.child({
if window.is_maximized() {
WindowControl::new(LinuxControl::Restore, IconName::WindowRestore)
WindowControl::new(LinuxControl::Restore, CoopIcon::WindowRestore)
} else {
WindowControl::new(LinuxControl::Maximize, IconName::WindowMaximize)
WindowControl::new(LinuxControl::Maximize, CoopIcon::WindowMaximize)
}
})
})
.child(
WindowControl::new(LinuxControl::Close, IconName::WindowClose)
WindowControl::new(LinuxControl::Close, CoopIcon::WindowClose)
.when_some(self.close_window_action, |this, close_action| {
this.close_action(close_action)
}),

View File

@@ -2,3 +2,37 @@
pub mod linux;
pub mod mac;
pub mod windows;
#[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)
}
}

View File

@@ -1,10 +1,9 @@
use gpui::prelude::FluentBuilder;
use gpui::{
div, px, App, ElementId, Hsla, InteractiveElement, IntoElement, ParentElement, Pixels,
RenderOnce, Rgba, StatefulInteractiveElement, Styled, Window, WindowControlArea,
App, ElementId, Hsla, InteractiveElement, IntoElement, ParentElement, Pixels, RenderOnce, Rgba,
StatefulInteractiveElement, Styled, Window, WindowControlArea, div, px,
};
use theme::ActiveTheme;
use ui::h_flex;
use gpui_component::{ActiveTheme, h_flex};
#[derive(IntoElement)]
pub struct WindowsWindowControls {
@@ -45,8 +44,8 @@ impl RenderOnce for WindowsWindowControls {
a: 1.0,
};
let button_hover_color = cx.theme().ghost_element_hover;
let button_active_color = cx.theme().ghost_element_active;
let button_hover_color = cx.theme().transparent;
let button_active_color = cx.theme().secondary_active;
div()
.id("windows-window-controls")