use core::ops::RangeInclusive;
use crate::abi::UiWidget;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Screen {
Menu,
Loading,
InGame,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Style {
#[default]
Body,
Secondary,
H1,
H2,
H3,
Warning,
Positive,
Negative,
}
impl Style {
pub(super) fn to_raw(self) -> u32 {
match self {
Self::Body => UiWidget::STYLE_BODY,
Self::Secondary => UiWidget::STYLE_SECONDARY,
Self::H1 => UiWidget::STYLE_H1,
Self::H2 => UiWidget::STYLE_H2,
Self::H3 => UiWidget::STYLE_H3,
Self::Warning => UiWidget::STYLE_WARNING,
Self::Positive => UiWidget::STYLE_POSITIVE,
Self::Negative => UiWidget::STYLE_NEGATIVE,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Sound {
Click,
Confirm,
Back,
Error,
}
impl Sound {
pub(super) fn to_raw(self) -> u32 {
match self {
Self::Click => UiWidget::SOUND_CLICK,
Self::Confirm => UiWidget::SOUND_CONFIRM,
Self::Back => UiWidget::SOUND_BACK,
Self::Error => UiWidget::SOUND_ERROR,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Label<'a> {
pub(super) text: &'a str,
pub(super) style: Style,
pub(super) flags: u32,
}
impl<'a> Label<'a> {
#[must_use]
pub const fn new(text: &'a str) -> Self {
Self {
text,
style: Style::Body,
flags: 0,
}
}
#[must_use]
pub const fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
#[must_use]
pub const fn wrap(mut self) -> Self {
self.flags |= UiWidget::WRAP;
self
}
#[must_use]
pub const fn center(mut self) -> Self {
self.flags |= UiWidget::CENTER;
self
}
}
impl<'a> From<&'a str> for Label<'a> {
fn from(text: &'a str) -> Self {
Self::new(text)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Button<'a> {
pub(super) text: &'a str,
pub(super) enabled: bool,
}
impl<'a> Button<'a> {
#[must_use]
pub const fn new(text: &'a str) -> Self {
Self {
text,
enabled: true,
}
}
#[must_use]
pub const fn enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}
}
impl<'a> From<&'a str> for Button<'a> {
fn from(text: &'a str) -> Self {
Self::new(text)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Toggle<'a> {
pub(super) label: &'a str,
pub(super) read_only: bool,
}
impl<'a> Toggle<'a> {
#[must_use]
pub const fn new(label: &'a str) -> Self {
Self {
label,
read_only: false,
}
}
#[must_use]
pub const fn read_only(mut self, read_only: bool) -> Self {
self.read_only = read_only;
self
}
}
impl<'a> From<&'a str> for Toggle<'a> {
fn from(label: &'a str) -> Self {
Self::new(label)
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Slider<'a> {
pub(super) label: &'a str,
pub(super) range: RangeInclusive<f32>,
pub(super) steps: u32,
pub(super) read_only: bool,
}
impl<'a> Slider<'a> {
#[must_use]
pub const fn new(label: &'a str, range: RangeInclusive<f32>) -> Self {
Self {
label,
range,
steps: 0,
read_only: false,
}
}
#[must_use]
pub const fn steps(mut self, steps: u32) -> Self {
self.steps = steps;
self
}
#[must_use]
pub const fn read_only(mut self, read_only: bool) -> Self {
self.read_only = read_only;
self
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Dropdown<'a> {
pub(super) label: &'a str,
pub(super) options: &'a [&'a str],
pub(super) read_only: bool,
}
impl<'a> Dropdown<'a> {
#[must_use]
pub const fn new(label: &'a str, options: &'a [&'a str]) -> Self {
Self {
label,
options,
read_only: false,
}
}
#[must_use]
pub const fn read_only(mut self, read_only: bool) -> Self {
self.read_only = read_only;
self
}
}
pub(super) const fn read_only_flag(read_only: bool) -> u32 {
if read_only { UiWidget::READ_ONLY } else { 0 }
}