Add SAO UI Palette widget

This commit is contained in:
mars 2022-11-19 15:11:09 -07:00
parent 59c34d6aca
commit d7323323f8
4 changed files with 149 additions and 2 deletions

View File

@ -7,6 +7,7 @@ use crate::{DrawContext, Rect};
use button::{RectButton, RoundButton, RoundButtonStyle};
use dialog::{Dialog, DialogInfo, DialogResponse, DialogStyle};
use menu::{SlotMenu, SlotMenuEvent, TabMenu};
use palette::Palette;
use shell::{Offset, OffsetAlignment, Popup, Reveal};
use text::LabelText;
@ -47,6 +48,7 @@ pub struct MainMenu {
pub menu: Offset<SlotMenu<RoundButton>>,
pub player_info: Reveal<Offset<PlayerInfo>>,
pub inventory: Reveal<Offset<TabMenu>>,
pub palette: Reveal<Offset<Palette>>,
pub settings: Reveal<Offset<SettingsMenu>>,
}
@ -102,6 +104,15 @@ impl Default for MainMenu {
let inventory = Offset::new(inventory, submenu_spacing_right);
let inventory = Reveal::new(inventory, reveal_slide, reveal_duration);
let palette = Palette::new(Default::default());
let palette = Offset::new_aligned(
palette,
submenu_spacing_left,
OffsetAlignment::End,
OffsetAlignment::Center,
);
let palette = Reveal::new(palette, -reveal_slide, reveal_duration);
let settings = SettingsMenu::new();
let settings = Offset::new(settings, submenu_spacing_right);
let settings = Reveal::new(settings, reveal_slide, reveal_duration);
@ -110,6 +121,7 @@ impl Default for MainMenu {
menu,
player_info,
inventory,
palette,
settings,
}
}
@ -120,6 +132,7 @@ impl Container for MainMenu {
f(&mut self.menu);
f(&mut self.player_info);
f(&mut self.inventory);
f(&mut self.palette);
f(&mut self.settings);
}
@ -139,8 +152,14 @@ impl Container for MainMenu {
self.player_info.hide();
self.inventory.hide();
}
SlotMenuEvent::SubmenuOpen(4) => self.settings.show(),
SlotMenuEvent::SubmenuClose(4) => self.settings.hide(),
SlotMenuEvent::SubmenuOpen(4) => {
self.palette.show();
self.settings.show();
}
SlotMenuEvent::SubmenuClose(4) => {
self.palette.hide();
self.settings.hide();
}
_ => {}
};
}

View File

@ -18,6 +18,27 @@ pub struct Palette {
pub white: Color,
}
impl Palette {
pub fn make_label_pairs(&self) -> Vec<(&'static str, Color)> {
vec![
("Base", self.base),
("Base Hover", self.base_hover),
("Base Active", self.base_active),
("Surface", self.surface),
("Overlay", self.overlay),
("Text", self.text),
("Black", self.black),
("Red", self.red),
("Green", self.green),
("Yellow", self.yellow),
("Blue", self.blue),
("Magenta", self.magenta),
("Cyan", self.cyan),
("White", self.white),
]
}
}
/// The common base color alpha shared between all themes.
pub const BASE_ALPHA: u8 = 0xc0;

View File

@ -8,6 +8,7 @@ pub mod button;
pub mod dialog;
pub mod flex;
pub mod menu;
pub mod palette;
pub mod scroll;
pub mod shell;
pub mod text;

View File

@ -0,0 +1,106 @@
use super::prelude::*;
use shell::Offset;
use text::{HorizontalAlignment, Label, LabelText};
pub struct PaletteStyle {
pub bg: Color,
pub text: Color,
pub rounding: f32,
pub text_size: f32,
pub line_spacing: f32,
pub color_radius: f32,
pub margin: Rect,
}
impl Default for PaletteStyle {
fn default() -> Self {
Self {
bg: THEME.palette.surface,
text: THEME.palette.text,
rounding: THEME.metrics.surface_rounding,
text_size: 5.0,
line_spacing: 8.0,
color_radius: 3.0,
margin: Rect::from_xy_size(Vec2::splat(10.0), Vec2::ZERO),
}
}
}
/// A widget that displays all the colors in the global palette.
pub struct Palette {
body: Rect,
style: PaletteStyle,
labels: Vec<Offset<Label>>,
colors: Vec<(Vec2, Color)>,
}
impl Palette {
pub fn new(style: PaletteStyle) -> Self {
let width = 70.0;
let pairs = THEME.palette.make_label_pairs();
let label_font = Font::new(crate::CONTENT_FONT);
let mut label_cursor = Vec2::new(0.0, style.line_spacing) + style.margin.tl;
let mut color_cursor = Vec2::new(
width - style.margin.br.x,
style.line_spacing / 2.0 + style.margin.tl.y,
);
let mut labels = Vec::new();
let mut colors = Vec::new();
for (text, color) in pairs {
let text = LabelText {
font: label_font,
text: text.to_string(),
};
let label = Label::new(
text,
HorizontalAlignment::Left,
style.text_size,
style.text,
0.0,
0.0,
0.0,
);
let label = Offset::new(label, label_cursor);
labels.push(label);
colors.push((color_cursor, color));
label_cursor.y += style.line_spacing;
color_cursor.y += style.line_spacing;
}
let height = label_cursor.y + style.margin.br.y;
Self {
body: Rect::from_xy_size(Vec2::ZERO, Vec2::new(width, height)),
style,
labels,
colors,
}
}
}
impl RectBounds for Palette {
fn get_bounds(&self) -> Rect {
self.body
}
}
impl Widget for Palette {
fn draw(&mut self, ctx: &DrawContext) {
ctx.draw_rounded_rect(self.body, self.style.rounding, self.style.bg);
for label in self.labels.iter_mut() {
label.draw(ctx);
}
for (center, color) in self.colors.iter() {
ctx.draw_circle(*center, self.style.color_radius, *color);
}
}
}