mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 19:26:09 +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)
|
if ncurses::getmouse(&mut mevent as *mut ncurses::MEVENT)
|
||||||
== ncurses::OK
|
== ncurses::OK
|
||||||
{
|
{
|
||||||
// eprintln!("{:032b}", mevent.bstate);
|
|
||||||
// Currently unused
|
// Currently unused
|
||||||
|
let _ctrl = (mevent.bstate & ncurses::BUTTON_CTRL as mmask_t) != 0;
|
||||||
let _shift =
|
let _shift =
|
||||||
(mevent.bstate & ncurses::BUTTON_SHIFT as mmask_t) != 0;
|
(mevent.bstate & ncurses::BUTTON_SHIFT as mmask_t) != 0;
|
||||||
let _alt = (mevent.bstate & ncurses::BUTTON_ALT 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
|
mevent.bstate &= !(ncurses::BUTTON_SHIFT
|
||||||
| ncurses::BUTTON_ALT
|
| ncurses::BUTTON_ALT
|
||||||
| ncurses::BUTTON_CTRL)
|
| ncurses::BUTTON_CTRL)
|
||||||
as mmask_t;
|
as mmask_t;
|
||||||
|
|
||||||
|
// This makes a full `Event` from a `MouseEvent`.
|
||||||
let make_event = |event| Event::Mouse {
|
let make_event = |event| Event::Mouse {
|
||||||
offset: Vec2::zero(),
|
offset: Vec2::zero(),
|
||||||
position: Vec2::new(mevent.x as usize, mevent.y as usize),
|
position: Vec2::new(mevent.x as usize, mevent.y as usize),
|
||||||
|
@ -189,7 +189,11 @@ where
|
|||||||
|
|
||||||
/// Returns the size available for the child view.
|
/// Returns the size available for the child view.
|
||||||
fn available_size(&self) -> Vec2 {
|
fn available_size(&self) -> Vec2 {
|
||||||
|
if self.show_scrollbars {
|
||||||
self.last_size.saturating_sub(self.scrollbar_size())
|
self.last_size.saturating_sub(self.scrollbar_size())
|
||||||
|
} else {
|
||||||
|
self.last_size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the size we would need.
|
/// Compute the size we would need.
|
||||||
@ -231,20 +235,21 @@ where
|
|||||||
///
|
///
|
||||||
/// Returns `true` if the event was consumed.
|
/// Returns `true` if the event was consumed.
|
||||||
fn start_drag(&mut self, position: Vec2) -> bool {
|
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 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 lengths = self.scrollbar_thumb_lengths();
|
||||||
let offsets = self.scrollbar_thumb_offsets(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
|
for (orientation, pos, length, offset) in
|
||||||
XY::zip4(Orientation::pair(), position, lengths, offsets)
|
XY::zip4(Orientation::pair(), position, lengths, offsets)
|
||||||
.zip(grabbed.swap())
|
.keep(grabbed.and(self.enabled))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|&(_, grab)| grab)
|
.filter_map(|x| x)
|
||||||
.map(|(x, _)| x)
|
|
||||||
{
|
{
|
||||||
if pos >= offset && pos < offset + length {
|
if pos >= offset && pos < offset + length {
|
||||||
// We grabbed the thumb! Now scroll from that position.
|
// We grabbed the thumb! Now scroll from that position.
|
||||||
@ -262,7 +267,9 @@ where
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called when a mouse drag is detected.
|
||||||
fn drag(&mut self, position: Vec2) {
|
fn drag(&mut self, position: Vec2) {
|
||||||
|
// Only do something if we grabbed something before.
|
||||||
if let Some((orientation, grab)) = self.thumb_grab {
|
if let Some((orientation, grab)) = self.thumb_grab {
|
||||||
self.scroll_to_thumb(
|
self.scroll_to_thumb(
|
||||||
orientation,
|
orientation,
|
||||||
@ -466,7 +473,8 @@ where
|
|||||||
event: MouseEvent::Press(MouseButton::Left),
|
event: MouseEvent::Press(MouseButton::Left),
|
||||||
position,
|
position,
|
||||||
offset,
|
offset,
|
||||||
} if position
|
} if self.show_scrollbars
|
||||||
|
&& position
|
||||||
.checked_sub(offset)
|
.checked_sub(offset)
|
||||||
.map(|position| self.start_drag(position))
|
.map(|position| self.start_drag(position))
|
||||||
.unwrap_or(false) =>
|
.unwrap_or(false) =>
|
||||||
@ -477,7 +485,8 @@ where
|
|||||||
event: MouseEvent::Hold(MouseButton::Left),
|
event: MouseEvent::Hold(MouseButton::Left),
|
||||||
position,
|
position,
|
||||||
offset,
|
offset,
|
||||||
} => {
|
} if self.show_scrollbars =>
|
||||||
|
{
|
||||||
let position = position.saturating_sub(offset);
|
let position = position.saturating_sub(offset);
|
||||||
self.drag(position);
|
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))
|
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> {
|
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> {
|
pub fn select_or<T>(&self, if_true: XY<T>, if_false: XY<T>) -> XY<T> {
|
||||||
self.select(if_true).unwrap_or(if_false)
|
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> {
|
impl<T: Copy> XY<T> {
|
||||||
|
Loading…
Reference in New Issue
Block a user