chore: update gpui components

This commit is contained in:
2025-06-17 14:50:46 +07:00
parent 052b0163cb
commit 5f5bb33654
3 changed files with 58 additions and 35 deletions

View File

@@ -1051,10 +1051,12 @@ impl Render for TabPanel {
} }
v_flex() v_flex()
.when(!self.is_collapsed, |this| {
this.on_action(cx.listener(Self::on_action_toggle_zoom))
.on_action(cx.listener(Self::on_action_close_panel))
})
.id("tab-panel") .id("tab-panel")
.track_focus(&focus_handle) .track_focus(&focus_handle)
.on_action(cx.listener(Self::on_action_toggle_zoom))
.on_action(cx.listener(Self::on_action_close_panel))
.size_full() .size_full()
.overflow_hidden() .overflow_hidden()
.child(self.render_title_bar(&state, window, cx)) .child(self.render_title_bar(&state, window, cx))

View File

@@ -43,6 +43,7 @@ impl BlinkCursor {
fn blink(&mut self, epoch: usize, cx: &mut Context<Self>) { fn blink(&mut self, epoch: usize, cx: &mut Context<Self>) {
if self.paused || epoch != self.epoch { if self.paused || epoch != self.epoch {
self.visible = true;
return; return;
} }

View File

@@ -4,13 +4,12 @@ use gpui::prelude::FluentBuilder as _;
use gpui::{ use gpui::{
black, div, px, relative, white, AnyElement, App, ClickEvent, Div, Element, Hsla, black, div, px, relative, white, AnyElement, App, ClickEvent, Div, Element, Hsla,
InteractiveElement as _, IntoElement, MouseButton, ParentElement, Pixels, RenderOnce, Rgba, InteractiveElement as _, IntoElement, MouseButton, ParentElement, Pixels, RenderOnce, Rgba,
Stateful, StatefulInteractiveElement as _, Style, Styled, Window, Stateful, StatefulInteractiveElement as _, Style, Styled, Window, WindowControlArea,
}; };
use theme::ActiveTheme; use theme::ActiveTheme;
use crate::{h_flex, Icon, IconName, InteractiveElementExt as _, Sizable as _}; use crate::{h_flex, Icon, IconName, InteractiveElementExt as _, Sizable as _};
const HEIGHT: Pixels = px(34.);
const TITLE_BAR_HEIGHT: Pixels = px(34.); const TITLE_BAR_HEIGHT: Pixels = px(34.);
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
const TITLE_BAR_LEFT_PADDING: Pixels = px(80.); const TITLE_BAR_LEFT_PADDING: Pixels = px(80.);
@@ -32,7 +31,7 @@ pub struct TitleBar {
impl TitleBar { impl TitleBar {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
base: div().id("title-bar").pl(TITLE_BAR_LEFT_PADDING), base: div().id("title-bar"),
children: Vec::new(), children: Vec::new(),
on_close_window: None, on_close_window: None,
} }
@@ -62,14 +61,14 @@ impl Default for TitleBar {
// We don't need implementation the click event for the control buttons. // We don't need implementation the click event for the control buttons.
// If user clicked in the bounds, the window event will be triggered. // If user clicked in the bounds, the window event will be triggered.
#[derive(IntoElement, Clone)] #[derive(IntoElement, Clone)]
enum Control { enum ControlIcon {
Minimize, Minimize,
Restore, Restore,
Maximize, Maximize,
Close { on_close_window: OnCloseWindow }, Close { on_close_window: OnCloseWindow },
} }
impl Control { impl ControlIcon {
fn minimize() -> Self { fn minimize() -> Self {
Self::Minimize Self::Minimize
} }
@@ -104,11 +103,19 @@ impl Control {
} }
} }
fn window_control_area(&self) -> WindowControlArea {
match self {
Self::Minimize => WindowControlArea::Min,
Self::Restore | Self::Maximize => WindowControlArea::Max,
Self::Close { .. } => WindowControlArea::Close,
}
}
fn is_close(&self) -> bool { fn is_close(&self) -> bool {
matches!(self, Self::Close { .. }) matches!(self, Self::Close { .. })
} }
fn fg(&self, _window: &Window, cx: &App) -> Hsla { fn fg(&self, cx: &App) -> Hsla {
if cx.theme().mode.is_dark() { if cx.theme().mode.is_dark() {
white() white()
} else { } else {
@@ -116,7 +123,7 @@ impl Control {
} }
} }
fn hover_fg(&self, _window: &Window, cx: &App) -> Hsla { fn hover_fg(&self, cx: &App) -> Hsla {
if self.is_close() || cx.theme().mode.is_dark() { if self.is_close() || cx.theme().mode.is_dark() {
white() white()
} else { } else {
@@ -124,7 +131,7 @@ impl Control {
} }
} }
fn hover_bg(&self, _window: &Window, cx: &App) -> Rgba { fn hover_bg(&self, cx: &App) -> Rgba {
if self.is_close() { if self.is_close() {
Rgba { Rgba {
r: 232.0 / 255.0, r: 232.0 / 255.0,
@@ -150,42 +157,47 @@ impl Control {
} }
} }
impl RenderOnce for Control { impl RenderOnce for ControlIcon {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement { fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
let fg = self.fg(window, cx);
let hover_fg = self.hover_fg(window, cx);
let hover_bg = self.hover_bg(window, cx);
let icon = self.clone();
let is_linux = cfg!(target_os = "linux"); let is_linux = cfg!(target_os = "linux");
let on_close_window = match &icon { let is_windows = cfg!(target_os = "windows");
Control::Close { on_close_window } => on_close_window.clone(), let fg = self.fg(cx);
let hover_fg = self.hover_fg(cx);
let hover_bg = self.hover_bg(cx);
let icon = self.clone();
let on_close_window = match &self {
ControlIcon::Close { on_close_window } => on_close_window.clone(),
_ => None, _ => None,
}; };
div() div()
.id(self.id()) .id(self.id())
.flex() .flex()
.cursor_pointer()
.w(TITLE_BAR_HEIGHT) .w(TITLE_BAR_HEIGHT)
.h_full() .h_full()
.justify_center() .justify_center()
.content_center() .content_center()
.items_center() .items_center()
.text_color(fg) .text_color(fg)
.when(is_windows, |this| {
this.window_control_area(self.window_control_area())
})
.when(is_linux, |this| { .when(is_linux, |this| {
this.on_mouse_down(MouseButton::Left, move |_, window, cx| { this.on_mouse_down(MouseButton::Left, move |_, window, cx| {
window.prevent_default(); window.prevent_default();
cx.stop_propagation(); cx.stop_propagation();
}) })
.on_click(move |_, window, cx| match icon { .on_click(move |_, window, cx| {
Self::Minimize => window.minimize_window(), cx.stop_propagation();
Self::Restore => window.zoom_window(), match icon {
Self::Maximize => window.zoom_window(), Self::Minimize => window.minimize_window(),
Self::Close { .. } => { Self::Restore | Self::Maximize => window.zoom_window(),
if let Some(f) = on_close_window.clone() { Self::Close { .. } => {
f(&ClickEvent::default(), window, cx); if let Some(f) = on_close_window.clone() {
} else { f(&ClickEvent::default(), window, cx);
window.remove_window(); } else {
window.remove_window();
}
} }
} }
}) })
@@ -202,7 +214,7 @@ struct WindowControls {
} }
impl RenderOnce for WindowControls { impl RenderOnce for WindowControls {
fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement { fn render(self, window: &mut Window, _: &mut App) -> impl IntoElement {
if cfg!(target_os = "macos") { if cfg!(target_os = "macos") {
return div().id("window-controls"); return div().id("window-controls");
} }
@@ -217,14 +229,14 @@ impl RenderOnce for WindowControls {
.justify_center() .justify_center()
.content_stretch() .content_stretch()
.h_full() .h_full()
.child(Control::minimize()) .child(ControlIcon::minimize())
.child(if window.is_maximized() { .child(if window.is_maximized() {
Control::restore() ControlIcon::restore()
} else { } else {
Control::maximize() ControlIcon::maximize()
}), }),
) )
.child(Control::close(self.on_close_window)) .child(ControlIcon::close(self.on_close_window))
} }
} }
@@ -242,6 +254,8 @@ impl ParentElement for TitleBar {
impl RenderOnce for TitleBar { impl RenderOnce for TitleBar {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement { fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
const HEIGHT: Pixels = px(34.);
let is_linux = cfg!(target_os = "linux"); let is_linux = cfg!(target_os = "linux");
div().flex_shrink_0().child( div().flex_shrink_0().child(
@@ -253,13 +267,19 @@ impl RenderOnce for TitleBar {
.h(HEIGHT) .h(HEIGHT)
.bg(cx.theme().title_bar) .bg(cx.theme().title_bar)
.when(window.is_fullscreen(), |this| this.pl(px(12.))) .when(window.is_fullscreen(), |this| this.pl(px(12.)))
.on_double_click(|_, window, _cx| window.zoom_window()) .when(is_linux, |this| {
this.on_double_click(|_, window, _| window.zoom_window())
})
.child( .child(
h_flex() h_flex()
.h_full() .id("bar")
.pl(TITLE_BAR_LEFT_PADDING)
.when(window.is_fullscreen(), |this| this.pl(px(12.)))
.window_control_area(WindowControlArea::Drag)
.justify_between() .justify_between()
.flex_shrink_0() .flex_shrink_0()
.flex_1() .flex_1()
.h_full()
.when(is_linux, |this| { .when(is_linux, |this| {
this.child( this.child(
div() div()