Skip to main content

vgtk/vdom/
mod.rs

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    /// Build a full state from a `VItem` spec.
21    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    /// Build a full state from a `VItem` spec.
36    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                // let comp = (vcomp.constructor)(&vcomp.props, parent, &vcomp.child_props, scope);
45                // State::Component(comp)
46                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    /// Patch a state in place with a `VItem` spec.
62    ///
63    /// Returns true if patching succeeded, or false if a rebuild is required.
64    #[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    /// Get the Glib `Object` represented by this state.
91    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    /// Get the Gtk `Widget` represented by this state, if it has a `Widget`.
99    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}