use crate::{
common::ToOpenTimelineType, components::TimelineEntityGui, config::SharedConfig,
impl_is_valid_method_for_iterable, impl_valid_asynchronous_macro_never_called,
};
use eframe::egui::{Context, Ui};
use open_timeline_core::{IsReducedCollection, ReducedEntities};
use open_timeline_gui_core::{
Draw, Valid, ValidSynchronous, ValidityAsynchronous, ValiditySynchronous,
};
use std::sync::Arc;
#[derive(Debug)]
pub struct TimelineEntitiesGui {
entities: Vec<TimelineEntityGui>,
shared_config: SharedConfig,
}
impl TimelineEntitiesGui {
pub fn new(shared_config: SharedConfig) -> Self {
Self {
entities: vec![],
shared_config,
}
}
pub fn add_empty_entity(&mut self) {
let shared_config = Arc::clone(&self.shared_config);
self.entities.push(TimelineEntityGui::new(shared_config));
}
pub fn from_reduced_entities(
shared_config: SharedConfig,
original_entities: Option<ReducedEntities>,
) -> Self {
let entities = match original_entities.clone() {
None => Vec::new(),
Some(tags) => tags
.into_iter()
.map(|entity| {
TimelineEntityGui::from_reduced_entity(Arc::clone(&shared_config), entity)
})
.collect(),
};
Self {
entities,
shared_config,
}
}
}
impl ValidSynchronous for TimelineEntitiesGui {
fn is_valid_synchronous(&self) -> bool {
self.entities
.iter()
.all(|entity| entity.is_valid_synchronous())
}
fn update_validity_synchronous(&mut self) {
self.entities
.iter_mut()
.for_each(|entity| entity.update_validity_synchronous())
}
fn validity_synchronous(&self) -> ValiditySynchronous {
for entity in &self.entities {
match entity.validity_synchronous() {
ValiditySynchronous::Invalid(error) => return ValiditySynchronous::Invalid(error),
ValiditySynchronous::Valid => continue,
}
}
ValiditySynchronous::Valid
}
}
impl_valid_asynchronous_macro_never_called!(TimelineEntitiesGui);
impl Valid for TimelineEntitiesGui {
fn validity(&self) -> ValidityAsynchronous {
let validity: Vec<ValidityAsynchronous> = self
.entities
.iter()
.map(|entity| entity.validity())
.collect();
impl_is_valid_method_for_iterable!(validity)
}
fn update_validity(&mut self) {
panic!()
}
}
impl ToOpenTimelineType<Option<ReducedEntities>> for TimelineEntitiesGui {
fn to_opentimeline_type(&self) -> Option<ReducedEntities> {
let mut entities = ReducedEntities::new();
for entity in &self.entities {
let entity = entity.to_opentimeline_type();
entities.collection_mut().insert(entity);
}
(!entities.collection().is_empty()).then_some(entities)
}
}
impl Draw for TimelineEntitiesGui {
fn draw(&mut self, ctx: &Context, ui: &mut Ui) {
open_timeline_gui_core::Label::sub_heading(ui, "Entities");
if self.entities.is_empty() {
open_timeline_gui_core::Label::none(ui);
} else {
for entity in &mut self.entities {
entity.draw(ctx, ui);
}
self.entities.retain(|entity| !entity.to_be_removed());
}
ui.add_space(5.0);
if open_timeline_gui_core::Button::add(ui).clicked() {
self.add_empty_entity();
}
}
}