mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Don't drag scrollbars if they're not visible
This commit is contained in:
parent
2935f0f569
commit
bd78bca91b
@ -89,18 +89,19 @@ impl InputParser {
|
||||
if ncurses::getmouse(&mut mevent as *mut ncurses::MEVENT)
|
||||
== ncurses::OK
|
||||
{
|
||||
// eprintln!("{:032b}", mevent.bstate);
|
||||
// Currently unused
|
||||
let _ctrl = (mevent.bstate & ncurses::BUTTON_CTRL as mmask_t) != 0;
|
||||
let _shift =
|
||||
(mevent.bstate & ncurses::BUTTON_SHIFT as mmask_t) != 0;
|
||||
let _alt = (mevent.bstate & ncurses::BUTTON_ALT as mmask_t) != 0;
|
||||
let _ctrl = (mevent.bstate & ncurses::BUTTON_CTRL as mmask_t) != 0;
|
||||
|
||||
// Keep the base state, without the modifiers
|
||||
mevent.bstate &= !(ncurses::BUTTON_SHIFT
|
||||
| ncurses::BUTTON_ALT
|
||||
| ncurses::BUTTON_CTRL)
|
||||
as mmask_t;
|
||||
|
||||
// This makes a full `Event` from a `MouseEvent`.
|
||||
let make_event = |event| Event::Mouse {
|
||||
offset: Vec2::zero(),
|
||||
position: Vec2::new(mevent.x as usize, mevent.y as usize),
|
||||
|
@ -189,7 +189,11 @@ where
|
||||
|
||||
/// Returns the size available for the child view.
|
||||
fn available_size(&self) -> Vec2 {
|
||||
self.last_size.saturating_sub(self.scrollbar_size())
|
||||
if self.show_scrollbars {
|
||||
self.last_size.saturating_sub(self.scrollbar_size())
|
||||
} else {
|
||||
self.last_size
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute the size we would need.
|
||||
@ -231,20 +235,21 @@ where
|
||||
///
|
||||
/// Returns `true` if the event was consumed.
|
||||
fn start_drag(&mut self, position: Vec2) -> bool {
|
||||
// For each scrollbar, how far it is.
|
||||
let scrollbar_pos = self.last_size.saturating_sub((1, 1));
|
||||
|
||||
let grabbed = scrollbar_pos.zip_map(position, |s, p| s == p);
|
||||
// This is true for Y if we grabbed the vertical scrollbar
|
||||
let grabbed = scrollbar_pos.zip_map(position, |s, p| s == p).swap();
|
||||
|
||||
let lengths = self.scrollbar_thumb_lengths();
|
||||
let offsets = self.scrollbar_thumb_offsets(lengths);
|
||||
|
||||
// See if we grabbed one of the scrollbars
|
||||
// Iterate on axises, and keep the one we grabbed.
|
||||
for (orientation, pos, length, offset) in
|
||||
XY::zip4(Orientation::pair(), position, lengths, offsets)
|
||||
.zip(grabbed.swap())
|
||||
.keep(grabbed.and(self.enabled))
|
||||
.into_iter()
|
||||
.filter(|&(_, grab)| grab)
|
||||
.map(|(x, _)| x)
|
||||
.filter_map(|x| x)
|
||||
{
|
||||
if pos >= offset && pos < offset + length {
|
||||
// We grabbed the thumb! Now scroll from that position.
|
||||
@ -262,7 +267,9 @@ where
|
||||
false
|
||||
}
|
||||
|
||||
/// Called when a mouse drag is detected.
|
||||
fn drag(&mut self, position: Vec2) {
|
||||
// Only do something if we grabbed something before.
|
||||
if let Some((orientation, grab)) = self.thumb_grab {
|
||||
self.scroll_to_thumb(
|
||||
orientation,
|
||||
@ -466,10 +473,11 @@ where
|
||||
event: MouseEvent::Press(MouseButton::Left),
|
||||
position,
|
||||
offset,
|
||||
} if position
|
||||
.checked_sub(offset)
|
||||
.map(|position| self.start_drag(position))
|
||||
.unwrap_or(false) =>
|
||||
} if self.show_scrollbars
|
||||
&& position
|
||||
.checked_sub(offset)
|
||||
.map(|position| self.start_drag(position))
|
||||
.unwrap_or(false) =>
|
||||
{
|
||||
// Just consume the event.
|
||||
}
|
||||
@ -477,7 +485,8 @@ where
|
||||
event: MouseEvent::Hold(MouseButton::Left),
|
||||
position,
|
||||
offset,
|
||||
} => {
|
||||
} if self.show_scrollbars =>
|
||||
{
|
||||
let position = position.saturating_sub(offset);
|
||||
self.drag(position);
|
||||
}
|
||||
|
15
src/xy.rs
15
src/xy.rs
@ -140,6 +140,11 @@ impl<T> XY<T> {
|
||||
{
|
||||
XY::new(f(self.x, other.x), f(self.y, other.y))
|
||||
}
|
||||
|
||||
/// For each axis, keep the element from `self` if `keep` is `true`.
|
||||
pub fn keep(self, keep: XY<bool>) -> XY<Option<T>> {
|
||||
keep.select(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> XY<T> {
|
||||
@ -192,6 +197,16 @@ impl XY<bool> {
|
||||
pub fn select_or<T>(&self, if_true: XY<T>, if_false: XY<T>) -> XY<T> {
|
||||
self.select(if_true).unwrap_or(if_false)
|
||||
}
|
||||
|
||||
/// Returns a term-by-term AND operation.
|
||||
pub fn and(&self, other: Self) -> Self {
|
||||
self.zip_map(other, |s, o| s && o)
|
||||
}
|
||||
|
||||
/// Returns a term-by-term OR operation.
|
||||
pub fn or(&self, other: Self) -> Self {
|
||||
self.zip_map(other, |s, o| s || o)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> XY<T> {
|
||||
|
Loading…
Reference in New Issue
Block a user