mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #3539 from nrq6993-a11y/stream/vc-featD-g4-mixed-paragraph-kinsoku-mojikumi
G4: Mixed paragraph kinsoku and mojikumi dropdowns
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
use egui::{Ui, vec2};
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_doc::{Composer, HyphenationOptions, Justify, NodeKind, ParaDirection, ParaStyle};
|
||||
use vectorcraft_doc::{Composer, HyphenationOptions, Justify, Kinsoku, Mojikumi, NodeKind, ParaDirection, ParaStyle};
|
||||
|
||||
use super::character::{Metric, Shared, text_style};
|
||||
use super::{pstate, set_pstate};
|
||||
@@ -179,32 +179,28 @@ fn shared_para_field(app: &VectorcraftApp, field: impl Fn(&ParaStyle) -> f64) ->
|
||||
acc.value().map(|m| m.0)
|
||||
}
|
||||
|
||||
/// The composer every paragraph in scope shares, or `None` when they differ (neither menu item checked).
|
||||
fn shared_composer(app: &VectorcraftApp) -> Option<Composer> {
|
||||
/// A paragraph attribute shared by every paragraph in scope, or `None` when they differ.
|
||||
fn shared_para<T: PartialEq + Copy>(app: &VectorcraftApp, field: impl Fn(&ParaStyle) -> T) -> Option<T> {
|
||||
let mut acc = Shared::None;
|
||||
let mut any = false;
|
||||
visit_paragraphs(app, |p| {
|
||||
any = true;
|
||||
acc.add(p.composer);
|
||||
acc.add(field(p));
|
||||
});
|
||||
if !any {
|
||||
return text_style(app).map(|(_, p)| p.composer);
|
||||
return text_style(app).map(|(_, p)| field(&p));
|
||||
}
|
||||
acc.value()
|
||||
}
|
||||
|
||||
/// The composer every paragraph in scope shares, or `None` when they differ (neither menu item checked).
|
||||
fn shared_composer(app: &VectorcraftApp) -> Option<Composer> {
|
||||
shared_para(app, |p| p.composer)
|
||||
}
|
||||
|
||||
/// Hyphenation shared by every paragraph in scope, or `None` when they differ (checkbox off).
|
||||
fn shared_hyphenate(app: &VectorcraftApp) -> Option<bool> {
|
||||
let mut acc = Shared::None;
|
||||
let mut any = false;
|
||||
visit_paragraphs(app, |p| {
|
||||
any = true;
|
||||
acc.add(p.hyphenate);
|
||||
});
|
||||
if !any {
|
||||
return text_style(app).map(|(_, p)| p.hyphenate);
|
||||
}
|
||||
acc.value()
|
||||
shared_para(app, |p| p.hyphenate)
|
||||
}
|
||||
|
||||
/// None means differing displayed alignments, following the other mixed-value controls.
|
||||
@@ -340,7 +336,11 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
ui.horizontal(|ui| {
|
||||
widgets::dim_label(ui, tl!("Mojikumi Set"));
|
||||
let sets = [tl!("None"), tl!("Line-end Punctuation Half Width")];
|
||||
let current = if para.mojikumi == vectorcraft_doc::Mojikumi::LineEndHalf { sets[1] } else { sets[0] };
|
||||
let current = match shared_para(app, |p| p.mojikumi) {
|
||||
Some(Mojikumi::LineEndHalf) => sets[1],
|
||||
Some(Mojikumi::None) => sets[0],
|
||||
None => "",
|
||||
};
|
||||
// Already translated: shown as they are.
|
||||
if let Some(i) = widgets::dropdown_names(ui, "pa-mojikumi", current, &sets, ui.available_width() - 4.0) {
|
||||
format(app, json!({"mojikumi": if i == 1 { "lineEndHalf" } else { "none" }}));
|
||||
@@ -348,11 +348,10 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
});
|
||||
// Which characters may not start or end a line.
|
||||
ui.horizontal(|ui| {
|
||||
use vectorcraft_doc::Kinsoku;
|
||||
widgets::dim_label(ui, tl!("Kinsoku Set"));
|
||||
let sets = [(tl!("None"), Kinsoku::None, "none"), (tl!("Hard"), Kinsoku::Hard, "hard"), (tl!("Soft"), Kinsoku::Soft, "soft")];
|
||||
let names = sets.map(|s| s.0);
|
||||
let current = sets.iter().find(|s| s.1 == para.kinsoku).map_or(names[1], |s| s.0);
|
||||
let current = shared_para(app, |p| p.kinsoku).and_then(|k| sets.iter().find(|s| s.1 == k).map(|s| s.0)).unwrap_or("");
|
||||
// Already translated: shown as they are.
|
||||
if let Some(i) = widgets::dropdown_names(ui, "pa-kinsoku", current, &names, ui.available_width() - 4.0)
|
||||
&& let Some((_, _, key)) = sets.get(i)
|
||||
@@ -530,6 +529,20 @@ mod tests {
|
||||
assert_eq!(shared_hyphenate(&app), Some(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paragraph_mixed_kinsoku_and_mojikumi_show_blank_dropdowns() {
|
||||
let (mut app, id) = editing_text("A\nB\n");
|
||||
app.session.prefs.show_east_asian_options = true;
|
||||
app.run("text.setFormat", json!({"id": id, "kinsoku": "hard", "mojikumi": "none"})).unwrap();
|
||||
app.run("text.setFormat", json!({"id": id, "start": 2, "end": 3, "kinsoku": "soft", "mojikumi": "lineEndHalf"})).unwrap();
|
||||
app.session.set_tool_option("selectAll", &json!(true));
|
||||
assert_eq!(shared_para(&app, |p| p.kinsoku), None);
|
||||
assert_eq!(shared_para(&app, |p| p.mojikumi), None);
|
||||
app.run("text.setFormat", json!({"id": id, "kinsoku": "hard", "mojikumi": "lineEndHalf"})).unwrap();
|
||||
assert_eq!(shared_para(&app, |p| p.kinsoku), Some(Kinsoku::Hard));
|
||||
assert_eq!(shared_para(&app, |p| p.mojikumi), Some(Mojikumi::LineEndHalf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paragraph_mixed_indent_fields_show_blank() {
|
||||
let (mut app, id) = editing_text("A\nB\n");
|
||||
|
||||
Reference in New Issue
Block a user