pub struct BoardState {
pub columns: Vec<BoardColumn>,
pub hidden: Vec<BoardColumn>,
pub mismatch: BoardColumn,
pub show_mismatch: bool,
pub active_col: usize,
pub selected: usize,
pub hover: Option<(usize, usize)>,
pub hover_col: Option<usize>,
pub filter: Option<String>,
}Fields§
§columns: Vec<BoardColumn>Visible columns only — configured columns not listed in the active
Columns hidden from the active board configuration. Their cards stay in board state (keyed by column name) and remain reachable via filters/search (DM-01M2MHJB884WCTVCDHPD2T3GE7); they never render.
mismatch: BoardColumn§show_mismatch: boolWhether the computed “Mismatched” pseudo-column is part of the
navigation/render surface (C-002 / FR-003). Cards in unknown statuses
are always collected into BoardState::mismatch; the column is only
shown when the effective configuration sets show_mismatch.
active_col: usize§selected: usize§hover: Option<(usize, usize)>The (col, card index) the pointer is hovering (D8), set by Moved
events and cleared on Up / when the pointer leaves the board.
Rendered as a highlight only — it never changes the selection.
hover_col: Option<usize>The column the pointer is over, set for any position inside a column —
including empty space below the last card, where hover is None. The
renderer marks the hovered column from this, so an empty column lights up
too. Cleared with hover.
filter: Option<String>Implementations§
Source§impl BoardState
impl BoardState
Sourcepub fn build_filtered(
board_config: &BoardConfiguration,
config: &Config,
corpus: &Corpus,
query: &str,
filter: &StructuredFilter,
resolution: &CategoryResolution,
) -> Self
pub fn build_filtered( board_config: &BoardConfiguration, config: &Config, corpus: &Corpus, query: &str, filter: &StructuredFilter, resolution: &CategoryResolution, ) -> Self
Build a board from the search corpus, keeping only cards whose full
serialized text matches both the fuzzy query layer and the
structured filter layer (FR-012/FR-013). Both predicates run in a
single pass over the corpus via crate::search::matches (NFR-001).
When a filter is active (non-empty query or structured criteria set),
hidden columns’ matching cards are revealed in the rendered surface
(DM-01M2MHJB884WCTVCDHPD2T3GE7: hidden-column cards reachable via
filters/search). When no filter is active, matching cards from hidden
columns are stashed in BoardState::hidden (no visual presence).
Sourcepub fn build_filtered_with(
board_config: &BoardConfiguration,
config: &Config,
corpus: &Corpus,
query: &str,
filter: &StructuredFilter,
resolution: &CategoryResolution,
show_children: bool,
) -> Self
pub fn build_filtered_with( board_config: &BoardConfiguration, config: &Config, corpus: &Corpus, query: &str, filter: &StructuredFilter, resolution: &CategoryResolution, show_children: bool, ) -> Self
BoardState::build_filtered, optionally rendering sub-issues under their
parents (tix #1399).
The u toggle is global, so it must keep working while a search or
structured filter is active: build_filtered delegates here with
show_children == false and the TUI passes its flag through.
Source§impl BoardState
impl BoardState
Sourcepub fn hit_test(
&self,
area: Rect,
display: BoardDisplay,
status: bool,
x: u16,
y: u16,
) -> Option<HitTarget>
pub fn hit_test( &self, area: Rect, display: BoardDisplay, status: bool, x: u16, y: u16, ) -> Option<HitTarget>
Map a terminal pointer (x, y) — given against the same area passed
to render — to the card or column underneath. status mirrors
whether render is drawing a status message, so the status row (not
part of any column) never resolves to a target. Returns None for
positions outside the board area (y above the columns or beyond the
board) or when nothing is drawn. Uses compute_column_rects and
super::widgets::card_line_count — the geometry render draws with —
so the hit-tested layout matches the rendered one by construction (D3).
Source§impl BoardState
impl BoardState
Sourcepub fn resolution_for(
store: &Store,
board_config: &BoardConfiguration,
) -> CategoryResolution
pub fn resolution_for( store: &Store, board_config: &BoardConfiguration, ) -> CategoryResolution
WP05: the resolution must be for the board this call is building, not for
whichever board happens to be default.
board_config can be any of the configured boards, and a board selected in
the TUI is not necessarily the default one. Resolving against the default
would give a card on the staging board the categories configured for
default — a wrong answer rather than a missing one, which is worse.
The board is identified by pointer identity against the config’s boards,
because build receives a &BoardConfiguration and not a name. That is exact
and needs no name plumbing; a board not found in the config falls back to its
own columns with the global vocabulary, which is the honest reading of a
configuration tix did not load.
Public so the startup path can build a board from a single shared
enumeration (tix #1518) instead of each caller re-deriving it.
pub fn build(store: &Store, board_config: &BoardConfiguration) -> Self
Sourcepub fn build_with_archived(
store: &Store,
board_config: &BoardConfiguration,
include_archived: bool,
) -> Self
pub fn build_with_archived( store: &Store, board_config: &BoardConfiguration, include_archived: bool, ) -> Self
BoardState::build, optionally including archived issues (issue #1492).
include_archived == false is the default and the fast path: enumeration reads
Store::list, which drops a dot-prefixed filename from the directory entry
without opening the file. true reads Store::list_all, which is what the
TUI’s archive toggle asks for on demand — the point being that a repository
with thousands of archived issues is never walked for a board that does not
show them.
Sourcepub fn build_with(
store: &Store,
board_config: &BoardConfiguration,
include_archived: bool,
show_children: bool,
) -> Self
pub fn build_with( store: &Store, board_config: &BoardConfiguration, include_archived: bool, show_children: bool, ) -> Self
BoardState::build_with_archived, optionally rendering sub-issues under
their parents (tix #1399).
show_children == true reorders every column so a card’s direct sub-issues
follow it, marked depth = 1 (see [nest_children]). The reorder happens at
build time, not at draw time, because the selection index and the pointer
hit-test both address cards by their index inside a column — a tree only the
renderer knew about would make a click or a j land on the wrong card.
Sourcepub fn build_from_issues(
issues: &[Issue],
board_config: &BoardConfiguration,
config: &Config,
resolution: &CategoryResolution,
show_children: bool,
) -> Self
pub fn build_from_issues( issues: &[Issue], board_config: &BoardConfiguration, config: &Config, resolution: &CategoryResolution, show_children: bool, ) -> Self
Build a board from an in-memory slice of issues (issue #10 follow-up).
The single build path: BoardState::build_with reads the store and
delegates here, and the TUI’s incremental refresh rebuilds from its
in-memory corpus without re-reading the tree. config supplies the
completion column; resolution is the category resolution of the board
being built (see BoardState::resolution_for).
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
True when no card anywhere is visible (used for zero-match feedback).
pub fn total_cols(&self) -> usize
Sourcepub fn real_cols(&self) -> usize
pub fn real_cols(&self) -> usize
Columns a card can be moved into: the configured columns plus (when
shown) the “Mismatched” sentinel, which is never a move target. The
</> move keys navigate among movable columns only.
pub fn column_name(&self, idx: usize) -> &str
Sourcepub fn active_column_name(&self) -> &str
pub fn active_column_name(&self) -> &str
The name under the active cursor, resolving hidden columns too
(visible region first, then hidden, then Unknown). Lets toggle keep a
logical cursor on a just-hidden column so a second press re-shows it
(T017: “a second press on the same column re-shows it”).
pub fn column_cards(&self, idx: usize) -> &[Card]
pub fn get_selected_card(&self) -> Option<&Card>
Sourcepub fn sole_visible_card(&self) -> Option<(usize, usize)>
pub fn sole_visible_card(&self) -> Option<(usize, usize)>
The (column, row) of the only card the board is displaying, if there is
exactly one (tix #1744).
“Displayed” is what render and hit_test address: the active board’s
visible columns plus the “Mismatched” pseudo-column when it is shown.
Hidden columns never render, so their cards do not count. None when the
board shows zero cards or more than one.
pub fn move_left(&mut self)
pub fn move_right(&mut self)
pub fn move_up(&mut self)
pub fn move_down(&mut self)
Sourcepub fn move_selection_by(&mut self, cards: i32)
pub fn move_selection_by(&mut self, cards: i32)
Move the selection by cards (negative moves up), clamped to the column
(tix #1442 follow-up).
The page step: move_up/move_down are the one-card steps, this is the same
move by a screenful. It clamps for the reason the detail pane’s scroll does — a
jump past the end should land on the last card, not walk off it.
pub fn clamp_selection(&mut self)
pub fn select_column(&mut self, col: usize)
Trait Implementations§
Source§impl Clone for BoardState
impl Clone for BoardState
Auto Trait Implementations§
impl Freeze for BoardState
impl RefUnwindSafe for BoardState
impl Send for BoardState
impl Sync for BoardState
impl Unpin for BoardState
impl UnsafeUnpin for BoardState
impl UnwindSafe for BoardState
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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 more