1use glib::{Cast, Object};
2use gtk::{self, Widget};
3
4use crate::component::Component;
5use crate::scope::Scope;
6use crate::vnode::VNode;
7
8mod component_state;
9pub(crate) use component_state::ComponentState;
10
11mod gtk_state;
12use gtk_state::GtkState;
13
14pub(crate) enum State<Model: Component> {
15 Gtk(GtkState<Model>),
16 Component(ComponentState<Model>),
17}
18
19impl<Model: 'static + Component> State<Model> {
20 pub(crate) fn build(
22 vnode: &VNode<Model>,
23 parent: Option<&Object>,
24 scope: &Scope<Model>,
25 ) -> Self {
26 match vnode {
27 VNode::Object(object) => State::Gtk(GtkState::build(object, parent, scope)),
28 VNode::Component(vcomp) => {
29 let comp = (vcomp.constructor)(&vcomp.props, parent, &vcomp.child_props, scope);
30 State::Component(comp)
31 }
32 }
33 }
34
35 pub(crate) fn build_root(
37 vnode: &VNode<Model>,
38 parent: Option<&Object>,
39 scope: &Scope<Model>,
40 ) -> Self {
41 match vnode {
42 VNode::Object(object) => State::Gtk(GtkState::build_root(object, parent, scope)),
43 VNode::Component(_vcomp) => {
44 unimplemented!()
47 }
48 }
49 }
50
51 pub(crate) fn build_children(&mut self, vnode: &VNode<Model>, scope: &Scope<Model>) {
52 match vnode {
53 VNode::Object(vobject) => match self {
54 State::Gtk(gtk_state) => gtk_state.build_children(vobject, scope),
55 _ => unimplemented!(),
56 },
57 _ => unimplemented!(),
58 }
59 }
60
61 #[must_use]
65 pub(crate) fn patch(
66 &mut self,
67 vnode: &VNode<Model>,
68 parent: Option<&Object>,
69 scope: &Scope<Model>,
70 ) -> bool {
71 match vnode {
72 VNode::Object(object) => match self {
73 State::Gtk(state) => state.patch(object, parent, scope),
74 State::Component(_) => false,
75 },
76 VNode::Component(vcomp) => match self {
77 State::Component(state) => state.patch(vcomp, parent, scope),
78 State::Gtk(_) => false,
79 },
80 }
81 }
82
83 pub(crate) fn unmount(self) {
84 match self {
85 State::Gtk(state) => state.unmount(),
86 State::Component(state) => state.unmount(),
87 }
88 }
89
90 pub(crate) fn object(&self) -> &Object {
92 match self {
93 State::Gtk(state) => &state.object,
94 State::Component(state) => &state.object,
95 }
96 }
97
98 pub(crate) fn widget(&self) -> Option<&Widget> {
100 match self {
101 State::Gtk(state) => state.object.downcast_ref::<Widget>(),
102 State::Component(state) => state.object.downcast_ref::<Widget>(),
103 }
104 }
105}