#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
#![allow(clippy::type_complexity)]
#![allow(clippy::too_many_arguments)]
use crate::page::Page;
use crate::spawner::PageSpawner;
use crate::systems::PageSystemSet;
use crate::widgets::Widget;
use bevy::app::{App, Plugin, Update};
use bevy::asset::{AssetApp, AssetEvent};
use bevy::prelude::{IntoScheduleConfigs, on_message, resource_exists};
use rustc_hash::FxHashMap;
pub mod element;
pub mod events;
pub mod loader;
pub mod page;
pub mod spawner;
pub mod widgets;
pub mod parser;
pub mod props;
pub mod utils;
pub(crate) mod systems;
pub struct PagesPlugin {
initial_read_capacity: usize,
widgets: FxHashMap<&'static str, Box<dyn Widget>>,
}
impl PagesPlugin {
#[inline(always)]
pub fn empty() -> Self {
Self {
initial_read_capacity: 2048,
widgets: FxHashMap::default(),
}
}
#[inline(always)]
pub fn with_initial_read_capacity(mut self, initial_read_capacity: usize) -> Self {
self.initial_read_capacity = initial_read_capacity;
self
}
#[inline(always)]
pub fn with_widget<W: Widget + Default>(mut self) -> Self {
self.widgets.insert(W::name(), Box::new(W::default()));
self
}
#[inline(always)]
pub fn with_default_widgets(self) -> Self {
self.with_widget::<widgets::node::NodeWidget>()
.with_widget::<widgets::button::ButtonWidget>()
.with_widget::<widgets::text::TextWidget>()
.with_widget::<widgets::checkbox::CheckboxWidget>()
.with_widget::<widgets::switch::SwitchWidget>()
.with_widget::<widgets::text_input::TextInputWidget>()
.with_widget::<widgets::slider::SliderWidget>()
.with_widget::<widgets::progress_bar::ProgressBarWidget>()
.with_widget::<widgets::image::ImageWidget>()
.with_widget::<widgets::tooltip::TooltipWidget>()
.with_widget::<widgets::dropdown::DropdownWidget>()
.with_widget::<widgets::divider::DividerWidget>()
.with_widget::<widgets::scroll_view::ScrollViewWidget>()
}
}
impl Plugin for PagesPlugin {
fn build(&self, app: &mut App) {
app.init_asset::<Page>()
.register_asset_loader(loader::PageLoader {
initial_read_capacity: self.initial_read_capacity,
widgets: self.widgets.clone(),
})
.insert_resource(PageSpawner::new())
.configure_sets(Update, PageSystemSet.run_if(resource_exists::<Page>))
.add_systems(
Update,
(
systems::interactions.in_set(PageSystemSet),
spawner::spawn_page.run_if(on_message::<AssetEvent<Page>>),
),
)
.add_observer(spawner::despawn_page);
for widget in self.widgets.values() {
widget.setup(app);
}
}
}
impl Default for PagesPlugin {
#[inline(always)]
fn default() -> Self {
Self {
initial_read_capacity: 2048,
widgets: FxHashMap::default(),
}
.with_default_widgets()
}
}