WIP scroll bar

This commit is contained in:
mars 2022-07-12 22:38:59 -06:00
parent 9f52ff584f
commit 87ec9f0f52
1 changed files with 82 additions and 25 deletions

View File

@ -189,6 +189,70 @@ impl Widget for RectButton {
}
}
pub struct ScrollBarStyle {
pub margin: Vec2,
pub body_radius: f32,
pub body_width: f32,
pub body_idle_color: Color,
pub body_hover_color: Color,
pub body_active_color: Color,
pub rail_width: f32,
pub rail_color: Color,
}
impl Default for ScrollBarStyle {
fn default() -> Self {
Self {
margin: Vec2::new(0.01, 0.01),
body_radius: 0.005,
body_width: 0.015,
body_idle_color: Color::new(0.5, 0.5, 0.5, 1.0),
body_hover_color: Color::new(0.8, 0.8, 0.8, 1.0),
body_active_color: Color::new(1.0, 1.0, 0.0, 1.0),
rail_width: 0.005,
rail_color: Color::new(0.7, 0.7, 0.7, 0.5),
}
}
}
pub struct ScrollBar {
height: f32,
style: ScrollBarStyle,
scroll: f32,
content_height: f32,
}
impl ScrollBar {
pub fn new(height: f32, content_height: f32, style: ScrollBarStyle) -> Self {
Self {
height,
style,
scroll: height,
content_height,
}
}
}
impl Widget for ScrollBar {
fn update(&mut self, dt: f32) {}
fn draw(&mut self, ctx: &DrawContext) {
let style = &self.style;
let center_x = style.body_width / 2.0 + style.margin.x;
let rail_xy = Vec2::new(center_x - style.rail_width / 2.0, self.style.margin.y);
let rail_size = Vec2::new(style.rail_width, self.height - style.margin.y * 2.0);
let body_height = (self.height / self.content_height) * rail_size.y;
let body_y = rail_size.y - (self.scroll / self.content_height) * rail_size.y - body_height;
let body_xy = Vec2::new(style.margin.x, body_y + style.margin.y);
let body_size = Vec2::new(style.body_width, body_height);
ctx.draw_rect(rail_xy, rail_size, style.rail_color);
ctx.draw_rounded_rect(body_xy, body_size, style.body_radius, style.body_idle_color);
}
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {}
}
#[derive(Eq, PartialEq)]
pub enum ScrollMenuState {
Opening,
@ -544,6 +608,7 @@ impl Widget for MainMenu {
pub struct TabMenu {
tabs: Vec<RectButton>,
scroll_bar: Offset<ScrollBar>,
}
impl TabMenu {
@ -554,10 +619,7 @@ impl TabMenu {
const TAB_NUM: usize = 6;
const SEPARATOR_WIDTH: f32 = 0.015;
const INNER_RADIUS: f32 = 0.005;
const BOX_SIZE: f32 = 0.05;
const BOX_MARGIN: f32 = 0.01;
const BOX_PADDING: f32 = 0.005;
const BOX_GRID_WIDTH: usize = 8;
const CONTENT_WIDTH: f32 = 0.4;
pub fn new() -> Self {
let tab_size = Vec2::new(Self::TAB_WIDTH, Self::TAB_HEIGHT);
@ -577,7 +639,12 @@ impl TabMenu {
tabs.push(RectButton::new(pos, tab_size, corners, radius));
}
Self { tabs }
let scroll_height = Self::TAB_NUM as f32 * Self::TAB_HEIGHT;
let scroll_bar = ScrollBar::new(scroll_height, scroll_height * 3.0, Default::default());
let scroll_x = Self::TAB_WIDTH + Self::SEPARATOR_WIDTH + Self::CONTENT_WIDTH;
let scroll_bar = Offset::new(scroll_bar, Vec2::new(scroll_x, -scroll_height));
Self { tabs, scroll_bar }
}
}
@ -586,6 +653,8 @@ impl Widget for TabMenu {
for tab in self.tabs.iter_mut() {
tab.update(dt);
}
self.scroll_bar.update(dt);
}
fn draw(&mut self, ctx: &DrawContext) {
@ -604,10 +673,11 @@ impl Widget for TabMenu {
let tab_list_height = Self::TAB_NUM as f32 * Self::TAB_HEIGHT;
let separator_xy = Vec2::new(Self::TAB_WIDTH, -tab_list_height);
let separator_size = Vec2::new(Self::SEPARATOR_WIDTH, tab_list_height);
let body_width = Self::BOX_GRID_WIDTH as f32 * (Self::BOX_SIZE + Self::BOX_PADDING)
+ Self::BOX_MARGIN * 2.0;
let body_height = tab_list_height - Self::BOX_MARGIN * 2.0;
let head_width = Self::TAB_WIDTH + Self::SEPARATOR_WIDTH + body_width;
let head_width = Self::TAB_WIDTH
+ Self::SEPARATOR_WIDTH
+ Self::CONTENT_WIDTH
+ self.scroll_bar.inner.style.body_width
+ self.scroll_bar.inner.style.margin.x * 2.0;
let head_inner_xy = Vec2::ZERO;
let head_inner_size = Vec2::new(head_width, Self::HEAD_HEIGHT - Self::HEAD_RADIUS);
let head_edge_xy = Vec2::new(Self::HEAD_RADIUS, Self::HEAD_HEIGHT - Self::HEAD_RADIUS);
@ -629,27 +699,14 @@ impl Widget for TabMenu {
ctx.draw_quarter_circle(Corner::TopLeft, head_tl_xy, Self::HEAD_RADIUS, head_color);
ctx.draw_quarter_circle(Corner::TopRight, head_tr_xy, Self::HEAD_RADIUS, head_color);
// placeholder inventory item boxes
let box_grid_stride = Self::BOX_SIZE + Self::BOX_PADDING;
let box_grid_height = (body_height / box_grid_stride).floor() as usize;
let box_rect_size = Vec2::new(Self::BOX_SIZE, Self::BOX_SIZE);
let box_grid_xy = Vec2::new(
Self::TAB_WIDTH + Self::SEPARATOR_WIDTH + Self::BOX_MARGIN,
-Self::BOX_MARGIN - Self::BOX_SIZE,
);
let box_radius = 0.005;
for x in 0..Self::BOX_GRID_WIDTH {
for y in 0..box_grid_height {
let box_rect_xy = Vec2::new(x as f32, -(y as f32)) * box_grid_stride + box_grid_xy;
ctx.draw_rounded_rect(box_rect_xy, box_rect_size, box_radius, head_color);
}
}
self.scroll_bar.draw(ctx);
}
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
for tab in self.tabs.iter_mut() {
tab.on_cursor_event(kind, at);
}
self.scroll_bar.on_cursor_event(kind, at);
}
}