mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Simplify event loop start-up
Move the layout constraint tracker into the window where we can apply the constraints right before drawing, instead of doing that from within the event loop. This allows to remove the component parameter from the run function.
This commit is contained in:
parent
f8e5982ab4
commit
c258a907f0
8 changed files with 57 additions and 66 deletions
|
@ -84,9 +84,7 @@ public:
|
||||||
template<typename Component>
|
template<typename Component>
|
||||||
void run(const Component *c) const
|
void run(const Component *c) const
|
||||||
{
|
{
|
||||||
auto self_rc = c->self_weak.lock().value();
|
sixtyfps_component_window_run(&inner);
|
||||||
sixtyfps_component_window_run(&inner,
|
|
||||||
reinterpret_cast<cbindgen_private::ComponentRc *>(&self_rc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float scale_factor() const { return sixtyfps_component_window_get_scale_factor(&inner); }
|
float scale_factor() const { return sixtyfps_component_window_get_scale_factor(&inner); }
|
||||||
|
|
|
@ -329,7 +329,7 @@ declare_types! {
|
||||||
let component = cx.borrow(&mut this, |x| x.0.clone());
|
let component = cx.borrow(&mut this, |x| x.0.clone());
|
||||||
let component = component.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
|
let component = component.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
|
||||||
run_scoped(&mut cx,this.downcast().unwrap(), || {
|
run_scoped(&mut cx,this.downcast().unwrap(), || {
|
||||||
component.window().run(&vtable::VRc::into_dyn(component));
|
component.window().run();
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
Ok(JsUndefined::new().as_value(&mut cx))
|
Ok(JsUndefined::new().as_value(&mut cx))
|
||||||
|
|
|
@ -127,6 +127,6 @@ impl WrappedCompiledComp {
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn run(&self, canvas_id: String) {
|
pub fn run(&self, canvas_id: String) {
|
||||||
let component = self.0.clone().create(canvas_id);
|
let component = self.0.clone().create(canvas_id);
|
||||||
component.window().run(&vtable::VRc::into_dyn(component));
|
component.window().run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -584,8 +584,7 @@ fn generate_component(
|
||||||
}
|
}
|
||||||
impl sixtyfps::Component for #component_id {
|
impl sixtyfps::Component for #component_id {
|
||||||
fn run(self: ::core::pin::Pin<&Self>) {
|
fn run(self: ::core::pin::Pin<&Self>) {
|
||||||
use sixtyfps::re_exports::*;
|
self.as_ref().window.run();
|
||||||
self.as_ref().window.run(&VRc::into_dyn(self.as_ref().self_weak.get().unwrap().upgrade().unwrap()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
|
@ -22,10 +22,7 @@ use std::{
|
||||||
};
|
};
|
||||||
use vtable::*;
|
use vtable::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::input::{KeyEvent, MouseEventType};
|
||||||
input::{KeyEvent, MouseEventType},
|
|
||||||
properties::PropertyTracker,
|
|
||||||
};
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use winit::platform::desktop::EventLoopExtDesktop;
|
use winit::platform::desktop::EventLoopExtDesktop;
|
||||||
|
|
||||||
|
@ -91,8 +88,6 @@ pub trait GenericWindow {
|
||||||
fn set_height(&self, height: f32);
|
fn set_height(&self, height: f32);
|
||||||
/// Returns the geometry of the window
|
/// Returns the geometry of the window
|
||||||
fn get_geometry(&self) -> crate::graphics::Rect;
|
fn get_geometry(&self) -> crate::graphics::Rect;
|
||||||
/// apply the constraints
|
|
||||||
fn apply_geometry_constraint(&self, constraints: crate::layout::LayoutInfo);
|
|
||||||
|
|
||||||
/// This function is called by the generated code when a component and therefore its tree of items are destroyed. The
|
/// This function is called by the generated code when a component and therefore its tree of items are destroyed. The
|
||||||
/// implementation typically uses this to free the underlying graphics resources cached via [`crate::graphics::RenderingCache`].
|
/// implementation typically uses this to free the underlying graphics resources cached via [`crate::graphics::RenderingCache`].
|
||||||
|
@ -134,12 +129,12 @@ impl ComponentWindow {
|
||||||
Self(window_impl)
|
Self(window_impl)
|
||||||
}
|
}
|
||||||
/// Spins an event loop and renders the items of the provided component in this window.
|
/// Spins an event loop and renders the items of the provided component in this window.
|
||||||
pub fn run(&self, component: &ComponentRc) {
|
pub fn run(&self) {
|
||||||
let event_loop = crate::eventloop::EventLoop::new();
|
let event_loop = crate::eventloop::EventLoop::new();
|
||||||
|
|
||||||
self.0.clone().map_window(&event_loop);
|
self.0.clone().map_window(&event_loop);
|
||||||
|
|
||||||
event_loop.run(ComponentRc::borrow_pin(component));
|
event_loop.run();
|
||||||
|
|
||||||
self.0.clone().unmap_window();
|
self.0.clone().unmap_window();
|
||||||
}
|
}
|
||||||
|
@ -242,10 +237,9 @@ impl EventLoop {
|
||||||
/// Runs the event loop and renders the items in the provided `component` in its
|
/// Runs the event loop and renders the items in the provided `component` in its
|
||||||
/// own window.
|
/// own window.
|
||||||
#[allow(unused_mut)] // mut need changes for wasm
|
#[allow(unused_mut)] // mut need changes for wasm
|
||||||
pub fn run(mut self, component: core::pin::Pin<crate::component::ComponentRef>) {
|
pub fn run(mut self) {
|
||||||
use winit::event::Event;
|
use winit::event::Event;
|
||||||
use winit::event_loop::{ControlFlow, EventLoopWindowTarget};
|
use winit::event_loop::{ControlFlow, EventLoopWindowTarget};
|
||||||
let layout_listener = Rc::pin(PropertyTracker::default());
|
|
||||||
|
|
||||||
let mut cursor_pos = winit::dpi::PhysicalPosition::new(0., 0.);
|
let mut cursor_pos = winit::dpi::PhysicalPosition::new(0., 0.);
|
||||||
let mut pressed = false;
|
let mut pressed = false;
|
||||||
|
@ -265,14 +259,6 @@ impl EventLoop {
|
||||||
if let Some(Some(window)) =
|
if let Some(Some(window)) =
|
||||||
windows.borrow().get(&id).map(|weakref| weakref.upgrade())
|
windows.borrow().get(&id).map(|weakref| weakref.upgrade())
|
||||||
{
|
{
|
||||||
if layout_listener.as_ref().is_dirty() {
|
|
||||||
layout_listener.as_ref().evaluate(|| {
|
|
||||||
window.apply_geometry_constraint(
|
|
||||||
component.as_ref().layout_info(),
|
|
||||||
);
|
|
||||||
component.as_ref().apply_layout(window.get_geometry())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
window.draw();
|
window.draw();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -569,12 +555,9 @@ pub mod ffi {
|
||||||
|
|
||||||
/// Spins an event loop and renders the items of the provided component in this window.
|
/// Spins an event loop and renders the items of the provided component in this window.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sixtyfps_component_window_run(
|
pub unsafe extern "C" fn sixtyfps_component_window_run(handle: *const ComponentWindowOpaque) {
|
||||||
handle: *const ComponentWindowOpaque,
|
|
||||||
component: &ComponentRc,
|
|
||||||
) {
|
|
||||||
let window = &*(handle as *const ComponentWindow);
|
let window = &*(handle as *const ComponentWindow);
|
||||||
window.run(component);
|
window.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the window scale factor.
|
/// Returns the window scale factor.
|
||||||
|
|
|
@ -23,7 +23,7 @@ extern crate alloc;
|
||||||
use crate::component::{ComponentRc, ComponentWeak};
|
use crate::component::{ComponentRc, ComponentWeak};
|
||||||
use crate::input::{KeyEvent, KeyboardModifiers, MouseEvent, MouseEventType};
|
use crate::input::{KeyEvent, KeyboardModifiers, MouseEvent, MouseEventType};
|
||||||
use crate::items::ItemRef;
|
use crate::items::ItemRef;
|
||||||
use crate::properties::{InterpolatedPropertyValue, Property};
|
use crate::properties::{InterpolatedPropertyValue, Property, PropertyTracker};
|
||||||
#[cfg(feature = "rtti")]
|
#[cfg(feature = "rtti")]
|
||||||
use crate::rtti::{BuiltinItem, FieldInfo, PropertyInfo, ValueType};
|
use crate::rtti::{BuiltinItem, FieldInfo, PropertyInfo, ValueType};
|
||||||
use crate::SharedArray;
|
use crate::SharedArray;
|
||||||
|
@ -522,6 +522,7 @@ pub struct GraphicsWindow<Backend: GraphicsBackend + 'static> {
|
||||||
cursor_blinker: std::cell::RefCell<pin_weak::rc::PinWeak<TextCursorBlinker>>,
|
cursor_blinker: std::cell::RefCell<pin_weak::rc::PinWeak<TextCursorBlinker>>,
|
||||||
keyboard_modifiers: std::cell::Cell<KeyboardModifiers>,
|
keyboard_modifiers: std::cell::Cell<KeyboardModifiers>,
|
||||||
component: std::cell::RefCell<ComponentWeak>,
|
component: std::cell::RefCell<ComponentWeak>,
|
||||||
|
layout_listener: Pin<Rc<PropertyTracker>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Backend: GraphicsBackend + 'static> GraphicsWindow<Backend> {
|
impl<Backend: GraphicsBackend + 'static> GraphicsWindow<Backend> {
|
||||||
|
@ -542,6 +543,7 @@ impl<Backend: GraphicsBackend + 'static> GraphicsWindow<Backend> {
|
||||||
cursor_blinker: Default::default(),
|
cursor_blinker: Default::default(),
|
||||||
keyboard_modifiers: Default::default(),
|
keyboard_modifiers: Default::default(),
|
||||||
component: Default::default(),
|
component: Default::default(),
|
||||||
|
layout_listener: Rc::pin(Default::default()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,6 +551,39 @@ impl<Backend: GraphicsBackend + 'static> GraphicsWindow<Backend> {
|
||||||
pub fn id(&self) -> Option<winit::window::WindowId> {
|
pub fn id(&self) -> Option<winit::window::WindowId> {
|
||||||
Some(self.map_state.borrow().as_mapped().backend.borrow().window().id())
|
Some(self.map_state.borrow().as_mapped().backend.borrow().window().id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_geometry_constraint(&self, constraints: crate::layout::LayoutInfo) {
|
||||||
|
match &*self.map_state.borrow() {
|
||||||
|
GraphicsWindowBackendState::Unmapped => {}
|
||||||
|
GraphicsWindowBackendState::Mapped(window) => {
|
||||||
|
if constraints != window.constraints.get() {
|
||||||
|
let min_width = constraints.min_width.min(constraints.max_width);
|
||||||
|
let min_height = constraints.min_height.min(constraints.max_height);
|
||||||
|
let max_width = constraints.max_width.max(constraints.min_width);
|
||||||
|
let max_height = constraints.max_height.max(constraints.min_height);
|
||||||
|
|
||||||
|
window.backend.borrow().window().set_min_inner_size(
|
||||||
|
if min_width > 0. || min_height > 0. {
|
||||||
|
Some(winit::dpi::PhysicalSize::new(min_width, min_height))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
);
|
||||||
|
window.backend.borrow().window().set_max_inner_size(
|
||||||
|
if max_width < f32::MAX || max_height < f32::MAX {
|
||||||
|
Some(winit::dpi::PhysicalSize::new(
|
||||||
|
max_width.min(65535.),
|
||||||
|
max_height.min(65535.),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
);
|
||||||
|
window.constraints.set(constraints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Backend: GraphicsBackend> Drop for GraphicsWindow<Backend> {
|
impl<Backend: GraphicsBackend> Drop for GraphicsWindow<Backend> {
|
||||||
|
@ -574,6 +609,15 @@ impl<Backend: GraphicsBackend> crate::eventloop::GenericWindow for GraphicsWindo
|
||||||
let component = self.component.borrow().upgrade().unwrap();
|
let component = self.component.borrow().upgrade().unwrap();
|
||||||
let component = ComponentRc::borrow_pin(&component);
|
let component = ComponentRc::borrow_pin(&component);
|
||||||
|
|
||||||
|
{
|
||||||
|
if self.layout_listener.as_ref().is_dirty() {
|
||||||
|
self.layout_listener.as_ref().evaluate(|| {
|
||||||
|
self.apply_geometry_constraint(component.as_ref().layout_info());
|
||||||
|
component.as_ref().apply_layout(self.get_geometry())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let map_state = self.map_state.borrow();
|
let map_state = self.map_state.borrow();
|
||||||
let window = map_state.as_mapped();
|
let window = map_state.as_mapped();
|
||||||
|
@ -776,39 +820,6 @@ impl<Backend: GraphicsBackend> crate::eventloop::GenericWindow for GraphicsWindo
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_geometry_constraint(&self, constraints: crate::layout::LayoutInfo) {
|
|
||||||
match &*self.map_state.borrow() {
|
|
||||||
GraphicsWindowBackendState::Unmapped => {}
|
|
||||||
GraphicsWindowBackendState::Mapped(window) => {
|
|
||||||
if constraints != window.constraints.get() {
|
|
||||||
let min_width = constraints.min_width.min(constraints.max_width);
|
|
||||||
let min_height = constraints.min_height.min(constraints.max_height);
|
|
||||||
let max_width = constraints.max_width.max(constraints.min_width);
|
|
||||||
let max_height = constraints.max_height.max(constraints.min_height);
|
|
||||||
|
|
||||||
window.backend.borrow().window().set_min_inner_size(
|
|
||||||
if min_width > 0. || min_height > 0. {
|
|
||||||
Some(winit::dpi::PhysicalSize::new(min_width, min_height))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
);
|
|
||||||
window.backend.borrow().window().set_max_inner_size(
|
|
||||||
if max_width < f32::MAX || max_height < f32::MAX {
|
|
||||||
Some(winit::dpi::PhysicalSize::new(
|
|
||||||
max_width.min(65535.),
|
|
||||||
max_height.min(65535.),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
);
|
|
||||||
window.constraints.set(constraints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn free_graphics_resources(
|
fn free_graphics_resources(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
component: core::pin::Pin<crate::component::ComponentRef>,
|
component: core::pin::Pin<crate::component::ComponentRef>,
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl<'id> ComponentBox<'id> {
|
||||||
pub fn run(self) {
|
pub fn run(self) {
|
||||||
let rc_box = vtable::VRc::new(ErasedComponentBox::from(self));
|
let rc_box = vtable::VRc::new(ErasedComponentBox::from(self));
|
||||||
let window = rc_box.0.window();
|
let window = rc_box.0.window();
|
||||||
window.run(&vtable::VRc::into_dyn(rc_box));
|
window.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,6 @@ fn main() -> std::io::Result<()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let component = c.create();
|
let component = c.create();
|
||||||
component.window().run(&vtable::VRc::into_dyn(component));
|
component.window().run();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue