fix(ui): fit dialogs beside the toolbar on narrow screens (Issue #50)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f279790e00
commit
14abadbd03
1 file changed
+51
-11
@@ -2942,8 +2942,9 @@ fn file_picker_dialog(ctx: &egui::Context, state: &mut UiState, actions: &mut Ve
|
||||
),
|
||||
),
|
||||
};
|
||||
let width = dialog_width(ctx, state, 460.0);
|
||||
dialog_window(title, state, false).show(ctx, |ui| {
|
||||
ui.set_width(460.0);
|
||||
ui.set_width(width);
|
||||
touch_friendly_spacing(ui);
|
||||
if dialog_header(ui, header, true) {
|
||||
close = true;
|
||||
@@ -3114,6 +3115,17 @@ fn dialog_window(title: &'static str, state: &UiState, danger: bool) -> egui::Wi
|
||||
.frame(dialog_frame(danger))
|
||||
}
|
||||
|
||||
/// Content width of a dialog: `wanted`, but at most what fits beside the toolbar, so that on a
|
||||
/// phone the dialog is neither hidden under the toolbar nor cut off at the edge (Issue #50).
|
||||
fn dialog_width(ctx: &egui::Context, state: &UiState, wanted: f32) -> f32 {
|
||||
// Frame margins (20 each side) and a gap to the toolbar and the screen edge
|
||||
let free = ctx.screen_rect().width()
|
||||
- state.sidebar_reserved_width()
|
||||
- 2.0 * 20.0
|
||||
- 2.0 * UiState::SIDEBAR_MARGIN;
|
||||
wanted.min(free).max(200.0)
|
||||
}
|
||||
|
||||
/// Kopfzeile eines Dialogs mit Titel und optionalem Schließen-Knopf.
|
||||
/// Gibt `true` zurück, wenn „Schließen“ getippt wurde.
|
||||
fn dialog_header(ui: &mut egui::Ui, title: &str, closable: bool) -> bool {
|
||||
@@ -4937,9 +4949,10 @@ pub fn render_ui(
|
||||
|
||||
// 3b. Dokumenten-Manager (Notizbücher wechseln, anlegen, umbenennen, löschen)
|
||||
if state.is_document_menu_open {
|
||||
let width = dialog_width(ctx, state, 420.0);
|
||||
let doc_win = dialog_window(t!("Dokumenten-Manager"), state, false)
|
||||
.show(ctx, |ui| {
|
||||
ui.set_width(420.0);
|
||||
ui.set_width(width);
|
||||
touch_friendly_spacing(ui);
|
||||
if dialog_header(ui, t!("📚 Notizbücher"), true) {
|
||||
state.is_document_menu_open = false;
|
||||
@@ -4955,13 +4968,13 @@ pub fn render_ui(
|
||||
folder_breadcrumbs(ui, state, &folder);
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Neues Notizbuch oder neuer Ordner hier
|
||||
ui.horizontal(|ui| {
|
||||
// Neues Notizbuch oder neuer Ordner hier (narrow screens: buttons below)
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
let text_edit = ui.add(
|
||||
egui::TextEdit::singleline(&mut state.new_notebook_title_input)
|
||||
.hint_text(t!("Name …"))
|
||||
.margin(egui::vec2(8.0, 8.0))
|
||||
.desired_width(190.0),
|
||||
.desired_width(190.0_f32.min(ui.available_width())),
|
||||
);
|
||||
let create_btn = ui
|
||||
.button(egui::RichText::new(t!("➕ Notizbuch")).strong())
|
||||
@@ -5039,7 +5052,7 @@ pub fn render_ui(
|
||||
let edit = ui.add(
|
||||
egui::TextEdit::singleline(&mut state.renaming_title_input)
|
||||
.margin(egui::vec2(8.0, 8.0))
|
||||
.desired_width(260.0),
|
||||
.desired_width(260.0_f32.min(ui.available_width() - 80.0)),
|
||||
);
|
||||
if ui.button("✔").clicked()
|
||||
|| (edit.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)))
|
||||
@@ -5204,9 +5217,10 @@ pub fn render_ui(
|
||||
|
||||
// 3c. Release- & Update-Center (Gitea Releases)
|
||||
if state.is_update_dialog_open {
|
||||
let width = dialog_width(ctx, state, 460.0);
|
||||
let win = dialog_window(t!("Release- & Update-Center"), state, false)
|
||||
.show(ctx, |ui| {
|
||||
ui.set_width(460.0);
|
||||
ui.set_width(width);
|
||||
touch_friendly_spacing(ui);
|
||||
if dialog_header(ui, t!("🚀 Updates & Versionen"), true) {
|
||||
state.is_update_dialog_open = false;
|
||||
@@ -5428,11 +5442,11 @@ pub fn render_ui(
|
||||
.show(ui, |ui| {
|
||||
ui.add_space(4.0);
|
||||
ui.label(egui::RichText::new(t!("Gitea Server-URL:")).size(11.0));
|
||||
ui.add(egui::TextEdit::singleline(&mut state.updater_server_url_input).desired_width(380.0));
|
||||
ui.add(egui::TextEdit::singleline(&mut state.updater_server_url_input).desired_width(380.0_f32.min(ui.available_width())));
|
||||
|
||||
ui.add_space(4.0);
|
||||
ui.label(egui::RichText::new(t!("Personal Access Token (optional für private Repos):")).size(11.0));
|
||||
ui.add(egui::TextEdit::singleline(&mut state.updater_token_input).password(true).desired_width(380.0));
|
||||
ui.add(egui::TextEdit::singleline(&mut state.updater_token_input).password(true).desired_width(380.0_f32.min(ui.available_width())));
|
||||
|
||||
ui.add_space(6.0);
|
||||
if ui.button(egui::RichText::new(t!("💾 Einstellungen speichern")).size(11.5)).clicked() {
|
||||
@@ -5504,9 +5518,10 @@ pub fn render_ui(
|
||||
|
||||
// 5. Nicht-wegklickbare Warnung bei Ladefehlern / Quarantäne (Block 1)
|
||||
if let Some(warning) = notebook.load_warnings.get(¬ebook.current_page().id) {
|
||||
let width = dialog_width(ctx, state, 420.0);
|
||||
dialog_window(t!("⚠ Datenintegritäts-Warnung"), state, true)
|
||||
.show(ctx, |ui| {
|
||||
ui.set_width(420.0);
|
||||
ui.set_width(width);
|
||||
touch_friendly_spacing(ui);
|
||||
ui.horizontal(|ui| {
|
||||
ui.colored_label(egui::Color32::from_rgb(255, 80, 80), "⚠");
|
||||
@@ -5575,8 +5590,9 @@ pub fn render_ui(
|
||||
// Notfall-/Sicherheits-Dialog bei Fehlschlag des Speicherns vor dem Beenden
|
||||
if let Some(err) = &state.shutdown_error {
|
||||
let mut dismiss = false;
|
||||
let width = dialog_width(ctx, state, 460.0);
|
||||
dialog_window(t!("⚠ Ungespeicherte Änderungen"), state, true).show(ctx, |ui| {
|
||||
ui.set_width(460.0);
|
||||
ui.set_width(width);
|
||||
touch_friendly_spacing(ui);
|
||||
ui.horizontal(|ui| {
|
||||
ui.colored_label(egui::Color32::from_rgb(255, 80, 80), "⚠");
|
||||
@@ -5758,6 +5774,30 @@ mod tests {
|
||||
assert_eq!(PEN_WIDTH_PRESETS[3].0, 1.2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_notebook_dialog_fits_beside_the_toolbar_on_a_phone() {
|
||||
// Phone in portrait (Issue #50): the dialog was wider than the screen
|
||||
let mut state = UiState::new();
|
||||
state.is_document_menu_open = true;
|
||||
state.available_notebooks = vec![NotebookSummary {
|
||||
id: "nb-1".to_string(),
|
||||
title: "Default notebook".to_string(),
|
||||
page_count: 1,
|
||||
modified_at: 100,
|
||||
status: crate::storage::NotebookStatus::Normal,
|
||||
error: None,
|
||||
}];
|
||||
state.current_notebook_id = "nb-1".to_string();
|
||||
let screen = egui::vec2(412.0, 900.0);
|
||||
let ctx = render_frames_sized(&mut state, &Notebook::new(), 8, screen);
|
||||
let dialog = ctx
|
||||
.memory(|m| m.area_rect(egui::Id::new(t!("Dokumenten-Manager"))))
|
||||
.unwrap();
|
||||
let toolbar = state.toolbar_rect.unwrap();
|
||||
assert!(dialog.left() >= toolbar.right(), "{dialog:?} {toolbar:?}");
|
||||
assert!(dialog.right() <= screen.x, "{dialog:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_document_manager_ui_actions() {
|
||||
let mut state = UiState::new();
|
||||
|
||||
Reference in new issue
Block a user