vn-settings 0.4.0

Various settings intended to simulate visual novels
Documentation
use super::{Resettable, Settings};

use simple_color::Color;

#[derive(Clone, Debug)]
pub struct BoxColors<T> {
    pub text_line: T,
    pub text_fill: T,
    pub name_line: T,
    pub name_fill: T,
}

impl<T: From<Color>> BoxColors<T> {
    pub fn common() -> Self {
        Self {
            text_line: Color::WHITE.into(),
            text_fill: Color::BLACK.into(),
            name_line: Color::WHITE.into(),
            name_fill: Color::BLACK.into(),
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum BoxColorParameter {
    TextLine,
    TextFill,
    NameLine,
    NameFill,
}

impl<T> Settings<BoxColorParameter> for BoxColors<T> {
    type Value = T;

    fn get_mut(&mut self, parameter: &BoxColorParameter) -> &mut T {
        use BoxColorParameter::*;
        match parameter {
            TextLine => &mut self.text_line,
            TextFill => &mut self.text_fill,
            NameLine => &mut self.name_line,
            NameFill => &mut self.name_fill,
        }
    }
}

impl<T: Resettable> Resettable for BoxColors<T> {
    fn reset(&mut self) {
        self.text_line.reset();
        self.text_fill.reset();
        self.name_line.reset();
        self.name_fill.reset();
    }

    fn reset_aspects(&mut self) {
        self.text_line.reset_aspects();
        self.text_fill.reset_aspects();
        self.name_line.reset_aspects();
        self.name_fill.reset_aspects();
    }
}

#[derive(Clone, Debug)]
pub struct SelectableBoxColors<T> {
    pub default: BoxColors<T>,
    pub selected: BoxColors<T>,
}

impl<T: From<Color>> SelectableBoxColors<T> {
    pub fn common() -> Self {
        Self {
            default: BoxColors::common(),
            selected: BoxColors {
                text_fill: Color::gray(64).into(),
                ..BoxColors::common()
            },
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SelectableBoxColorParameter {
    pub selected: bool,
    pub parameter: BoxColorParameter,
}

impl<T> Settings<SelectableBoxColorParameter> for SelectableBoxColors<T> {
    type Value = T;

    fn get_mut(&mut self, parameter: &SelectableBoxColorParameter) -> &mut T {
        if parameter.selected {
            &mut self.selected
        } else {
            &mut self.default
        }
        .get_mut(&parameter.parameter)
    }
}

impl<T: Resettable> Resettable for SelectableBoxColors<T> {
    fn reset(&mut self) {
        self.default.reset();
        self.selected.reset();
    }

    fn reset_aspects(&mut self) {
        self.default.reset_aspects();
        self.selected.reset_aspects();
    }
}

#[derive(Clone)]
pub struct ColorSettings<T> {
    pub background: T,
    pub foreground: T,
    pub dialog_box: BoxColors<T>,
    pub select_box: SelectableBoxColors<T>,
    pub revert_box: SelectableBoxColors<T>,
}

impl<T: From<Color>> ColorSettings<T> {
    pub fn common() -> Self {
        Self {
            background: Color::BLACK.into(),
            foreground: Color::BLACK.a(0).into(),
            dialog_box: BoxColors::common(),
            select_box: SelectableBoxColors::common(),
            revert_box: SelectableBoxColors::common(),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ColorParameter {
    Background,
    Foreground,
    Dialog(BoxColorParameter),
    Choice(SelectableBoxColorParameter),
    Revert(SelectableBoxColorParameter),
}

impl<T> Settings<ColorParameter> for ColorSettings<T> {
    type Value = T;

    fn get_mut(&mut self, parameter: &ColorParameter) -> &mut T {
        use ColorParameter::*;
        match parameter {
            Background => &mut self.background,
            Foreground => &mut self.foreground,
            Dialog(parameter) => self.dialog_box.get_mut(parameter),
            Choice(parameter) => self.select_box.get_mut(parameter),
            Revert(parameter) => self.revert_box.get_mut(parameter),
        }
    }
}

impl<T: Resettable> Resettable for ColorSettings<T> {
    fn reset(&mut self) {
        self.background.reset();
        self.foreground.reset();
        self.dialog_box.reset();
        self.select_box.reset();
        self.revert_box.reset();
    }

    fn reset_aspects(&mut self) {
        self.background.reset_aspects();
        self.foreground.reset_aspects();
        self.dialog_box.reset_aspects();
        self.select_box.reset_aspects();
        self.revert_box.reset_aspects();
    }
}