fix dioxus-tui events

This commit is contained in:
Evan Almloff committed 2023-09-06 12:51:02 -05:00
1 parent 0ab7a02777
commit d06e64e5ad
19 files changed
+221 -21

No files matched your search

+1 -3
View File
@@ -14,9 +14,7 @@ fn miri_rollover() {
for _ in 0..3 {
dom.handle_event(
"click",
Rc::new(PlatformEventData::new(Box::new(
SerializedMouseData::default(),
))),
Rc::new(PlatformEventData::new(Box::<SerializedMouseData>::default())),
ElementId(2),
true,
);
+4 -4
View File
@@ -1,7 +1,6 @@
use std::{
any::Any,
fmt::{Display, Formatter},
rc::Rc,
};
use dioxus_core::{ElementId, Mutations, VirtualDom};
@@ -30,7 +29,7 @@ pub(crate) fn find_mount_events(mutations: &Mutations) -> Vec<ElementId> {
// We need to queue the mounted events to give rink time to rendere and resolve the layout of elements after they are created
pub(crate) fn create_mounted_events(
vdom: &VirtualDom,
events: &mut Vec<(ElementId, &'static str, Rc<dyn Any>, bool)>,
events: &mut Vec<(ElementId, &'static str, Box<dyn Any>, bool)>,
mount_events: impl Iterator<Item = (ElementId, NodeId)>,
) {
let query: Query = vdom
@@ -42,11 +41,12 @@ pub(crate) fn create_mounted_events(
query: query.clone(),
id: node_id,
};
events.push((id, "mounted", Rc::new(MountedData::new(element)), false));
events.push((id, "mounted", Box::new(MountedData::new(element)), false));
}
}
struct TuiElement {
#[derive(Clone)]
pub(crate) struct TuiElement {
query: Query,
id: NodeId,
}
+108
View File
@@ -0,0 +1,108 @@
use core::panic;
use dioxus_html::*;
use crate::element::TuiElement;
fn downcast(event: &PlatformEventData) -> plasmo::EventData {
event
.downcast::<plasmo::EventData>()
.expect("event should be of type EventData")
.clone()
}
pub(crate) struct SerializedHtmlEventConverter;
impl HtmlEventConverter for SerializedHtmlEventConverter {
fn convert_animation_data(&self, _: &PlatformEventData) -> AnimationData {
panic!("animation events not supported")
}
fn convert_clipboard_data(&self, _: &PlatformEventData) -> ClipboardData {
panic!("clipboard events not supported")
}
fn convert_composition_data(&self, _: &PlatformEventData) -> CompositionData {
panic!("composition events not supported")
}
fn convert_drag_data(&self, _: &PlatformEventData) -> DragData {
panic!("drag events not supported")
}
fn convert_focus_data(&self, event: &PlatformEventData) -> FocusData {
if let plasmo::EventData::Focus(event) = downcast(event) {
FocusData::new(event)
} else {
panic!("event should be of type Focus")
}
}
fn convert_form_data(&self, event: &PlatformEventData) -> FormData {
if let plasmo::EventData::Form(event) = downcast(event) {
FormData::new(event)
} else {
panic!("event should be of type Form")
}
}
fn convert_image_data(&self, _: &PlatformEventData) -> ImageData {
panic!("image events not supported")
}
fn convert_keyboard_data(&self, event: &PlatformEventData) -> KeyboardData {
if let plasmo::EventData::Keyboard(event) = downcast(event) {
KeyboardData::new(event)
} else {
panic!("event should be of type Keyboard")
}
}
fn convert_media_data(&self, _: &PlatformEventData) -> MediaData {
panic!("media events not supported")
}
fn convert_mounted_data(&self, event: &PlatformEventData) -> MountedData {
event.downcast::<TuiElement>().cloned().unwrap().into()
}
fn convert_mouse_data(&self, event: &PlatformEventData) -> MouseData {
if let plasmo::EventData::Mouse(event) = downcast(event) {
MouseData::new(event)
} else {
panic!("event should be of type Mouse")
}
}
fn convert_pointer_data(&self, _: &PlatformEventData) -> PointerData {
panic!("pointer events not supported")
}
fn convert_scroll_data(&self, _: &PlatformEventData) -> ScrollData {
panic!("scroll events not supported")
}
fn convert_selection_data(&self, _: &PlatformEventData) -> SelectionData {
panic!("selection events not supported")
}
fn convert_toggle_data(&self, _: &PlatformEventData) -> ToggleData {
panic!("toggle events not supported")
}
fn convert_touch_data(&self, _: &PlatformEventData) -> TouchData {
panic!("touch events not supported")
}
fn convert_transition_data(&self, _: &PlatformEventData) -> TransitionData {
panic!("transition events not supported")
}
fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData {
if let plasmo::EventData::Wheel(event) = downcast(event) {
WheelData::new(event)
} else {
panic!("event should be of type Wheel")
}
}
}
+11 -3
View File
@@ -1,4 +1,5 @@
mod element;
mod events;
use std::{
any::Any,
@@ -8,6 +9,7 @@ use std::{
};
use dioxus_core::{Component, ElementId, VirtualDom};
use dioxus_html::PlatformEventData;
use dioxus_native_core::dioxus::{DioxusState, NodeImmutableDioxusExt};
use dioxus_native_core::prelude::*;
@@ -24,6 +26,8 @@ pub fn launch_cfg(app: Component<()>, cfg: Config) {
}
pub fn launch_cfg_with_props<Props: 'static>(app: Component<Props>, props: Props, cfg: Config) {
dioxus_html::set_event_converter(Box::new(events::SerializedHtmlEventConverter));
render(cfg, |rdom, taffy, event_tx| {
let dioxus_state = {
let mut rdom = rdom.write().unwrap();
@@ -81,7 +85,7 @@ struct DioxusRenderer {
vdom: VirtualDom,
dioxus_state: Rc<RwLock<DioxusState>>,
// Events that are queued up to be sent to the vdom next time the vdom is polled
queued_events: Vec<(ElementId, &'static str, Rc<dyn Any>, bool)>,
queued_events: Vec<(ElementId, &'static str, Box<dyn Any>, bool)>,
#[cfg(all(feature = "hot-reload", debug_assertions))]
hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver<dioxus_hot_reload::HotReloadMsg>,
}
@@ -122,15 +126,19 @@ impl Driver for DioxusRenderer {
let id = { rdom.read().unwrap().get(id).unwrap().mounted_id() };
if let Some(id) = id {
let inner_value = value.deref().clone();
let boxed_event = Box::new(inner_value);
let platform_event = PlatformEventData::new(boxed_event);
self.vdom
.handle_event(event, inner_value.into_any(), id, bubbles);
.handle_event(event, Rc::new(platform_event), id, bubbles);
}
}
fn poll_async(&mut self) -> std::pin::Pin<Box<dyn futures::Future<Output = ()> + '_>> {
// Add any queued events
for (id, event, value, bubbles) in self.queued_events.drain(..) {
self.vdom.handle_event(event, value, id, bubbles);
let platform_event = PlatformEventData::new(value);
self.vdom
.handle_event(event, Rc::new(platform_event), id, bubbles);
}
#[cfg(all(feature = "hot-reload", debug_assertions))]
+11
View File
@@ -7,18 +7,29 @@ pub struct AnimationData {
}
impl AnimationData {
/// Create a new AnimationData
pub fn new(inner: impl HasAnimationData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// The name of the animation
pub fn animation_name(&self) -> String {
self.inner.animation_name()
}
/// The name of the pseudo-element the animation runs on
pub fn pseudo_element(&self) -> String {
self.inner.pseudo_element()
}
/// The amount of time the animation has been running
pub fn elapsed_time(&self) -> f32 {
self.inner.elapsed_time()
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_ref().as_any().downcast_ref::<T>()
}
+2
View File
@@ -25,12 +25,14 @@ impl PartialEq for ClipboardData {
}
impl ClipboardData {
/// Create a new ClipboardData
pub fn new(inner: impl HasClipboardData) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_ref().as_any().downcast_ref::<T>()
}
+8
View File
@@ -27,6 +27,14 @@ impl PartialEq for CompositionData {
}
impl CompositionData {
/// Create a new CompositionData
pub fn new(inner: impl HasCompositionData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// The characters generated by the input method that raised the event
pub fn data(&self) -> String {
self.inner.data()
}
+7
View File
@@ -44,6 +44,13 @@ impl PartialEq for DragData {
}
impl DragData {
/// Create a new DragData
pub fn new(inner: impl HasDragData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event data to a specific type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
+7
View File
@@ -25,6 +25,13 @@ impl PartialEq for FocusData {
}
impl FocusData {
/// Create a new FocusData
pub fn new(inner: impl HasFocusData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event data to a specific type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
+7
View File
@@ -46,6 +46,13 @@ impl PartialEq for KeyboardData {
}
impl KeyboardData {
/// Create a new KeyboardData
pub fn new(inner: impl HasKeyboardData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// The value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
pub fn key(&self) -> Key {
self.inner.key()
+7
View File
@@ -24,6 +24,13 @@ impl PartialEq for MediaData {
}
impl MediaData {
/// Create a new MediaData
pub fn new(inner: impl HasMediaData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
+7
View File
@@ -13,6 +13,13 @@ impl<E: HasScrollData> From<E> for ScrollData {
}
impl ScrollData {
/// Create a new ScrollData
pub fn new(inner: impl HasScrollData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
+7
View File
@@ -7,6 +7,13 @@ pub struct SelectionData {
}
impl SelectionData {
/// Create a new SelectionData
pub fn new(inner: impl HasSelectionData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
+7
View File
@@ -25,6 +25,13 @@ impl PartialEq for ToggleData {
}
impl ToggleData {
/// Create a new ToggleData
pub fn new(inner: impl HasToggleData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
+7
View File
@@ -32,6 +32,13 @@ impl PartialEq for TouchData {
}
impl TouchData {
/// Create a new TouchData
pub fn new(inner: impl HasTouchData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Returns true if the "ALT" key was down when the touch event was fired.
pub fn alt_key(&self) -> bool {
self.inner.alt_key()
+7
View File
@@ -31,6 +31,13 @@ impl PartialEq for TransitionData {
}
impl TransitionData {
/// Create a new TransitionData
pub fn new(inner: impl HasTransitionData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
+7
View File
@@ -30,6 +30,13 @@ impl PartialEq for WheelData {
}
impl WheelData {
/// Create a new WheelData
pub fn new(inner: impl HasWheelData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// The amount of wheel movement
#[allow(deprecated)]
pub fn delta(&self) -> WheelDelta {
+2 -1
View File
@@ -1,3 +1,4 @@
use dioxus_html::HasFormData;
use dioxus_native_core::{
prelude::*,
real_dom::{NodeImmutable, NodeTypeMut},
@@ -79,7 +80,7 @@ impl Driver for Counter {
if event_type == "input" {
// when the button is clicked, increment the counter
if let EventData::Form(input_event) = &*event {
if let Ok(value) = input_event.value.parse::<f64>() {
if let Ok(value) = input_event.value().parse::<f64>() {
self.count = value;
}
}
+4 -10
View File
@@ -57,18 +57,18 @@ impl EventData {
EventData::Keyboard(k) => Rc::new(k),
EventData::Focus(f) => Rc::new(f),
EventData::Wheel(w) => Rc::new(w),
EventData::Form(f) => Rc::new(f.into_html()),
EventData::Form(f) => Rc::new(f),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct FormData {
pub value: String,
pub(crate) value: String,
pub values: HashMap<String, Vec<String>>,
pub(crate) values: HashMap<String, Vec<String>>,
pub files: Option<Files>,
pub(crate) files: Option<Files>,
}
impl HasFormData for FormData {
@@ -85,12 +85,6 @@ impl HasFormData for FormData {
}
}
impl FormData {
fn into_html(self) -> dioxus_html::FormData {
dioxus_html::FormData::new(self)
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Files {
files: FxHashMap<String, File>,