Option<T> impls Widget + RectButtonStyle

This commit is contained in:
marceline-cramer 2022-07-26 23:09:52 -06:00
parent 529bcad32c
commit 6c44feab62
3 changed files with 70 additions and 42 deletions

View File

@ -78,9 +78,7 @@ impl Widget for RoundButton {
ctx.draw_circle(self.pos, self.radius, color); ctx.draw_circle(self.pos, self.radius, color);
ctx.draw_ring(self.pos, self.radius + spacing, self.thickness, color); ctx.draw_ring(self.pos, self.radius + spacing, self.thickness, color);
if let Some(label) = self.label.as_mut() { self.label.draw(ctx);
label.draw(ctx);
}
} }
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) { fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
@ -103,10 +101,30 @@ impl Widget for RoundButton {
} }
} }
pub struct RectButton { #[derive(Clone, Debug)]
pub rect: Rect, pub struct RectButtonStyle {
pub rounded_corners: CornerFlags, pub rounded_corners: CornerFlags,
pub radius: f32, pub radius: f32,
pub inactive_color: Color,
pub hover_color: Color,
pub selected_color: Color,
}
impl Default for RectButtonStyle {
fn default() -> Self {
Self {
rounded_corners: CornerFlags::empty(),
radius: 0.0,
inactive_color: Color::new(1., 1., 1., 0.2),
hover_color: Color::new(1., 1., 1., 0.8),
selected_color: Color::new(1., 1., 0., 1.),
}
}
}
pub struct RectButton {
pub style: RectButtonStyle,
pub rect: Rect,
pub was_clicked: bool, pub was_clicked: bool,
pub is_selected: bool, pub is_selected: bool,
pub is_hovering: bool, pub is_hovering: bool,
@ -121,16 +139,7 @@ impl Button for RectButton {
} }
impl RectButton { impl RectButton {
pub const INACTIVE_COLOR: Color = Color::new(1., 1., 1., 0.2); pub fn new(style: RectButtonStyle, label: Option<LabelText>, rect: Rect) -> Self {
pub const HOVER_COLOR: Color = Color::new(1., 1., 1., 0.8);
pub const SELECTED_COLOR: Color = Color::new(1., 1., 0., 1.);
pub fn new(
label: Option<LabelText>,
rect: Rect,
rounded_corners: CornerFlags,
radius: f32,
) -> Self {
let label_height_scale = 0.7; let label_height_scale = 0.7;
let label_baseline_scale = 0.25; let label_baseline_scale = 0.25;
@ -149,19 +158,16 @@ impl RectButton {
) )
}); });
let color_anim =
Animation::new(EaseInQuad, 0.05, style.inactive_color, style.inactive_color);
Self { Self {
style,
rect, rect,
rounded_corners,
radius,
was_clicked: false, was_clicked: false,
is_selected: false, is_selected: false,
is_hovering: false, is_hovering: false,
color_anim: Animation::new( color_anim,
EaseInQuad,
0.05,
Self::INACTIVE_COLOR,
Self::INACTIVE_COLOR,
),
label, label,
} }
} }
@ -175,31 +181,30 @@ impl Widget for RectButton {
fn draw(&mut self, ctx: &DrawContext) { fn draw(&mut self, ctx: &DrawContext) {
ctx.draw_partially_rounded_rect( ctx.draw_partially_rounded_rect(
self.rounded_corners, self.style.rounded_corners,
self.rect, self.rect,
self.radius, self.style.radius,
self.color_anim.get(), self.color_anim.get(),
); );
if let Some(label) = self.label.as_mut() { self.label.draw(ctx);
label.draw(ctx);
}
} }
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) { fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
let is_on = self.rect.contains_point(at); let is_on = self.rect.contains_point(at);
let style = &self.style;
match kind { match kind {
CursorEventKind::Hover | CursorEventKind::Drag => { CursorEventKind::Hover | CursorEventKind::Drag => {
if is_on { if is_on {
if !self.is_hovering && !self.is_selected { if !self.is_hovering && !self.is_selected {
self.color_anim.ease_to(Self::HOVER_COLOR); self.color_anim.ease_to(style.hover_color);
} }
self.is_hovering = true; self.is_hovering = true;
} else { } else {
if self.is_hovering && !self.is_selected { if self.is_hovering && !self.is_selected {
self.color_anim.ease_to(Self::INACTIVE_COLOR); self.color_anim.ease_to(style.inactive_color);
} }
self.is_hovering = false; self.is_hovering = false;
@ -208,7 +213,7 @@ impl Widget for RectButton {
CursorEventKind::Select => { CursorEventKind::Select => {
if is_on { if is_on {
self.is_selected = true; self.is_selected = true;
self.color_anim.ease_to(Self::SELECTED_COLOR); self.color_anim.ease_to(style.selected_color);
} }
} }
CursorEventKind::Deselect => { CursorEventKind::Deselect => {
@ -217,9 +222,9 @@ impl Widget for RectButton {
self.is_selected = false; self.is_selected = false;
if self.is_hovering { if self.is_hovering {
self.color_anim.ease_to(Self::HOVER_COLOR); self.color_anim.ease_to(style.hover_color);
} else { } else {
self.color_anim.ease_to(Self::INACTIVE_COLOR); self.color_anim.ease_to(style.inactive_color);
} }
} }
} }

View File

@ -229,16 +229,16 @@ impl TabMenu {
for i in 0..Self::TAB_NUM { for i in 0..Self::TAB_NUM {
let y = (i + 1) as f32 * Self::TAB_HEIGHT; let y = (i + 1) as f32 * Self::TAB_HEIGHT;
let pos = Vec2::new(0.0, -y); let pos = Vec2::new(0.0, -y);
let radius = Self::HEAD_RADIUS;
let corners = if i == Self::TAB_NUM - 1 { let mut style = RectButtonStyle::default();
CornerFlags::BOTTOM_LEFT style.radius = Self::HEAD_RADIUS;
} else {
CornerFlags::empty() if i == Self::TAB_NUM - 1 {
}; style.rounded_corners = CornerFlags::BOTTOM_LEFT;
}
let rect = Rect::from_xy_size(pos, tab_size); let rect = Rect::from_xy_size(pos, tab_size);
tabs.push(RectButton::new(None, rect, corners, radius)); tabs.push(RectButton::new(style, None, rect));
} }
let tab_list_height = Self::TAB_NUM as f32 * Self::TAB_HEIGHT; let tab_list_height = Self::TAB_NUM as f32 * Self::TAB_HEIGHT;

View File

@ -10,18 +10,39 @@ pub mod scroll;
pub mod shell; pub mod shell;
pub mod text; pub mod text;
use button::{Button, RectButton, RoundButton}; use button::{Button, RectButton, RectButtonStyle, RoundButton};
use menu::{SlotMenu, SlotMenuEvent, TabMenu}; use menu::{SlotMenu, SlotMenuEvent, TabMenu};
use scroll::{ScrollBar, ScrollView}; use scroll::{ScrollBar, ScrollView};
use shell::{Offset, Reveal}; use shell::{Offset, Reveal};
use text::{HorizontalAlignment, Label, LabelText}; use text::{HorizontalAlignment, Label, LabelText};
#[allow(unused)]
pub trait Widget { pub trait Widget {
fn update(&mut self, dt: f32) {} fn update(&mut self, dt: f32) {}
fn draw(&mut self, ctx: &DrawContext) {} fn draw(&mut self, ctx: &DrawContext) {}
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {} fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {}
} }
impl<T: Widget> Widget for Option<T> {
fn update(&mut self, dt: f32) {
if let Some(inner) = self.as_mut() {
inner.update(dt);
}
}
fn draw(&mut self, ctx: &DrawContext) {
if let Some(inner) = self.as_mut() {
inner.draw(ctx);
}
}
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
if let Some(inner) = self.as_mut() {
inner.on_cursor_event(kind, at);
}
}
}
pub trait FixedWidth { pub trait FixedWidth {
fn get_width(&self) -> f32; fn get_width(&self) -> f32;
} }
@ -164,7 +185,9 @@ impl SettingsMenu {
text: text.to_string(), text: text.to_string(),
}; };
let button = RectButton::new(Some(text), button_rect, CornerFlags::empty(), 0.0); let style = Default::default();
let button = RectButton::new(style, Some(text), button_rect);
buttons.push(button); buttons.push(button);
} }