mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-04 21:38:12 +08:00
Add visualization overlays to G/R/S (#2195)
* Make HintInfo label use Cow<'static, str> instead of String Fixes https://discord.com/channels/731730685944922173/881073965047636018/931942323644928040 tmp, will amend later * Replaces dynamic hint used by transform layer with overlays * Adds a scaling factor accounting for document and viewport scales Also moves whole code to single unit * Make overlays relative to viewport rather than document * Add visualization overlays to G/R/S in the Select tool * Prevents quick measurements from showing up when resizing bounds Fixes https://discord.com/channels/731730685944922173/881073965047636018/1328282633456713762 * Add local axes which activates on double constraints. * Handle the bounding box of a collection of layers as select tool does * Replaced hard coded transparent color and removed debug! which slipped in * Make rotation axes start along local axis * Fix typed distance being in doc space and negatives * Fix missing undo transactions for some actions * Code review --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
3048466e86
commit
de36d4967d
@@ -1,5 +1,7 @@
|
||||
use super::utility_functions::overlay_canvas_context;
|
||||
use crate::consts::{COLOR_OVERLAY_BLUE, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER};
|
||||
use crate::consts::{
|
||||
COLOR_OVERLAY_BLUE, COLOR_OVERLAY_TRANSPARENT, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
|
||||
};
|
||||
use crate::messages::prelude::Message;
|
||||
|
||||
use bezier_rs::{Bezier, Subpath};
|
||||
@@ -188,6 +190,65 @@ impl OverlayContext {
|
||||
self.render_context.fill();
|
||||
self.render_context.stroke();
|
||||
}
|
||||
|
||||
pub fn draw_arc(&mut self, center: DVec2, radius: f64, start_from: f64, end_at: f64) {
|
||||
let segments = ((end_at - start_from).abs() / (std::f64::consts::PI / 4.)).ceil() as usize;
|
||||
let step = (end_at - start_from) / segments as f64;
|
||||
let half_step = step / 2.;
|
||||
let factor = 4. / 3. * half_step.sin() / (1. + half_step.cos());
|
||||
|
||||
self.render_context.begin_path();
|
||||
|
||||
for i in 0..segments {
|
||||
let start_angle = start_from + step * i as f64;
|
||||
let end_angle = start_angle + step;
|
||||
let start_vec = DVec2::from_angle(start_angle);
|
||||
let end_vec = DVec2::from_angle(end_angle);
|
||||
|
||||
let start = center + radius * start_vec;
|
||||
let end = center + radius * end_vec;
|
||||
|
||||
let handle_start = start + start_vec.perp() * radius * factor;
|
||||
let handle_end = end - end_vec.perp() * radius * factor;
|
||||
|
||||
let bezier = Bezier {
|
||||
start,
|
||||
end,
|
||||
handles: bezier_rs::BezierHandles::Cubic { handle_start, handle_end },
|
||||
};
|
||||
|
||||
self.bezier_command(bezier, DAffine2::IDENTITY, i == 0);
|
||||
}
|
||||
|
||||
self.render_context.stroke();
|
||||
}
|
||||
|
||||
pub fn draw_angle(&mut self, pivot: DVec2, radius: f64, arc_radius: f64, offset_angle: f64, angle: f64) {
|
||||
let color_line = COLOR_OVERLAY_BLUE;
|
||||
|
||||
let end_point1 = pivot + radius * DVec2::from_angle(angle + offset_angle);
|
||||
let end_point2 = pivot + radius * DVec2::from_angle(offset_angle);
|
||||
self.line(pivot, end_point1, Some(color_line));
|
||||
self.line(pivot, end_point2, Some(color_line));
|
||||
|
||||
self.draw_arc(pivot, arc_radius, offset_angle, (angle) % TAU + offset_angle);
|
||||
}
|
||||
|
||||
pub fn draw_scale(&mut self, start: DVec2, scale: f64, radius: f64, text: &str) {
|
||||
let sign = scale.signum();
|
||||
self.line(start + DVec2::X * radius * sign, start + DVec2::X * (radius * scale), None);
|
||||
self.circle(start, radius, Some(COLOR_OVERLAY_TRANSPARENT), None);
|
||||
self.circle(start, radius * scale.abs(), Some(COLOR_OVERLAY_TRANSPARENT), None);
|
||||
self.text(
|
||||
text,
|
||||
COLOR_OVERLAY_BLUE,
|
||||
None,
|
||||
DAffine2::from_translation(start + sign * DVec2::X * radius * (1. + scale.abs()) / 2.),
|
||||
2.,
|
||||
[Pivot::Middle, Pivot::End],
|
||||
)
|
||||
}
|
||||
|
||||
pub fn pivot(&mut self, position: DVec2) {
|
||||
let (x, y) = (position.round() - DVec2::splat(0.5)).into();
|
||||
|
||||
@@ -300,6 +361,10 @@ impl OverlayContext {
|
||||
self.render_context.stroke();
|
||||
}
|
||||
|
||||
pub fn get_width(&self, text: &str) -> f64 {
|
||||
self.render_context.measure_text(text).expect("Failed to measure text dimensions").width()
|
||||
}
|
||||
|
||||
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 x = match pivot[0] {
|
||||
|
||||
Reference in New Issue
Block a user