use crate::tokens::DESIGN_TOKENS;
use egui::Color32;
pub struct IndicatorPalette {
pub primary: Vec<Color32>,
pub bullish: Vec<Color32>,
pub bearish: Vec<Color32>,
pub neutral: Vec<Color32>,
pub accent: Vec<Color32>,
}
impl Default for IndicatorPalette {
fn default() -> Self {
Self {
primary: vec![
DESIGN_TOKENS.semantic.extended.info, DESIGN_TOKENS.semantic.extended.success, DESIGN_TOKENS.semantic.extended.warning, DESIGN_TOKENS.semantic.extended.purple, DESIGN_TOKENS.semantic.extended.error, DESIGN_TOKENS.semantic.extended.cyan, DESIGN_TOKENS.semantic.extended.caution, DESIGN_TOKENS.semantic.extended.brown, ],
bullish: vec![
DESIGN_TOKENS.semantic.extended.success, DESIGN_TOKENS.semantic.extended.bullish, DESIGN_TOKENS.semantic.extended.success_light, DESIGN_TOKENS.semantic.extended.bullish, ],
bearish: vec![
DESIGN_TOKENS.semantic.extended.error, DESIGN_TOKENS.semantic.extended.bearish, DESIGN_TOKENS.semantic.extended.bearish, DESIGN_TOKENS.semantic.extended.error, ],
neutral: vec![
DESIGN_TOKENS.semantic.extended.disabled, DESIGN_TOKENS.semantic.extended.text_muted, DESIGN_TOKENS.semantic.extended.chart_text_secondary, DESIGN_TOKENS.semantic.extended.bg_active, ],
accent: vec![
DESIGN_TOKENS.semantic.extended.favorite_gold, DESIGN_TOKENS.semantic.extended.pink, DESIGN_TOKENS.semantic.extended.deep_purple, DESIGN_TOKENS.semantic.extended.bullish, DESIGN_TOKENS.semantic.extended.deep_orange, DESIGN_TOKENS.semantic.extended.success_light, ],
}
}
}
impl IndicatorPalette {
pub fn get_color(&self, category: ColorCategory, index: usize) -> Color32 {
let colors = match category {
ColorCategory::Primary => &self.primary,
ColorCategory::Bullish => &self.bullish,
ColorCategory::Bearish => &self.bearish,
ColorCategory::Neutral => &self.neutral,
ColorCategory::Accent => &self.accent,
};
colors[index % colors.len()]
}
pub fn primary(&self, index: usize) -> Color32 {
self.primary[index % self.primary.len()]
}
pub fn bullish(&self, index: usize) -> Color32 {
self.bullish[index % self.bullish.len()]
}
pub fn bearish(&self, index: usize) -> Color32 {
self.bearish[index % self.bearish.len()]
}
pub fn neutral(&self, index: usize) -> Color32 {
self.neutral[index % self.neutral.len()]
}
pub fn accent(&self, index: usize) -> Color32 {
self.accent[index % self.accent.len()]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColorCategory {
Primary,
Bullish,
Bearish,
Neutral,
Accent,
}
pub struct IndicatorColorSchemes;
impl IndicatorColorSchemes {
pub fn sma() -> Color32 {
DESIGN_TOKENS.semantic.indicators.ma
}
pub fn ema() -> Color32 {
DESIGN_TOKENS.semantic.indicators.ema
}
pub fn bollinger_bands() -> Vec<Color32> {
vec![
DESIGN_TOKENS.semantic.indicators.bb_upper, DESIGN_TOKENS.semantic.indicators.bb_middle, DESIGN_TOKENS.semantic.indicators.bb_lower, ]
}
pub fn rsi() -> Color32 {
DESIGN_TOKENS.semantic.indicators.rsi
}
pub fn macd() -> Vec<Color32> {
vec![
DESIGN_TOKENS.semantic.indicators.macd_line, DESIGN_TOKENS.semantic.indicators.macd_signal, DESIGN_TOKENS.semantic.extended.disabled, ]
}
pub fn volume() -> Vec<Color32> {
vec![
DESIGN_TOKENS.semantic.extended.bullish, DESIGN_TOKENS.semantic.extended.bearish, ]
}
pub fn stochastic() -> Vec<Color32> {
vec![
DESIGN_TOKENS.semantic.extended.info, DESIGN_TOKENS.semantic.extended.error, ]
}
pub fn atr() -> Color32 {
DESIGN_TOKENS.semantic.extended.cyan
}
pub fn ichimoku() -> Vec<Color32> {
vec![
DESIGN_TOKENS.semantic.extended.info, DESIGN_TOKENS.semantic.extended.error, DESIGN_TOKENS.semantic.extended.success, DESIGN_TOKENS.semantic.extended.warning, DESIGN_TOKENS.semantic.extended.purple, ]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_palette_cycling() {
let palette = IndicatorPalette::default();
let color1 = palette.primary(0);
let color2 = palette.primary(8); assert_eq!(color1, color2);
}
#[test]
fn test_color_categories() {
let palette = IndicatorPalette::default();
assert!(!palette.primary.is_empty());
assert!(!palette.bullish.is_empty());
assert!(!palette.bearish.is_empty());
assert!(!palette.neutral.is_empty());
assert!(!palette.accent.is_empty());
}
}