use crate::abi::{Header, Status, Str, UiMarker};
use super::{Ui, UiError};
pub const MAX_MARKERS: usize = super::MARKER_LIMIT;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum MarkerColor {
#[default]
White,
Red,
Green,
Blue,
Yellow,
Purple,
Turquoise,
Black,
}
impl MarkerColor {
fn to_raw(self) -> u32 {
match self {
Self::White => UiMarker::WHITE,
Self::Red => UiMarker::RED,
Self::Green => UiMarker::GREEN,
Self::Blue => UiMarker::BLUE,
Self::Yellow => UiMarker::YELLOW,
Self::Purple => UiMarker::PURPLE,
Self::Turquoise => UiMarker::TURQUOISE,
Self::Black => UiMarker::BLACK,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Marker<'a> {
position: [f64; 3],
label: &'a str,
color: MarkerColor,
}
impl<'a> Marker<'a> {
#[must_use]
pub const fn new(position: [f64; 3]) -> Self {
Self {
position,
label: "",
color: MarkerColor::White,
}
}
#[must_use]
pub const fn label(mut self, label: &'a str) -> Self {
self.label = label;
self
}
#[must_use]
pub const fn color(mut self, color: MarkerColor) -> Self {
self.color = color;
self
}
}
impl Ui {
pub fn set_markers(&self, markers: &[Marker<'_>]) -> Result<(), UiError> {
let api = self.host.api();
if markers.len() > MAX_MARKERS {
return Err(UiError::Refused);
}
let raw: Vec<UiMarker> = markers
.iter()
.map(|m| UiMarker {
header: Header::of::<UiMarker>(),
position: crate::ecs::fixed(m.position),
label: Str::new(m.label),
color: m.color.to_raw(),
reserved: 0,
})
.collect();
let count = u32::try_from(raw.len()).map_err(|_| UiError::Refused)?;
match (api.ui_markers)(self.host.handle(), raw.as_ptr(), count) {
Status::OK => Ok(()),
Status::MISSING => Err(UiError::Unavailable),
_ => Err(UiError::Refused),
}
}
pub fn clear_markers(&self) -> Result<(), UiError> {
self.set_markers(&[])
}
}