From e37369ea1621da7f2dc4411cc09a4a06ab0f5408 Mon Sep 17 00:00:00 2001 From: Floyd Wang Date: Tue, 12 Aug 2025 14:16:31 +0800 Subject: [PATCH] plot: Support multiple directions for the tooltip cross line (#1128) --- crates/ui/src/plot/tooltip.rs | 84 +++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/crates/ui/src/plot/tooltip.rs b/crates/ui/src/plot/tooltip.rs index 45dd7f4a..3a913e03 100644 --- a/crates/ui/src/plot/tooltip.rs +++ b/crates/ui/src/plot/tooltip.rs @@ -5,10 +5,31 @@ use gpui::{ use crate::{v_flex, ActiveTheme}; +#[derive(Default)] +pub enum CrossLineAxis { + #[default] + Vertical, + Horizontal, + Both, +} + +impl CrossLineAxis { + #[inline] + pub fn show_vertical(&self) -> bool { + matches!(self, CrossLineAxis::Vertical | CrossLineAxis::Both) + } + + #[inline] + pub fn show_horizontal(&self) -> bool { + matches!(self, CrossLineAxis::Horizontal | CrossLineAxis::Both) + } +} + #[derive(IntoElement)] pub struct CrossLine { point: Point, height: Option, + direction: CrossLineAxis, } impl CrossLine { @@ -16,9 +37,20 @@ impl CrossLine { Self { point, height: None, + direction: Default::default(), } } + pub fn horizontal(mut self) -> Self { + self.direction = CrossLineAxis::Horizontal; + self + } + + pub fn both(mut self) -> Self { + self.direction = CrossLineAxis::Both; + self + } + pub fn height(mut self, height: f32) -> Self { self.height = Some(height); self @@ -38,30 +70,34 @@ impl RenderOnce for CrossLine { .absolute() .top_0() .left_0() - .child( - div() - .absolute() - .w(px(1.)) - .bg(cx.theme().border) - .top_0() - .left(self.point.x) - .map(|this| { - if let Some(height) = self.height { - this.h(px(height)) - } else { - this.h_full() - } - }), - ) - .child( - div() - .absolute() - .w_full() - .h(px(1.)) - .bg(cx.theme().border) - .left_0() - .top(self.point.y), - ) + .when(self.direction.show_vertical(), |this| { + this.child( + div() + .absolute() + .w(px(1.)) + .bg(cx.theme().border) + .top_0() + .left(self.point.x) + .map(|this| { + if let Some(height) = self.height { + this.h(px(height)) + } else { + this.h_full() + } + }), + ) + }) + .when(self.direction.show_horizontal(), |this| { + this.child( + div() + .absolute() + .w_full() + .h(px(1.)) + .bg(cx.theme().border) + .left_0() + .top(self.point.y), + ) + }) } }