Reveal + submenu events
This commit is contained in:
parent
977ce92599
commit
97b993e470
148
src/widgets.rs
148
src/widgets.rs
|
@ -94,10 +94,18 @@ impl Widget for RoundButton {
|
|||
pub enum ScrollMenuState {
|
||||
Opening,
|
||||
Idle,
|
||||
Scrolling,
|
||||
Closing,
|
||||
Closed,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum ScrollMenuEvent {
|
||||
None,
|
||||
SubmenuOpen(usize),
|
||||
SubmenuClose(usize),
|
||||
}
|
||||
|
||||
pub struct ScrollMenuButton<T> {
|
||||
pub widget: T,
|
||||
pub slide_anim: Animation<EaseOut>,
|
||||
|
@ -109,7 +117,9 @@ pub struct ScrollMenu<T> {
|
|||
pub spacing: f32,
|
||||
pub scroll_anim: Animation<EaseInOutQuint>,
|
||||
pub state: ScrollMenuState,
|
||||
pub selected: usize,
|
||||
pub was_clicked: Option<usize>,
|
||||
pub event: ScrollMenuEvent,
|
||||
}
|
||||
|
||||
impl<T> ScrollMenu<T> {
|
||||
|
@ -146,22 +156,32 @@ impl<T> ScrollMenu<T> {
|
|||
Self {
|
||||
buttons,
|
||||
spacing,
|
||||
scroll_anim: Animation::new(EaseInOutQuint, 0.2, 0.0, 0.0),
|
||||
scroll_anim: Animation::new(EaseInOutQuint, 0.25, 0.0, 0.0),
|
||||
state: ScrollMenuState::Opening,
|
||||
selected: 0,
|
||||
was_clicked: None,
|
||||
event: ScrollMenuEvent::None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn was_clicked(&self) -> Option<usize> {
|
||||
pub fn get_event(&self) -> ScrollMenuEvent {
|
||||
self.event
|
||||
}
|
||||
|
||||
pub fn get_was_clicked(&self) -> Option<usize> {
|
||||
self.was_clicked
|
||||
}
|
||||
|
||||
pub fn scroll_to(&mut self, button_id: usize) {
|
||||
pub fn select(&mut self, button_id: usize) {
|
||||
self.scroll_anim.ease_to(button_id as f32);
|
||||
self.state = ScrollMenuState::Scrolling;
|
||||
self.event = ScrollMenuEvent::SubmenuClose(self.selected);
|
||||
self.selected = button_id;
|
||||
}
|
||||
|
||||
pub fn close(&mut self) {
|
||||
self.state = ScrollMenuState::Closing;
|
||||
self.event = ScrollMenuEvent::SubmenuClose(self.selected);
|
||||
|
||||
for button in self.buttons.iter_mut() {
|
||||
button.slide_anim.ease_out();
|
||||
|
@ -194,19 +214,27 @@ impl<T> ScrollMenu<T> {
|
|||
|
||||
impl<T: Widget + Button> Widget for ScrollMenu<T> {
|
||||
fn update(&mut self, dt: f32) {
|
||||
self.event = ScrollMenuEvent::None;
|
||||
self.was_clicked = None;
|
||||
|
||||
match self.state {
|
||||
ScrollMenuState::Idle => {
|
||||
self.scroll_anim.update(dt);
|
||||
|
||||
self.for_buttons(|button, _i, _y| {
|
||||
button.widget.update(dt);
|
||||
});
|
||||
}
|
||||
ScrollMenuState::Opening => {
|
||||
if self.animate_buttons(dt) {
|
||||
self.state = ScrollMenuState::Idle;
|
||||
self.event = ScrollMenuEvent::SubmenuOpen(self.selected);
|
||||
}
|
||||
}
|
||||
ScrollMenuState::Idle => {}
|
||||
ScrollMenuState::Scrolling => {
|
||||
self.for_buttons(|button, _i, _y| {
|
||||
button.widget.update(dt);
|
||||
});
|
||||
|
||||
self.scroll_anim.update(dt);
|
||||
|
||||
if !self.scroll_anim.is_active() {
|
||||
self.state = ScrollMenuState::Idle;
|
||||
self.event = ScrollMenuEvent::SubmenuOpen(self.selected);
|
||||
}
|
||||
}
|
||||
ScrollMenuState::Closing => {
|
||||
|
@ -214,8 +242,14 @@ impl<T: Widget + Button> Widget for ScrollMenu<T> {
|
|||
self.state = ScrollMenuState::Closed;
|
||||
}
|
||||
}
|
||||
ScrollMenuState::Closed => {}
|
||||
ScrollMenuState::Closed => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self.for_buttons(|button, _i, _y| {
|
||||
button.widget.update(dt);
|
||||
});
|
||||
}
|
||||
|
||||
fn draw(&mut self, ctx: &DrawContext) {
|
||||
|
@ -253,13 +287,81 @@ impl<T: Widget + Button> Widget for ScrollMenu<T> {
|
|||
}
|
||||
});
|
||||
|
||||
self.was_clicked = was_clicked;
|
||||
if let Some(clicked) = was_clicked {
|
||||
if clicked != self.selected {
|
||||
self.was_clicked = Some(clicked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Reveal<T> {
|
||||
inner: T,
|
||||
slide_anim: Animation<EaseIn>,
|
||||
opacity_anim: Animation<EaseOut>,
|
||||
state: bool,
|
||||
}
|
||||
|
||||
impl<T: Widget> Reveal<T> {
|
||||
pub fn new(inner: T, slide: f32, duration: f32) -> Self {
|
||||
Self {
|
||||
inner,
|
||||
slide_anim: Animation::new(EaseIn, duration, slide, 0.0),
|
||||
opacity_anim: Animation::new(EaseOut, duration, 0.0, 1.0),
|
||||
state: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_offset(&self) -> Vec2 {
|
||||
Vec2::new(self.slide_anim.get(), 0.0)
|
||||
}
|
||||
|
||||
pub fn show(&mut self) {
|
||||
self.state = true;
|
||||
self.slide_anim.ease_in();
|
||||
self.opacity_anim.ease_in();
|
||||
}
|
||||
|
||||
pub fn hide(&mut self) {
|
||||
self.state = false;
|
||||
self.slide_anim.ease_out();
|
||||
self.opacity_anim.ease_out();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Widget> Widget for Reveal<T> {
|
||||
fn update(&mut self, dt: f32) {
|
||||
self.slide_anim.update(dt);
|
||||
self.opacity_anim.update(dt);
|
||||
self.inner.update(dt);
|
||||
}
|
||||
|
||||
fn draw(&mut self, ctx: &DrawContext) {
|
||||
let ctx = ctx.with_offset(Vec2::new(self.slide_anim.get(), 0.0));
|
||||
let ctx = if self.opacity_anim.is_active() {
|
||||
ctx.with_opacity(self.opacity_anim.get())
|
||||
} else if self.state {
|
||||
ctx
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.inner.draw(&ctx);
|
||||
}
|
||||
|
||||
fn on_cursor_event(&mut self, kind: CursorEventKind, mut at: Vec2) {
|
||||
if !self.state || self.opacity_anim.is_active() {
|
||||
return;
|
||||
}
|
||||
|
||||
at -= Vec2::new(self.slide_anim.get(), 0.0);
|
||||
self.inner.on_cursor_event(kind, at);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MainMenu {
|
||||
pub menu: ScrollMenu<RoundButton>,
|
||||
pub inventory: Inventory,
|
||||
pub inventory: Reveal<Inventory>,
|
||||
}
|
||||
|
||||
impl Default for MainMenu {
|
||||
|
@ -270,28 +372,38 @@ impl Default for MainMenu {
|
|||
buttons.push(button);
|
||||
}
|
||||
|
||||
let inventory = Inventory::new();
|
||||
let inventory = Reveal::new(inventory, -0.02, 0.1);
|
||||
|
||||
Self {
|
||||
menu: ScrollMenu::new(buttons, 0.1),
|
||||
inventory: Inventory::new(),
|
||||
inventory,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for MainMenu {
|
||||
fn update(&mut self, dt: f32) {
|
||||
match self.menu.was_clicked() {
|
||||
match self.menu.get_was_clicked() {
|
||||
None => {}
|
||||
Some(4) => self.menu.close(),
|
||||
Some(button) => self.menu.scroll_to(button),
|
||||
Some(button) => self.menu.select(button),
|
||||
};
|
||||
|
||||
match self.menu.get_event() {
|
||||
ScrollMenuEvent::SubmenuOpen(0) => self.inventory.show(),
|
||||
ScrollMenuEvent::SubmenuClose(0) => self.inventory.hide(),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
self.menu.update(dt);
|
||||
self.inventory.update(dt);
|
||||
}
|
||||
|
||||
fn draw(&mut self, ctx: &DrawContext) {
|
||||
self.menu.draw(&ctx);
|
||||
|
||||
let inventory_ctx = ctx.with_offset(Vec2::new(0.1, 0.0));
|
||||
let inventory_ctx = ctx.with_offset(Vec2::new(0.05, 0.0));
|
||||
self.inventory.draw(&inventory_ctx);
|
||||
}
|
||||
|
||||
|
@ -335,7 +447,7 @@ impl Widget for Inventory {
|
|||
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;
|
||||
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 head_inner_xy = Vec2::ZERO;
|
||||
|
|
Loading…
Reference in New Issue