mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 11:16:03 +00:00
Fixes for ScrollView
This commit is contained in:
parent
804e41ec43
commit
f3d822c00c
18
src/vec.rs
18
src/vec.rs
@ -1,8 +1,11 @@
|
|||||||
//! Points on the 2D character grid.
|
//! Points on the 2D character grid.
|
||||||
|
|
||||||
use num::traits::Zero;
|
|
||||||
use std::cmp::{max, min, Ordering};
|
use std::cmp::{max, min, Ordering};
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
|
|
||||||
|
use num::traits::Zero;
|
||||||
|
|
||||||
|
use div;
|
||||||
use XY;
|
use XY;
|
||||||
|
|
||||||
/// Simple 2D size, in cells.
|
/// Simple 2D size, in cells.
|
||||||
@ -30,6 +33,11 @@ impl<T: PartialOrd> PartialOrd for XY<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl XY<usize> {
|
impl XY<usize> {
|
||||||
|
/// Returns a `Vec2` with `usize::max_value()` in each axis.
|
||||||
|
pub fn max_value() -> Self {
|
||||||
|
Self::new(usize::max_value(), usize::max_value())
|
||||||
|
}
|
||||||
|
|
||||||
/// Saturating subtraction. Computes `self - other`, saturating at 0.
|
/// Saturating subtraction. Computes `self - other`, saturating at 0.
|
||||||
///
|
///
|
||||||
/// Never panics.
|
/// Never panics.
|
||||||
@ -53,6 +61,14 @@ impl XY<usize> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Term-by-term integer division that rounds up.
|
||||||
|
pub fn div_up<O>(&self, other: O) -> Self
|
||||||
|
where
|
||||||
|
O: Into<Self>,
|
||||||
|
{
|
||||||
|
self.zip_map(other.into(), div::div_up)
|
||||||
|
}
|
||||||
|
|
||||||
/// Checked subtraction. Computes `self - other` if possible.
|
/// Checked subtraction. Computes `self - other` if possible.
|
||||||
///
|
///
|
||||||
/// Returns `None` if `self.x < other.x || self.y < other.y`.
|
/// Returns `None` if `self.x < other.x || self.y < other.y`.
|
||||||
|
@ -149,6 +149,7 @@ impl<V> ScrollView<V> {
|
|||||||
/// Will be zero in axis where we're not scrolling.
|
/// Will be zero in axis where we're not scrolling.
|
||||||
fn scrollbar_size(&self) -> Vec2 {
|
fn scrollbar_size(&self) -> Vec2 {
|
||||||
self.is_scrolling()
|
self.is_scrolling()
|
||||||
|
.swap()
|
||||||
.select_or(self.scrollbar_padding + (1, 1), Vec2::zero())
|
.select_or(self.scrollbar_padding + (1, 1), Vec2::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +173,7 @@ where
|
|||||||
) -> (Vec2, Vec2, XY<bool>) {
|
) -> (Vec2, Vec2, XY<bool>) {
|
||||||
// This is the size taken by the scrollbars.
|
// This is the size taken by the scrollbars.
|
||||||
let scrollbar_size = scrollable
|
let scrollbar_size = scrollable
|
||||||
|
.swap()
|
||||||
.select_or(self.scrollbar_padding + (1, 1), Vec2::zero());
|
.select_or(self.scrollbar_padding + (1, 1), Vec2::zero());
|
||||||
|
|
||||||
let available = constraint.saturating_sub(scrollbar_size);
|
let available = constraint.saturating_sub(scrollbar_size);
|
||||||
@ -244,11 +246,15 @@ where
|
|||||||
let lengths = self.scrollbar_thumb_lengths();
|
let lengths = self.scrollbar_thumb_lengths();
|
||||||
let available = self.available_size();
|
let available = self.available_size();
|
||||||
|
|
||||||
|
// We want self.scrollbar_thumb_offsets() to be thumb_pos
|
||||||
|
// steps * self.o / (self.inner + 1 - available) = thumb_pos
|
||||||
|
// self.o = thumb_pos * (self.inner + 1 - available) / (available + 1 - lengths)
|
||||||
|
|
||||||
// The new offset is:
|
// The new offset is:
|
||||||
// thumb_pos * (content + 1 - available) / (available + 1 - thumb size)
|
// thumb_pos * (content + 1 - available) / (available + 1 - thumb size)
|
||||||
let new_offset = (self.inner_size + (1, 1)).saturating_sub(available)
|
let new_offset = ((self.inner_size + (1, 1)).saturating_sub(available)
|
||||||
* thumb_pos
|
* thumb_pos)
|
||||||
/ (available + (1, 1)).saturating_sub(lengths);
|
.div_up((available + (1, 1)).saturating_sub(lengths));
|
||||||
let max_offset = self.inner_size.saturating_sub(self.available_size());
|
let max_offset = self.inner_size.saturating_sub(self.available_size());
|
||||||
self.offset
|
self.offset
|
||||||
.set_axis_from(orientation, &new_offset.or_min(max_offset));
|
.set_axis_from(orientation, &new_offset.or_min(max_offset));
|
||||||
@ -433,12 +439,39 @@ where
|
|||||||
self.release_grab();
|
self.release_grab();
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
Event::Key(Key::Home) if self.enabled.any() => {
|
||||||
|
self.offset =
|
||||||
|
self.enabled.select_or(Vec2::zero(), self.offset);
|
||||||
|
EventResult::Consumed(None)
|
||||||
|
}
|
||||||
|
Event::Key(Key::End) if self.enabled.any() => {
|
||||||
|
let max_offset = self
|
||||||
|
.inner_size
|
||||||
|
.saturating_sub(self.available_size());
|
||||||
|
self.offset =
|
||||||
|
self.enabled.select_or(max_offset, self.offset);
|
||||||
|
EventResult::Consumed(None)
|
||||||
|
}
|
||||||
Event::Ctrl(Key::Up) | Event::Key(Key::Up)
|
Event::Ctrl(Key::Up) | Event::Key(Key::Up)
|
||||||
if self.enabled.y && self.offset.y > 0 =>
|
if self.enabled.y && self.offset.y > 0 =>
|
||||||
{
|
{
|
||||||
self.offset.y -= 1;
|
self.offset.y -= 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
Event::Key(Key::PageUp)
|
||||||
|
if self.enabled.y && self.offset.y > 0 =>
|
||||||
|
{
|
||||||
|
self.offset.y = self.offset.y.saturating_sub(5);
|
||||||
|
EventResult::Consumed(None)
|
||||||
|
}
|
||||||
|
Event::Key(Key::PageDown)
|
||||||
|
if self.enabled.y
|
||||||
|
&& (self.offset.y + self.available_size().y
|
||||||
|
< self.inner_size.y) =>
|
||||||
|
{
|
||||||
|
self.offset.y += 5;
|
||||||
|
EventResult::Consumed(None)
|
||||||
|
}
|
||||||
Event::Ctrl(Key::Down) | Event::Key(Key::Down)
|
Event::Ctrl(Key::Down) | Event::Key(Key::Down)
|
||||||
if self.enabled.y
|
if self.enabled.y
|
||||||
&& (self.offset.y + self.available_size().y
|
&& (self.offset.y + self.available_size().y
|
||||||
|
Loading…
Reference in New Issue
Block a user