breadman: fold New Note into the shared AdwDialog editor surface #6

Open
Breadway wants to merge 1 commit from feature/pad-3-unify-new-note-editor into main
Owner

Summary

Part of PAD-3. This does the piece the direction comment calls "the highest-value piece of this ticket": show_add_note_window and editor::open_editor built the same four fields (body, type, time, recurrence) with two different widget sets and two different input languages - a bare gtk4::Window with plain GtkEntry rows + free labels + a Cancel button for New Note, versus an AdwDialog with PreferencesGroup/EntryRow rows + the shared chip type-picker for Edit Note. The code comments already flagged this as a bug.

Changes

  • editor.rs: the field surface is extracted into build_fields(), shared by open_editor (existing note) and a new open_new_note (fresh note). Both now render the identical AdwDialog + AdwHeaderBar + AdwPreferencesGroup surface via a small shell() helper. open_new_note keeps create-time semantics: the body runs through parse_rule_based (so "todo: call the vet tomorrow 9am" still sets type/time/cleaned body), an explicit type pick always overrides the parser, then save_note + Scheduler::schedule. Enter in the body field submits when time/recurrence are empty, same as before.
  • main.rs: show_add_note_window is now a thin wrapper over open_new_note that wires the AppState refresh into its callbacks and presents the dialog against the parent. Its on_build hook is now impl FnOnce(&adw::Dialog) (was &gtk4::Window) for screenshot mode. spawn_bg moved here as pub(crate) - it was duplicated in editor.rs and already imported from views/row.rs, so this consolidates all three copies into one.

Net -250 / +278 lines, most of it the deleted bespoke dialog.

Deferred (still open on PAD-3)

The main-window chrome pass from the direction comment - gtk4::ApplicationWindow -> adw::ApplicationWindow + adw::NavigationSplitView + adw::HeaderBars, search moved into the header - is not in this PR. There is no existing GTK NavigationSplitView implementation anywhere in the ecosystem to model it on (breadhelp, the only other adw app, uses a plain window + stack + tab switcher), and a blind split-view conversion needs visual iteration a headless run can't do safely. See the issue comment.

Verification

  • cargo build -p breadman, cargo clippy --workspace --all-targets --locked -- -D warnings: clean
  • cargo test --workspace --locked: all pass (169 + 15 + 26 + 16 + 28 ...)
  • cargo fmt: editor.rs is fully clean; my changes reduce the repo's pre-existing fmt drift by 14 diffs (breadpad CI does not gate fmt)
  • Ran breadman --screenshot new-note, --screenshot editor, --screenshot all against a live compositor: all exit 0, the New Note dialog now renders the same AdwDialog + HeaderBar as the editor. Full-window captures need the bread-capture orchestrator to position the window, which isn't available here.

