From d7323323f8b07a15bf6d291c54ba738b54b7f0d6 Mon Sep 17 00:00:00 2001 From: mars Date: Sat, 19 Nov 2022 15:11:09 -0700 Subject: [PATCH] Add SAO UI Palette widget --- scripts/sao-ui/src/main_menu.rs | 23 +++++- scripts/sao-ui/src/style.rs | 21 +++++ scripts/sao-ui/src/widgets/mod.rs | 1 + scripts/sao-ui/src/widgets/palette.rs | 106 ++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 scripts/sao-ui/src/widgets/palette.rs diff --git a/scripts/sao-ui/src/main_menu.rs b/scripts/sao-ui/src/main_menu.rs index 8ae2206..b921a46 100644 --- a/scripts/sao-ui/src/main_menu.rs +++ b/scripts/sao-ui/src/main_menu.rs @@ -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>, pub player_info: Reveal>, pub inventory: Reveal>, + pub palette: Reveal>, pub settings: Reveal>, } @@ -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(); + } _ => {} }; } diff --git a/scripts/sao-ui/src/style.rs b/scripts/sao-ui/src/style.rs index c56e702..afc002f 100644 --- a/scripts/sao-ui/src/style.rs +++ b/scripts/sao-ui/src/style.rs @@ -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; diff --git a/scripts/sao-ui/src/widgets/mod.rs b/scripts/sao-ui/src/widgets/mod.rs index fee8899..310bf1a 100644 --- a/scripts/sao-ui/src/widgets/mod.rs +++ b/scripts/sao-ui/src/widgets/mod.rs @@ -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; diff --git a/scripts/sao-ui/src/widgets/palette.rs b/scripts/sao-ui/src/widgets/palette.rs new file mode 100644 index 0000000..d045feb --- /dev/null +++ b/scripts/sao-ui/src/widgets/palette.rs @@ -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>, + 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); + } + } +}