2022-07-21 21:19:57 +00:00
|
|
|
use crate::anim::Animation;
|
|
|
|
use crate::{Color, CursorEventKind, Vec2};
|
2022-07-24 07:26:57 +00:00
|
|
|
use canary_script::draw::{CornerFlags, DrawContext, Rect};
|
2022-07-23 08:39:34 +00:00
|
|
|
use canary_script::{Font, TextLayout};
|
2022-07-21 21:19:57 +00:00
|
|
|
use keyframe::functions::*;
|
|
|
|
|
|
|
|
pub mod button;
|
|
|
|
pub mod menu;
|
|
|
|
pub mod scroll;
|
|
|
|
pub mod shell;
|
|
|
|
pub mod text;
|
|
|
|
|
|
|
|
use button::{Button, RectButton, RoundButton};
|
2022-07-24 07:26:57 +00:00
|
|
|
use menu::{SlotMenu, SlotMenuEvent, TabMenu};
|
2022-07-21 21:19:57 +00:00
|
|
|
use scroll::{ScrollBar, ScrollView};
|
|
|
|
use shell::{Offset, Reveal};
|
|
|
|
use text::{HorizontalAlignment, Label, LabelText};
|
|
|
|
|
|
|
|
pub trait Widget {
|
|
|
|
fn update(&mut self, dt: f32) {}
|
|
|
|
fn draw(&mut self, ctx: &DrawContext) {}
|
|
|
|
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait FixedWidth {
|
|
|
|
fn get_width(&self) -> f32;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct MainMenu {
|
|
|
|
pub menu: SlotMenu<RoundButton>,
|
|
|
|
pub inventory: Reveal<Offset<TabMenu>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MainMenu {
|
|
|
|
pub const SUBMENU_SPACING: f32 = 0.1;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for MainMenu {
|
|
|
|
fn default() -> Self {
|
|
|
|
let icon_font = Font::new("Iosevka Nerd Font");
|
|
|
|
let icons = ["", "", "", "", ""];
|
|
|
|
|
|
|
|
let mut buttons = Vec::new();
|
|
|
|
for icon in icons {
|
|
|
|
let text = LabelText {
|
|
|
|
font: icon_font,
|
|
|
|
text: icon.to_string(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let button = RoundButton::new(Some(text));
|
|
|
|
buttons.push(button);
|
|
|
|
}
|
|
|
|
|
|
|
|
let inventory = TabMenu::new();
|
|
|
|
let inventory = Offset::new(inventory, Vec2::new(Self::SUBMENU_SPACING, 0.0));
|
|
|
|
let inventory = Reveal::new(inventory, -0.02, 0.1);
|
|
|
|
|
|
|
|
Self {
|
|
|
|
menu: SlotMenu::new(buttons, 0.2),
|
|
|
|
inventory,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Widget for MainMenu {
|
|
|
|
fn update(&mut self, dt: f32) {
|
|
|
|
match self.menu.get_was_clicked() {
|
|
|
|
None => {}
|
|
|
|
Some(4) => self.menu.close(),
|
|
|
|
Some(button) => self.menu.select(button),
|
|
|
|
};
|
|
|
|
|
|
|
|
match self.menu.get_event() {
|
|
|
|
SlotMenuEvent::SubmenuOpen(0) => self.inventory.show(),
|
|
|
|
SlotMenuEvent::SubmenuClose(0) => self.inventory.hide(),
|
|
|
|
_ => {}
|
|
|
|
};
|
|
|
|
|
|
|
|
self.menu.update(dt);
|
|
|
|
self.inventory.update(dt);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw(&mut self, ctx: &DrawContext) {
|
|
|
|
self.menu.draw(&ctx);
|
|
|
|
self.inventory.draw(&ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
|
|
|
|
self.menu.on_cursor_event(kind, at);
|
|
|
|
self.inventory.on_cursor_event(kind, at);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Inventory {
|
|
|
|
width: f32,
|
|
|
|
height: f32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Inventory {
|
|
|
|
pub fn new(available_width: f32) -> (Self, f32) {
|
|
|
|
let height = 1.28;
|
|
|
|
|
|
|
|
(
|
|
|
|
Self {
|
|
|
|
width: available_width,
|
|
|
|
height,
|
|
|
|
},
|
|
|
|
height,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Widget for Inventory {
|
|
|
|
fn draw(&mut self, ctx: &DrawContext) {
|
|
|
|
let box_size = 0.06;
|
|
|
|
let box_margin = 0.02;
|
|
|
|
let box_stride = box_size + box_margin;
|
|
|
|
|
|
|
|
let grid_width = (self.width / box_stride).floor() as usize;
|
|
|
|
let grid_height = (self.height / box_stride).floor() as usize;
|
|
|
|
let grid_offset = Vec2::new(box_margin, box_margin) / 2.0;
|
|
|
|
|
|
|
|
for x in 0..grid_width {
|
|
|
|
for y in 0..grid_height {
|
|
|
|
let off = Vec2::new(x as f32, y as f32) * box_stride + grid_offset;
|
|
|
|
let rect = Rect::from_xy_size(off, Vec2::new(box_size, box_size));
|
|
|
|
let color = Color::MAGENTA;
|
|
|
|
ctx.draw_rect(rect, color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|