mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-27 19:27:21 -06:00
Merge pull request #4184 from dotCooCoo/fix/character-direction-empty-caret
Character: Character Direction is off at a caret with no characters selected
This commit is contained in:
@@ -775,16 +775,18 @@ fn style_toggle(ui: &mut Ui, g: Glyph, tip: &str, on: bool) -> bool {
|
||||
/// The Character Direction submenu: Default, Left to Right and Right to Left set the characters the
|
||||
/// panel acts on ([`char_cmd`]) as the bidi algorithm sets them, or left to right or right to left
|
||||
/// inside their paragraph. The direction those characters share is checked, and none is checked
|
||||
/// when they differ.
|
||||
/// when they differ. At a caret in text the Type tool edits, with no characters selected, the items
|
||||
/// are disabled.
|
||||
fn char_direction_items(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
use vectorcraft_doc::ParaDirection;
|
||||
let direction = shared(app, |s| s.char_direction);
|
||||
let enabled = text_editing(app).is_none_or(|(_, a, b)| b > a);
|
||||
for (label, d, key) in [
|
||||
(tl!("Default"), None, "default"),
|
||||
(tl!("Left to Right"), Some(ParaDirection::LeftToRight), "leftToRight"),
|
||||
(tl!("Right to Left"), Some(ParaDirection::RightToLeft), "rightToLeft"),
|
||||
] {
|
||||
if menu_item(ui, label, true, direction == Some(d)) {
|
||||
if menu_item(ui, label, enabled, direction == Some(d)) {
|
||||
format(app, json!({"charDirection": key}));
|
||||
}
|
||||
}
|
||||
@@ -1437,6 +1439,36 @@ mod tests {
|
||||
assert_eq!(checked(&mut app), ["Default"]);
|
||||
}
|
||||
|
||||
/// At a caret in text the Type tool edits, with no characters selected, the Character
|
||||
/// Direction items are disabled: a click on one leaves the direction of every character as it was.
|
||||
#[test]
|
||||
fn character_direction_does_nothing_at_an_empty_caret() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 300, "height": 200})).unwrap();
|
||||
let id = app.run("text.create", json!({"x": 20, "y": 50, "text": "שלום 21 10 2026"})).unwrap()["id"].as_u64().unwrap();
|
||||
app.run("select.set", json!({"ids": [id]})).unwrap();
|
||||
app.select_tool("type");
|
||||
app.session.apply_actions(vec![vectorcraft_tools::Action::Notify("text.editNew".into())]).unwrap();
|
||||
app.session.set_tool_option("select", &json!({"start": 3, "end": 3}));
|
||||
let directions = |app: &VectorcraftApp| match &app.session.active().unwrap().doc.node(NodeId(id)).unwrap().kind {
|
||||
NodeKind::Text(t) => t.runs.iter().map(|r| (r.text.clone(), r.style.char_direction)).collect::<Vec<_>>(),
|
||||
_ => panic!("text"),
|
||||
};
|
||||
let before = directions(&app);
|
||||
let ctx = egui::Context::default();
|
||||
let click_rtl = |app: &mut VectorcraftApp| {
|
||||
let texts = super::super::tests_appearance::frame_events(&ctx, app, vec![], char_direction_items);
|
||||
let at = texts.iter().find(|(t, _)| t.trim_start_matches(['✓', ' ']) == "Right to Left").unwrap_or_else(|| panic!("{texts:?}")).1;
|
||||
super::super::tests_appearance::click(&ctx, app, at.center(), char_direction_items);
|
||||
};
|
||||
click_rtl(&mut app);
|
||||
assert_eq!(directions(&app), before);
|
||||
// With characters selected, the same click sets their direction.
|
||||
app.session.set_tool_option("select", &json!({"start": 0, "end": 4}));
|
||||
click_rtl(&mut app);
|
||||
assert_ne!(directions(&app), before);
|
||||
}
|
||||
|
||||
/// No Break is in the panel menu, and choosing it marks the selected characters.
|
||||
#[test]
|
||||
fn no_break_menu_item_toggles_the_selected_characters() {
|
||||
|
||||
Reference in New Issue
Block a user