Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSRV=1.75: RPITIT; fixes #433

Merged
merged 6 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
toolchain: [stable]
include:
- os: ubuntu-latest
toolchain: "1.67.0"
toolchain: "1.75.0"
- os: ubuntu-latest
toolchain: beta

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ keywords = ["gui"]
categories = ["gui"]
repository = "https://github.com/kas-gui/kas"
exclude = ["/examples"]
rust-version = "1.66.0"
rust-version = "1.75.0"

[package.metadata.docs.rs]
features = ["stable"]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ KAS GUI
[![Crates.io](https://img.shields.io/crates/v/kas.svg)](https://crates.io/crates/kas)
[![kas-text](https://img.shields.io/badge/GitHub-kas--text-blueviolet)](https://github.com/kas-gui/kas-text/)
[![Docs](https://docs.rs/kas/badge.svg)](https://docs.rs/kas)
![Minimum rustc version](https://img.shields.io/badge/rustc-1.66+-lightgray.svg)
![Minimum rustc version](https://img.shields.io/badge/rustc-1.75+-lightgray.svg)

KAS is a stateful, pure-Rust GUI toolkit supporting:

Expand Down
4 changes: 1 addition & 3 deletions crates/kas-view/src/data_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ macro_rules! impl_list_data {
}
}
impl<T: Clone + Debug + 'static> ListData for $ty {
type KeyIter<'b> = std::ops::Range<usize>;

fn is_empty(&self) -> bool {
(*self).is_empty()
}
Expand All @@ -36,7 +34,7 @@ macro_rules! impl_list_data {
(*self).len()
}

fn iter_from(&self, start: usize, limit: usize) -> Self::KeyIter<'_> {
fn iter_from(&self, start: usize, limit: usize) -> impl Iterator<Item = Self::Key> {
let len = (*self).len();
start.min(len)..(start + limit).min(len)
}
Expand Down
45 changes: 8 additions & 37 deletions crates/kas-view/src/data_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,6 @@ pub trait SharedData: Debug {
#[allow(clippy::len_without_is_empty)]
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, std::rc::Rc<T>, std::sync::Arc<T>, Box<T>)]
pub trait ListData: SharedData {
type KeyIter<'b>: Iterator<Item = Self::Key>
where
Self: 'b;

/// No data is available
fn is_empty(&self) -> bool {
self.len() == 0
Expand All @@ -156,15 +152,13 @@ pub trait ListData: SharedData {
///
/// An example where `type Key = usize`:
/// ```ignore
/// type KeyIter<'b> = std::ops::Range<usize>;
///
/// fn iter_from(&self, start: usize, limit: usize) -> Self::KeyIter<'_> {
/// fn iter_from(&self, start: usize, limit: usize) -> impl Iterator<Item = usize> {
/// start.min(self.len)..(start + limit).min(self.len)
/// }
/// ```
///
/// This method is called on every update so should be reasonably fast.
fn iter_from(&self, start: usize, limit: usize) -> Self::KeyIter<'_>;
fn iter_from(&self, start: usize, limit: usize) -> impl Iterator<Item = Self::Key>;
}

/// Trait for viewable data matrices
Expand All @@ -177,13 +171,6 @@ pub trait MatrixData: SharedData {
/// Row key type
type RowKey;

type ColKeyIter<'b>: Iterator<Item = Self::ColKey>
where
Self: 'b;
type RowKeyIter<'b>: Iterator<Item = Self::RowKey>
where
Self: 'b;

/// No data is available
fn is_empty(&self) -> bool;

Expand All @@ -192,35 +179,19 @@ pub trait MatrixData: SharedData {
/// Note: users may assume this is `O(1)`.
fn len(&self) -> (usize, usize);

/// Iterate over column keys
/// Iterate over up to `limit` column keys from `start`
///
/// The result will be in deterministic implementation-defined order, with
/// a length of `max(limit, data_len)` where `data_len` is the number of
/// a length of `max(limit, data_len - start)` where `data_len` is the number of
/// items available.
#[inline]
fn col_iter_limit(&self, limit: usize) -> Self::ColKeyIter<'_> {
self.col_iter_from(0, limit)
}

/// Iterate over column keys from an arbitrary start-point
///
/// The result is the same as `self.iter_limit(start + limit).skip(start)`.
fn col_iter_from(&self, start: usize, limit: usize) -> Self::ColKeyIter<'_>;
fn col_iter_from(&self, start: usize, limit: usize) -> impl Iterator<Item = Self::ColKey>;

/// Iterate over row keys
/// Iterate over up to `limit` row keys from `start`
///
/// The result will be in deterministic implementation-defined order, with
/// a length of `max(limit, data_len)` where `data_len` is the number of
/// a length of `max(limit, data_len - start)` where `data_len` is the number of
/// items available.
#[inline]
fn row_iter_limit(&self, limit: usize) -> Self::RowKeyIter<'_> {
self.row_iter_from(0, limit)
}

/// Iterate over row keys from an arbitrary start-point
///
/// The result is the same as `self.iter_limit(start + limit).skip(start)`.
fn row_iter_from(&self, start: usize, limit: usize) -> Self::RowKeyIter<'_>;
fn row_iter_from(&self, start: usize, limit: usize) -> impl Iterator<Item = Self::RowKey>;

/// Make a key from parts
fn make_key(&self, col: &Self::ColKey, row: &Self::RowKey) -> Self::Key;
Expand Down
5 changes: 1 addition & 4 deletions crates/kas-view/src/filter/filter_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,14 @@ impl_scope! {
}

impl ListData for Self {
type KeyIter<'b> = KeyIter<'b, A::Key>
where Self: 'b;

fn is_empty(&self) -> bool {
self.view.is_empty()
}
fn len(&self) -> usize {
self.view.len()
}

fn iter_from(&self, start: usize, limit: usize) -> Self::KeyIter<'_> {
fn iter_from(&self, start: usize, limit: usize) -> impl Iterator<Item = Self::Key> {
let end = self.len().min(start + limit);
KeyIter { list: &self.view[start..end], index: 0 }
}
Expand Down
4 changes: 4 additions & 0 deletions crates/kas-view/src/list_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ impl_scope! {
impl<A: ListData, V: Driver<A::Item, A>> ListView<A, V, Direction> {
/// Set the direction of contents
pub fn set_direction(&mut self, direction: Direction) -> Action {
if direction == self.direction {
return Action::empty();
}

self.direction = direction;
Action::SET_RECT
}
Expand Down
7 changes: 5 additions & 2 deletions crates/kas-widgets/src/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -920,8 +920,11 @@ impl_scope! {
self.selection.set_max_len(len);
if self.text.try_prepare().is_ok() {
self.text_size = Vec2::from(self.text.bounding_box().unwrap().1).cast_ceil();
self.view_offset = self.view_offset.min(self.max_scroll_offset());
action = Action::SCROLLED;
let view_offset = self.view_offset.min(self.max_scroll_offset());
if view_offset != self.view_offset {
action = Action::SCROLLED;
self.view_offset = view_offset;
}
}
action | self.set_error_state(false)
}
Expand Down
4 changes: 4 additions & 0 deletions crates/kas-widgets/src/tab_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ impl_scope! {
///
/// Default value: [`Direction::Up`]
pub fn set_direction(&mut self, direction: Direction) -> Action {
if direction == self.direction {
return Action::empty();
}

self.direction = direction;
// Note: most of the time SET_RECT would be enough, but margins can be different
Action::RESIZE
Expand Down
32 changes: 4 additions & 28 deletions examples/data-list-view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,27 +141,6 @@ impl_scope! {
}
}

// Once RPITIT is stable we can replace this with range + map
struct KeyIter {
start: usize,
end: usize,
}
impl Iterator for KeyIter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
let mut item = None;
if self.start < self.end {
item = Some(self.start);
self.start += 1;
}
item
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.end.saturating_sub(self.start);
(len, Some(len))
}
}

impl SharedData for Data {
type Key = usize;
type Item = Item;
Expand All @@ -175,17 +154,14 @@ impl SharedData for Data {
}
}
impl ListData for Data {
type KeyIter<'b> = KeyIter;

fn len(&self) -> usize {
self.len
}

fn iter_from(&self, start: usize, limit: usize) -> Self::KeyIter<'_> {
KeyIter {
start: start.min(self.len),
end: (start + limit).min(self.len),
}
fn iter_from(&self, start: usize, limit: usize) -> impl Iterator<Item = usize> {
let start = start.min(self.len);
let end = (start + limit).min(self.len);
(start..end).into_iter()
}
}

Expand Down
3 changes: 0 additions & 3 deletions examples/times-tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ impl MatrixData for TableSize {
type ColKey = usize;
type RowKey = usize;

type ColKeyIter<'b> = std::ops::Range<usize>;
type RowKeyIter<'b> = std::ops::Range<usize>;

fn is_empty(&self) -> bool {
self.0 == 0
}
Expand Down