WIP scroll bar
This commit is contained in:
parent
9f52ff584f
commit
87ec9f0f52
107
src/widgets.rs
107
src/widgets.rs
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue