mod bindings;
pub mod builder;
pub mod converter;
pub mod inline_functions;
pub mod reload;
pub use bindings::HtmlEventBindingsPlugin;
pub use inline_functions::{
HtmlInlineAction, HtmlInlineEventBindings, HtmlInlineFunction, parse_html_inline_action,
};
pub use inventory;
#[cfg(feature = "extended-framework")]
use crate::framework::sync_ui_binding_store_values;
use crate::html::builder::HtmlBuilderSystem;
use crate::html::converter::HtmlConverterSystem;
use crate::html::reload::HtmlReloadPlugin;
use crate::lang::{UILang, UiLangState, UiLangVariables, UiSharedValues, refresh_shared_values};
use bevy::ecs::system::SystemId;
use bevy::prelude::*;
use std::collections::{HashMap, HashSet};
use std::sync::atomic::{AtomicUsize, Ordering};
#[cfg(feature = "extended-dialog")]
use crate::dialog::DialogWidget;
use crate::io::{CssAsset, HtmlAsset};
use crate::styles::Style;
use crate::styles::parser::apply_property_to_style;
use crate::widgets::{
Badge, Body, Button, CheckBox, ChoiceBox, ColorPicker, DatePicker, Div, Divider, FieldSet,
Form, Headline, HyperLink, Img, InputField, ListBox, Paragraph, ProgressBar, RadioButton,
Scrollbar, Slider, SwitchButton, ToggleButton, ToolTip, ValidationRules, Widget,
};
pub static HTML_ID_COUNTER: AtomicUsize = AtomicUsize::new(1);
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub enum HtmlSystemSet {
Convert,
Build,
ShowWidgets,
Bindings,
}
#[derive(Component, Reflect, Debug, Clone)]
#[reflect(Component)]
pub struct HtmlSource {
pub handle: Handle<HtmlAsset>,
pub source_id: String,
pub controller: Option<String>,
}
impl HtmlSource {
pub fn from_handle(handle: Handle<HtmlAsset>) -> Self {
Self {
handle,
source_id: String::new(),
controller: None,
}
}
pub fn get_source_path(&self) -> String {
self.handle
.path()
.map(|asset_path| asset_path.path().to_string_lossy().replace('\\', "/"))
.unwrap_or_default()
}
}
#[derive(Event, Message)]
pub struct HtmlAllWidgetsSpawned;
#[derive(Event, Message)]
pub struct HtmlAllWidgetsVisible;
#[derive(Component, Default)]
pub struct HtmlInitEmitted;
#[derive(Resource, Default)]
pub struct HtmlInitDelay(pub Option<u8>);
#[derive(Component)]
pub struct NeedHidden;
#[derive(Resource, Default)]
pub struct ShowWidgetsTimer {
pub timer: Timer,
pub active: bool,
}
#[derive(Event, Message)]
pub struct HtmlChangeEvent;
#[derive(Resource, Default)]
pub struct HtmlDirty(pub bool, pub HashSet<String>);
#[derive(Resource, Default)]
pub struct HtmlPendingReveal(pub HashSet<String>);
#[derive(Component, Reflect, Debug, Clone, PartialEq)]
#[reflect(Component)]
pub struct HtmlStyle(pub Style);
impl HtmlStyle {
pub fn from_str(style_code: &str) -> HtmlStyle {
let mut style = Style::default();
for part in style_code.split(';') {
let trimmed = part.trim();
if trimmed.is_empty() {
continue;
}
let (name, value) = if let Some((k, v)) = trimmed.split_once(':') {
(k.trim(), v.trim())
} else if let Some((k, v)) = trimmed.split_once(' ') {
(k.trim(), v.trim())
} else {
continue;
};
apply_property_to_style(&mut style, name, value);
}
HtmlStyle(style)
}
}
#[derive(Component, Reflect, Debug, Clone, Default, PartialEq)]
#[reflect(Component)]
pub struct HtmlTextBinding {
pub template: String,
pub bindings: Vec<String>,
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct HtmlMeta {
pub css: Vec<Handle<CssAsset>>,
pub id: Option<String>,
pub class: Option<Vec<String>>,
pub style: Option<HtmlStyle>,
pub validation: Option<ValidationRules>,
pub inner_content: HtmlInnerContent,
pub text_binding: Option<HtmlTextBinding>,
}
#[derive(Component, Reflect, Debug, Clone, Default, PartialEq)]
#[reflect(Component)]
pub struct HtmlInnerContent {
inner_text: String,
inner_html: String,
inner_bindings: Vec<String>,
}
impl HtmlInnerContent {
pub fn new(
inner_text: impl Into<String>,
inner_html: impl Into<String>,
inner_bindings: Vec<String>,
) -> Self {
Self {
inner_text: inner_text.into(),
inner_html: inner_html.into(),
inner_bindings,
}
}
pub fn inner_text(&self) -> &str {
&self.inner_text
}
pub fn inner_html(&self) -> &str {
&self.inner_html
}
pub fn inner_bindings(&self) -> &[String] {
&self.inner_bindings
}
pub fn set_inner_text(&mut self, value: impl Into<String>) {
self.inner_text = value.into();
}
pub fn set_inner_html(&mut self, value: impl Into<String>) {
self.inner_html = value.into();
}
pub fn set_inner_bindings(&mut self, value: Vec<String>) {
self.inner_bindings = value;
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct HtmlStates {
pub hidden: bool,
pub disabled: bool,
pub readonly: bool,
}
#[derive(Debug, Clone)]
pub enum HtmlWidgetNode {
Body(
Body,
HtmlMeta,
HtmlStates,
Vec<HtmlWidgetNode>,
HtmlEventBindings,
Widget,
HtmlID,
),
Div(
Div,
HtmlMeta,
HtmlStates,
Vec<HtmlWidgetNode>,
HtmlEventBindings,
Widget,
HtmlID,
),
Form(
Form,
HtmlMeta,
HtmlStates,
Vec<HtmlWidgetNode>,
HtmlEventBindings,
Widget,
HtmlID,
),
#[cfg(feature = "extended-dialog")]
Dialog(
DialogWidget,
HtmlMeta,
HtmlStates,
Vec<HtmlWidgetNode>,
HtmlEventBindings,
Widget,
HtmlID,
),
Divider(
Divider,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
Button(
Button,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
CheckBox(
CheckBox,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
ColorPicker(
ColorPicker,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
ChoiceBox(
ChoiceBox,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
DatePicker(
DatePicker,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
FieldSet(
FieldSet,
HtmlMeta,
HtmlStates,
Vec<HtmlWidgetNode>,
HtmlEventBindings,
Widget,
HtmlID,
),
Headline(
Headline,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
HyperLink(
HyperLink,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
Img(Img, HtmlMeta, HtmlStates, HtmlEventBindings, Widget, HtmlID),
Input(
InputField,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
Paragraph(
Paragraph,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
ToolTip(
ToolTip,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
Badge(
Badge,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
ProgressBar(
ProgressBar,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
RadioButton(
RadioButton,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
Scrollbar(
Scrollbar,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
Slider(
Slider,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
SwitchButton(
SwitchButton,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
ToggleButton(
ToggleButton,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
ListBox(
ListBox,
HtmlMeta,
HtmlStates,
HtmlEventBindings,
Widget,
HtmlID,
),
}
#[derive(Resource)]
pub struct HtmlStructureMap {
pub html_map: HashMap<String, Vec<HtmlWidgetNode>>,
pub active: Option<Vec<String>>,
}
impl Default for HtmlStructureMap {
fn default() -> Self {
Self {
html_map: HashMap::new(),
active: None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Component)]
pub struct HtmlID(pub usize);
impl Default for HtmlID {
fn default() -> Self {
Self(HTML_ID_COUNTER.fetch_add(1, Ordering::Relaxed))
}
}
pub enum HtmlFnRegistration {
HtmlEvent {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlEvent>, ()>,
},
HtmlClick {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlClick>, ()>,
},
HtmlMouseDown {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlMouseDown>, ()>,
},
HtmlMouseUp {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlMouseUp>, ()>,
},
HtmlChange {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlChange>, ()>,
},
HtmlSubmit {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlSubmit>, ()>,
},
HtmlInit {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlInit>, ()>,
},
HtmlMouseOut {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlMouseOut>, ()>,
},
HtmlMouseOver {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlMouseOver>, ()>,
},
HtmlFocus {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlFocus>, ()>,
},
HtmlScroll {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlScroll>, ()>,
},
HtmlWheel {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlWheel>, ()>,
},
HtmlKeyDown {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlKeyDown>, ()>,
},
HtmlKeyUp {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlKeyUp>, ()>,
},
HtmlDragStart {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlDragStart>, ()>,
},
HtmlDrag {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlDrag>, ()>,
},
HtmlDragStop {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlDragStop>, ()>,
},
HtmlTouchStart {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlTouchStart>, ()>,
},
HtmlTouchMove {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlTouchMove>, ()>,
},
HtmlTouchEnd {
name: &'static str,
build: fn(&mut World) -> SystemId<In<HtmlTouchEnd>, ()>,
},
}
inventory::collect!(HtmlFnRegistration);
pub struct ComponentInitRegistration {
pub name: &'static str,
pub build: fn(&mut World) -> SystemId<(), ()>,
}
inventory::collect!(ComponentInitRegistration);
#[derive(Clone, Copy)]
pub struct HtmlEvent {
pub entity: Entity,
}
impl HtmlEvent {
pub fn target(&self) -> Entity {
self.entity
}
}
#[derive(Default, Resource)]
pub struct HtmlFunctionRegistry {
pub click: HashMap<String, SystemId<In<HtmlEvent>>>,
pub mousedown: HashMap<String, SystemId<In<HtmlEvent>>>,
pub mouseup: HashMap<String, SystemId<In<HtmlEvent>>>,
pub over: HashMap<String, SystemId<In<HtmlEvent>>>,
pub out: HashMap<String, SystemId<In<HtmlEvent>>>,
pub change: HashMap<String, SystemId<In<HtmlEvent>>>,
pub submit: HashMap<String, SystemId<In<HtmlEvent>>>,
pub init: HashMap<String, SystemId<In<HtmlEvent>>>,
pub focus: HashMap<String, SystemId<In<HtmlEvent>>>,
pub scroll: HashMap<String, SystemId<In<HtmlEvent>>>,
pub wheel: HashMap<String, SystemId<In<HtmlEvent>>>,
pub keydown: HashMap<String, SystemId<In<HtmlEvent>>>,
pub keyup: HashMap<String, SystemId<In<HtmlEvent>>>,
pub dragstart: HashMap<String, SystemId<In<HtmlEvent>>>,
pub drag: HashMap<String, SystemId<In<HtmlEvent>>>,
pub dragstop: HashMap<String, SystemId<In<HtmlEvent>>>,
pub touchstart: HashMap<String, SystemId<In<HtmlEvent>>>,
pub touchmove: HashMap<String, SystemId<In<HtmlEvent>>>,
pub touchend: HashMap<String, SystemId<In<HtmlEvent>>>,
pub click_typed: HashMap<String, SystemId<In<HtmlClick>>>,
pub mousedown_typed: HashMap<String, SystemId<In<HtmlMouseDown>>>,
pub mouseup_typed: HashMap<String, SystemId<In<HtmlMouseUp>>>,
pub over_typed: HashMap<String, SystemId<In<HtmlMouseOver>>>,
pub out_typed: HashMap<String, SystemId<In<HtmlMouseOut>>>,
pub change_typed: HashMap<String, SystemId<In<HtmlChange>>>,
pub submit_typed: HashMap<String, SystemId<In<HtmlSubmit>>>,
pub init_typed: HashMap<String, SystemId<In<HtmlInit>>>,
pub focus_typed: HashMap<String, SystemId<In<HtmlFocus>>>,
pub scroll_typed: HashMap<String, SystemId<In<HtmlScroll>>>,
pub wheel_typed: HashMap<String, SystemId<In<HtmlWheel>>>,
pub keydown_typed: HashMap<String, SystemId<In<HtmlKeyDown>>>,
pub keyup_typed: HashMap<String, SystemId<In<HtmlKeyUp>>>,
pub dragstart_typed: HashMap<String, SystemId<In<HtmlDragStart>>>,
pub drag_typed: HashMap<String, SystemId<In<HtmlDrag>>>,
pub dragstop_typed: HashMap<String, SystemId<In<HtmlDragStop>>>,
pub touchstart_typed: HashMap<String, SystemId<In<HtmlTouchStart>>>,
pub touchmove_typed: HashMap<String, SystemId<In<HtmlTouchMove>>>,
pub touchend_typed: HashMap<String, SystemId<In<HtmlTouchEnd>>>,
}
#[derive(Component, Reflect, Default, Clone, Debug, PartialEq)]
#[reflect(Component)]
pub struct HtmlEventBindings {
pub onclick: Option<String>,
pub onmousedown: Option<String>,
pub onmouseup: Option<String>,
pub onmouseover: Option<String>,
pub onmouseout: Option<String>,
pub onchange: Option<String>,
pub oninit: Option<String>,
pub onfoucs: Option<String>,
pub onscroll: Option<String>,
pub onwheel: Option<String>,
pub onkeydown: Option<String>,
pub onkeyup: Option<String>,
pub ondragstart: Option<String>,
pub ondrag: Option<String>,
pub ondragstop: Option<String>,
pub ontouchstart: Option<String>,
pub ontouchmove: Option<String>,
pub ontouchend: Option<String>,
#[reflect(ignore)]
pub inline: HtmlInlineEventBindings,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlClick {
#[event_target]
pub entity: Entity,
pub position: Vec2,
pub inner_position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlMouseDown {
#[event_target]
pub entity: Entity,
pub button: PointerButton,
pub position: Vec2,
pub inner_position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlMouseUp {
#[event_target]
pub entity: Entity,
pub button: PointerButton,
pub position: Vec2,
pub inner_position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlMouseOver {
#[event_target]
pub entity: Entity,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlMouseOut {
#[event_target]
pub entity: Entity,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HtmlChangeAction {
State,
Style,
Unknown,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlChange {
#[event_target]
pub entity: Entity,
pub action: HtmlChangeAction,
}
#[derive(EntityEvent, Clone)]
pub struct HtmlSubmit {
#[event_target]
pub entity: Entity,
pub submitter: Entity,
pub action: String,
pub data: HashMap<String, String>,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlInit {
#[event_target]
pub entity: Entity,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HtmlFocusState {
Gained,
Lost,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlFocus {
#[event_target]
pub entity: Entity,
pub state: HtmlFocusState,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlScroll {
#[event_target]
pub entity: Entity,
pub delta: Vec2,
pub x: f32,
pub y: f32,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlWheel {
#[event_target]
pub entity: Entity,
pub unit: bevy::input::mouse::MouseScrollUnit,
pub delta: Vec2,
pub position: Vec2,
pub inner_position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlKeyDown {
#[event_target]
pub entity: Entity,
pub key: KeyCode,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlKeyUp {
#[event_target]
pub entity: Entity,
pub key: KeyCode,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlDragStart {
#[event_target]
pub entity: Entity,
pub position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlDrag {
#[event_target]
pub entity: Entity,
pub position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlDragStop {
#[event_target]
pub entity: Entity,
pub position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlTouchStart {
#[event_target]
pub entity: Entity,
pub touch_id: u64,
pub position: Vec2,
pub inner_position: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlTouchMove {
#[event_target]
pub entity: Entity,
pub touch_id: u64,
pub position: Vec2,
pub inner_position: Vec2,
pub delta: Vec2,
}
#[derive(EntityEvent, Clone, Copy)]
pub struct HtmlTouchEnd {
#[event_target]
pub entity: Entity,
pub touch_id: u64,
pub position: Vec2,
pub inner_position: Vec2,
}
pub struct ExtendedUiHtmlPlugin;
impl Plugin for ExtendedUiHtmlPlugin {
fn build(&self, app: &mut App) {
app.add_message::<HtmlChangeEvent>();
app.init_resource::<HtmlStructureMap>();
app.init_resource::<HtmlFunctionRegistry>();
app.init_resource::<HtmlDirty>();
app.init_resource::<HtmlPendingReveal>();
app.init_resource::<HtmlInitDelay>();
app.init_resource::<UILang>();
app.init_resource::<UiLangState>();
app.init_resource::<UiLangVariables>();
app.init_resource::<UiSharedValues>();
app.register_type::<HtmlEventBindings>();
app.register_type::<HtmlSource>();
app.register_type::<HtmlStyle>();
app.register_type::<HtmlInnerContent>();
app.register_type::<HtmlTextBinding>();
app.configure_sets(
Update,
(
HtmlSystemSet::Convert,
HtmlSystemSet::Build,
HtmlSystemSet::ShowWidgets,
HtmlSystemSet::Bindings,
)
.chain(),
);
app.add_plugins((
HtmlConverterSystem,
HtmlBuilderSystem,
HtmlReloadPlugin,
HtmlEventBindingsPlugin,
));
app.add_systems(PreUpdate, sync_shared_values_system);
app.add_systems(Startup, (run_component_inits, register_html_fns));
}
}
fn sync_shared_values_system(world: &mut World) {
refresh_shared_values(world);
#[cfg(feature = "extended-framework")]
sync_ui_binding_store_values(world);
}
pub fn register_html_fns(world: &mut World) {
let mut to_insert: Vec<(String, SystemId<In<HtmlEvent>>)> = Vec::new();
for item in inventory::iter::<HtmlFnRegistration> {
match item {
HtmlFnRegistration::HtmlEvent { name, build } => {
let id = (*build)(world);
to_insert.push(((*name).to_string(), id));
}
HtmlFnRegistration::HtmlClick { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.click_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlMouseDown { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.mousedown_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlMouseUp { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.mouseup_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlChange { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.change_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlSubmit { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.submit_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlInit { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.init_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlMouseOut { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.out_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlMouseOver { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.over_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlFocus { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.focus_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlScroll { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.scroll_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlWheel { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.wheel_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlKeyDown { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.keydown_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlKeyUp { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.keyup_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlDragStart { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.dragstart_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlDrag { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.drag_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlDragStop { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.dragstop_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlTouchStart { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.touchstart_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlTouchMove { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.touchmove_typed
.insert((*name).to_string(), id);
}
HtmlFnRegistration::HtmlTouchEnd { name, build } => {
let id = (*build)(world);
world
.resource_mut::<HtmlFunctionRegistry>()
.touchend_typed
.insert((*name).to_string(), id);
}
}
}
let mut reg = world.resource_mut::<HtmlFunctionRegistry>();
for (name, id) in to_insert {
reg.change.insert(name.clone(), id);
reg.submit.insert(name.clone(), id);
reg.click.insert(name.clone(), id);
reg.mousedown.insert(name.clone(), id);
reg.mouseup.insert(name.clone(), id);
reg.focus.insert(name.clone(), id);
reg.init.insert(name.clone(), id);
reg.scroll.insert(name.clone(), id);
reg.wheel.insert(name.clone(), id);
reg.keydown.insert(name.clone(), id);
reg.keyup.insert(name.clone(), id);
reg.dragstart.insert(name.clone(), id);
reg.drag.insert(name.clone(), id);
reg.dragstop.insert(name.clone(), id);
reg.touchstart.insert(name.clone(), id);
reg.touchmove.insert(name.clone(), id);
reg.touchend.insert(name.clone(), id);
reg.out.insert(name.clone(), id);
reg.over.insert(name.clone(), id);
debug!("Registered html fn '{name}' with id {id:?}");
}
}
pub fn run_component_inits(world: &mut World) {
for item in inventory::iter::<ComponentInitRegistration> {
let id = (item.build)(world);
if let Err(err) = world.run_system(id) {
warn!("component init '{}' failed: {err}", item.name);
}
}
}