use super::{App, context};
use crate::render::backend::Backend;
use crate::style::Stylesheet;
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub struct StylesheetId(u64);
#[derive(Debug, Default)]
pub(super) struct StylesheetIdAllocator {
next: u64,
}
impl StylesheetIdAllocator {
pub(super) fn allocate(&mut self) -> StylesheetId {
let id = StylesheetId(self.next);
self.next += 1;
id
}
}
impl<B: Backend> App<B> {
pub fn set_stylesheet(&mut self, sheet: Stylesheet) -> StylesheetId {
let id = self.stylesheet_ids.allocate();
self.replace_stylesheets(id, sheet);
id
}
pub fn push_stylesheet(&mut self, sheet: Stylesheet) -> StylesheetId {
let id = self.stylesheet_ids.allocate();
self.append_stylesheet(id, sheet);
id
}
fn replace_stylesheets(&mut self, id: StylesheetId, sheet: Stylesheet) {
self.stylesheets.clear();
self.append_stylesheet(id, sheet);
}
fn append_stylesheet(&mut self, id: StylesheetId, sheet: Stylesheet) {
debug_assert!(
self.stylesheets.iter().all(|(sid, _)| *sid != id),
"a StylesheetId is registered at most once"
);
self.stylesheets.push((id, sheet));
self.invalidate_cascade();
}
pub fn remove_stylesheet(&mut self, id: StylesheetId) {
if let Some(pos) = self.stylesheets.iter().position(|(sid, _)| *sid == id) {
self.stylesheets.remove(pos);
self.invalidate_cascade();
}
}
pub(super) fn apply_stylesheet_intents(&mut self, intents: Vec<context::StylesheetIntent>) {
for intent in intents {
match intent {
context::StylesheetIntent::Set(id, sheet) => self.replace_stylesheets(id, sheet),
context::StylesheetIntent::Push(id, sheet) => self.append_stylesheet(id, sheet),
context::StylesheetIntent::Remove(id) => self.remove_stylesheet(id),
}
}
}
pub(super) fn invalidate_cascade(&mut self) {
self.prelude
.sheets_changed(&self.tracker, &self.stylesheets, &mut self.redraw);
}
pub fn style_sheets(&self) -> Vec<&Stylesheet> {
self.stylesheets.iter().map(|(_, s)| s).collect()
}
pub fn style_element_warnings(&self) -> Vec<&rdom_css::Warning> {
self.prelude.style_elements.warnings().collect()
}
}