diff --git a/crates/ui-egui/src/a11y_ui.rs b/crates/ui-egui/src/a11y_ui.rs index ef372a93..9482ed63 100644 --- a/crates/ui-egui/src/a11y_ui.rs +++ b/crates/ui-egui/src/a11y_ui.rs @@ -493,8 +493,7 @@ pub(crate) fn alt_body(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tokens) -> ui.add_space(8.0); ui.add_enabled_ui(!d.decorative[i], |ui| { let l = ui.label(tl!("Alternate text")); - ui.add(egui::TextEdit::multiline(&mut d.texts[i]).desired_rows(3).desired_width(380.0).hint_text(tl!("Describe the figure"))) - .labelled_by(l.id); + ui.add(crate::widgets::block(&mut d.texts[i]).desired_rows(3).desired_width(380.0).hint_text(tl!("Describe the figure"))).labelled_by(l.id); }); ui.checkbox(&mut d.decorative[i], tl!("Decorative figure")); ui.add_space(10.0); diff --git a/crates/ui-egui/src/actions_ui.rs b/crates/ui-egui/src/actions_ui.rs index b3142637..89cf2569 100644 --- a/crates/ui-egui/src/actions_ui.rs +++ b/crates/ui-egui/src/actions_ui.rs @@ -307,10 +307,10 @@ fn edit_body(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tokens) -> bool { ui.add_space(8.0); egui::Grid::new("action-edit").num_columns(2).spacing([12.0, 8.0]).show(ui, |ui| { ui.label(tl!("Action name:")); - ui.add(egui::TextEdit::singleline(&mut a.name).desired_width(320.0).id_salt("action-name")); + ui.add(crate::widgets::line(&mut a.name).desired_width(320.0).id_salt("action-name")); ui.end_row(); ui.label(tl!("Description:")); - ui.add(egui::TextEdit::singleline(&mut a.description).desired_width(320.0).id_salt("action-description")); + ui.add(crate::widgets::line(&mut a.description).desired_width(320.0).id_salt("action-description")); ui.end_row(); }); ui.add_space(6.0); @@ -326,7 +326,7 @@ fn edit_body(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tokens) -> bool { ui.horizontal(|ui| { ui.label(format!("{}. {}", i + 1, tl!(s.label()))); if let Some(arg) = s.arg_mut() { - ui.add(egui::TextEdit::singleline(arg).desired_width(220.0)); + ui.add(crate::widgets::line(arg).desired_width(220.0)); } ui.with_layout(Layout::right_to_left(Align::Center), |ui| { if ui.button(tl!("Remove")).clicked() { diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 32273a96..b6c1fffe 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -2190,6 +2190,14 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) { }; let mut open_signature = false; let mut hover_text: Option<(Pos2, String)> = None; + // A dialog, save prompt or palette covers the page. Hover tips are drawn above those + // windows, so a comment under the pointer would otherwise float over the dialog. + let page_covered = app.dialog.is_some() + || app.close_request.is_some() + || app.palette_open + || app.password_prompt.is_some() + || app.pending_link.is_some() + || app.updates.open; let mut clicked_link: Option = None; let mut canvas_action: Option = None; let mut field_menu: Option = None; @@ -2734,7 +2742,8 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) { } } // Fill & Sign keeps its placement cursor clear of link/comment hover feedback. - if !matches!(tool, QuickTool::Fill(_)) + if !page_covered + && !matches!(tool, QuickTool::Fill(_)) && let Some(p) = pointer { for l in info.links.iter().filter(|l| l.page == i) { @@ -3479,12 +3488,14 @@ fn quick_bar(app: &mut PdfCraftApp, area: Rect, ui: &mut egui::Ui) { ui.painter().rect_filled(row, CornerRadius::same(4), t.hover); } icons::paint(ui, Rect::from_min_size(row.min + vec2(8.0, 6.0), vec2(16.0, 16.0)), tool.icon(), 16.0, t.text); - ui.painter().text( + let reserve = if on { 28.0 } else { 8.0 }; + crate::widgets::paint_left( + ui, row.left_center() + vec2(34.0, 0.0), - Align2::LEFT_CENTER, tl!(tool.label()), theme::regular(13.0), t.text, + (row.width() - 34.0 - reserve).max(0.0), ); if on { icons::paint( @@ -3544,12 +3555,14 @@ fn quick_bar(app: &mut PdfCraftApp, area: Rect, ui: &mut egui::Ui) { ui.painter().rect_filled(row, CornerRadius::same(4), t.hover); } icons::paint(ui, Rect::from_min_size(row.min + vec2(8.0, 6.0), vec2(16.0, 16.0)), tool.icon(), 16.0, t.text); - ui.painter().text( + let reserve = if on { 28.0 } else { 8.0 }; + crate::widgets::paint_left( + ui, row.left_center() + vec2(34.0, 0.0), - Align2::LEFT_CENTER, tl!(tool.label()), theme::regular(13.0), t.text, + (row.width() - 34.0 - reserve).max(0.0), ); if on { icons::paint( @@ -3834,7 +3847,17 @@ fn organize_grid(view: &mut DocView, info: &DocInfo, editable: bool, dirty: bool ui.painter().image(tex.id(), pr, Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)), Color32::WHITE); } ui.painter().rect_stroke(pr, CornerRadius::ZERO, Stroke::new(1.0, t.border), egui::StrokeKind::Outside); - ui.painter().text(pos2(c.center().x, c.bottom() - 48.0), Align2::CENTER_CENTER, &p.label, theme::medium(12.0), t.text_muted); + let label_font = theme::medium(12.0); + let label_w = (c.width() - 12.0).max(0.0); + let page_label = crate::widgets::fit_line(&p.label, label_w, |s| crate::widgets::text_width(ui, s, &label_font)); + let label_pos = pos2(c.center().x, c.bottom() - 48.0); + ui.painter().with_clip_rect(Rect::from_center_size(label_pos, vec2(label_w, 18.0))).text( + label_pos, + Align2::CENTER_CENTER, + page_label, + label_font, + t.text_muted, + ); // The checkbox toggles just this page without requiring a modifier. Keep it // outside the page image, including on very tall or wide pages. let mut checked = view.selected.contains(&i); diff --git a/crates/ui-egui/src/combine_ui.rs b/crates/ui-egui/src/combine_ui.rs index eb5a7ba7..7e6d1cc0 100644 --- a/crates/ui-egui/src/combine_ui.rs +++ b/crates/ui-egui/src/combine_ui.rs @@ -898,8 +898,8 @@ fn unlock_prompt(app: &mut PdfCraftApp, ctx: &egui::Context) { } ui.add_space(8.0); ui.horizontal(|ui| { - let field = - ui.add(egui::TextEdit::singleline(&mut prompt.input.0).password(!prompt.show).hint_text(tl!("Password")).desired_width(290.0)); + crate::widgets::begin_dialog(ui); + let field = ui.add(crate::widgets::line(&mut prompt.input.0).password(!prompt.show).hint_text(tl!("Password")).desired_width(290.0)); if !prompt.focused { field.request_focus(); prompt.focused = true; @@ -1374,9 +1374,10 @@ fn table_body( } // The range field and how many pages it takes. SortKey::Pages => { + crate::widgets::begin_dialog(ui); let edit = ui.add_enabled( f.problem.is_none(), - egui::TextEdit::singleline(&mut f.range).hint_text(tl!("All pages")).desired_width(88.0), + crate::widgets::line(&mut f.range).frame(egui::Frame::NONE).hint_text(tl!("All pages")).desired_width(88.0), ); // A visible field on plain and striped rows alike; red when the range is wrong. let border = if check.is_err() { Stroke::new(1.5, ERROR) } else { Stroke::new(1.0, t.border) }; diff --git a/crates/ui-egui/src/comment_props.rs b/crates/ui-egui/src/comment_props.rs index 11776bca..a01bb94a 100644 --- a/crates/ui-egui/src/comment_props.rs +++ b/crates/ui-egui/src/comment_props.rs @@ -167,7 +167,7 @@ pub(crate) fn body(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tokens) -> (boo let kind = tl!(crate::comments_panel::subtype_label(&d.edited.subtype)).to_string(); ui.label(egui::RichText::new(crate::i18n::fmt(tl!("{kind} Properties"), &[("kind", &kind)])).font(theme::semibold(18.0))); ui.add_space(6.0); - ui.horizontal(|ui| { + ui.horizontal_wrapped(|ui| { for (tab, label) in [(PropsTab::Appearance, tl!("Appearance")), (PropsTab::General, tl!("General")), (PropsTab::ReviewHistory, tl!("Review History"))] { @@ -240,10 +240,10 @@ pub(crate) fn body(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tokens) -> (boo PropsTab::General => { egui::Grid::new("comment-general").num_columns(2).spacing([12.0, 10.0]).show(ui, |ui| { let l = ui.label(tl!("Author")); - ui.add(egui::TextEdit::singleline(&mut e.author).desired_width(280.0)).labelled_by(l.id); + ui.add(crate::widgets::line(&mut e.author).desired_width(280.0)).labelled_by(l.id); ui.end_row(); let l = ui.label(tl!("Subject")); - ui.add(egui::TextEdit::singleline(&mut e.subject).desired_width(280.0)).labelled_by(l.id); + ui.add(crate::widgets::line(&mut e.subject).desired_width(280.0)).labelled_by(l.id); ui.end_row(); ui.label(tl!("Modified")); ui.label(e.modified.as_deref().map(pdfcraft_render::pretty_date).unwrap_or_else(|| "—".into())); diff --git a/crates/ui-egui/src/comments_panel.rs b/crates/ui-egui/src/comments_panel.rs index 4dc4dfb7..5182fadc 100644 --- a/crates/ui-egui/src/comments_panel.rs +++ b/crates/ui-egui/src/comments_panel.rs @@ -109,10 +109,11 @@ pub(crate) fn show( allowed: bool, nav: &mut Option