mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
refactor(colorscheme): add RosePine enum
This commit is contained in:
parent
4635b0f134
commit
3b5c92e998
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
@ -27,9 +27,7 @@ jobs:
|
|||||||
sweep-cache: true
|
sweep-cache: true
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
cargo test --locked --workspace --all-features --all-targets
|
cargo test --locked --workspace --no-default-features
|
||||||
# Workaround for https://github.com/rust-lang/cargo/issues/6669
|
|
||||||
cargo test --locked --workspace --all-features --doc
|
|
||||||
# Run clippy lints.
|
# Run clippy lints.
|
||||||
clippy:
|
clippy:
|
||||||
name: Clippy
|
name: Clippy
|
||||||
|
|||||||
41
Cargo.lock
generated
41
Cargo.lock
generated
@ -2645,6 +2645,12 @@ dependencies = [
|
|||||||
"foldhash",
|
"foldhash",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -2669,9 +2675,9 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hexlab"
|
name = "hexlab"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94f91bb99b0ef58661cc4c18e9bab7bba9e66a3d3047fec9af76e31381647442"
|
checksum = "f19ccfce524b2ad659c08508de50522933909ed9787e4c4001cf80d4d380e789"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_reflect",
|
"bevy_reflect",
|
||||||
"bevy_utils",
|
"bevy_utils",
|
||||||
@ -3159,7 +3165,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maze-ascension"
|
name = "maze-ascension"
|
||||||
version = "0.2.3"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bevy",
|
"bevy",
|
||||||
@ -3171,6 +3177,7 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"rstest",
|
"rstest",
|
||||||
"rstest_reuse",
|
"rstest_reuse",
|
||||||
|
"strum",
|
||||||
"test-log",
|
"test-log",
|
||||||
"thiserror 2.0.6",
|
"thiserror 2.0.6",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -4227,6 +4234,12 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustybuzz"
|
name = "rustybuzz"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
@ -4465,6 +4478,28 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.26.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||||
|
dependencies = [
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.26.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "svg_fmt"
|
name = "svg_fmt"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "maze-ascension"
|
name = "maze-ascension"
|
||||||
authors = ["Kristofers Solo <dev@kristofers.xyz>"]
|
authors = ["Kristofers Solo <dev@kristofers.xyz>"]
|
||||||
version = "0.2.3"
|
version = "0.3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -18,11 +18,12 @@ tracing = { version = "0.1", features = [
|
|||||||
"release_max_level_warn",
|
"release_max_level_warn",
|
||||||
] }
|
] }
|
||||||
hexx = { version = "0.19", features = ["bevy_reflect", "grid"] }
|
hexx = { version = "0.19", features = ["bevy_reflect", "grid"] }
|
||||||
hexlab = { version = "0.4", features = ["bevy_reflect"] }
|
hexlab = { version = "0.5", features = ["bevy_reflect"] }
|
||||||
bevy-inspector-egui = { version = "0.28", optional = true }
|
bevy-inspector-egui = { version = "0.28", optional = true }
|
||||||
bevy_egui = { version = "0.31", optional = true }
|
bevy_egui = { version = "0.31", optional = true }
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
strum = { version = "0.26", features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rstest = "0.23"
|
rstest = "0.23"
|
||||||
|
|||||||
@ -14,7 +14,7 @@ impl TransitionFloor {
|
|||||||
self.into()
|
self.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opposite(&self) -> Self {
|
pub const fn opposite(&self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Ascend => Self::Descend,
|
Self::Ascend => Self::Descend,
|
||||||
Self::Descend => Self::Ascend,
|
Self::Descend => Self::Ascend,
|
||||||
@ -31,7 +31,7 @@ impl TransitionFloor {
|
|||||||
|
|
||||||
impl From<TransitionFloor> for f32 {
|
impl From<TransitionFloor> for f32 {
|
||||||
fn from(value: TransitionFloor) -> Self {
|
fn from(value: TransitionFloor) -> Self {
|
||||||
f32::from(&value)
|
Self::from(&value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use crate::theme::palette::rose_pine::{LOVE, PINE};
|
|
||||||
|
|
||||||
use super::resources::GlobalMazeConfig;
|
use super::resources::GlobalMazeConfig;
|
||||||
|
use crate::theme::{palette::rose_pine::RosePine, prelude::ColorScheme};
|
||||||
use bevy::{prelude::*, utils::HashMap};
|
use bevy::{prelude::*, utils::HashMap};
|
||||||
use std::f32::consts::FRAC_PI_2;
|
use std::f32::consts::FRAC_PI_2;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
const WALL_OVERLAP_MODIFIER: f32 = 1.25;
|
const WALL_OVERLAP_MODIFIER: f32 = 1.25;
|
||||||
const HEX_SIDES: u32 = 6;
|
const HEX_SIDES: u32 = 6;
|
||||||
@ -13,7 +13,7 @@ pub struct MazeAssets {
|
|||||||
pub wall_mesh: Handle<Mesh>,
|
pub wall_mesh: Handle<Mesh>,
|
||||||
pub hex_material: Handle<StandardMaterial>,
|
pub hex_material: Handle<StandardMaterial>,
|
||||||
pub wall_material: Handle<StandardMaterial>,
|
pub wall_material: Handle<StandardMaterial>,
|
||||||
pub custom_materials: HashMap<String, Handle<StandardMaterial>>,
|
pub custom_materials: HashMap<RosePine, Handle<StandardMaterial>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MazeAssets {
|
impl MazeAssets {
|
||||||
@ -22,11 +22,9 @@ impl MazeAssets {
|
|||||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||||
global_config: &GlobalMazeConfig,
|
global_config: &GlobalMazeConfig,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut custom_materials = HashMap::new();
|
let custom_materials = RosePine::iter()
|
||||||
custom_materials.extend(vec![
|
.map(|color| (color, materials.add(color.to_standart_material())))
|
||||||
("LOVE".to_string(), materials.add(red_material())),
|
.collect();
|
||||||
("PINE".to_string(), materials.add(blue_material())),
|
|
||||||
]);
|
|
||||||
Self {
|
Self {
|
||||||
hex_mesh: meshes.add(generate_hex_mesh(
|
hex_mesh: meshes.add(generate_hex_mesh(
|
||||||
global_config.hex_size,
|
global_config.hex_size,
|
||||||
@ -73,17 +71,3 @@ pub fn white_material() -> StandardMaterial {
|
|||||||
..default()
|
..default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn red_material() -> StandardMaterial {
|
|
||||||
StandardMaterial {
|
|
||||||
emissive: LOVE.to_linear(),
|
|
||||||
..default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blue_material() -> StandardMaterial {
|
|
||||||
StandardMaterial {
|
|
||||||
emissive: PINE.to_linear(),
|
|
||||||
..default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use crate::{
|
|||||||
events::SpawnMaze,
|
events::SpawnMaze,
|
||||||
resources::GlobalMazeConfig,
|
resources::GlobalMazeConfig,
|
||||||
},
|
},
|
||||||
|
theme::palette::rose_pine::RosePine,
|
||||||
};
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use hexlab::prelude::*;
|
use hexlab::prelude::*;
|
||||||
@ -100,12 +101,12 @@ pub(super) fn spawn_single_hex_tile(
|
|||||||
let material = match tile.pos() {
|
let material = match tile.pos() {
|
||||||
pos if pos == maze_config.start_pos => assets
|
pos if pos == maze_config.start_pos => assets
|
||||||
.custom_materials
|
.custom_materials
|
||||||
.get("PINE")
|
.get(&RosePine::Pine)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
pos if pos == maze_config.end_pos => assets
|
pos if pos == maze_config.end_pos => assets
|
||||||
.custom_materials
|
.custom_materials
|
||||||
.get("LOVE")
|
.get(&RosePine::Love)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
_ => assets.hex_material.clone(),
|
_ => assets.hex_material.clone(),
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::theme::palette::rose_pine::PINE;
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::theme::{palette::rose_pine::RosePine, prelude::ColorScheme};
|
||||||
|
|
||||||
pub(super) fn generate_pill_mesh(radius: f32, half_length: f32) -> Mesh {
|
pub(super) fn generate_pill_mesh(radius: f32, half_length: f32) -> Mesh {
|
||||||
Mesh::from(Capsule3d {
|
Mesh::from(Capsule3d {
|
||||||
radius,
|
radius,
|
||||||
@ -9,9 +10,10 @@ pub(super) fn generate_pill_mesh(radius: f32, half_length: f32) -> Mesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn blue_material() -> StandardMaterial {
|
pub(super) fn blue_material() -> StandardMaterial {
|
||||||
|
let color = RosePine::Pine;
|
||||||
StandardMaterial {
|
StandardMaterial {
|
||||||
base_color: PINE,
|
base_color: color.to_color(),
|
||||||
emissive: PINE.to_linear() * 3.,
|
emissive: color.to_linear_rgba() * 3.,
|
||||||
..default()
|
..default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
104
src/theme/colorscheme.rs
Normal file
104
src/theme/colorscheme.rs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
/// A trait for types that can be converted to a Bevy `Color`.
|
||||||
|
///
|
||||||
|
/// Implementing this trait allows a type to be easily converted to various Bevy color types.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use bevy::prelude::*;
|
||||||
|
/// use maze_ascension::theme::prelude::ColorScheme;
|
||||||
|
///
|
||||||
|
/// struct MyColor(u8, u8, u8);
|
||||||
|
///
|
||||||
|
/// impl ColorScheme for MyColor {
|
||||||
|
/// fn to_color(&self) -> Color {
|
||||||
|
/// Color::srgb(
|
||||||
|
/// self.0 as f32 / 255.0,
|
||||||
|
/// self.1 as f32 / 255.0,
|
||||||
|
/// self.2 as f32 / 255.0
|
||||||
|
/// )
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let my_color = MyColor(255, 0, 0);
|
||||||
|
/// let bevy_color: Color = my_color.to_color();
|
||||||
|
/// assert_eq!(bevy_color, Color::srgb(1., 0., 0.));
|
||||||
|
/// ```
|
||||||
|
pub trait ColorScheme {
|
||||||
|
/// Converts the implementing type to a Bevy `Color`.
|
||||||
|
fn to_color(&self) -> Color;
|
||||||
|
|
||||||
|
/// Converts the implementing type to a Bevy `LinearRgba`.
|
||||||
|
///
|
||||||
|
/// This method provides a default implementation based on `to_color()`.
|
||||||
|
fn to_linear_rgba(&self) -> LinearRgba {
|
||||||
|
self.to_color().to_linear()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts the implementing type to a Bevy `StandardMaterial`.
|
||||||
|
///
|
||||||
|
/// This method provides a default implementation that sets the emissive color.
|
||||||
|
fn to_standart_material(&self) -> StandardMaterial {
|
||||||
|
StandardMaterial {
|
||||||
|
emissive: self.to_linear_rgba(),
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A wrapper type that implements `From` traits for types implementing `ColorScheme`.
|
||||||
|
///
|
||||||
|
/// This wrapper allows for easy conversion from `ColorScheme` types to Bevy color types.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use bevy::prelude::*;
|
||||||
|
/// use maze_ascension::theme::prelude::{ColorScheme, ColorSchemeWrapper};
|
||||||
|
///
|
||||||
|
/// struct MyColor(u8, u8, u8);
|
||||||
|
///
|
||||||
|
/// impl ColorScheme for MyColor {
|
||||||
|
/// fn to_color(&self) -> Color {
|
||||||
|
/// Color::srgb(
|
||||||
|
/// self.0 as f32 / 255.0,
|
||||||
|
/// self.1 as f32 / 255.0,
|
||||||
|
/// self.2 as f32 / 255.0
|
||||||
|
/// )
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let my_color = MyColor(0, 255, 0);
|
||||||
|
/// let wrapper = ColorSchemeWrapper(my_color);
|
||||||
|
/// let bevy_color: Color = wrapper.into();
|
||||||
|
/// assert_eq!(bevy_color, Color::srgb(0., 1., 0.));
|
||||||
|
/// ```
|
||||||
|
pub struct ColorSchemeWrapper<T: ColorScheme>(pub T);
|
||||||
|
|
||||||
|
impl<T: ColorScheme> From<T> for ColorSchemeWrapper<T> {
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ColorScheme> Deref for ColorSchemeWrapper<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ColorScheme> From<ColorSchemeWrapper<T>> for Color {
|
||||||
|
fn from(value: ColorSchemeWrapper<T>) -> Self {
|
||||||
|
value.to_color()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ColorScheme> From<ColorSchemeWrapper<T>> for LinearRgba {
|
||||||
|
fn from(value: ColorSchemeWrapper<T>) -> Self {
|
||||||
|
value.to_linear_rgba()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
// Unused utilities may trigger this lints undesirably.
|
// Unused utilities may trigger this lints undesirably.
|
||||||
|
|
||||||
|
mod colorscheme;
|
||||||
pub mod interaction;
|
pub mod interaction;
|
||||||
pub mod palette;
|
pub mod palette;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
@ -9,6 +10,7 @@ mod widgets;
|
|||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use super::{
|
pub use super::{
|
||||||
|
colorscheme::{ColorScheme, ColorSchemeWrapper},
|
||||||
interaction::{InteractionPalette, OnPress},
|
interaction::{InteractionPalette, OnPress},
|
||||||
palette as ui_palette,
|
palette as ui_palette,
|
||||||
widgets::{Containers as _, Widgets as _},
|
widgets::{Containers as _, Widgets as _},
|
||||||
|
|||||||
@ -1,18 +1,45 @@
|
|||||||
use super::rgb_u8;
|
use super::rgb_u8;
|
||||||
|
use crate::theme::prelude::ColorScheme;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use strum::EnumIter;
|
||||||
|
|
||||||
pub const BASE: Color = rgb_u8(25, 23, 36);
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)]
|
||||||
pub const SURFACE: Color = rgb_u8(31, 29, 46);
|
pub enum RosePine {
|
||||||
pub const OVERLAY: Color = rgb_u8(38, 35, 58);
|
Base,
|
||||||
pub const MUTED: Color = rgb_u8(110, 106, 134);
|
Surface,
|
||||||
pub const SUBTLE: Color = rgb_u8(144, 140, 170);
|
Overlay,
|
||||||
pub const TEXT: Color = rgb_u8(224, 222, 244);
|
Muted,
|
||||||
pub const LOVE: Color = rgb_u8(235, 111, 146);
|
Subtle,
|
||||||
pub const GOLD: Color = rgb_u8(246, 193, 119);
|
Text,
|
||||||
pub const ROSE: Color = rgb_u8(235, 188, 186);
|
Love,
|
||||||
pub const PINE: Color = rgb_u8(49, 116, 143);
|
Gold,
|
||||||
pub const FOAM: Color = rgb_u8(156, 207, 216);
|
Rose,
|
||||||
pub const IRIS: Color = rgb_u8(196, 167, 231);
|
Pine,
|
||||||
pub const HIGHLIGHT_LOW: Color = rgb_u8(33, 32, 46);
|
Foam,
|
||||||
pub const HIGHLIGHT_MED: Color = rgb_u8(64, 61, 82);
|
Iris,
|
||||||
pub const HIGHLIGHT_HIGH: Color = rgb_u8(82, 79, 103);
|
HighlightLow,
|
||||||
|
HighlightMed,
|
||||||
|
HighlightHigh,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorScheme for RosePine {
|
||||||
|
fn to_color(&self) -> Color {
|
||||||
|
match self {
|
||||||
|
Self::Base => rgb_u8(25, 23, 36),
|
||||||
|
Self::Surface => rgb_u8(31, 29, 46),
|
||||||
|
Self::Overlay => rgb_u8(38, 35, 58),
|
||||||
|
Self::Muted => rgb_u8(110, 106, 134),
|
||||||
|
Self::Subtle => rgb_u8(144, 140, 170),
|
||||||
|
Self::Text => rgb_u8(224, 222, 244),
|
||||||
|
Self::Love => rgb_u8(235, 111, 146),
|
||||||
|
Self::Gold => rgb_u8(246, 193, 119),
|
||||||
|
Self::Rose => rgb_u8(235, 188, 186),
|
||||||
|
Self::Pine => rgb_u8(49, 116, 143),
|
||||||
|
Self::Foam => rgb_u8(156, 207, 216),
|
||||||
|
Self::Iris => rgb_u8(196, 167, 231),
|
||||||
|
Self::HighlightLow => rgb_u8(33, 32, 46),
|
||||||
|
Self::HighlightMed => rgb_u8(64, 61, 82),
|
||||||
|
Self::HighlightHigh => rgb_u8(82, 79, 103),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user