make TUI widgets cross framework

This commit is contained in:
Evan Almloff committed 2023-03-24 12:43:51 -05:00
1 parent 9a16687bdc
commit 625dc662d2
32 files changed
+3023 -1091

No files matched your search

+95
View File
@@ -0,0 +1,95 @@
mod button;
mod checkbox;
mod input;
mod number;
mod password;
mod slider;
mod textbox;
use std::sync::{Arc, RwLock};
use dioxus_native_core::{
real_dom::RealDom,
utils::widget_watcher::{Widget, WidgetFactory, WidgetUpdater, WidgetWatcher},
};
use futures_channel::mpsc::UnboundedSender;
use shipyard::{Component, Unique};
use crate::Event;
pub(crate) fn register_widgets(rdom: &mut RealDom, sender: UnboundedSender<Event>) {
// inject the widget context
rdom.raw_world().add_unique(WidgetContext { sender });
// create the widget watcher
let mut widget_watcher = WidgetWatcher::default();
widget_watcher
.register_widget::<RinkWidgetTraitObjectFactory<input::Input>, RinkWidgetTraitObject>();
widget_watcher.attach(rdom);
}
trait RinkWidget: Sync + Send + Widget + 'static {
fn handle_event(&mut self, event: &Event, node: &mut dioxus_native_core::real_dom::NodeMut);
}
pub trait RinkWidgetResponder: WidgetUpdater {
fn handle_event(&mut self, event: &Event, node: &mut dioxus_native_core::real_dom::NodeMut);
}
impl<W: RinkWidget> RinkWidgetResponder for W {
fn handle_event(&mut self, event: &Event, node: &mut dioxus_native_core::real_dom::NodeMut) {
RinkWidget::handle_event(self, event, node)
}
}
struct RinkWidgetTraitObjectFactory<W: RinkWidget> {
_marker: std::marker::PhantomData<W>,
}
impl<W: RinkWidget> WidgetFactory<RinkWidgetTraitObject> for RinkWidgetTraitObjectFactory<W> {
const NAME: &'static str = W::NAME;
fn create(node: &mut dioxus_native_core::real_dom::NodeMut) -> RinkWidgetTraitObject {
let myself = RinkWidgetTraitObject {
widget: Arc::new(RwLock::new(W::create(node))),
};
node.insert(myself.clone());
myself
}
}
#[derive(Clone, Component)]
pub(crate) struct RinkWidgetTraitObject {
widget: Arc<RwLock<dyn RinkWidgetResponder + Send + Sync>>,
}
impl WidgetUpdater for RinkWidgetTraitObject {
fn attributes_changed(
&mut self,
root: dioxus_native_core::real_dom::NodeMut,
attributes: &dioxus_native_core::node_ref::AttributeMask,
) {
let mut widget = self.widget.write().unwrap();
widget.attributes_changed(root, attributes);
}
}
impl RinkWidgetResponder for RinkWidgetTraitObject {
fn handle_event(&mut self, event: &Event, node: &mut dioxus_native_core::real_dom::NodeMut) {
let mut widget = self.widget.write().unwrap();
widget.handle_event(event, node);
}
}
#[derive(Unique)]
pub(crate) struct WidgetContext {
sender: UnboundedSender<Event>,
}
impl WidgetContext {
pub(crate) fn send(&self, event: Event) {
self.sender.unbounded_send(event).unwrap();
}
}