1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
use palette::Srgba;
use serde::{Deserialize, Serialize};
use crate::composite::over;
/// Theme Container colors of a theme, can be a theme background container, primary container, or secondary container
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[must_use]
pub struct Container {
/// the color of the container
pub base: Srgba,
/// the color of components in the container
pub component: Component,
/// the color of dividers in the container
pub divider: Srgba,
/// the color of text in the container
pub on: Srgba,
/// the color of @small_widget_container
pub small_widget: Srgba,
}
impl Container {
pub(crate) fn new(
component: Component,
base: Srgba,
on: Srgba,
mut small_widget: Srgba,
) -> Self {
let mut divider_c = on;
divider_c.alpha = 0.2;
small_widget.alpha = 0.25;
Self {
base,
component,
divider: over(divider_c, base),
on,
small_widget,
}
}
}
/// The colors for a widget of the Cosmic theme
#[derive(Clone, PartialEq, Debug, Default, Deserialize, Serialize)]
#[must_use]
pub struct Component {
/// The base color of the widget
pub base: Srgba,
/// The color of the widget when it is hovered
pub hover: Srgba,
/// the color of the widget when it is pressed
pub pressed: Srgba,
/// the color of the widget when it is selected
pub selected: Srgba,
/// the color of the widget when it is selected
pub selected_text: Srgba,
/// the color of the widget when it is focused
pub focus: Srgba,
/// the color of dividers for this widget
pub divider: Srgba,
/// the color of text for this widget
pub on: Srgba,
// the color of text with opacity 80 for this widget
// pub text_opacity_80: Srgba,
/// the color of the widget when it is disabled
pub disabled: Srgba,
/// the color of text in the widget when it is disabled
pub on_disabled: Srgba,
/// the color of the border for the widget
pub border: Srgba,
/// the color of the border for the widget when it is disabled
pub disabled_border: Srgba,
}
#[allow(clippy::must_use_candidate)]
#[allow(clippy::doc_markdown)]
impl Component {
/// get @hover_state_color
pub fn hover_state_color(&self) -> Srgba {
self.hover
}
/// get @pressed_state_color
pub fn pressed_state_color(&self) -> Srgba {
self.pressed
}
/// get @selected_state_color
pub fn selected_state_color(&self) -> Srgba {
self.selected
}
/// get @selected_state_text_color
pub fn selected_state_text_color(&self) -> Srgba {
self.selected_text
}
/// get @focus_color
pub fn focus_color(&self) -> Srgba {
self.focus
}
/// helper for producing a component from a base color a neutral and an accent
pub fn colored_component(
base: Srgba,
neutral: Srgba,
accent: Srgba,
hovered: Srgba,
pressed: Srgba,
) -> Self {
let base: Srgba = base;
let mut base_50 = base;
base_50.alpha *= 0.5;
let on_20 = neutral;
let mut on_50: Srgba = on_20;
on_50.alpha = 0.5;
Component {
base,
hover: over(hovered, base),
pressed: over(pressed, base),
selected: over(hovered, base),
selected_text: accent,
divider: on_20,
on: neutral,
disabled: over(base_50, base),
on_disabled: over(on_50, base),
focus: accent,
border: base,
disabled_border: base_50,
}
}
/// helper for producing a button component
pub fn colored_button(
base: Srgba,
overlay: Srgba,
on_button: Srgba,
accent: Srgba,
hovered: Srgba,
pressed: Srgba,
) -> Self {
let mut component = Component::colored_component(base, overlay, accent, hovered, pressed);
component.on = on_button;
let mut on_disabled = on_button;
on_disabled.alpha = 0.5;
component.on_disabled = on_disabled;
component
}
/// helper for producing a component color theme
#[allow(clippy::self_named_constructors)]
pub fn component(
base: Srgba,
accent: Srgba,
on_component: Srgba,
hovered: Srgba,
pressed: Srgba,
is_high_contrast: bool,
border: Srgba,
) -> Self {
let mut base_50 = base;
base_50.alpha *= 0.5;
let mut on_20 = on_component;
let mut on_50 = on_20;
on_20.alpha = 0.2;
on_50.alpha = 0.5;
let mut disabled_border = border;
disabled_border.alpha *= 0.5;
Component {
base,
hover: if base.alpha < 0.001 {
hovered
} else {
over(hovered, base)
},
pressed: if base.alpha < 0.001 {
pressed
} else {
over(pressed, base)
},
selected: if base.alpha < 0.001 {
hovered
} else {
over(hovered, base)
},
selected_text: accent,
focus: accent,
divider: if is_high_contrast { on_50 } else { on_20 },
on: on_component,
disabled: over(base_50, base),
on_disabled: over(on_50, base),
border,
disabled_border,
}
}
}