From 2e32a8743ea98395c6e8712ef49cdcfd9d721cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Fri, 3 Jul 2026 08:37:22 +0200 Subject: [PATCH] :recycle: Refactor rulers into ui modules (#10461) * :recycle: Move rulers rendering to ui submodule * :recycle: Refactor RulerState into UIState --- render-wasm/src/render.rs | 5 +- render-wasm/src/render/ui.rs | 11 ++-- render-wasm/src/render/{ => ui}/rulers.rs | 2 +- render-wasm/src/state.rs | 3 +- render-wasm/src/state/rulers.rs | 42 --------------- render-wasm/src/state/ui.rs | 63 +++++++++++++++++++++-- render-wasm/src/ui.rs | 3 +- render-wasm/src/wasm.rs | 1 - render-wasm/src/wasm/rulers.rs | 49 ------------------ render-wasm/src/wasm/ui.rs | 45 +++++++++++++++- 10 files changed, 117 insertions(+), 107 deletions(-) rename render-wasm/src/render/{ => ui}/rulers.rs (99%) delete mode 100644 render-wasm/src/state/rulers.rs delete mode 100644 render-wasm/src/wasm/rulers.rs diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index a75d2fcb8e..a45de5296f 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -7,7 +7,6 @@ pub mod grid_layout; mod images; mod options; pub mod pdf; -pub mod rulers; mod shadows; pub mod shape_renderer; mod strokes; @@ -30,7 +29,7 @@ use crate::shapes::{ all_with_ancestors, radius_to_sigma, Blur, BlurType, Corners, Fill, Shadow, Shape, SolidColor, Stroke, StrokeKind, TextContent, Type, }; -use crate::state::{RulerState, ShapesPoolMutRef, ShapesPoolRef}; +use crate::state::{ShapesPoolMutRef, ShapesPoolRef}; use crate::tiles::{self, PendingTiles, TileRect}; use crate::uuid::Uuid; use crate::view::Viewbox; @@ -374,7 +373,6 @@ pub(crate) struct RenderState { pub nested_blurs: Vec>, // FIXME: why is this an option? pub nested_shadows: Vec>, pub show_grid: Option, - pub rulers: RulerState, pub focus_mode: FocusMode, /// Viewer-only whitelist for fixed-scroll layer passes. pub include_filter: Option>, @@ -584,7 +582,6 @@ impl RenderState { nested_blurs: vec![], nested_shadows: vec![], show_grid: None, - rulers: RulerState::default(), focus_mode: FocusMode::new(), include_filter: None, viewer_render_root: None, diff --git a/render-wasm/src/render/ui.rs b/render-wasm/src/render/ui.rs index cf3f2d7963..19854df768 100644 --- a/render-wasm/src/render/ui.rs +++ b/render-wasm/src/render/ui.rs @@ -2,9 +2,10 @@ use skia_safe::{self as skia, Color4f}; use super::{RenderState, ShapesPoolRef, SurfaceId}; use crate::globals::get_ui_state; -use crate::render::{grid_layout, rulers}; +use crate::render::grid_layout; use crate::shapes::{Layout, Type}; pub mod guides; +pub mod rulers; pub fn render(render_state: &mut RenderState, shapes: ShapesPoolRef) { let canvas = render_state.surfaces.canvas(SurfaceId::UI); @@ -63,8 +64,12 @@ pub fn render(render_state: &mut RenderState, shapes: ShapesPoolRef) { } let viewbox = render_state.viewbox; - let ruler_state = render_state.rulers; - rulers::render(canvas, viewbox, &render_state.fonts, &ruler_state); + rulers::render( + canvas, + viewbox, + &render_state.fonts, + get_ui_state().ruler_state(), + ); // Width of the ruler bars in document coordinates. // Note that when rulers are hidden, guides are not shown either, so we diff --git a/render-wasm/src/render/rulers.rs b/render-wasm/src/render/ui/rulers.rs similarity index 99% rename from render-wasm/src/render/rulers.rs rename to render-wasm/src/render/ui/rulers.rs index 0d4fbd2379..16bf6f4acc 100644 --- a/render-wasm/src/render/rulers.rs +++ b/render-wasm/src/render/ui/rulers.rs @@ -9,7 +9,7 @@ use skia_safe::{self as skia, Color, Font, Paint, PaintStyle, PathFillType, Point, RRect, Rect}; -use super::fonts::FontStore; +use crate::render::fonts::FontStore; use crate::state::RulerState; use crate::view::Viewbox; diff --git a/render-wasm/src/state.rs b/render-wasm/src/state.rs index 2ae6ba4067..c38b604592 100644 --- a/render-wasm/src/state.rs +++ b/render-wasm/src/state.rs @@ -1,13 +1,12 @@ use skia_safe::{self as skia, textlayout::FontCollection, Path, Point}; use std::collections::HashMap; -mod rulers; mod shapes_pool; mod text_editor; mod ui; -pub use rulers::RulerState; pub use shapes_pool::{ShapesPool, ShapesPoolMutRef, ShapesPoolRef}; pub use text_editor::*; +pub use ui::RulerState; pub use ui::UIState; use crate::error::{Error, Result}; diff --git a/render-wasm/src/state/rulers.rs b/render-wasm/src/state/rulers.rs deleted file mode 100644 index c17cd46a71..0000000000 --- a/render-wasm/src/state/rulers.rs +++ /dev/null @@ -1,42 +0,0 @@ -use skia_safe::{self as skia, Rect}; - -#[derive(Debug, Clone, Copy)] -pub struct RulerState { - pub visible: bool, - // The rounded canvas frame/border. Drawn even when `visible` is false - // (rulers toggled off), but hidden in hide-UI mode. - pub frame: bool, - pub offset_x: f32, - pub offset_y: f32, - pub selection: Option, - pub bg_color: skia::Color, - pub border_color: skia::Color, - pub label_color: skia::Color, - pub accent_color: skia::Color, -} - -impl Default for RulerState { - fn default() -> Self { - Self { - visible: false, - frame: true, - offset_x: 0.0, - offset_y: 0.0, - selection: None, - bg_color: skia::Color::from_argb(0xff, 0x18, 0x18, 0x1a), - border_color: skia::Color::from_argb(0xff, 0x2e, 0x2e, 0x36), - label_color: skia::Color::from_argb(0xff, 0xb1, 0xb2, 0xb5), - accent_color: skia::Color::from_argb(0xff, 0x91, 0xff, 0x11), - } - } -} - -impl RulerState { - pub fn set_selection(&mut self, has: bool, x: f32, y: f32, w: f32, h: f32) { - self.selection = if has { - Some(Rect::from_xywh(x, y, w, h)) - } else { - None - }; - } -} diff --git a/render-wasm/src/state/ui.rs b/render-wasm/src/state/ui.rs index 607dc3117b..d29645cc02 100644 --- a/render-wasm/src/state/ui.rs +++ b/render-wasm/src/state/ui.rs @@ -1,4 +1,4 @@ -use crate::ui::{Guide, GuideKind}; +use crate::ui::{Color, Guide, GuideKind, Rect}; pub struct GuidePool { horizontal: Vec, @@ -78,15 +78,64 @@ impl GuidePool { } } +impl Default for GuidePool { + fn default() -> Self { + Self::new() + } +} + +#[derive(Debug, Clone, Copy)] +pub struct RulerState { + pub visible: bool, + // The rounded canvas frame/border. Drawn even when `visible` is false + // (rulers toggled off), but hidden in hide-UI mode. + pub frame: bool, + pub offset_x: f32, + pub offset_y: f32, + pub selection: Option, + pub bg_color: Color, + pub border_color: Color, + pub label_color: Color, + pub accent_color: Color, +} + +impl Default for RulerState { + fn default() -> Self { + Self { + visible: false, + frame: true, + offset_x: 0.0, + offset_y: 0.0, + selection: None, + bg_color: Color::from_argb(0xff, 0x18, 0x18, 0x1a), + border_color: Color::from_argb(0xff, 0x2e, 0x2e, 0x36), + label_color: Color::from_argb(0xff, 0xb1, 0xb2, 0xb5), + accent_color: Color::from_argb(0xff, 0x91, 0xff, 0x11), + } + } +} + +impl RulerState { + pub fn set_selection(&mut self, has: bool, x: f32, y: f32, w: f32, h: f32) { + self.selection = if has { + Some(Rect::from_xywh(x, y, w, h)) + } else { + None + }; + } +} + pub struct UIState { guides: GuidePool, - // TODO: show grid, rulers, etc. + rulers: RulerState, + // TODO: show grid } impl UIState { pub fn new() -> Self { Self { - guides: GuidePool::new(), + guides: GuidePool::default(), + rulers: RulerState::default(), } } @@ -101,6 +150,14 @@ impl UIState { pub fn find_guide_at(&self, x: f32, y: f32, zoom: f32, tolerance: f32) -> Option<&Guide> { self.guides.find_at(x, y, zoom, tolerance) } + + pub fn ruler_state(&self) -> &RulerState { + &self.rulers + } + + pub fn ruler_state_mut(&mut self) -> &mut RulerState { + &mut self.rulers + } } #[cfg(test)] diff --git a/render-wasm/src/ui.rs b/render-wasm/src/ui.rs index 156b4a8748..d0e47c18e7 100644 --- a/render-wasm/src/ui.rs +++ b/render-wasm/src/ui.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; -use crate::shapes::Color; +pub use crate::math::Rect; +pub use crate::shapes::Color; #[derive(Debug, Clone, Copy, PartialEq)] pub enum GuideKind { diff --git a/render-wasm/src/wasm.rs b/render-wasm/src/wasm.rs index 86f3101a83..a5d8261f4d 100644 --- a/render-wasm/src/wasm.rs +++ b/render-wasm/src/wasm.rs @@ -5,7 +5,6 @@ pub mod fonts; pub mod layouts; pub mod mem; pub mod paths; -pub mod rulers; pub mod shadows; pub mod shapes; pub mod strokes; diff --git a/render-wasm/src/wasm/rulers.rs b/render-wasm/src/wasm/rulers.rs deleted file mode 100644 index 7f7191e5eb..0000000000 --- a/render-wasm/src/wasm/rulers.rs +++ /dev/null @@ -1,49 +0,0 @@ -use macros::wasm_error; -use skia_safe::{self as skia}; - -#[allow(unused_imports)] -use crate::error::{Error, Result}; -use crate::get_render_state; - -#[no_mangle] -#[wasm_error] -pub extern "C" fn set_rulers_visible(visible: u32) -> Result<()> { - get_render_state().rulers.visible = visible != 0; - Ok(()) -} - -#[no_mangle] -#[wasm_error] -pub extern "C" fn set_rulers_frame_visible(visible: u32) -> Result<()> { - get_render_state().rulers.frame = visible != 0; - Ok(()) -} - -#[no_mangle] -#[wasm_error] -pub extern "C" fn set_rulers_offsets(offset_x: f32, offset_y: f32) -> Result<()> { - let r = &mut get_render_state().rulers; - r.offset_x = offset_x; - r.offset_y = offset_y; - Ok(()) -} - -#[no_mangle] -#[wasm_error] -pub extern "C" fn set_rulers_selection(has: u32, x: f32, y: f32, w: f32, h: f32) -> Result<()> { - get_render_state() - .rulers - .set_selection(has != 0, x, y, w, h); - Ok(()) -} - -#[no_mangle] -#[wasm_error] -pub extern "C" fn set_rulers_colors(bg: u32, border: u32, label: u32, accent: u32) -> Result<()> { - let r = &mut get_render_state().rulers; - r.bg_color = skia::Color::new(bg); - r.border_color = skia::Color::new(border); - r.label_color = skia::Color::new(label); - r.accent_color = skia::Color::new(accent); - Ok(()) -} diff --git a/render-wasm/src/wasm/ui.rs b/render-wasm/src/wasm/ui.rs index e71fd20388..3ef343618c 100644 --- a/render-wasm/src/wasm/ui.rs +++ b/render-wasm/src/wasm/ui.rs @@ -3,7 +3,7 @@ use crate::with_state; use crate::{ error::{Error, Result}, globals::{get_render_state, get_ui_state}, - ui::{Guide, GuideKind}, + ui::{Color, Guide, GuideKind}, }; use macros::{wasm_error, ToJs}; @@ -122,3 +122,46 @@ pub extern "C" fn find_guide_at(x: f32, y: f32, zoom: f32, tolerance: f32) -> Re .map(|guide| guide.index as i32) .unwrap_or(-1)) } + +#[no_mangle] +#[wasm_error] +pub extern "C" fn set_rulers_visible(visible: u32) -> Result<()> { + get_ui_state().ruler_state_mut().visible = visible != 0; + Ok(()) +} + +#[no_mangle] +#[wasm_error] +pub extern "C" fn set_rulers_frame_visible(visible: u32) -> Result<()> { + get_ui_state().ruler_state_mut().frame = visible != 0; + Ok(()) +} + +#[no_mangle] +#[wasm_error] +pub extern "C" fn set_rulers_offsets(offset_x: f32, offset_y: f32) -> Result<()> { + let r = &mut get_ui_state().ruler_state_mut(); + r.offset_x = offset_x; + r.offset_y = offset_y; + Ok(()) +} + +#[no_mangle] +#[wasm_error] +pub extern "C" fn set_rulers_selection(has: u32, x: f32, y: f32, w: f32, h: f32) -> Result<()> { + get_ui_state() + .ruler_state_mut() + .set_selection(has != 0, x, y, w, h); + Ok(()) +} + +#[no_mangle] +#[wasm_error] +pub extern "C" fn set_rulers_colors(bg: u32, border: u32, label: u32, accent: u32) -> Result<()> { + let r = &mut get_ui_state().ruler_state_mut(); + r.bg_color = Color::new(bg); + r.border_color = Color::new(border); + r.label_color = Color::new(label); + r.accent_color = Color::new(accent); + Ok(()) +}