mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-26 19:26:46 -06:00
UI: drop cap fields, selection over drop caps
This commit is contained in:
@@ -1004,6 +1004,15 @@ fn draw_text_selection(
|
||||
let x1 = if e == l.range.end && range.end > l.range.end { l.end_x.max(x0 + 3.0) } else { compose::caret_x(l, e) };
|
||||
quads.push(quad(x0, x1));
|
||||
}
|
||||
// A selected drop cap is highlighted down to its baseline.
|
||||
if let Some(dc) = l.drop_cap {
|
||||
let sel = l.glyphs.iter().filter(|g| g.len > 0 && g.byte < dc.end && g.byte >= s && g.byte < e);
|
||||
let (a, b) = sel.fold((f64::INFINITY, f64::NEG_INFINITY), |(a, b), g| (a.min(g.x), b.max(g.x + g.adv)));
|
||||
if a < b {
|
||||
let r = dc.rect;
|
||||
quads.push([Point::new(a, r.y0), Point::new(b, r.y0), Point::new(b, r.y1), Point::new(a, r.y1)]);
|
||||
}
|
||||
}
|
||||
for (gi, g) in l.glyphs.iter().enumerate() {
|
||||
if g.visible && g.len > 0 && g.byte >= s && g.byte < e {
|
||||
glyphs.push((li, gi));
|
||||
|
||||
@@ -1771,6 +1771,35 @@ fn paragraph_style_options(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialo
|
||||
});
|
||||
}
|
||||
"nested" => {
|
||||
crate::rtl::label(ui, egui::RichText::new(crate::i18n::tr(&app.ui.language, "Drop Caps")).font(semibold(12.0)));
|
||||
egui::Grid::new("psdc").num_columns(2).spacing([8.0, 6.0]).show(ui, |ui| {
|
||||
for (label, key, max) in [
|
||||
("Lines:", "dropCapLines", designcraft_compose::MAX_DROP_CAP_LINES),
|
||||
("Characters:", "dropCapChars", designcraft_compose::MAX_DROP_CAP_CHARS),
|
||||
] {
|
||||
crate::rtl::label(ui, crate::i18n::tr(&app.ui.language, label));
|
||||
let v = cur(d, &format!("p.{key}"), &pv[key]).as_f64();
|
||||
if let Some(n) = crate::widgets::number(ui, &format!("ps{key}"), v, "", 60.0, 0) {
|
||||
d.fields.insert(format!("p.{key}"), json!((n.max(0.0) as u64).min(max as u64)));
|
||||
}
|
||||
ui.end_row();
|
||||
}
|
||||
crate::rtl::label(ui, crate::i18n::tr(&app.ui.language, "Character Style:"));
|
||||
let style = cur(d, "p.dropCapStyle", &pv["dropCapStyle"]).as_str().unwrap_or("").to_string();
|
||||
let style = if style.is_empty() { designcraft_doc::NO_CHAR_STYLE.to_string() } else { style };
|
||||
egui::ComboBox::from_id_salt("ps_dropcap_style")
|
||||
.selected_text(crate::rtl::widget(ui, crate::i18n::style_name(&app.ui.language, &style)))
|
||||
.width(160.0)
|
||||
.show_ui(ui, |ui| {
|
||||
for c in &cnames {
|
||||
if ui.selectable_label(*c == style, crate::rtl::widget(ui, crate::i18n::style_name(&app.ui.language, c))).clicked() {
|
||||
d.fields.insert("p.dropCapStyle".into(), json!(c));
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.end_row();
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
crate::rtl::label(ui, egui::RichText::new(crate::i18n::tr(&app.ui.language, "Nested Styles")).font(semibold(12.0)));
|
||||
let mut list: Vec<Value> = cur(d, "p.nestedStyles", &pv["nestedStyles"]).as_array().cloned().unwrap_or_default();
|
||||
let mut changed = false;
|
||||
@@ -1814,9 +1843,19 @@ fn paragraph_style_options(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialo
|
||||
.selected_text(crate::rtl::widget(ui, crate::i18n::tr(&app.ui.language, &kind)))
|
||||
.width(100.0)
|
||||
.show_ui(ui, |ui| {
|
||||
for k in
|
||||
["sentences", "words", "characters", "letters", "digits", "tab", "forcedLineBreak", "emSpace", "enSpace", "chars"]
|
||||
{
|
||||
for k in [
|
||||
"sentences",
|
||||
"words",
|
||||
"characters",
|
||||
"letters",
|
||||
"digits",
|
||||
"tab",
|
||||
"forcedLineBreak",
|
||||
"emSpace",
|
||||
"enSpace",
|
||||
"dropcap",
|
||||
"chars",
|
||||
] {
|
||||
if ui.selectable_label(k == kind, crate::rtl::widget(ui, crate::i18n::tr(&app.ui.language, k))).clicked() {
|
||||
ns["until"] = if k == "chars" { json!({"kind": "chars", "chars": ":"}) } else { json!({"kind": k}) };
|
||||
changed = true;
|
||||
|
||||
@@ -1891,6 +1891,12 @@ const TABLE: &[(&str, [&str; 5])] = &[
|
||||
("forcedLineBreak", ["forcedLineBreak", "forcedLineBreak", "forcedLineBreak", "forcedLineBreak", "强制换行符"]),
|
||||
("emSpace", ["emSpace", "emSpace", "emSpace", "emSpace", "全角空格"]),
|
||||
("enSpace", ["enSpace", "enSpace", "enSpace", "enSpace", "半角空格"]),
|
||||
("dropcap", ["Initiale", "lettrine", "capitular", "ドロップキャップ", "首字下沉"]),
|
||||
("Drop Caps", ["Initialen", "Lettrines", "Capitulares", "ドロップキャップ", "首字下沉"]),
|
||||
("Lines:", ["Zeilen:", "Lignes :", "Líneas:", "行数:", "行数:"]),
|
||||
("Characters:", ["Zeichen:", "Caractères :", "Caracteres:", "文字数:", "字符数:"]),
|
||||
("Drop Lines", ["Initialzeilen", "Lignes lettrine", "Líneas capitular", "ドロップ行数", "下沉行数"]),
|
||||
("Drop Chars", ["Initialzeichen", "Car. lettrine", "Car. capitular", "ドロップ文字数", "下沉字符数"]),
|
||||
("chars", ["chars", "chars", "chars", "chars", "指定字符"]),
|
||||
("[Automatic]", ["[Automatic]", "[Automatic]", "[Automatic]", "[Automatic]", "[自动]"]),
|
||||
("Tracking:", ["Tracking:", "Tracking:", "Tracking:", "Tracking:", "字距:"]),
|
||||
|
||||
@@ -317,6 +317,12 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("forcedLineBreak", "فاصل سطر إجباري"),
|
||||
("emSpace", "مسافة em"),
|
||||
("enSpace", "مسافة en"),
|
||||
("dropcap", "الحرف الاستهلالي"),
|
||||
("Drop Caps", "الأحرف الاستهلالية"),
|
||||
("Lines:", "الأسطر:"),
|
||||
("Characters:", "الأحرف:"),
|
||||
("Drop Lines", "أسطر الاستهلال"),
|
||||
("Drop Chars", "أحرف الاستهلال"),
|
||||
("chars", "محارف محددة"),
|
||||
("[Automatic]", "[تلقائي]"),
|
||||
("Size:", "الحجم:"),
|
||||
|
||||
@@ -1452,6 +1452,17 @@ pub fn paragraph_panel(app: &mut DesignApp, ui: &mut egui::Ui) {
|
||||
}
|
||||
ui.end_row();
|
||||
}
|
||||
// Drop cap: number of lines and characters.
|
||||
for (label, key, max, id) in [
|
||||
("Drop Lines", "dropCapLines", designcraft_compose::MAX_DROP_CAP_LINES, "ppdl"),
|
||||
("Drop Chars", "dropCapChars", designcraft_compose::MAX_DROP_CAP_CHARS, "ppdc"),
|
||||
] {
|
||||
caption(ui, crate::i18n::tr(&app.ui.language, label));
|
||||
if let Some(v) = number(ui, id, p[key].as_f64(), "", 64.0, 0) {
|
||||
let _ = app.run("type.para", json!({"attrs": {key: (v.max(0.0) as u64).min(max as u64)}}));
|
||||
}
|
||||
}
|
||||
ui.end_row();
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
let mut h = p["hyphenate"].as_bool().unwrap_or(true);
|
||||
|
||||
Reference in New Issue
Block a user