editor-gui: a duration palette over set_selection_duration
A toolbar palette — 1 / 1/2 / 1/4 / 1/8 / 1/16 — sets the selected note or rest's written value via set_selection_duration(NoteValue::whole_note_fraction), with the editor's make-room overwrite when lengthening; refusals (tuplet member, decomposed event, non-note selection) surface in the status line. The palette lives in the toolbar, which runs before the frame's rerender slot, so it has no stale-texture concern. Adds epiphany-core as a direct dependency for NoteValue (already a transitive workspace member, so no MSRV/CI impact). The module doc and crate description are updated; only an undo UI remains unbuilt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NAtEiJtt9yKVV1zjKYmZhS
This commit is contained in:
parent
0f298508af
commit
872ff03dd5
|
|
@ -1098,6 +1098,7 @@ name = "epiphany-editor-gui"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"epiphany-core",
|
||||
"epiphany-editor-core",
|
||||
"epiphany-engrave",
|
||||
"epiphany-layout-ir",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ version = "0.0.0"
|
|||
edition.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
description = "A thin native (egui) GUI shell over epiphany-editor-core: renders the score with epiphany-render-svg (rasterized by resvg), click to select, and a toolbar/keys for the note-editing intents. A vertical slice proving the editor seam — no duration editing, empty-space insert, or undo UI yet."
|
||||
description = "A thin native (egui) GUI shell over epiphany-editor-core: renders the score with epiphany-render-svg (rasterized by resvg), click to select, a pencil mode that clicks notes onto the staff, and a toolbar/keys for the note-editing intents and a duration palette. A vertical slice proving the editor seam — no undo UI yet."
|
||||
|
||||
# A demo binary, not a library other crates build on, so it carries the heavy GUI
|
||||
# dependency tree (eframe/winit/wgpu, resvg/usvg/tiny-skia) the rest of the
|
||||
|
|
@ -14,6 +14,8 @@ description = "A thin native (egui) GUI shell over epiphany-editor-core: renders
|
|||
[dependencies]
|
||||
# The headless editor this GUI drives.
|
||||
epiphany-editor-core.workspace = true
|
||||
# Musical-duration / note-value types, for the duration palette.
|
||||
epiphany-core.workspace = true
|
||||
# The real constraint solver (so the GUI shows a genuinely engraved score).
|
||||
epiphany-engrave.workspace = true
|
||||
# SVG rendering of the resolved layout, and the layout/hit-test geometry types.
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@
|
|||
//! `resvg` into an `egui` texture, resolves clicks back to world coordinates to
|
||||
//! select, and drives the note-editing intents from a toolbar and keyboard.
|
||||
//!
|
||||
//! Intentionally narrow (per the GUI vertical-slice plan): no duration editing and no
|
||||
//! undo UI — the debug panel just shows the selection and the last applied op, enough
|
||||
//! to confirm the op log is usable. A **pencil mode** turns a click into a
|
||||
//! click-to-insert ([`EditorSession::insert_note_at`]) with make-room overwrite, on a
|
||||
//! quarter-note grid. The GUI is the thing meant to surface the next real core gaps.
|
||||
//! Intentionally narrow (per the GUI vertical-slice plan): no undo UI — the debug
|
||||
//! panel just shows the selection and the last applied op, enough to confirm the op log
|
||||
//! is usable. A **pencil mode** turns a click into a click-to-insert
|
||||
//! ([`EditorSession::insert_note_at`]) with make-room overwrite on a quarter-note grid,
|
||||
//! and a **duration palette** resizes the selection
|
||||
//! ([`EditorSession::set_selection_duration`]). The GUI is the thing meant to surface
|
||||
//! the next real core gaps.
|
||||
//!
|
||||
//! It is a demo binary; there is no headless way to assert its rendering here, so the
|
||||
//! one piece of nontrivial logic — the screen↔world coordinate map a click depends on
|
||||
|
|
@ -19,6 +21,7 @@
|
|||
|
||||
use eframe::egui;
|
||||
|
||||
use epiphany_core::NoteValue;
|
||||
use epiphany_editor_core::{EditOutcome, EditorError, EditorSession, GridResolution};
|
||||
use epiphany_engrave::Engraver;
|
||||
use epiphany_layout_ir::{BoundingBox, HitShape, Point};
|
||||
|
|
@ -247,6 +250,23 @@ impl EditorApp {
|
|||
self.run("insert after", |s| s.insert_note_after_selection());
|
||||
}
|
||||
ui.separator();
|
||||
// Duration palette: set the selected note/rest's written value (make-room
|
||||
// overwrite when lengthening).
|
||||
ui.label("Dur:");
|
||||
for (label, value) in [
|
||||
("1", NoteValue::Whole),
|
||||
("1/2", NoteValue::Half),
|
||||
("1/4", NoteValue::Quarter),
|
||||
("1/8", NoteValue::Eighth),
|
||||
("1/16", NoteValue::Sixteenth),
|
||||
] {
|
||||
if ui.button(label).clicked() {
|
||||
self.run(&format!("duration {label}"), |s| {
|
||||
s.set_selection_duration(value.whole_note_fraction())
|
||||
});
|
||||
}
|
||||
}
|
||||
ui.separator();
|
||||
ui.toggle_value(&mut self.pencil, "✏ Pencil (insert)");
|
||||
ui.separator();
|
||||
if ui
|
||||
|
|
|
|||
Loading…
Reference in New Issue