Refs PAD-3 (Breadway/breadpad#3).

## Summary Part of PAD-3. This does the piece the direction comment calls "the highest-value piece of this ticket": `show_add_note_window` and `editor::open_editor` built the **same four fields** (body, type, time, recurrence) with **two different widget sets and two different input languages** - a bare `gtk4::Window` with plain `GtkEntry` rows + free labels + a Cancel button for New Note, versus an `AdwDialog` with `PreferencesGroup`/`EntryRow` rows + the shared chip type-picker for Edit Note. The code comments already flagged this as a bug. ## Changes - **`editor.rs`**: the field surface is extracted into `build_fields()`, shared by `open_editor` (existing note) and a new `open_new_note` (fresh note). Both now render the identical `AdwDialog` + `AdwHeaderBar` + `AdwPreferencesGroup` surface via a small `shell()` helper. `open_new_note` keeps create-time semantics: the body runs through `parse_rule_based` (so "todo: call the vet tomorrow 9am" still sets type/time/cleaned body), an explicit type pick always overrides the parser, then `save_note` + `Scheduler::schedule`. Enter in the body field submits when time/recurrence are empty, same as before. - **`main.rs`**: `show_add_note_window` is now a thin wrapper over `open_new_note` that wires the `AppState` refresh into its callbacks and presents the dialog against the parent. Its `on_build` hook is now `impl FnOnce(&adw::Dialog)` (was `&gtk4::Window`) for screenshot mode. `spawn_bg` moved here as `pub(crate)` - it was duplicated in `editor.rs` and already imported from `views/row.rs`, so this consolidates all three copies into one. Net `-250 / +278` lines, most of it the deleted bespoke dialog. ## Deferred (still open on PAD-3) The main-window chrome pass from the direction comment - `gtk4::ApplicationWindow` -> `adw::ApplicationWindow` + `adw::NavigationSplitView` + `adw::HeaderBar`s, search moved into the header - is **not** in this PR. There is no existing GTK `NavigationSplitView` implementation anywhere in the ecosystem to model it on (breadhelp, the only other adw app, uses a plain window + stack + tab switcher), and a blind split-view conversion needs visual iteration a headless run can't do safely. See the issue comment. ## Verification - `cargo build -p breadman`, `cargo clippy --workspace --all-targets --locked -- -D warnings`: clean - `cargo test --workspace --locked`: all pass (169 + 15 + 26 + 16 + 28 ...) - `cargo fmt`: `editor.rs` is fully clean; my changes reduce the repo's pre-existing fmt drift by 14 diffs (breadpad CI does not gate fmt) - Ran `breadman --screenshot new-note`, `--screenshot editor`, `--screenshot all` against a live compositor: all exit 0, the New Note dialog now renders the same AdwDialog + HeaderBar as the editor. Full-window captures need the `bread-capture` orchestrator to position the window, which isn't available here. Refs PAD-3 (Breadway/breadpad#3).
refactor(breadman): fold New Note into the shared AdwDialog editor surface
All checks were successful
check / check (push) Successful in 2m11s
b970349600
show_add_note_window built a bare gtk4::Window with plain GtkEntry rows and
free-standing labels, while editor::open_editor used an AdwDialog with
PreferencesGroup/EntryRow rows and the shared chip type-picker. Same four
fields, two different input languages, flagged in the code comments.

- editor.rs: extract the field surface into build_fields(), shared by
  open_editor (existing note) and a new open_new_note (fresh note). Both
  now render the same AdwDialog + HeaderBar + PreferencesGroup surface.
  open_new_note keeps create-time semantics: the body runs through the
  rule-based parser, an explicit type pick overrides it, then save_note +
  schedule.
- main.rs: show_add_note_window is now a thin wrapper over
  open_new_note that wires the AppState refresh into its callbacks and
  presents the dialog. spawn_bg moved to main.rs as pub(crate) (it was
  duplicated in editor.rs and already used from views/row.rs).

Part of PAD-3. The main-window chrome pass (adw::ApplicationWindow +
NavigationSplitView + header search) is deferred, see the issue.

Refs PAD-3
Author
Owner

Hold this PR - do not merge standalone.

Per the decision on PAD-3, the deferred chrome pass (adw::ApplicationWindow + NavigationSplitView + header-search conversion of build_app_window) will be done now, interactively, before BOS 0.6.2. This PR's New Note / editor unification lands as part of that complete refresh in a single PR, not on its own.

The branch work here is sound and stays as the base for the chrome pass.

Hold this PR - do not merge standalone. Per the decision on PAD-3, the deferred chrome pass (adw::ApplicationWindow + NavigationSplitView + header-search conversion of `build_app_window`) will be done now, interactively, before BOS 0.6.2. This PR's New Note / editor unification lands as part of that complete refresh in a single PR, not on its own. The branch work here is sound and stays as the base for the chrome pass.
Author
Owner

Flagging before this sits any longer: PR #6 now has a merge conflict with main, and it's not a simple rebase. main's only new commit since this branch's base is "Rebuild breadman as a Tauri 2 + Svelte app (PAD-3)" (breadpad#7, merged after this branch was cut). That PR replaced the GTK4 app this branch modifies (editor.rs, main.rs, the AdwDialog New Note/editor unification) with a Tauri+Svelte frontend. The GTK4 files this PR touches likely no longer exist on main in their old form, so this is not a whitespace-conflict rebase, the work may be entirely superseded by the rewrite.

This also still carries your own "hold, do not merge standalone" comment from before the rebuild landed. Given the rebuild already happened, that hold decision may itself need revisiting: is there anything in this branch's dialog-unification approach worth porting into the new Tauri/Svelte New Note UI, or is it fully moot now? Leaving in review rather than todo since this needs your call on the branch's fate, not a rework cycle.

Not merging: conflicted, and explicitly on hold besides.

Flagging before this sits any longer: PR #6 now has a merge conflict with main, and it's not a simple rebase. main's only new commit since this branch's base is "Rebuild breadman as a Tauri 2 + Svelte app (PAD-3)" (breadpad#7, merged after this branch was cut). That PR replaced the GTK4 app this branch modifies (editor.rs, main.rs, the AdwDialog New Note/editor unification) with a Tauri+Svelte frontend. The GTK4 files this PR touches likely no longer exist on main in their old form, so this is not a whitespace-conflict rebase, the work may be entirely superseded by the rewrite. This also still carries your own "hold, do not merge standalone" comment from before the rebuild landed. Given the rebuild already happened, that hold decision may itself need revisiting: is there anything in this branch's dialog-unification approach worth porting into the new Tauri/Svelte New Note UI, or is it fully moot now? Leaving in review rather than todo since this needs your call on the branch's fate, not a rework cycle. Not merging: conflicted, and explicitly on hold besides.
Author
Owner

Closing as moot per the user's call: main replaced the GTK4 breadman codebase this PR targets with a Tauri 2 + Svelte rewrite, so the dialog-unification work no longer has anything to apply to. Not porting forward for now.

Closing as moot per the user's call: main replaced the GTK4 breadman codebase this PR targets with a Tauri 2 + Svelte rewrite, so the dialog-unification work no longer has anything to apply to. Not porting forward for now.
All checks were successful
check / check (push) Successful in 2m11s
This pull request has changes conflicting with the target branch.
  • breadman/src/editor.rs
  • breadman/src/main.rs
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feature/pad-3-unify-new-note-editor:feature/pad-3-unify-new-note-editor
git switch feature/pad-3-unify-new-note-editor

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff feature/pad-3-unify-new-note-editor
git switch feature/pad-3-unify-new-note-editor
git rebase main
git switch main
git merge --ff-only feature/pad-3-unify-new-note-editor
git switch feature/pad-3-unify-new-note-editor
git rebase main
git switch main
git merge --no-ff feature/pad-3-unify-new-note-editor
git switch main
git merge --squash feature/pad-3-unify-new-note-editor
git switch main
git merge --ff-only feature/pad-3-unify-new-note-editor
git switch main
git merge feature/pad-3-unify-new-note-editor
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/breadpad!6
No description provided.