Skip to main content

Scroller

Struct Scroller 

Source
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: f64

Where 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: Floors

Each window’s own floor, as the caller last handed them in (#115). See Self::set_floors.

Implementations§

Source§

impl Scroller

Source

pub fn new() -> Self

Source

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.

Source

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.

Source

pub fn is_empty(&self) -> bool

Source

pub fn columns(&self) -> &[Column]

Source

pub fn active_column(&self) -> usize

Source

pub fn focused(&self) -> Option<u64>

The focused window, if there is one.

Source

pub fn contains(&self, id: u64) -> bool

Source

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.

Source

fn floor_of(&self, index: usize) -> f64

The widest floor among the windows of the column at index, or zero.

Source

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.

Source

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.

Source

pub fn insert_into_active(&mut self, id: u64, area: Rect, settings: Settings)

Add a window to the active column instead of beside it.

Source

pub fn remove(&mut self, id: u64)

Source

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.

Source

pub fn focus_sideways(&mut self, by: isize, area: Rect, settings: Settings)

Move focus one column left or right, taking the view with it.

Source

pub fn focus_vertically(&mut self, by: isize)

Move focus within the active column.

Source

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.

Source

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.

Source

pub fn consume(&mut self)

Pull the next column’s focused window into this one.

Source

pub fn expel(&mut self, area: Rect, settings: Settings)

Push the focused window out into a column of its own.

Source

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.

Source

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.

Source

pub fn cycle_width(&mut self, area: Rect, settings: Settings)

Cycle the active column through the preset widths.

Source

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.

Source

pub fn scroll_by(&mut self, delta: f64)

Scroll the view by a distance, without moving focus.

Source

pub fn layout(&self, area: Rect, settings: Settings) -> Vec<(u64, Rect)>

Where every window goes.

Source

fn view_position(&self, view: Rect, settings: Settings) -> f64

The left edge of the view, in strip coordinates.

Source

fn column_x(&self, index: usize, view: Rect, settings: Settings) -> f64

Where a column starts along the strip.

Source

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.

Trait Implementations§

Source§

impl Clone for Scroller

Source§

fn clone(&self) -> Scroller

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Scroller

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Scroller

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.