pub struct Scroller {
columns: Vec<Column>,
active: usize,
view_offset: f64,
widths: Vec<f64>,
preset: usize,
floors: Floors,
}Expand description
A scrolling workspace.
Fields§
§columns: Vec<Column>§active: usize§view_offset: f64Where the view sits relative to the active column’s left edge.
widths: Vec<f64>The widths this strip cycles through, as shares of the view.
Held per strip rather than carried in crate::Settings because
Settings is Copy and is rebuilt from a Lua table on every call —
a list allocated per keystroke to describe something that cannot change
between them. It is also per strip in truth: the widths are read once,
where the strip is made.
Never empty. Every read indexes it, and the two constructors below are the only things that fill it.
preset: usize§floors: FloorsEach window’s own floor, as the caller last handed them in (#115). See
Self::set_floors.
Implementations§
Source§impl Scroller
impl Scroller
pub fn new() -> Self
Sourcepub fn with_widths(widths: &[f64], start: usize) -> Self
pub fn with_widths(widths: &[f64], start: usize) -> Self
A strip cycling through widths of the caller’s choosing.
start is a zero-based index into widths — the width a new column
opens at, and the point the cycle begins from. lua/config.lua spells
it default_width and counts from one, the way Lua counts; the
subtraction happens at that boundary, not here.
What it does with a list it cannot use. Anything not a share of a
view has already been dropped by the caller, which is where the log is;
this sees the survivors. If there are none it falls back to PRESETS,
because every read of widths indexes it and a strip with no widths at
all has no width to open a column at. An out-of-range start is clamped
to the last width rather than refused, for the same reason: there is no
answer to “start at the fourth of three” that is not a choice, and
refusing would mean a session with no scrolling layout over one number.
Sourcefn width_now(&self) -> f64
fn width_now(&self) -> f64
The width a column takes now, as a share of the view.
preset is kept in range by both constructors and by cycle_width’s
modulo, so this cannot miss; the unwrap_or is what stands in for the
index that would panic if one of those three ever stopped being true,
and the crate denies panicking outright.
pub fn is_empty(&self) -> bool
pub fn columns(&self) -> &[Column]
pub fn active_column(&self) -> usize
pub fn contains(&self, id: u64) -> bool
Sourcepub fn set_floors(&mut self, floors: Floors)
pub fn set_floors(&mut self, floors: Floors)
Each window’s own floor, by id, for every call after this one (#115).
Replaced whole, as Tiling::set_floors replaces its own: what every
window says now, and a window missing from it has no floor. Only the
width is read: a column is never laid out narrower than the widest
floor in it – see Self::width_of. Its height is the view’s, which
the strip does not scroll, so a stack too tall for it has nowhere else
to go.
Sourcefn floor_of(&self, index: usize) -> f64
fn floor_of(&self, index: usize) -> f64
The widest floor among the windows of the column at index, or zero.
Sourcefn width_of(&self, index: usize, view: Rect) -> f64
fn width_of(&self, index: usize, view: Rect) -> f64
How wide the column at index is laid out, in view: its share of
the view, or the widest floor among its windows where that is wider.
Everything that measures a column asks this, so where a column is drawn,
where the next one starts and what the view scrolls to agree about its
width. floors::a_column_is_never_narrower_than_its_widest_floor and
floors::the_next_column_starts_after_a_widened_one.
Sourcepub fn insert(&mut self, id: u64, area: Rect, settings: Settings)
pub fn insert(&mut self, id: u64, area: Rect, settings: Settings)
Open a window in a new column, to the right of the active one.
Sourcepub fn insert_into_active(&mut self, id: u64, area: Rect, settings: Settings)
pub fn insert_into_active(&mut self, id: u64, area: Rect, settings: Settings)
Add a window to the active column instead of beside it.
pub fn remove(&mut self, id: u64)
Sourcepub fn focus_window(&mut self, id: u64, area: Rect, settings: Settings)
pub fn focus_window(&mut self, id: u64, area: Rect, settings: Settings)
Focus a particular window, bringing its column into view.
This is what makes clicking a half-visible column work: the click says which window, and the view follows. Without it a column can hold focus while hanging off the edge of the screen, which is the state that makes a scroller feel like it is fighting you.
Sourcepub fn focus_sideways(&mut self, by: isize, area: Rect, settings: Settings)
pub fn focus_sideways(&mut self, by: isize, area: Rect, settings: Settings)
Move focus one column left or right, taking the view with it.
Sourcepub fn focus_vertically(&mut self, by: isize)
pub fn focus_vertically(&mut self, by: isize)
Move focus within the active column.
Sourcepub fn move_vertically(&mut self, by: isize) -> bool
pub fn move_vertically(&mut self, by: isize) -> bool
Swap the focused window with the one above it in its column (by is
-1) or below it (1), carrying focus along: niri’s move-window-up and
move-window-down (#150). Returns whether anything moved, which it
does not at the top or the bottom of the column.
move_vertically_swaps_within_the_column_and_stops_at_its_ends.
Sourcepub fn move_column(&mut self, by: isize, area: Rect, settings: Settings) -> bool
pub fn move_column(&mut self, by: isize, area: Rect, settings: Settings) -> bool
Swap the active column with its neighbour, carrying focus along.
Returns whether it moved, which it does not at either end of the strip
(#150). move_column_says_whether_it_moved.
Sourcepub fn expel(&mut self, area: Rect, settings: Settings)
pub fn expel(&mut self, area: Rect, settings: Settings)
Push the focused window out into a column of its own.
Sourcepub fn move_to_column_of(
&mut self,
id: u64,
target: u64,
area: Rect,
settings: Settings,
)
pub fn move_to_column_of( &mut self, id: u64, target: u64, area: Rect, settings: Settings, )
Move a window into the column another window is in.
What a drag means in a scroller: not a free position, but a change of which column something belongs to. Dropping onto a window in another column stacks it there.
Sourcepub fn widen(&mut self, id: u64, by: f64, area: Rect, settings: Settings)
pub fn widen(&mut self, id: u64, by: f64, area: Rect, settings: Settings)
Widen or narrow the column a window sits in.
Every window in a column shares its width, so a drag on one window’s edge can only mean the column. Clamped so a column can neither vanish nor grow past the view — past that it would be left-aligned anyway and dragging further would appear to do nothing.
Sourcepub fn cycle_width(&mut self, area: Rect, settings: Settings)
pub fn cycle_width(&mut self, area: Rect, settings: Settings)
Cycle the active column through the preset widths.
Sourcepub fn configure_like(&mut self, like: &Self)
pub fn configure_like(&mut self, like: &Self)
Take the widths like was made with, and keep everything else.
For a strip that outlives the configuration that made it, which is what
a reload does to one (#118). The columns, their widths, the focus and
the view are the arrangement, and a reload does not change the
arrangement. The list a column is cycled through and the width the next
one opens at are configuration, so they come from like, which is
made from the file as it reads now. See
a_strip_configured_again_keeps_its_columns_and_takes_the_new_widths.
Sourcepub fn layout(&self, area: Rect, settings: Settings) -> Vec<(u64, Rect)>
pub fn layout(&self, area: Rect, settings: Settings) -> Vec<(u64, Rect)>
Where every window goes.
Sourcefn view_position(&self, view: Rect, settings: Settings) -> f64
fn view_position(&self, view: Rect, settings: Settings) -> f64
The left edge of the view, in strip coordinates.
Sourcefn column_x(&self, index: usize, view: Rect, settings: Settings) -> f64
fn column_x(&self, index: usize, view: Rect, settings: Settings) -> f64
Where a column starts along the strip.
Sourcefn focus_column(&mut self, index: usize, area: Rect, settings: Settings)
fn focus_column(&mut self, index: usize, area: Rect, settings: Settings)
Point focus at a column and bring it into view.
The offset is rebased first, by the distance between the old column and the new one. Skipping that is what makes a scroller feel disconnected: the view would keep an offset measured from a column that is no longer the one it is describing.