From a761e7803eb87214f6907aabf9f7d7a3ec55530e Mon Sep 17 00:00:00 2001 From: James Lindsay <78500760+0HyperCube@users.noreply.github.com> Date: Sun, 13 Oct 2024 22:35:50 +0100 Subject: [PATCH] Improve text overlay styling and fix artboard label positioning bug (#2032) * Improve text overlays * I can't test code --- editor/src/consts.rs | 1 + .../document/document_message_handler.rs | 9 ++-- .../document/overlays/utility_types.rs | 53 ++++++++----------- .../tool/common_functionality/measure.rs | 6 +-- .../tool/common_functionality/snapping.rs | 7 +-- 5 files changed, 34 insertions(+), 42 deletions(-) diff --git a/editor/src/consts.rs b/editor/src/consts.rs index 37287a9d..3f4f3c5c 100644 --- a/editor/src/consts.rs +++ b/editor/src/consts.rs @@ -83,6 +83,7 @@ pub const COLOR_OVERLAY_GREEN: &str = "#63ce63"; pub const COLOR_OVERLAY_RED: &str = "#ef5454"; pub const COLOR_OVERLAY_GRAY: &str = "#cccccc"; pub const COLOR_OVERLAY_WHITE: &str = "#ffffff"; +pub const COLOR_OVERLAY_SNAP_BACKGROUND: &str = "#000000cc"; // Document pub const DEFAULT_DOCUMENT_NAME: &str = "Untitled Document"; diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index ab68b45b..b1e0dfc1 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -384,11 +384,12 @@ impl MessageHandler> for DocumentMessag let name = self.network_interface.frontend_display_name(&layer.to_node(), &[]); - let (scale, angle, translation) = self.metadata().document_to_viewport.to_scale_angle_translation(); - let translation = translation + scale * bounds[0].min(bounds[1]) - DVec2::Y * 4.; - let transform = DAffine2::from_angle_translation(angle, translation); + let transform = self.metadata().document_to_viewport + * DAffine2::from_translation(bounds[0].min(bounds[1])) + * DAffine2::from_scale(DVec2::splat(self.document_ptz.zoom().recip())) + * DAffine2::from_translation(-DVec2::Y * 4.); - overlay_context.text_with_transform(&name, COLOR_OVERLAY_GRAY, None, transform, Pivot::BottomLeft); + overlay_context.text(&name, COLOR_OVERLAY_GRAY, None, transform, 0., [Pivot::Start, Pivot::End]); } } DocumentMessage::DuplicateSelectedLayers => { diff --git a/editor/src/messages/portfolio/document/overlays/utility_types.rs b/editor/src/messages/portfolio/document/overlays/utility_types.rs index 4112e1ff..2e3fd649 100644 --- a/editor/src/messages/portfolio/document/overlays/utility_types.rs +++ b/editor/src/messages/portfolio/document/overlays/utility_types.rs @@ -247,52 +247,41 @@ impl OverlayContext { self.render_context.stroke(); } - pub fn text(&self, text: &str, font_color: &str, background_color: Option<&str>, pos: DVec2) { + pub fn text(&self, text: &str, font_color: &str, background_color: Option<&str>, transform: DAffine2, padding: f64, pivot: [Pivot; 2]) { let metrics = self.render_context.measure_text(text).expect("Failed to measure the text dimensions"); - let local_position = pos.round(); - - self.draw_text(background_color, local_position, metrics, font_color, text); - } - - pub fn text_with_transform(&self, text: &str, font_color: &str, background_color: Option<&str>, transform: DAffine2, origin: Pivot) { - let [a, b, c, d, e, f] = transform.to_cols_array(); - self.render_context.set_transform(a, b, c, d, e, f).expect("Failed to rotate the render context to the specified angle"); - - let metrics = self.render_context.measure_text(text).expect("Failed to measure the text dimensions"); - let local_position = match origin { - Pivot::CenterLeft => DVec2::new(0., (metrics.actual_bounding_box_ascent() + metrics.actual_bounding_box_descent()) / 2.), - Pivot::TopCenter => DVec2::new(-(metrics.actual_bounding_box_right() + metrics.actual_bounding_box_left()) / 2., metrics.font_bounding_box_ascent()), - Pivot::BottomLeft => DVec2::ZERO, + let x = match pivot[0] { + Pivot::Start => padding, + Pivot::Middle => -(metrics.actual_bounding_box_right() + metrics.actual_bounding_box_left()) / 2., + Pivot::End => -padding - metrics.actual_bounding_box_right() + metrics.actual_bounding_box_left(), + }; + let y = match pivot[1] { + Pivot::Start => padding + metrics.font_bounding_box_ascent() - metrics.font_bounding_box_descent(), + Pivot::Middle => (metrics.font_bounding_box_ascent() + metrics.font_bounding_box_descent()) / 2., + Pivot::End => -padding, }; - self.draw_text(background_color, local_position, metrics, font_color, text); + let [a, b, c, d, e, f] = (transform * DAffine2::from_translation(DVec2::new(x, y))).to_cols_array(); + self.render_context.set_transform(a, b, c, d, e, f).expect("Failed to rotate the render context to the specified angle"); - self.render_context.reset_transform().expect("Failed to reset the render context transform"); - } - - fn draw_text(&self, background_color: Option<&str>, local_position: DVec2, metrics: web_sys::TextMetrics, font_color: &str, text: &str) { - // Render background if let Some(background) = background_color { self.render_context.set_fill_style_str(background); self.render_context.fill_rect( - local_position.x + metrics.actual_bounding_box_left(), - local_position.y - metrics.font_bounding_box_ascent() - metrics.font_bounding_box_descent(), - metrics.actual_bounding_box_right() - metrics.actual_bounding_box_left(), - metrics.font_bounding_box_ascent() + metrics.font_bounding_box_descent(), + -padding, + padding, + metrics.actual_bounding_box_right() - metrics.actual_bounding_box_left() + padding * 2., + metrics.font_bounding_box_descent() - metrics.font_bounding_box_ascent() - padding * 2., ); } - // Render text self.render_context.set_font("12px Source Sans Pro, Arial, sans-serif"); self.render_context.set_fill_style_str(font_color); - self.render_context - .fill_text(text, local_position.x, local_position.y - metrics.font_bounding_box_descent()) - .expect("Failed to draw the text on the canvas"); + self.render_context.fill_text(text, 0., 0.).expect("Failed to draw the text at the calculated position"); + self.render_context.reset_transform().expect("Failed to reset the render context transform"); } } pub enum Pivot { - TopCenter, - CenterLeft, - BottomLeft, + Start, + Middle, + End, } diff --git a/editor/src/messages/tool/common_functionality/measure.rs b/editor/src/messages/tool/common_functionality/measure.rs index 256121d0..14b8a85e 100644 --- a/editor/src/messages/tool/common_functionality/measure.rs +++ b/editor/src/messages/tool/common_functionality/measure.rs @@ -1,5 +1,5 @@ use crate::consts::COLOR_OVERLAY_BLUE; -use crate::messages::portfolio::document::overlays::utility_types::{self, OverlayContext}; +use crate::messages::portfolio::document::overlays::utility_types::{OverlayContext, Pivot}; use crate::messages::tool::tool_messages::tool_prelude::*; use graphene_std::renderer::Rect; @@ -25,7 +25,7 @@ pub fn overlay(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, let length = format!("{:.2}", transform_to_document.transform_vector2(DVec2::X * (turn_x - selected_x)).length()); let direction = -(min_viewport - max_viewport).normalize_or_zero(); let transform = DAffine2::from_translation((min_viewport + max_viewport) / 2.) * DAffine2::from_angle(-direction.angle_to(DVec2::X)); - overlay_context.text_with_transform(&length, COLOR_OVERLAY_BLUE, None, transform, utility_types::Pivot::TopCenter); + overlay_context.text(&length, COLOR_OVERLAY_BLUE, None, transform, 5., [Pivot::Middle, Pivot::Start]); } if turn_y != hovered_y { let min_viewport = transform.transform_point2(DVec2::new(turn_x, turn_y.min(hovered_y))); @@ -34,6 +34,6 @@ pub fn overlay(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, let length = format!("{:.2}", transform_to_document.transform_vector2(DVec2::Y * (turn_y - hovered_y)).length()); let direction = (min_viewport - max_viewport).normalize_or_zero().perp(); let transform = DAffine2::from_translation((min_viewport + max_viewport) / 2.) * DAffine2::from_angle(-direction.angle_to(DVec2::X)); - overlay_context.text_with_transform(&length, COLOR_OVERLAY_BLUE, None, transform, utility_types::Pivot::CenterLeft); + overlay_context.text(&length, COLOR_OVERLAY_BLUE, None, transform, 5., [Pivot::Start, Pivot::Middle]); } } diff --git a/editor/src/messages/tool/common_functionality/snapping.rs b/editor/src/messages/tool/common_functionality/snapping.rs index ed0c98b6..f09f4c2c 100644 --- a/editor/src/messages/tool/common_functionality/snapping.rs +++ b/editor/src/messages/tool/common_functionality/snapping.rs @@ -5,8 +5,8 @@ mod layer_snapper; mod snap_results; pub use {alignment_snapper::*, distribution_snapper::*, grid_snapper::*, layer_snapper::*, snap_results::*}; -use crate::consts::{COLOR_OVERLAY_BLUE, COLOR_OVERLAY_WHITE}; -use crate::messages::portfolio::document::overlays::utility_types::OverlayContext; +use crate::consts::{COLOR_OVERLAY_BLUE, COLOR_OVERLAY_SNAP_BACKGROUND, COLOR_OVERLAY_WHITE}; +use crate::messages::portfolio::document::overlays::utility_types::{OverlayContext, Pivot}; use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier; use crate::messages::portfolio::document::utility_types::misc::{BoundingBoxSnapTarget, GeometrySnapTarget, GridSnapTarget, SnapTarget}; use crate::messages::prelude::*; @@ -467,7 +467,8 @@ impl SnapManager { if !any_align && ind.distribution_equal_distance_x.is_none() && ind.distribution_equal_distance_y.is_none() { let text = format!("{:?} to {:?}", ind.source, ind.target); - overlay_context.text(&text, COLOR_OVERLAY_BLUE, Some(COLOR_OVERLAY_WHITE), viewport - DVec2::new(0., 5.)); + let transform = DAffine2::from_translation(viewport - DVec2::new(0., 5.)); + overlay_context.text(&text, COLOR_OVERLAY_WHITE, Some(COLOR_OVERLAY_SNAP_BACKGROUND), transform, 5., [Pivot::Start, Pivot::End]); overlay_context.square(viewport, Some(4.), Some(COLOR_OVERLAY_BLUE), Some(COLOR_OVERLAY_BLUE)); } }