mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 02:39:28 +00:00
Rust: Allocate the window adapter lazily
This will be needed for embedding - to avoid creating two window adapters - and it will be needed for the API to allow creating a component from an existing window.
This commit is contained in:
parent
2a7b20b794
commit
01b00d26eb
21 changed files with 115 additions and 62 deletions
|
@ -327,8 +327,16 @@ fn generate_public_component(llr: &llr::PublicComponent) -> TokenStream {
|
|||
let inner_component_id = inner_component_id(&llr.item_tree.root);
|
||||
let global_container_id = format_ident!("Globals_{}", public_component_id);
|
||||
|
||||
let component =
|
||||
generate_item_tree(&llr.item_tree, llr, None, quote!(globals: #global_container_id), None);
|
||||
let component = generate_item_tree(
|
||||
&llr.item_tree,
|
||||
llr,
|
||||
None,
|
||||
quote!(
|
||||
globals: #global_container_id,
|
||||
window_adapter_: slint::private_unstable_api::re_exports::OnceCell<slint::private_unstable_api::re_exports::Rc<dyn slint::private_unstable_api::re_exports::WindowAdapter>>,
|
||||
),
|
||||
None,
|
||||
);
|
||||
|
||||
let ctx = EvaluationContext {
|
||||
public_component: llr,
|
||||
|
@ -393,15 +401,15 @@ fn generate_public_component(llr: &llr::PublicComponent) -> TokenStream {
|
|||
}
|
||||
|
||||
fn show(&self) -> core::result::Result<(), slint::PlatformError> {
|
||||
self.window().show()
|
||||
self.0.window_adapter_ref()?.window().show()
|
||||
}
|
||||
|
||||
fn hide(&self) -> core::result::Result<(), slint::PlatformError> {
|
||||
self.window().hide()
|
||||
self.0.window_adapter_ref()?.window().hide()
|
||||
}
|
||||
|
||||
fn window(&self) -> &slint::Window {
|
||||
vtable::VRc::as_pin_ref(&self.0).get_ref().window_adapter.get().unwrap().window()
|
||||
self.0.window_adapter_ref().unwrap().window()
|
||||
}
|
||||
|
||||
fn global<'a, T: slint::Global<'a, Self>>(&'a self) -> T {
|
||||
|
@ -989,8 +997,6 @@ fn generate_sub_component(
|
|||
#(#repeated_element_names : slint::private_unstable_api::re_exports::Repeater<#repeated_element_components>,)*
|
||||
self_weak : slint::private_unstable_api::re_exports::OnceCell<slint::private_unstable_api::re_exports::VWeakMapped<slint::private_unstable_api::re_exports::ComponentVTable, #inner_component_id>>,
|
||||
#(parent : #parent_component_type,)*
|
||||
// FIXME: Do we really need a window all the time?
|
||||
window_adapter: slint::private_unstable_api::re_exports::OnceCell<slint::private_unstable_api::re_exports::Rc<dyn slint::private_unstable_api::re_exports::WindowAdapter>>,
|
||||
root : slint::private_unstable_api::re_exports::OnceCell<slint::private_unstable_api::re_exports::VWeak<slint::private_unstable_api::re_exports::ComponentVTable, #root_component_id>>,
|
||||
tree_index: ::core::cell::Cell<u32>,
|
||||
tree_index_of_first_child: ::core::cell::Cell<u32>,
|
||||
|
@ -1006,7 +1012,6 @@ fn generate_sub_component(
|
|||
let _self = self_rc.as_pin_ref();
|
||||
_self.self_weak.set(VRcMapped::downgrade(&self_rc));
|
||||
_self.root.set(VRc::downgrade(root));
|
||||
_self.window_adapter.set(root.window_adapter.get().unwrap().clone());
|
||||
_self.tree_index.set(tree_index);
|
||||
_self.tree_index_of_first_child.set(tree_index_of_first_child);
|
||||
#(#init)*
|
||||
|
@ -1277,12 +1282,28 @@ fn generate_item_tree(
|
|||
quote!(&self_rc)
|
||||
};
|
||||
|
||||
let (create_window_adapter, init_window, new_result, new_end) = if let Some(parent_ctx) =
|
||||
parent_ctx
|
||||
{
|
||||
let (window_adapter_functions, new_result, new_end) = if let Some(parent_ctx) = parent_ctx {
|
||||
(
|
||||
None,
|
||||
None,
|
||||
quote!(
|
||||
#[allow(unused)]
|
||||
fn window_adapter(
|
||||
&self,
|
||||
) -> Rc<dyn slint::private_unstable_api::re_exports::WindowAdapter>
|
||||
{
|
||||
self.root.get().unwrap().upgrade().unwrap().window_adapter()
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn maybe_window_adapter(
|
||||
&self,
|
||||
) -> Option<Rc<dyn slint::private_unstable_api::re_exports::WindowAdapter>>
|
||||
{
|
||||
self.root
|
||||
.get()
|
||||
.and_then(|root_weak| root_weak.upgrade())
|
||||
.and_then(|root| root.maybe_window_adapter())
|
||||
}
|
||||
),
|
||||
quote!(vtable::VRc<slint::private_unstable_api::re_exports::ComponentVTable, Self>),
|
||||
if parent_ctx.repeater_index.is_some() {
|
||||
// Repeaters run their user_init() code from RepeatedComponent::init() after update() initialized model_data/index.
|
||||
|
@ -1296,13 +1317,41 @@ fn generate_item_tree(
|
|||
)
|
||||
} else {
|
||||
(
|
||||
Some(
|
||||
quote!(let window_adapter = slint::private_unstable_api::create_window_adapter()?;),
|
||||
quote!(
|
||||
#[allow(unused)]
|
||||
fn window_adapter(
|
||||
&self,
|
||||
) -> Rc<dyn slint::private_unstable_api::re_exports::WindowAdapter>
|
||||
{
|
||||
self.window_adapter_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
fn window_adapter_ref(
|
||||
&self,
|
||||
) -> Result<
|
||||
&Rc<dyn slint::private_unstable_api::re_exports::WindowAdapter>,
|
||||
slint::PlatformError,
|
||||
> {
|
||||
self.window_adapter_.get_or_try_init(|| {
|
||||
let adapter = slint::private_unstable_api::create_window_adapter()?;
|
||||
let self_rc =
|
||||
VRcMapped::origin(&self.self_weak.get().unwrap().upgrade().unwrap());
|
||||
slint::private_unstable_api::re_exports::WindowInner::from_pub(
|
||||
adapter.window(),
|
||||
)
|
||||
.set_component(&self_rc);
|
||||
core::result::Result::Ok(adapter)
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn maybe_window_adapter(
|
||||
&self,
|
||||
) -> Option<Rc<dyn slint::private_unstable_api::re_exports::WindowAdapter>>
|
||||
{
|
||||
self.window_adapter_.get().cloned()
|
||||
}
|
||||
),
|
||||
Some(quote! {
|
||||
_self.window_adapter.set(window_adapter);
|
||||
slint::private_unstable_api::re_exports::WindowInner::from_pub(_self.window_adapter.get().unwrap().window()).set_component(&VRc::into_dyn(self_rc.clone()));
|
||||
}),
|
||||
quote!(
|
||||
core::result::Result<
|
||||
vtable::VRc<slint::private_unstable_api::re_exports::ComponentVTable, Self>,
|
||||
|
@ -1384,13 +1433,11 @@ fn generate_item_tree(
|
|||
impl #inner_component_id {
|
||||
pub fn new(#(parent: #parent_component_type)*) -> #new_result {
|
||||
#![allow(unused)]
|
||||
#create_window_adapter // We must create the window first to initialize the backend before using the style
|
||||
let mut _self = Self::default();
|
||||
#(_self.parent = parent.clone() as #parent_component_type;)*
|
||||
let self_rc = VRc::new(_self);
|
||||
let _self = self_rc.as_pin_ref();
|
||||
#init_window
|
||||
slint::private_unstable_api::re_exports::register_component(_self, Self::item_array(), #root_token.window_adapter.get().unwrap());
|
||||
slint::private_unstable_api::re_exports::register_component(_self, Self::item_array(), (*#root_token).maybe_window_adapter());
|
||||
Self::init(slint::private_unstable_api::re_exports::VRc::map(self_rc.clone(), |x| x), #root_token, 0, 1);
|
||||
#new_end
|
||||
}
|
||||
|
@ -1407,6 +1454,8 @@ fn generate_item_tree(
|
|||
> = slint::private_unstable_api::re_exports::OnceBox::new();
|
||||
&*ITEM_ARRAY.get_or_init(|| Box::new([#(#item_array),*]))
|
||||
}
|
||||
|
||||
#window_adapter_functions
|
||||
}
|
||||
|
||||
impl slint::private_unstable_api::re_exports::PinnedDrop for #inner_component_id {
|
||||
|
@ -1414,7 +1463,9 @@ fn generate_item_tree(
|
|||
use slint::private_unstable_api::re_exports::*;
|
||||
ComponentVTable_static!(static VT for self::#inner_component_id);
|
||||
new_vref!(let vref : VRef<ComponentVTable> for Component = self.as_ref().get_ref());
|
||||
slint::private_unstable_api::re_exports::unregister_component(self.as_ref(), vref, Self::item_array(), self.window_adapter.get().unwrap());
|
||||
if let Some(wa) = self.maybe_window_adapter() {
|
||||
slint::private_unstable_api::re_exports::unregister_component(self.as_ref(), vref, Self::item_array(), &wa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1788,7 +1839,7 @@ fn follow_sub_component_path<'a>(
|
|||
|
||||
fn access_window_adapter_field(ctx: &EvaluationContext) -> TokenStream {
|
||||
let root = &ctx.generator_state;
|
||||
quote!(#root.window_adapter.get().unwrap())
|
||||
quote!((&#root.window_adapter()))
|
||||
}
|
||||
|
||||
/// Given a property reference to a native item (eg, the property name is empty)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue