mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-10 12:29:58 -06:00
Merge origin/main (6f52cc50, the squash of upstream pull request 471) into w/form-controls
Both sides added a kind of floating object (equation, form control); both are kept everywhere. ROADMAP.md: header combined (form controls first, then equations), catalog 281 / 296 as `cargo xtask parity` measures, the form-controls progress-log and revision rows above main's equation rows. crates/engine/src/cmd.rs: both spec lists (controls and equation). crates/engine/src/cmd/extra.rs: the arrange params docs list both kinds. crates/engine/src/cmd/extra/objects.rs: main's `found` match and `anchors_of` on ObjKind gain the Control arms; the unlocked check takes the parsed kind directly. crates/engine/src/cmd/insert.rs: the object params docs and the kind error name both kinds. crates/engine/src/tests.rs: both test modules. crates/engine/src/tests/objects.rs: every_kind returns six objects (equation at L18, slider at P18) and the anchor lists carry both. crates/model/src/features.rs: ObjKind has Equation and Control, ALL lists six kinds, name() both. crates/model/src/sheet.rs: both imports, both accessor arms, the order test inserts equations (6, 8) and controls (13, 15) and documents controls after slicers with equations counted as shapes. crates/model/src/workbook.rs: main's refresh_equations and this branch's free-id doc comment. crates/ui-egui/src/chartview.rs: both doc comments combined. crates/ui-egui/src/objects.rs: both OpenAction variants and arms. crates/ui-egui/src/ribbon/insert.rs: the import list is the union. docs/control-protocol.md: the kind list names equation and control; main's equation sentences and this branch's form-controls sentence. docs/file-format-parity.md: header combined; the xlsx row carries both additions; the form-controls revision row above main's equation rows. docs/parity-checklist.md: regenerated with `cargo xtask parity` (281 / 296). docs/target-app-parity.md: header combined; catalog 281 / 296; the Insert objects row carries both additions; the form-controls revision row (277 / 292 → 281 / 296) above main's. docs/ui-parity.md: header combined with catalog 281 / 296; main's move-and-resize row with equations plus the form-controls row; the form-controls revision row above main's.
This commit is contained in:
@@ -6,6 +6,7 @@ pub mod controls;
|
||||
pub mod data;
|
||||
pub mod draw;
|
||||
pub mod edit;
|
||||
pub mod equation;
|
||||
pub mod extra;
|
||||
pub mod file;
|
||||
pub mod forecast;
|
||||
@@ -41,7 +42,11 @@ pub struct CommandSpec {
|
||||
pub label: &'static str,
|
||||
/// Ribbon/menu placement, e.g. `["Home", "Font"]`. Empty = not in menus.
|
||||
pub menu: &'static [&'static str],
|
||||
/// Portable notation: `Cmd` is ⌘ on macOS and Ctrl elsewhere.
|
||||
pub shortcut: Option<&'static str>,
|
||||
/// macOS override when its key differs. Equal to `shortcut` marks a Mac-only shortcut
|
||||
/// (Align Left/Center): other platforms show none. See [`CommandInfo::shortcut_for_platform`].
|
||||
pub shortcut_mac: Option<&'static str>,
|
||||
pub params: &'static str,
|
||||
pub enabled: Enabled,
|
||||
pub run: Run,
|
||||
@@ -55,12 +60,32 @@ pub struct CommandInfo {
|
||||
pub label: &'static str,
|
||||
pub menu: Vec<&'static str>,
|
||||
pub shortcut: Option<&'static str>,
|
||||
pub shortcut_mac: Option<&'static str>,
|
||||
pub params: &'static str,
|
||||
pub enabled: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub disabled_reason: Option<String>,
|
||||
}
|
||||
|
||||
impl CommandInfo {
|
||||
/// Format the portable shortcut notation for the runtime operating system.
|
||||
pub fn shortcut_for_platform(&self, mac: bool) -> Option<String> {
|
||||
let keys = if mac {
|
||||
self.shortcut_mac.or(self.shortcut)
|
||||
} else if self.shortcut_mac.is_some() && self.shortcut_mac == self.shortcut {
|
||||
// An identical Mac override marks a Mac-only display shortcut.
|
||||
// The portable field remains unchanged for legacy CLI consumers.
|
||||
None
|
||||
} else {
|
||||
self.shortcut
|
||||
}?;
|
||||
if mac {
|
||||
return Some(keys.to_owned());
|
||||
}
|
||||
Some(keys.split('+').map(|part| if part == "Cmd" { "Ctrl" } else { part }).collect::<Vec<_>>().join("+"))
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandSpec {
|
||||
pub fn info(&self, s: &Session) -> CommandInfo {
|
||||
let e = (self.enabled)(s);
|
||||
@@ -69,6 +94,7 @@ impl CommandSpec {
|
||||
label: self.label,
|
||||
menu: self.menu.to_vec(),
|
||||
shortcut: self.shortcut,
|
||||
shortcut_mac: self.shortcut_mac,
|
||||
params: self.params,
|
||||
enabled: e.is_ok(),
|
||||
disabled_reason: e.err(),
|
||||
@@ -119,13 +145,13 @@ pub fn has_clipboard(s: &Session) -> std::result::Result<(), String> {
|
||||
|
||||
macro_rules! cmd {
|
||||
($id:literal, $label:literal, [$($m:literal),*], $sc:expr, $params:literal, $en:expr, $run:expr) => {
|
||||
$crate::cmd::CommandSpec { id: $id, label: $label, menu: &[$($m),*], shortcut: $sc, params: $params, enabled: $en, run: $run, journal: true, undoable: true }
|
||||
$crate::cmd::CommandSpec { id: $id, label: $label, menu: &[$($m),*], shortcut: $sc, shortcut_mac: None, params: $params, enabled: $en, run: $run, journal: true, undoable: true }
|
||||
};
|
||||
(query $id:literal, $label:literal, [$($m:literal),*], $sc:expr, $params:literal, $en:expr, $run:expr) => {
|
||||
$crate::cmd::CommandSpec { id: $id, label: $label, menu: &[$($m),*], shortcut: $sc, params: $params, enabled: $en, run: $run, journal: false, undoable: false }
|
||||
$crate::cmd::CommandSpec { id: $id, label: $label, menu: &[$($m),*], shortcut: $sc, shortcut_mac: None, params: $params, enabled: $en, run: $run, journal: false, undoable: false }
|
||||
};
|
||||
(noundo $id:literal, $label:literal, [$($m:literal),*], $sc:expr, $params:literal, $en:expr, $run:expr) => {
|
||||
$crate::cmd::CommandSpec { id: $id, label: $label, menu: &[$($m),*], shortcut: $sc, params: $params, enabled: $en, run: $run, journal: true, undoable: false }
|
||||
$crate::cmd::CommandSpec { id: $id, label: $label, menu: &[$($m),*], shortcut: $sc, shortcut_mac: None, params: $params, enabled: $en, run: $run, journal: true, undoable: false }
|
||||
};
|
||||
}
|
||||
pub(crate) use cmd;
|
||||
@@ -140,6 +166,7 @@ pub fn command_specs() -> &'static [CommandSpec] {
|
||||
v.extend(sheet::specs());
|
||||
v.extend(insert::specs());
|
||||
v.extend(controls::specs());
|
||||
v.extend(equation::specs());
|
||||
v.extend(data::specs());
|
||||
v.extend(formulas::specs());
|
||||
v.extend(review::specs());
|
||||
@@ -182,6 +209,7 @@ pub fn register_test_command(id: &'static str, run: Run) {
|
||||
label: id,
|
||||
menu: &[],
|
||||
shortcut: None,
|
||||
shortcut_mac: None,
|
||||
params: "",
|
||||
enabled: |_| Ok(()),
|
||||
run,
|
||||
@@ -199,6 +227,7 @@ pub(crate) fn register_undoable_test_command(id: &'static str, run: Run) {
|
||||
label: id,
|
||||
menu: &[],
|
||||
shortcut: None,
|
||||
shortcut_mac: None,
|
||||
params: "",
|
||||
enabled: |_| Ok(()),
|
||||
run,
|
||||
@@ -376,6 +405,9 @@ pub(crate) fn commit<R>(d: &mut DocState, f: impl FnOnce(&mut Ctx) -> Result<R>)
|
||||
};
|
||||
let r = f(&mut ctx)?;
|
||||
let Ctx { mut wb, changed, structural, mut fit_rows, protection_checked, edits, .. } = ctx;
|
||||
// Equations whose source changed (or that arrived without a layout, as from a paste) are
|
||||
// laid out here, so painting only ever reads the cache.
|
||||
wb.refresh_equations();
|
||||
if !protection_checked {
|
||||
check_protection(&d.wb, &wb, &d.unlocked_ranges)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user