diff --git a/crates/op-editor-ui/src/widgets/ai_chat_panel.rs b/crates/op-editor-ui/src/widgets/ai_chat_panel.rs index 2073d839c..98f6cdb5b 100644 --- a/crates/op-editor-ui/src/widgets/ai_chat_panel.rs +++ b/crates/op-editor-ui/src/widgets/ai_chat_panel.rs @@ -405,39 +405,42 @@ impl<'a> Widget for AIChatPlaceholder<'a> { &title, Point2D::new(rect.origin.x + PAD + 28.0, header_y + 14.0), ); + let tokens = crate::widgets::button::tokens_from_theme(&self.theme); let maximize_x = rect.origin.x + rect.size.x - PAD - 50.0; - let maximize_color = paint_header_btn_bg( - cx, - &self.theme, - maximize_x, - header_y, - self.header_hover == Some(ChatHeaderButton::ToggleMaximize), - self.header_pressed == Some(ChatHeaderButton::ToggleMaximize), - ); - draw_icon( + jian_widgets::components::icon_button::IconButton { + icon_paths: self.maximize_icon().paths(), + hovered: self.header_hover == Some(ChatHeaderButton::ToggleMaximize), + pressed: self.header_pressed == Some(ChatHeaderButton::ToggleMaximize), + active: false, + enabled: true, + icon_size: 18.0, + stroke_width: 1.4, + } + .paint( cx.backend, - self.maximize_icon(), - Point2D::new(maximize_x, header_y), - 18.0, - maximize_color, - 1.4, + Rect { + origin: Point2D::new(maximize_x, header_y), + size: Point2D::new(22.0, 22.0), + }, + &tokens, ); let new_chat_x = rect.origin.x + rect.size.x - PAD - 22.0; - let new_chat_color = paint_header_btn_bg( - cx, - &self.theme, - new_chat_x, - header_y, - self.header_hover == Some(ChatHeaderButton::NewChat), - self.header_pressed == Some(ChatHeaderButton::NewChat), - ); - draw_icon( + jian_widgets::components::icon_button::IconButton { + icon_paths: Icon::Plus.paths(), + hovered: self.header_hover == Some(ChatHeaderButton::NewChat), + pressed: self.header_pressed == Some(ChatHeaderButton::NewChat), + active: false, + enabled: true, + icon_size: 18.0, + stroke_width: 1.4, + } + .paint( cx.backend, - Icon::Plus, - Point2D::new(new_chat_x, header_y), - 18.0, - new_chat_color, - 1.4, + Rect { + origin: Point2D::new(new_chat_x, header_y), + size: Point2D::new(22.0, 22.0), + }, + &tokens, ); // Body — either messages or examples. @@ -786,26 +789,6 @@ fn chat_neutral_feedback_color(theme: &Theme, pressed: bool) -> Color { } } -/// Paint the `theme.button_hover` wash behind a bare header glyph -/// (18 px, drawn at `(icon_x, header_y)`) when the cursor rests on it, -/// returning the glyph color: foreground while hovered, muted -/// otherwise. The wash is a 24 px square centred on the glyph. -fn paint_header_btn_bg( - cx: &mut PaintCx<'_>, - theme: &Theme, - icon_x: f32, - header_y: f32, - hovered: bool, - pressed: bool, -) -> Color { - let center = Point2D::new(icon_x + 9.0, header_y + 9.0); - let r = Rect { - origin: Point2D::new(center.x - 12.0, center.y - 12.0), - size: Point2D::new(24.0, 24.0), - }; - crate::widgets::button::paint_ghost_button_feedback(cx.backend, theme, r, hovered, pressed) -} - #[cfg(test)] #[path = "ai_chat_panel/tests.rs"] mod tests; diff --git a/crates/op-editor-ui/src/widgets/component_browser_panel.rs b/crates/op-editor-ui/src/widgets/component_browser_panel.rs index abaea07af..e0c9087e7 100644 --- a/crates/op-editor-ui/src/widgets/component_browser_panel.rs +++ b/crates/op-editor-ui/src/widgets/component_browser_panel.rs @@ -8,7 +8,7 @@ //! click to a [`ComponentBrowserHit`], and owns the drag + insert. use crate::theme::Theme; -use crate::widgets::button::{paint_button_feedback_wash, paint_ghost_button_feedback}; +use crate::widgets::button::paint_button_feedback_wash; use crate::widgets::editor_state_ext::theme_for; use crate::widgets::{draw_icon, Icon, PaintCx}; use crate::{Color, Point2D, Rect, TextLayout}; @@ -425,20 +425,19 @@ impl<'a> ComponentBrowserPanel<'a> { cx.backend.fill_round_rect(close, 6.0, self.theme.muted); let close_hovered = self.hover == Some(ComponentBrowserButton::Close); let close_pressed = self.is_pressed(ComponentBrowserButton::Close); - let close_color = paint_ghost_button_feedback( + jian_widgets::components::icon_button::IconButton { + icon_paths: Icon::Close.paths(), + hovered: close_hovered, + pressed: close_pressed, + active: false, + enabled: true, + icon_size: CLOSE_BTN - 10.0, + stroke_width: 1.5, + } + .paint( cx.backend, - &self.theme, close, - close_hovered, - close_pressed, - ); - draw_icon( - cx.backend, - Icon::Close, - Point2D::new(close.origin.x + 5.0, close.origin.y + 5.0), - CLOSE_BTN - 10.0, - close_color, - 1.5, + &crate::widgets::button::tokens_from_theme(&self.theme), ); // Header kit actions — Download (export) + Upload (import), // TS `component-browser-panel.tsx` header buttons. @@ -456,15 +455,19 @@ impl<'a> ComponentBrowserPanel<'a> { ] { let hovered = self.hover == Some(hover_target); let pressed = self.is_pressed(hover_target); - let icon_color = - paint_ghost_button_feedback(cx.backend, &self.theme, btn, hovered, pressed); - draw_icon( + jian_widgets::components::icon_button::IconButton { + icon_paths: icon.paths(), + hovered, + pressed, + active: false, + enabled: true, + icon_size: CLOSE_BTN - 10.0, + stroke_width: 1.5, + } + .paint( cx.backend, - icon, - Point2D::new(btn.origin.x + 5.0, btn.origin.y + 5.0), - CLOSE_BTN - 10.0, - icon_color, - 1.5, + btn, + &crate::widgets::button::tokens_from_theme(&self.theme), ); } cx.backend.fill_rect( diff --git a/crates/op-editor-ui/src/widgets/figma_import.rs b/crates/op-editor-ui/src/widgets/figma_import.rs index d7950d963..68a153f72 100644 --- a/crates/op-editor-ui/src/widgets/figma_import.rs +++ b/crates/op-editor-ui/src/widgets/figma_import.rs @@ -7,7 +7,7 @@ use crate::theme::Theme; use crate::widgets::editor_state_ext::theme_for; -use crate::widgets::icons::{draw_icon, Icon}; +use crate::widgets::icons::Icon; use crate::widgets::{LayoutBox, LayoutCx, PaintCx, Widget, WidgetId}; use crate::{Point2D, Rect, TextLayout}; use op_editor_core::editor_ui_state::Locale; @@ -145,24 +145,19 @@ impl Widget for FigmaImportModal { origin: Point2D::new(close.origin.x - pad, close.origin.y - pad), size: Point2D::new(close.size.x + pad * 2.0, close.size.y + pad * 2.0), }; - crate::widgets::button::paint_ghost_button_feedback( + jian_widgets::components::icon_button::IconButton { + icon_paths: Icon::Close.paths(), + hovered: close_hovered, + pressed: close_pressed, + active: false, + enabled: true, + icon_size: close.size.x, + stroke_width: 1.6, + } + .paint( cx.backend, - &self.theme, bg, - close_hovered, - close_pressed, - ); - draw_icon( - cx.backend, - Icon::Close, - close.origin, - close.size.x, - if close_hovered || close_pressed { - self.theme.foreground - } else { - self.theme.muted_foreground - }, - 1.6, + &crate::widgets::button::tokens_from_theme(&self.theme), ); // Compact info panel with a small Figma glyph for character. diff --git a/crates/op-editor-ui/src/widgets/icon_picker_panel.rs b/crates/op-editor-ui/src/widgets/icon_picker_panel.rs index e25d644f5..daca7d5fe 100644 --- a/crates/op-editor-ui/src/widgets/icon_picker_panel.rs +++ b/crates/op-editor-ui/src/widgets/icon_picker_panel.rs @@ -1,7 +1,7 @@ //! Native Iconify picker used by the toolbar and icon property row. use crate::theme::Theme; -use crate::widgets::button::{paint_button_feedback_wash, paint_ghost_button_feedback}; +use crate::widgets::button::paint_button_feedback_wash; use crate::widgets::editor_state_ext::theme_for; use crate::widgets::icon_catalog::{search_icons, IconCatalogEntry, IconRenderStyle}; use crate::widgets::{ @@ -248,20 +248,19 @@ impl<'a> IconPickerPanel<'a> { let close = Self::close_rect(panel); let close_hovered = self.hover == Some(ICON_PICKER_CLOSE_HOVER); let close_pressed = self.pressed == Some(ICON_PICKER_CLOSE_HOVER); - let icon_color = paint_ghost_button_feedback( + jian_widgets::components::icon_button::IconButton { + icon_paths: Icon::Close.paths(), + hovered: close_hovered, + pressed: close_pressed, + active: false, + enabled: true, + icon_size: 14.0, + stroke_width: 1.4, + } + .paint( cx.backend, - &self.theme, close, - close_hovered, - close_pressed, - ); - draw_icon( - cx.backend, - Icon::Close, - Point2D::new(close.origin.x + 5.0, close.origin.y + 5.0), - 14.0, - icon_color, - 1.4, + &crate::widgets::button::tokens_from_theme(&self.theme), ); }