diff --git a/src/lib.rs b/src/lib.rs index 41cb7b4..77ba22c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,7 @@ pub struct Color { pub a: f32, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum CursorEventKind { Hover, Select, diff --git a/src/widgets.rs b/src/widgets.rs index 6b72ea5..5c43ab3 100644 --- a/src/widgets.rs +++ b/src/widgets.rs @@ -90,6 +90,57 @@ impl Widget for RoundButton { } } +pub struct RectButton { + pub pos: Vec2, + pub size: Vec2, + pub was_clicked: bool, + pub color: Color, +} + +impl Button for RectButton { + fn was_clicked(&self) -> bool { + self.was_clicked + } +} + +impl RectButton { + pub fn new(pos: Vec2, size: Vec2) -> Self { + Self { + pos, + size, + was_clicked: true, + color: Color { + r: 1.0, + g: 1.0, + b: 1.0, + a: 0.2, + }, + } + } +} + +impl Widget for RectButton { + fn update(&mut self, dt: f32) { + self.was_clicked = false; + } + + fn draw(&mut self, ctx: &DrawContext) { + ctx.draw_rect(self.pos, self.size, self.color); + } + + fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) { + let local = at - self.pos; + if kind == CursorEventKind::Deselect + && local.x > 0.0 + && local.y > 0.0 + && local.x < self.size.x + && local.y < self.size.y + { + self.was_clicked = true; + } + } +} + #[derive(Eq, PartialEq)] pub enum ScrollMenuState { Opening, @@ -412,29 +463,47 @@ impl Widget for MainMenu { } } -pub struct Inventory; +pub struct Inventory { + tabs: Vec, +} impl Inventory { + const HEAD_RADIUS: f32 = 0.025; + const HEAD_HEIGHT: f32 = 0.03; + const TAB_WIDTH: f32 = 0.04; + const TAB_HEIGHT: f32 = 0.06; + const TAB_NUM: usize = 6; + const SEPARATOR_WIDTH: f32 = 0.015; + const BOX_SIZE: f32 = 0.025; + const BOX_MARGIN: f32 = 0.01; + const BOX_PADDING: f32 = 0.005; + const BOX_GRID_WIDTH: usize = 12; + pub fn new() -> Self { - Self + let tab_size = Vec2::new(Self::TAB_WIDTH, Self::TAB_HEIGHT); + + let mut tabs = Vec::new(); + for i in 0..Self::TAB_NUM { + let y = (i + 1) as f32 * Self::TAB_HEIGHT; + let pos = Vec2::new(0.0, -y); + tabs.push(RectButton::new(pos, tab_size)); + } + + Self { tabs } } } impl Widget for Inventory { - fn update(&mut self, dt: f32) {} + fn update(&mut self, dt: f32) { + for tab in self.tabs.iter_mut() { + tab.update(dt); + } + } fn draw(&mut self, ctx: &DrawContext) { - // style constants - let head_radius = 0.025; - let head_height = 0.03; - let tab_width = 0.04; - let tab_height = 0.06; - let tab_num = 6; - let separator_width = 0.015; - let box_size = 0.025; - let box_margin = 0.01; - let box_padding = 0.005; - let box_grid_width = 12; + for tab in self.tabs.iter_mut() { + tab.draw(ctx); + } let head_color = Color { r: 1.0, @@ -444,16 +513,20 @@ impl Widget for Inventory { }; // alignment variables - let tab_list_height = tab_num as f32 * tab_height; - let separator_xy = Vec2::new(tab_width, separator_width - tab_list_height); - let separator_size = Vec2::new(separator_width, tab_list_height - separator_width); - let body_width = box_grid_width as f32 * (box_size + box_padding) + box_margin * 2.0; - let body_height = tab_list_height - box_margin * 2.0; - let head_width = tab_width + separator_width + body_width; + let tab_list_height = Self::TAB_NUM as f32 * Self::TAB_HEIGHT; + let separator_xy = Vec2::new(Self::TAB_WIDTH, Self::SEPARATOR_WIDTH - tab_list_height); + let separator_size = Vec2::new( + Self::SEPARATOR_WIDTH, + tab_list_height - Self::SEPARATOR_WIDTH, + ); + 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_inner_xy = Vec2::ZERO; - let head_inner_size = Vec2::new(head_width, head_height - head_radius); - let head_edge_xy = Vec2::new(head_radius, head_height - head_radius); - let head_edge_size = Vec2::new(head_width - head_radius * 2.0, head_radius); + 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); + let head_edge_size = Vec2::new(head_width - Self::HEAD_RADIUS * 2.0, Self::HEAD_RADIUS); let head_tl_xy = head_edge_xy; let head_tr_xy = head_tl_xy + Vec2::new(head_edge_size.x, 0.0); @@ -462,26 +535,26 @@ impl Widget for Inventory { ctx.draw_quarter_circle( Corner::BottomRight, separator_xy, - separator_width, + Self::SEPARATOR_WIDTH, head_color, ); ctx.draw_rect(head_inner_xy, head_inner_size, head_color); ctx.draw_rect(head_edge_xy, head_edge_size, head_color); - ctx.draw_quarter_circle(Corner::TopLeft, head_tl_xy, head_radius, head_color); - ctx.draw_quarter_circle(Corner::TopRight, head_tr_xy, head_radius, head_color); + 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 = box_size + box_padding; + 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(box_size, box_size); + let box_rect_size = Vec2::new(Self::BOX_SIZE, Self::BOX_SIZE); let box_grid_xy = Vec2::new( - tab_width + separator_width + box_margin, - -box_margin - box_size, + Self::TAB_WIDTH + Self::SEPARATOR_WIDTH + Self::BOX_MARGIN, + -Self::BOX_MARGIN - Self::BOX_SIZE, ); let box_radius = 0.005; - for x in 0..box_grid_width { + 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); @@ -489,5 +562,9 @@ impl Widget for Inventory { } } - fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {} + fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) { + for tab in self.tabs.iter_mut() { + tab.on_cursor_event(kind, at); + } + } }