#[cfg(feature = "bevy")]
use bevy::prelude::Component;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub enum LayerVisibility {
Opaque,
Alpha(f32),
Hidden,
}
pub trait VisibilityCycle {
type Value;
fn next(&self, transparency: f32) -> Self::Value;
fn label(&self) -> &'static str;
}
impl LayerVisibility {
pub fn alpha(&self) -> f32 {
match self {
LayerVisibility::Opaque => 1.0,
LayerVisibility::Alpha(a) => *a,
LayerVisibility::Hidden => 0.0,
}
}
pub fn is_opaque(&self) -> bool {
matches!(self, LayerVisibility::Opaque)
}
pub fn is_semi_transparent(&self, with_value: f32) -> bool {
if let LayerVisibility::Alpha(value) = self {
*value == with_value
} else {
false
}
}
pub fn is_floor_general_default(&self) -> bool {
self.is_semi_transparent(DEFAULT_FLOOR_SEMI_TRANSPARENCY)
}
pub fn is_hidden(&self) -> bool {
matches!(self, LayerVisibility::Hidden)
}
}
impl VisibilityCycle for LayerVisibility {
type Value = Self;
fn next(&self, transparency: f32) -> LayerVisibility {
match self {
LayerVisibility::Opaque => LayerVisibility::Alpha(transparency),
LayerVisibility::Alpha(_) => LayerVisibility::Hidden,
LayerVisibility::Hidden => LayerVisibility::Opaque,
}
}
fn label(&self) -> &'static str {
match self {
LayerVisibility::Opaque => "opaque",
LayerVisibility::Alpha(_) => "semi-transparent",
LayerVisibility::Hidden => "hidden",
}
}
}
impl VisibilityCycle for Option<LayerVisibility> {
type Value = Self;
fn next(&self, transparency: f32) -> Self {
match self {
Some(v) => match v {
LayerVisibility::Hidden => None,
_ => Some(v.next(transparency)),
},
None => Some(LayerVisibility::Opaque),
}
}
fn label(&self) -> &'static str {
match self {
Some(v) => v.label(),
None => "global default",
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct GlobalFloorVisibility {
#[serde(
default = "default_floor_without_drawings_visibility",
skip_serializing_if = "LayerVisibility::is_opaque"
)]
pub without_drawings: LayerVisibility,
#[serde(
default = "default_floor_general_visibility",
skip_serializing_if = "LayerVisibility::is_floor_general_default"
)]
pub general: LayerVisibility,
#[serde(
default = "default_floor_semi_transparency",
skip_serializing_if = "is_default_floor_semi_transparency"
)]
pub preferred_semi_transparency: f32,
}
impl Default for GlobalFloorVisibility {
fn default() -> Self {
Self {
without_drawings: LayerVisibility::Opaque,
general: LayerVisibility::Alpha(DEFAULT_FLOOR_SEMI_TRANSPARENCY),
preferred_semi_transparency: DEFAULT_FLOOR_SEMI_TRANSPARENCY,
}
}
}
pub const DEFAULT_FLOOR_SEMI_TRANSPARENCY: f32 = 0.7;
fn is_default_floor_semi_transparency(value: &f32) -> bool {
*value == DEFAULT_FLOOR_SEMI_TRANSPARENCY
}
fn default_floor_semi_transparency() -> f32 {
DEFAULT_FLOOR_SEMI_TRANSPARENCY
}
fn default_floor_without_drawings_visibility() -> LayerVisibility {
LayerVisibility::Opaque
}
fn default_floor_general_visibility() -> LayerVisibility {
LayerVisibility::Alpha(DEFAULT_FLOOR_SEMI_TRANSPARENCY)
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct GlobalDrawingVisibility {
#[serde(
default = "default_bottom_drawing_visibility",
skip_serializing_if = "LayerVisibility::is_opaque"
)]
pub bottom: LayerVisibility,
#[serde(
default = "default_drawing_semi_transparency",
skip_serializing_if = "is_default_drawing_semi_transparency"
)]
pub preferred_bottom_semi_transparency: f32,
#[serde(
default = "default_bottom_drawing_count",
skip_serializing_if = "is_default_bottom_drawing_count"
)]
pub bottom_count: usize,
#[serde(
default = "default_general_drawing_visibility",
skip_serializing_if = "is_default_drawing_visibility"
)]
pub general: LayerVisibility,
#[serde(
default = "default_drawing_semi_transparency",
skip_serializing_if = "is_default_drawing_semi_transparency"
)]
pub preferred_general_semi_transparency: f32,
}
impl Default for GlobalDrawingVisibility {
fn default() -> Self {
Self {
bottom: LayerVisibility::Opaque,
preferred_bottom_semi_transparency: DEFAULT_DRAWING_SEMI_TRANSPARENCY,
bottom_count: 1,
general: LayerVisibility::Alpha(DEFAULT_DRAWING_SEMI_TRANSPARENCY),
preferred_general_semi_transparency: DEFAULT_DRAWING_SEMI_TRANSPARENCY,
}
}
}
pub const DEFAULT_DRAWING_SEMI_TRANSPARENCY: f32 = 0.5;
fn is_default_drawing_semi_transparency(value: &f32) -> bool {
*value == DEFAULT_DRAWING_SEMI_TRANSPARENCY
}
fn default_drawing_semi_transparency() -> f32 {
DEFAULT_DRAWING_SEMI_TRANSPARENCY
}
fn default_bottom_drawing_visibility() -> LayerVisibility {
LayerVisibility::Opaque
}
fn default_general_drawing_visibility() -> LayerVisibility {
LayerVisibility::Alpha(DEFAULT_DRAWING_SEMI_TRANSPARENCY)
}
fn is_default_drawing_visibility(value: &LayerVisibility) -> bool {
value.is_semi_transparent(DEFAULT_DRAWING_SEMI_TRANSPARENCY)
}
fn default_bottom_drawing_count() -> usize {
1
}
fn is_default_bottom_drawing_count(value: &usize) -> bool {
*value == 1
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
#[serde(transparent)]
#[cfg_attr(feature = "bevy", derive(Component))]
pub struct PreferredSemiTransparency(pub f32);
impl PreferredSemiTransparency {
pub fn for_drawing() -> Self {
Self(DEFAULT_DRAWING_SEMI_TRANSPARENCY)
}
pub fn is_default_for_drawing(&self) -> bool {
self.0 == DEFAULT_DRAWING_SEMI_TRANSPARENCY
}
pub fn for_floor() -> Self {
Self(DEFAULT_FLOOR_SEMI_TRANSPARENCY)
}
pub fn is_default_for_floor(&self) -> bool {
self.0 == DEFAULT_FLOOR_SEMI_TRANSPARENCY
}
}