pub struct App {Show 22 fields
pub model: Model,
pub measures: Vec<MeasureId>,
pub selected: usize,
pub grid: Grid,
pub cursor_row: usize,
pub cursor_col: usize,
pub should_quit: bool,
pub engine: Option<Engine>,
pub snapshot: Snapshot,
pub applied_view: Option<ViewId>,
pub edit: Option<LineEdit>,
pub status: Option<String>,
pub save_token: SaveToken,
pub page_idx: Vec<usize>,
pub axis_order: Vec<CategoryId>,
pub filters: Vec<Filter>,
pub grid_geom: Option<GridGeom>,
pub anchor: Option<(usize, usize)>,
pub command: Option<(CommandKind, String)>,
pub help: Option<FnHelp>,
pub tab_cycle: Option<Cycle>,
pub diagnostic: Option<Diagnostic>,
}Expand description
The whole application state.
The live Engine tracks all derived measures in the model up front
(built once in new), so switching the viewed measure never rebuilds it and
there is no per-measure rebuild logic. Editing an input cell pushes a delta
through the engine and the returned snapshot is kept here to render derived
measures. A model with zero derived measures gets no engine (None); input
edits still work, there is just nothing to recompute.
Fields§
§model: Model§measures: Vec<MeasureId>§selected: usize§grid: Grid§cursor_row: usize§cursor_col: usize§should_quit: bool§engine: Option<Engine>Live incremental engine over all derived measures (None if there are none).
snapshot: SnapshotLatest derived-measure values from the engine.
applied_view: Option<ViewId>The last saved view applied via cycle_view, so cycling advances.
edit: Option<LineEdit>When Some, edit mode is active and this holds the in-progress text:
a cell value for an input measure, the formula for a derived one.
status: Option<String>Transient status/error message (e.g. “derived cells are computed”).
save_token: SaveTokenThe store high-water the model was loaded/last saved at; saves refuse
to clobber another process’s writes (StoreError::Conflict).
page_idx: Vec<usize>Selected item index for each extra (page) dimension of the viewed
measure; [ / ] cycle the first one. Reset when the measure changes.
axis_order: Vec<CategoryId>Current axis order (a permutation of the viewed measure’s categories): element 0 is on rows, 1 on columns, the rest are pages. Pivoting mutates this; it resets to the measure’s natural order on measure switch.
filters: Vec<Filter>Active per-category display filters for the current layout (which items of a category are shown). Presentation only — never changes model data. Captured when saving a view; reset on measure switch.
grid_geom: Option<GridGeom>Geometry of the last render, for mapping mouse clicks to cells.
anchor: Option<(usize, usize)>Fixed corner of a Shift+arrow range selection; None = one cell.
command: Option<(CommandKind, String)>When Some, the CSV import/export command prompt is active: which
command and its in-progress typed line. Mirrors edit’s shape but for
a whole command line rather than a single cell value.
help: Option<FnHelp>When Some, the function help overlay (? / F1) is open.
tab_cycle: Option<Cycle>The candidates a repeated Tab cycles through; reset by any other key.
diagnostic: Option<Diagnostic>Where the last formula commit failed to parse, while its text is unchanged: the edit line underlines the span and shows the message.
Implementations§
Source§impl App
impl App
pub fn new(model: Model) -> Result<App, String>
fn reselect(&mut self)
Sourcefn natural_axis_order(&self) -> Vec<CategoryId>
fn natural_axis_order(&self) -> Vec<CategoryId>
The viewed measure’s categories in natural (declared) order.
Sourcepub fn pivot(&mut self)
pub fn pivot(&mut self)
Pivot: rotate the axis order left, so rows->pages, cols->rows, first page->cols. A single discoverable key repeatedly cycles which category sits on each axis — the Improv/Quantrix “move a category to another axis” gesture, without touching formulas. No-op for < 2 categories.
Sourcepub fn page(&mut self, delta: isize)
pub fn page(&mut self, delta: isize)
Cycle the first page (extra) dimension’s selected item by delta
(wrapping). No-op if the viewed measure has no extra dimensions.
Sourcepub fn next_measure(&mut self)
pub fn next_measure(&mut self)
Cycle to the next measure (wraps).
Sourcepub fn step(&mut self, drow: isize, dcol: isize, extend: bool)
pub fn step(&mut self, drow: isize, dcol: isize, extend: bool)
An arrow step: extend (Shift held) keeps or sets the range anchor
at the cursor before moving; a plain step collapses the range.
Sourcepub fn is_selected(&self, row: usize, col: usize) -> bool
pub fn is_selected(&self, row: usize, col: usize) -> bool
True if [row][col] is inside the selection (anchor..=cursor).
Sourcepub fn selection_sum(&self) -> Option<f64>
pub fn selection_sum(&self) -> Option<f64>
Sum of the numeric cells in the selection; None if there are none
(text/empty cells contribute nothing, as in the GUI’s Sum readout).
Sourcepub fn formula_text(&self) -> Option<String>
pub fn formula_text(&self) -> Option<String>
The viewed derived measure’s formula as controlled English
(Price times Quantity); None for input measures.
Sourcepub fn move_cursor(&mut self, drow: isize, dcol: isize)
pub fn move_cursor(&mut self, drow: isize, dcol: isize)
Cursor movement, clamped to the grid (never goes out of range).
Sourcepub fn click_at(&mut self, col: u16, row: u16)
pub fn click_at(&mut self, col: u16, row: u16)
Handle a left-click at screen (col, row): if it lands on a data cell,
move the cursor there. Uses the geometry recorded by the last render.
Out-of-grid clicks are ignored. (Enables mouse-driven navigation; the
terminal must support mouse reporting, which improv-tui enables.)
Sourcefn addressable(&self, row: usize, col: usize) -> bool
fn addressable(&self, row: usize, col: usize) -> bool
True if [row][col] names a full coordinate: one item for every
category of the measure. False when an axis or page is empty (a
category with no items, or every item filtered out); writing there
would store a cell with a missing dimension.
Sourcepub fn viewed_is_input(&self) -> bool
pub fn viewed_is_input(&self) -> bool
True if the currently viewed measure is an input measure (editable).
Sourcepub fn editing_formula(&self) -> bool
pub fn editing_formula(&self) -> bool
True while the edit line holds a formula (the viewed measure is derived).
Sourcepub fn begin_edit(&mut self)
pub fn begin_edit(&mut self)
Enter edit mode: on the cell under the cursor for an input measure, on the formula (seeded with its controlled-English text) for a derived one.
Sourcepub fn edit_key(&mut self, code: KeyCode)
pub fn edit_key(&mut self, code: KeyCode)
A key in the edit line. In a formula, Tab completes the name before
the caret (complete::tab); any other key edits, and a change
clears the message about the old text.
Sourcepub fn cancel_edit(&mut self)
pub fn cancel_edit(&mut self)
Cancel edit mode without committing.
Sourcepub fn commit_edit(&mut self)
pub fn commit_edit(&mut self)
Commit the in-progress edit buffer. Parses it per the measure’s value type (or as a formula for a derived measure), applies it to the model + engine, refreshes the grid, and exits edit mode. On a parse error the buffer stays open with a status message.
Sourcepub fn apply_value(
&mut self,
row: usize,
col: usize,
value: Value,
) -> Result<(), String>
pub fn apply_value( &mut self, row: usize, col: usize, value: Value, ) -> Result<(), String>
Set input [row][col] to a typed value, pushed through the live
engine as one incremental edit. A value of the measure’s type enters
the engine as that cell; anything else clears it, exactly what a
rebuild would seed ([improv_engine::session::input_cell]).
Sourcepub fn set_formula(&mut self, formula: Formula) -> Result<(), String>
pub fn set_formula(&mut self, formula: Formula) -> Result<(), String>
Replace the viewed derived measure’s formula. Validated on a candidate model (a real engine build, which catches cycles and type errors) and only then published; on failure nothing changes and the error is returned.
Sourcepub fn begin_import_csv(&mut self)
pub fn begin_import_csv(&mut self)
Enter import-csv command-prompt mode (bound to I). Mirrors
begin_edit: starts an empty typed-line buffer.
Sourcepub fn begin_export_csv(&mut self)
pub fn begin_export_csv(&mut self)
Enter export-csv command-prompt mode (bound to E).
Sourcepub fn cancel_command(&mut self)
pub fn cancel_command(&mut self)
Cancel command-prompt mode without side effects.
Sourcepub fn commit_command(&mut self)
pub fn commit_command(&mut self)
Commit the in-progress command line: parse it per the active
CommandKind, run the storage_csv import/export, and set a status
message (success with a count, or the parse/IO error). Always exits
command mode — a malformed line reports the error rather than looping
(matching the TUI’s existing “generated view name” simplicity).
Sourcefn run_import_csv(&mut self, line: &str) -> String
fn run_import_csv(&mut self, line: &str) -> String
Parse and run an import-csv command line against self.model, and
rebuild the engine/grid so the new measure shows up immediately
(mirrors next_measure’s structural-rebuild path, since importing
adds a new measure — the engine’s fixed structure must be rebuilt).
Sourcefn run_export_csv(&mut self, line: &str) -> String
fn run_export_csv(&mut self, line: &str) -> String
Parse and run an export-csv command line against self.model.
Sourcefn rebuild_after_structural_change(&mut self) -> Result<(), String>
fn rebuild_after_structural_change(&mut self) -> Result<(), String>
Rebuild measures/engine/grid from the current self.model after a
structural change (a new measure/category/item), keeping the viewed
measure selected when it still exists. Mirrors the fresh-build logic in
App::new, since the live Engine’s tracked structure is fixed at
construction and a new measure needs a new engine. If the formulas no
longer build (an import changed a measure they use), the rest is still
rebuilt, with no engine, and the error is returned for the status.
Sourcefn viewed_measure(&self) -> MeasureId
fn viewed_measure(&self) -> MeasureId
The viewed measure’s id.
Sourcepub fn build_view(&self, id: ViewId, name: &str) -> View
pub fn build_view(&self, id: ViewId, name: &str) -> View
Build a View capturing the current layout: viewed measure, axis order,
pinned page items, and active filters. Presentation only — no data.
Sourcefn next_view_id(&self) -> ViewId
fn next_view_id(&self) -> ViewId
The smallest unused view id (>= 1).
Sourcepub fn save_view(&mut self, name: &str, path: Option<&str>) -> ViewId
pub fn save_view(&mut self, name: &str, path: Option<&str>) -> ViewId
Save the current layout as a named view: mint an id, add it to the
model, and (when path is set) persist immediately. Returns the id.
Sourcepub fn apply_view(&mut self, view: &View)
pub fn apply_view(&mut self, view: &View)
Apply a saved View to the live layout: select its measure, restore the
axis order, page items, and filters, then re-render. Presentation only
— measures and data are untouched. No-op if the measure is gone.
Sourcepub fn cycle_view(&mut self)
pub fn cycle_view(&mut self)
Cycle to the next saved view (by id order) and apply it. No-op if there are no saved views.
Sourcepub fn toggle_filter_item(&mut self, category: CategoryId, item: ItemId)
pub fn toggle_filter_item(&mut self, category: CategoryId, item: ItemId)
Toggle whether item of category is shown. Building the filter from
the full item set on first toggle, then removing/re-adding the item.
Removing the last shown item leaves an explicit empty filter (nothing
shown for that category). Presentation only.
Sourcepub fn clear_filters(&mut self)
pub fn clear_filters(&mut self)
Clear all active filters, showing every item again.
Auto Trait Implementations§
impl !RefUnwindSafe for App
impl !UnwindSafe for App
impl Freeze for App
impl Send for App
impl Sync for App
impl Unpin for App
impl UnsafeUnpin for App
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreimpl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
§impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
§fn plus_equals(&mut self, rhs: &&'a S)
fn plus_equals(&mut self, rhs: &&'a S)
std::ops::AddAssign, for types that do not implement AddAssign.