diff --git a/crates/engine/src/cmd/fileio/save.rs b/crates/engine/src/cmd/fileio/save.rs index 3eb64f3ea..1d70e99f2 100644 --- a/crates/engine/src/cmd/fileio/save.rs +++ b/crates/engine/src/cmd/fileio/save.rs @@ -300,7 +300,7 @@ fn disagreeing_option(p: &Value, svg: bool) -> std::result::Result Option { @@ -770,7 +770,7 @@ impl Cursor { | Cursor::SymbolScreener | Cursor::SymbolStyler | Cursor::Scissors => Some(Cursor::Crosshair), - Cursor::TypeVertical | Cursor::LoadedText => Some(Cursor::Text), + Cursor::TypeVertical => Some(Cursor::Text), Cursor::MeshAdd | Cursor::PuppetPin => Some(Cursor::PenAdd), Cursor::ScissorsNotAllowed => Some(Cursor::NotAllowed), _ => None, diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 6085f62dd..a951ef290 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -878,7 +878,8 @@ fn cursor_icon(c: Cursor) -> egui::CursorIcon { | Cursor::GroupSelection | Cursor::CornerRadius | Cursor::PathBracket - | Cursor::TypeWidget => C::Default, + | Cursor::TypeWidget + | Cursor::LoadedText => C::Default, Cursor::SelectionCopy => C::Copy, Cursor::Move => C::Move, Cursor::Crosshair => C::Crosshair, @@ -942,8 +943,7 @@ fn cursor_icon(c: Cursor) -> egui::CursorIcon { | Cursor::Scissors | Cursor::ScissorsNotAllowed | Cursor::MeshAdd - | Cursor::PuppetPin - | Cursor::LoadedText => cursor_icon(c.stand_in().unwrap_or(Cursor::Crosshair)), + | Cursor::PuppetPin => cursor_icon(c.stand_in().unwrap_or(Cursor::Crosshair)), } } diff --git a/crates/ui-egui/src/cursors.rs b/crates/ui-egui/src/cursors.rs index 0c1c208db..bfb28ef4d 100644 --- a/crates/ui-egui/src/cursors.rs +++ b/crates/ui-egui/src/cursors.rs @@ -294,6 +294,18 @@ fn type_widget(p: &mut Ink, o: Pos2) { line(p, b + vec2(4.0, 0.0), b + vec2(4.0, 9.0)); } +/// Overflow text the Selection tool carries after a click on the red out port: a small block of +/// lines at the hotspot (where a new frame's top-left would go). +fn loaded_text(p: &mut Ink, o: Pos2) { + let tl = o; + let br = o + vec2(14.0, 11.0); + let frame = vec![tl, pos2(br.x, tl.y), br, pos2(tl.x, br.y)]; + poly(p, frame, HALO, INK); + for y in [3.0, 6.5, 10.0] { + line(p, tl + vec2(2.0, y), tl + vec2(12.0, y)); + } +} + /// The gradient annotator's stop cursors: the arrow with a plus (add a stop) or minus (delete it) /// badge. fn stop_badge(p: &mut Ink, o: Pos2, add: bool) { @@ -593,6 +605,7 @@ fn glyph(c: Cursor, p: Pos2) -> Option> { Cursor::Blend | Cursor::BlendObject | Cursor::BlendAnchor => blend(ink, p, c), Cursor::PathBracket => path_bracket(ink, p), Cursor::TypeWidget => type_widget(ink, p), + Cursor::LoadedText => loaded_text(ink, p), Cursor::ShapeBuilder => shape_builder(ink, p, false), Cursor::ShapeBuilderErase => shape_builder(ink, p, true), Cursor::Hand => hand(ink, p, false), @@ -825,6 +838,17 @@ mod tests { } } + /// Loaded text after a click on the overflow out port is a text-block glyph, not the I-beam. + #[test] + fn loaded_text_cursor_is_not_the_text_i_beam() { + assert!(Cursor::LoadedText.stand_in().is_none()); + let loaded = rasterize(Cursor::LoadedText, 2.0).expect("loaded text bitmap"); + let ibeam = rasterize(Cursor::Text, 2.0).expect("text bitmap"); + assert_ne!(loaded.rgba, ibeam.rgba); + let [hx, hy] = loaded.hotspot.map(usize::from); + assert!(pixel(&loaded, hx, hy)[3] > 200, "hotspot lies on the drawn frame"); + } + #[test] fn every_glyph_becomes_a_bitmap_with_its_hotspot_inside() { for ppp in [1.0, 1.25, 1.5, 2.0, 3.0] {