mod scroll_bar;
mod scroll_thumb;
mod scroll_view;
mod use_scroll_controller;
mod virtual_scroll_view;
use freya_elements::events::{
keyboard::Key,
KeyboardEvent,
};
pub use scroll_bar::*;
pub use scroll_thumb::*;
pub use scroll_view::*;
pub use use_scroll_controller::*;
pub use virtual_scroll_view::*;
#[doc(hidden)]
pub const SCROLL_SPEED_MULTIPLIER: f32 = 5.0;
#[doc(hidden)]
#[derive(Debug, PartialEq, Eq)]
pub enum Axis {
X,
Y,
}
#[doc(hidden)]
pub fn get_container_size(
size: &str,
is_vertical: bool,
axis: Axis,
is_scrollbar_visible: bool,
scrollbar_size: &str,
) -> (String, String) {
let is_cross_fit = if is_vertical {
axis == Axis::X && size == "auto"
} else {
axis == Axis::Y && size == "auto"
};
if is_cross_fit {
(size.to_string(), size.to_string())
} else if is_scrollbar_visible {
(format!("calc(100% - {scrollbar_size})"), "fill".to_string())
} else {
("100%".to_string(), "fill".to_string())
}
}
#[doc(hidden)]
pub fn is_scrollbar_visible(
is_scrollbar_enabled: bool,
inner_size: f32,
viewport_size: f32,
) -> bool {
if is_scrollbar_enabled {
viewport_size < inner_size
} else {
false
}
}
#[doc(hidden)]
pub fn get_scrollbar_pos_and_size(
inner_size: f32,
viewport_size: f32,
scroll_position: f32,
) -> (f32, f32) {
let scrollbar_height = if viewport_size >= inner_size {
inner_size
} else {
let viewable_ratio_height = viewport_size / inner_size;
viewport_size * viewable_ratio_height
};
let scroll_position = (100.0 / inner_size) * -scroll_position;
let scrollbar_position = (scroll_position / 100.0) * viewport_size;
(scrollbar_position, scrollbar_height)
}
#[doc(hidden)]
pub fn get_scroll_position_from_cursor(
cursor_position: f32,
inner_size: f32,
viewport_size: f32,
) -> i32 {
let per = 100.0 / viewport_size * cursor_position;
if viewport_size >= inner_size {
return 0;
}
let new_position = -(inner_size / 100.0 * per);
if new_position >= 0.0 {
return 0;
}
if new_position <= -(inner_size - viewport_size) {
return -(inner_size - viewport_size) as i32;
}
new_position as i32
}
#[doc(hidden)]
pub fn get_scroll_position_from_wheel(
wheel_movement: f32,
inner_size: f32,
viewport_size: f32,
scroll_position: f32,
) -> i32 {
if viewport_size >= inner_size {
return 0;
}
let new_position = scroll_position + wheel_movement;
if new_position >= 0.0 && wheel_movement > 0.0 {
return 0;
}
if new_position <= -(inner_size - viewport_size) && wheel_movement < 0.0 {
return -(inner_size - viewport_size) as i32;
}
new_position as i32
}
#[doc(hidden)]
pub fn get_corrected_scroll_position(
inner_size: f32,
viewport_size: f32,
scroll_position: f32,
) -> f32 {
let overscrolled_start = scroll_position > 0.0;
let overscrolled_end = (-scroll_position + viewport_size) > inner_size;
if overscrolled_start {
0f32
} else if overscrolled_end {
if viewport_size < inner_size {
-(inner_size - viewport_size)
} else {
0f32
}
} else {
scroll_position
}
}
pub fn manage_key_event(
e: KeyboardEvent,
(mut x, mut y): (f32, f32),
inner_height: f32,
inner_width: f32,
viewport_height: f32,
viewport_width: f32,
) -> (f32, f32) {
let y_page_delta = viewport_height;
let y_line_delta = y_page_delta / 5.0;
let x_page_delta = viewport_width;
let x_line_delta = x_page_delta / 5.0;
match e.key {
Key::ArrowUp => {
y = get_corrected_scroll_position(inner_height, viewport_height, y + y_line_delta)
}
Key::ArrowDown => {
y = get_corrected_scroll_position(inner_height, viewport_height, y - y_line_delta)
}
Key::PageUp => {
y = get_corrected_scroll_position(inner_height, viewport_height, y + y_line_delta)
}
Key::PageDown => {
y = get_corrected_scroll_position(inner_height, viewport_height, y - y_line_delta)
}
Key::ArrowLeft => {
x = get_corrected_scroll_position(inner_width, viewport_width, x + x_line_delta)
}
Key::ArrowRight => {
x = get_corrected_scroll_position(inner_width, viewport_width, x - x_line_delta)
}
Key::Home => {
y = 0.0;
}
Key::End => {
y = -inner_height;
}
_ => {}
};
(x, y)
}