mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-03 07:04:34 +00:00
WIP: start splitting Window and PLatformWindow
This commit is contained in:
parent
76fbf46f23
commit
f1ce103c7b
6 changed files with 124 additions and 50 deletions
|
@ -10,7 +10,7 @@ LICENSE END */
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
//! Exposed Window API
|
//! Exposed Window API
|
||||||
|
|
||||||
use crate::component::ComponentRc;
|
use crate::component::{ComponentRc, ComponentWeak};
|
||||||
use crate::graphics::Point;
|
use crate::graphics::Point;
|
||||||
use crate::input::{KeyEvent, MouseEventType};
|
use crate::input::{KeyEvent, MouseEventType};
|
||||||
use crate::items::{ItemRc, ItemRef};
|
use crate::items::{ItemRc, ItemRef};
|
||||||
|
@ -24,10 +24,6 @@ use std::rc::Rc;
|
||||||
///
|
///
|
||||||
/// [`crate::graphics`] provides an implementation of this trait for use with [`crate::graphics::GraphicsBackend`].
|
/// [`crate::graphics`] provides an implementation of this trait for use with [`crate::graphics::GraphicsBackend`].
|
||||||
pub trait GenericWindow {
|
pub trait GenericWindow {
|
||||||
/// Associates this window with the specified component. Further event handling and rendering, etc. will be
|
|
||||||
/// done with that component.
|
|
||||||
fn set_component(self: Rc<Self>, component: &ComponentRc);
|
|
||||||
|
|
||||||
/// Draw the items of the specified `component` in the given window.
|
/// Draw the items of the specified `component` in the given window.
|
||||||
fn draw(self: Rc<Self>);
|
fn draw(self: Rc<Self>);
|
||||||
/// Receive a mouse event and pass it to the items of the component to
|
/// Receive a mouse event and pass it to the items of the component to
|
||||||
|
@ -100,21 +96,91 @@ pub trait GenericWindow {
|
||||||
) -> Option<Box<dyn crate::graphics::FontMetrics>>;
|
) -> Option<Box<dyn crate::graphics::FontMetrics>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Structure that represent a Window in the runtime
|
||||||
|
pub struct Window {
|
||||||
|
/// FIXME! use Box instead;
|
||||||
|
platform_window: Rc<dyn GenericWindow>,
|
||||||
|
component: std::cell::RefCell<ComponentWeak>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Window {
|
||||||
|
/// Create a new instance of the window, given the platform_window
|
||||||
|
pub fn new(platform_window: Rc<dyn GenericWindow>) -> Self {
|
||||||
|
Self { platform_window, component: Default::default() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Associates this window with the specified component. Further event handling and rendering, etc. will be
|
||||||
|
/// done with that component.
|
||||||
|
pub fn set_component(&self, component: &ComponentRc) {
|
||||||
|
self.component.replace(ComponentRc::downgrade(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return the component.
|
||||||
|
/// Panics if it wasn't set.
|
||||||
|
pub fn component(&self) -> ComponentRc {
|
||||||
|
self.component.borrow().upgrade().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receive a mouse event and pass it to the items of the component to
|
||||||
|
/// change their state.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// * `pos`: The position of the mouse event in window physical coordinates.
|
||||||
|
/// * `what`: The type of mouse event.
|
||||||
|
/// * `component`: The SixtyFPS compiled component that provides the tree of items.
|
||||||
|
pub fn process_mouse_input(self: Rc<Self>, pos: Point, what: MouseEventType) {
|
||||||
|
self.platform_window.clone().process_mouse_input(pos, what)
|
||||||
|
}
|
||||||
|
/// Receive a key event and pass it to the items of the component to
|
||||||
|
/// change their state.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// * `event`: The key event received by the windowing system.
|
||||||
|
/// * `component`: The SixtyFPS compiled component that provides the tree of items.
|
||||||
|
pub fn process_key_input(self: Rc<Self>, event: &KeyEvent) {
|
||||||
|
self.platform_window.clone().process_key_input(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Installs a binding on the specified property that's toggled whenever the text cursor is supposed to be visible or not.
|
||||||
|
pub fn set_cursor_blink_binding(&self, prop: &crate::properties::Property<bool>) {
|
||||||
|
self.platform_window.clone().set_cursor_blink_binding(prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the focus to the item pointed to by item_ptr. This will remove the focus from any
|
||||||
|
/// currently focused item.
|
||||||
|
pub fn set_focus_item(self: Rc<Self>, focus_item: &ItemRc) {
|
||||||
|
self.platform_window.clone().set_focus_item(focus_item)
|
||||||
|
}
|
||||||
|
/// Sets the focus on the window to true or false, depending on the have_focus argument.
|
||||||
|
/// This results in WindowFocusReceived and WindowFocusLost events.
|
||||||
|
pub fn set_focus(self: Rc<Self>, have_focus: bool) {
|
||||||
|
self.platform_window.clone().set_focus(have_focus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::Deref for Window {
|
||||||
|
type Target = dyn GenericWindow;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&*self.platform_window
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The ComponentWindow is the (rust) facing public type that can render the items
|
/// The ComponentWindow is the (rust) facing public type that can render the items
|
||||||
/// of components to the screen.
|
/// of components to the screen.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ComponentWindow(pub std::rc::Rc<dyn GenericWindow>);
|
pub struct ComponentWindow(pub std::rc::Rc<Window>);
|
||||||
|
|
||||||
impl ComponentWindow {
|
impl ComponentWindow {
|
||||||
/// Creates a new instance of a CompomentWindow based on the given window implementation. Only used
|
/// Creates a new instance of a CompomentWindow based on the given window implementation. Only used
|
||||||
/// internally.
|
/// internally.
|
||||||
pub fn new(window_impl: std::rc::Rc<dyn GenericWindow>) -> Self {
|
pub fn new(window_impl: std::rc::Rc<Window>) -> Self {
|
||||||
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) {
|
pub fn run(&self) {
|
||||||
self.0.clone().run();
|
self.0.platform_window.clone().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the scale factor set on the window.
|
/// Returns the scale factor set on the window.
|
||||||
|
@ -130,12 +196,12 @@ impl ComponentWindow {
|
||||||
/// 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 [RenderingCache][`crate::graphics::RenderingCache`].
|
/// implementation typically uses this to free the underlying graphics resources cached via [RenderingCache][`crate::graphics::RenderingCache`].
|
||||||
pub fn free_graphics_resources<'a>(&self, items: &Slice<'a, Pin<ItemRef<'a>>>) {
|
pub fn free_graphics_resources<'a>(&self, items: &Slice<'a, Pin<ItemRef<'a>>>) {
|
||||||
self.0.clone().free_graphics_resources(items);
|
self.0.platform_window.clone().free_graphics_resources(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Installs a binding on the specified property that's toggled whenever the text cursor is supposed to be visible or not.
|
/// Installs a binding on the specified property that's toggled whenever the text cursor is supposed to be visible or not.
|
||||||
pub(crate) fn set_cursor_blink_binding(&self, prop: &crate::properties::Property<bool>) {
|
pub(crate) fn set_cursor_blink_binding(&self, prop: &crate::properties::Property<bool>) {
|
||||||
self.0.clone().set_cursor_blink_binding(prop)
|
self.0.platform_window.clone().set_cursor_blink_binding(prop)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the currently active keyboard notifiers. This is used only for testing or directly
|
/// Sets the currently active keyboard notifiers. This is used only for testing or directly
|
||||||
|
@ -149,31 +215,31 @@ impl ComponentWindow {
|
||||||
|
|
||||||
/// Returns the currently active keyboard notifiers.
|
/// Returns the currently active keyboard notifiers.
|
||||||
pub(crate) fn current_keyboard_modifiers(&self) -> crate::input::KeyboardModifiers {
|
pub(crate) fn current_keyboard_modifiers(&self) -> crate::input::KeyboardModifiers {
|
||||||
self.0.clone().current_keyboard_modifiers()
|
self.0.platform_window.clone().current_keyboard_modifiers()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn process_key_input(&self, event: &KeyEvent) {
|
pub(crate) fn process_key_input(&self, event: &KeyEvent) {
|
||||||
self.0.clone().process_key_input(event)
|
self.0.platform_window.clone().process_key_input(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the focus on any previously focused item and makes the provided
|
/// Clears the focus on any previously focused item and makes the provided
|
||||||
/// item the focus item, in order to receive future key events.
|
/// item the focus item, in order to receive future key events.
|
||||||
pub fn set_focus_item(&self, focus_item: &ItemRc) {
|
pub fn set_focus_item(&self, focus_item: &ItemRc) {
|
||||||
self.0.clone().set_focus_item(focus_item)
|
self.0.platform_window.clone().set_focus_item(focus_item)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Associates this window with the specified component, for future event handling, etc.
|
/// Associates this window with the specified component, for future event handling, etc.
|
||||||
pub fn set_component(&self, component: &ComponentRc) {
|
pub fn set_component(&self, component: &ComponentRc) {
|
||||||
self.0.clone().set_component(component)
|
self.0.set_component(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show a popup at the given position
|
/// Show a popup at the given position
|
||||||
pub fn show_popup(&self, popup: &ComponentRc, position: Point) {
|
pub fn show_popup(&self, popup: &ComponentRc, position: Point) {
|
||||||
self.0.clone().show_popup(popup, position)
|
self.0.platform_window.clone().show_popup(popup, position)
|
||||||
}
|
}
|
||||||
/// Close the active popup if any
|
/// Close the active popup if any
|
||||||
pub fn close_popup(&self) {
|
pub fn close_popup(&self) {
|
||||||
self.0.clone().close_popup()
|
self.0.platform_window.clone().close_popup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,9 +253,9 @@ pub mod ffi {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
type c_void = ();
|
type c_void = ();
|
||||||
|
|
||||||
/// Same layout as ComponentWindow (fat pointer)
|
/// Same layout as ComponentWindow
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ComponentWindowOpaque(*const c_void, *const c_void);
|
pub struct ComponentWindowOpaque(*const c_void);
|
||||||
|
|
||||||
/// Releases the reference to the component window held by handle.
|
/// Releases the reference to the component window held by handle.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -31,6 +31,7 @@ euclid = "0.22.1"
|
||||||
pin-weak = "1"
|
pin-weak = "1"
|
||||||
scoped-tls-hkt = "0.1"
|
scoped-tls-hkt = "0.1"
|
||||||
smallvec = "1.4.1"
|
smallvec = "1.4.1"
|
||||||
|
once_cell = "1.5"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
web_sys = { version = "0.3", package = "web-sys", features=["console", "WebGlContextAttributes"] }
|
web_sys = { version = "0.3", package = "web-sys", features=["console", "WebGlContextAttributes"] }
|
||||||
|
|
|
@ -11,10 +11,10 @@ LICENSE END */
|
||||||
|
|
||||||
use core::cell::{Cell, RefCell};
|
use core::cell::{Cell, RefCell};
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::{Rc, Weak};
|
||||||
|
|
||||||
use const_field_offset::FieldOffsets;
|
use const_field_offset::FieldOffsets;
|
||||||
use corelib::component::{ComponentRc, ComponentWeak};
|
use corelib::component::ComponentRc;
|
||||||
use corelib::graphics::*;
|
use corelib::graphics::*;
|
||||||
use corelib::input::{KeyEvent, KeyboardModifiers, MouseEvent, MouseEventType, TextCursorBlinker};
|
use corelib::input::{KeyEvent, KeyboardModifiers, MouseEvent, MouseEventType, TextCursorBlinker};
|
||||||
use corelib::items::{ItemRc, ItemRef, ItemWeak};
|
use corelib::items::{ItemRc, ItemRef, ItemWeak};
|
||||||
|
@ -33,12 +33,12 @@ type WindowFactoryFn =
|
||||||
/// GraphicsWindow is an implementation of the [GenericWindow][`crate::eventloop::GenericWindow`] trait. This is
|
/// GraphicsWindow is an implementation of the [GenericWindow][`crate::eventloop::GenericWindow`] trait. This is
|
||||||
/// typically instantiated by entry factory functions of the different graphics backends.
|
/// typically instantiated by entry factory functions of the different graphics backends.
|
||||||
pub struct GraphicsWindow {
|
pub struct GraphicsWindow {
|
||||||
|
pub(crate) self_weak: once_cell::unsync::OnceCell<Weak<corelib::window::Window>>,
|
||||||
window_factory: Box<WindowFactoryFn>,
|
window_factory: Box<WindowFactoryFn>,
|
||||||
map_state: RefCell<GraphicsWindowBackendState>,
|
map_state: RefCell<GraphicsWindowBackendState>,
|
||||||
properties: Pin<Box<WindowProperties>>,
|
properties: Pin<Box<WindowProperties>>,
|
||||||
cursor_blinker: RefCell<pin_weak::rc::PinWeak<TextCursorBlinker>>,
|
|
||||||
keyboard_modifiers: std::cell::Cell<KeyboardModifiers>,
|
keyboard_modifiers: std::cell::Cell<KeyboardModifiers>,
|
||||||
component: std::cell::RefCell<ComponentWeak>,
|
cursor_blinker: RefCell<pin_weak::rc::PinWeak<TextCursorBlinker>>,
|
||||||
/// Gets dirty when the layout restrictions, or some other property of the windows change
|
/// Gets dirty when the layout restrictions, or some other property of the windows change
|
||||||
meta_property_listener: Pin<Rc<PropertyTracker>>,
|
meta_property_listener: Pin<Rc<PropertyTracker>>,
|
||||||
focus_item: std::cell::RefCell<ItemWeak>,
|
focus_item: std::cell::RefCell<ItemWeak>,
|
||||||
|
@ -60,12 +60,12 @@ impl GraphicsWindow {
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> Rc<Self> {
|
) -> Rc<Self> {
|
||||||
Rc::new(Self {
|
Rc::new(Self {
|
||||||
|
self_weak: Default::default(),
|
||||||
window_factory: Box::new(graphics_backend_factory),
|
window_factory: Box::new(graphics_backend_factory),
|
||||||
map_state: RefCell::new(GraphicsWindowBackendState::Unmapped),
|
map_state: RefCell::new(GraphicsWindowBackendState::Unmapped),
|
||||||
properties: Box::pin(WindowProperties::default()),
|
properties: Box::pin(WindowProperties::default()),
|
||||||
cursor_blinker: Default::default(),
|
cursor_blinker: Default::default(),
|
||||||
keyboard_modifiers: Default::default(),
|
keyboard_modifiers: Default::default(),
|
||||||
component: Default::default(),
|
|
||||||
meta_property_listener: Rc::pin(Default::default()),
|
meta_property_listener: Rc::pin(Default::default()),
|
||||||
focus_item: Default::default(),
|
focus_item: Default::default(),
|
||||||
mouse_input_state: Default::default(),
|
mouse_input_state: Default::default(),
|
||||||
|
@ -129,7 +129,7 @@ impl GraphicsWindow {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let component = self.component.borrow().upgrade().unwrap();
|
let component = self.component();
|
||||||
let component = ComponentRc::borrow_pin(&component);
|
let component = ComponentRc::borrow_pin(&component);
|
||||||
let root_item = component.as_ref().get_item_ref(0);
|
let root_item = component.as_ref().get_item_ref(0);
|
||||||
|
|
||||||
|
@ -222,6 +222,10 @@ impl GraphicsWindow {
|
||||||
existing_blinker.stop();
|
existing_blinker.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn component(&self) -> ComponentRc {
|
||||||
|
self.self_weak.get().unwrap().upgrade().unwrap().component()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for GraphicsWindow {
|
impl Drop for GraphicsWindow {
|
||||||
|
@ -239,12 +243,8 @@ impl Drop for GraphicsWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenericWindow for GraphicsWindow {
|
impl GenericWindow for GraphicsWindow {
|
||||||
fn set_component(self: Rc<Self>, component: &ComponentRc) {
|
|
||||||
*self.component.borrow_mut() = vtable::VRc::downgrade(&component)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(self: Rc<Self>) {
|
fn draw(self: Rc<Self>) {
|
||||||
let component_rc = self.component.borrow().upgrade().unwrap();
|
let component_rc = self.component();
|
||||||
let component = ComponentRc::borrow_pin(&component_rc);
|
let component = ComponentRc::borrow_pin(&component_rc);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -326,13 +326,13 @@ impl GenericWindow for GraphicsWindow {
|
||||||
}
|
}
|
||||||
popup.0.clone()
|
popup.0.clone()
|
||||||
} else {
|
} else {
|
||||||
self.component.borrow().upgrade().unwrap()
|
self.component()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.mouse_input_state.set(corelib::input::process_mouse_input(
|
self.mouse_input_state.set(corelib::input::process_mouse_input(
|
||||||
component,
|
component,
|
||||||
MouseEvent { pos, what },
|
MouseEvent { pos, what },
|
||||||
&ComponentWindow::new(self.clone()),
|
&ComponentWindow::new(self.self_weak.get().unwrap().upgrade().unwrap()),
|
||||||
self.mouse_input_state.take(),
|
self.mouse_input_state.take(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ impl GenericWindow for GraphicsWindow {
|
||||||
|
|
||||||
fn process_key_input(self: Rc<Self>, event: &KeyEvent) {
|
fn process_key_input(self: Rc<Self>, event: &KeyEvent) {
|
||||||
if let Some(focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
if let Some(focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
||||||
let window = &ComponentWindow::new(self.clone());
|
let window = &ComponentWindow::new(self.self_weak.get().unwrap().upgrade().unwrap());
|
||||||
focus_item.borrow().as_ref().key_event(event, &window);
|
focus_item.borrow().as_ref().key_event(event, &window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,7 +434,7 @@ impl GenericWindow for GraphicsWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_focus_item(self: Rc<Self>, focus_item: &ItemRc) {
|
fn set_focus_item(self: Rc<Self>, focus_item: &ItemRc) {
|
||||||
let window = ComponentWindow::new(self.clone());
|
let window = &ComponentWindow::new(self.self_weak.get().unwrap().upgrade().unwrap());
|
||||||
|
|
||||||
if let Some(old_focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
if let Some(old_focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
||||||
old_focus_item
|
old_focus_item
|
||||||
|
@ -449,7 +449,7 @@ impl GenericWindow for GraphicsWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_focus(self: Rc<Self>, have_focus: bool) {
|
fn set_focus(self: Rc<Self>, have_focus: bool) {
|
||||||
let window = ComponentWindow::new(self.clone());
|
let window = &ComponentWindow::new(self.self_weak.get().unwrap().upgrade().unwrap());
|
||||||
let event = if have_focus {
|
let event = if have_focus {
|
||||||
corelib::input::FocusEvent::WindowReceivedFocus
|
corelib::input::FocusEvent::WindowReceivedFocus
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1053,14 +1053,17 @@ pub const IS_AVAILABLE: bool = true;
|
||||||
pub struct Backend;
|
pub struct Backend;
|
||||||
impl sixtyfps_corelib::backend::Backend for Backend {
|
impl sixtyfps_corelib::backend::Backend for Backend {
|
||||||
fn create_window(&'static self) -> ComponentWindow {
|
fn create_window(&'static self) -> ComponentWindow {
|
||||||
ComponentWindow::new(GraphicsWindow::new(|event_loop, window_builder| {
|
let platform_window = GraphicsWindow::new(|event_loop, window_builder| {
|
||||||
GLRenderer::new(
|
GLRenderer::new(
|
||||||
&event_loop.get_winit_event_loop(),
|
&event_loop.get_winit_event_loop(),
|
||||||
window_builder,
|
window_builder,
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
"canvas",
|
"canvas",
|
||||||
)
|
)
|
||||||
}))
|
});
|
||||||
|
let window = Rc::new(sixtyfps_corelib::window::Window::new(platform_window.clone()));
|
||||||
|
platform_window.self_weak.set(Rc::downgrade(&window)).ok().unwrap();
|
||||||
|
ComponentWindow(window)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_application_font_from_memory(
|
fn register_application_font_from_memory(
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
LICENSE END */
|
LICENSE END */
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use sixtyfps_corelib::window::ComponentWindow;
|
use sixtyfps_corelib::window::ComponentWindow;
|
||||||
|
|
||||||
#[cfg(not(no_qt))]
|
#[cfg(not(no_qt))]
|
||||||
|
@ -95,7 +97,12 @@ impl sixtyfps_corelib::backend::Backend for Backend {
|
||||||
#[cfg(no_qt)]
|
#[cfg(no_qt)]
|
||||||
panic!("The Qt backend needs Qt");
|
panic!("The Qt backend needs Qt");
|
||||||
#[cfg(not(no_qt))]
|
#[cfg(not(no_qt))]
|
||||||
ComponentWindow::new(qt_window::QtWindow::new())
|
{
|
||||||
|
let qt_window = qt_window::QtWindow::new();
|
||||||
|
let window = Rc::new(sixtyfps_corelib::window::Window::new(qt_window.clone()));
|
||||||
|
qt_window.self_weak.set(Rc::downgrade(&window)).ok().unwrap();
|
||||||
|
ComponentWindow::new(window)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_application_font_from_memory(
|
fn register_application_font_from_memory(
|
||||||
|
|
|
@ -555,7 +555,7 @@ cpp_class!(unsafe struct QWidgetPtr as "std::unique_ptr<QWidget>");
|
||||||
|
|
||||||
pub struct QtWindow {
|
pub struct QtWindow {
|
||||||
widget_ptr: QWidgetPtr,
|
widget_ptr: QWidgetPtr,
|
||||||
self_weak: once_cell::unsync::OnceCell<Weak<QtWindow>>,
|
pub(crate) self_weak: once_cell::unsync::OnceCell<Weak<sixtyfps_corelib::window::Window>>,
|
||||||
component: RefCell<ComponentWeak>,
|
component: RefCell<ComponentWeak>,
|
||||||
/// Gets dirty when the layout restrictions, or some other property of the windows change
|
/// Gets dirty when the layout restrictions, or some other property of the windows change
|
||||||
meta_property_listener: Pin<Rc<PropertyTracker>>,
|
meta_property_listener: Pin<Rc<PropertyTracker>>,
|
||||||
|
@ -565,7 +565,7 @@ pub struct QtWindow {
|
||||||
focus_item: std::cell::RefCell<ItemWeak>,
|
focus_item: std::cell::RefCell<ItemWeak>,
|
||||||
cursor_blinker: RefCell<pin_weak::rc::PinWeak<TextCursorBlinker>>,
|
cursor_blinker: RefCell<pin_weak::rc::PinWeak<TextCursorBlinker>>,
|
||||||
|
|
||||||
popup_window: RefCell<Option<(Rc<QtWindow>, ComponentRc)>>,
|
popup_window: RefCell<Option<(Rc<sixtyfps_corelib::window::Window>, ComponentRc)>>,
|
||||||
|
|
||||||
cache: QtRenderingCache,
|
cache: QtRenderingCache,
|
||||||
|
|
||||||
|
@ -596,7 +596,6 @@ impl QtWindow {
|
||||||
scale_factor: Box::pin(Property::new(1.)),
|
scale_factor: Box::pin(Property::new(1.)),
|
||||||
});
|
});
|
||||||
let self_weak = Rc::downgrade(&rc);
|
let self_weak = Rc::downgrade(&rc);
|
||||||
rc.self_weak.set(self_weak.clone()).ok().unwrap();
|
|
||||||
let widget_ptr = rc.widget_ptr();
|
let widget_ptr = rc.widget_ptr();
|
||||||
let rust_window = Rc::as_ptr(&rc);
|
let rust_window = Rc::as_ptr(&rc);
|
||||||
cpp! {unsafe [widget_ptr as "SixtyFPSWidget*", rust_window as "void*"] {
|
cpp! {unsafe [widget_ptr as "SixtyFPSWidget*", rust_window as "void*"] {
|
||||||
|
@ -758,10 +757,6 @@ impl QtWindow {
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
impl GenericWindow for QtWindow {
|
impl GenericWindow for QtWindow {
|
||||||
fn set_component(self: Rc<Self>, component: &sixtyfps_corelib::component::ComponentRc) {
|
|
||||||
*self.component.borrow_mut() = vtable::VRc::downgrade(&component)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(self: Rc<Self>) {
|
fn draw(self: Rc<Self>) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -777,7 +772,7 @@ impl GenericWindow for QtWindow {
|
||||||
/// ### Candidate to be moved in corelib (same as GraphicsWindow::process_key_input)
|
/// ### Candidate to be moved in corelib (same as GraphicsWindow::process_key_input)
|
||||||
fn process_key_input(self: Rc<Self>, event: &sixtyfps_corelib::input::KeyEvent) {
|
fn process_key_input(self: Rc<Self>, event: &sixtyfps_corelib::input::KeyEvent) {
|
||||||
if let Some(focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
if let Some(focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
||||||
let window = &ComponentWindow::new(self.clone());
|
let window = &ComponentWindow::new(self.self_weak.get().unwrap().upgrade().unwrap());
|
||||||
focus_item.borrow().as_ref().key_event(event, &window);
|
focus_item.borrow().as_ref().key_event(event, &window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -864,7 +859,7 @@ impl GenericWindow for QtWindow {
|
||||||
|
|
||||||
/// ### Candidate to be moved in corelib as this kind of duplicate GraphicsWindow::set_focus_item
|
/// ### Candidate to be moved in corelib as this kind of duplicate GraphicsWindow::set_focus_item
|
||||||
fn set_focus_item(self: Rc<Self>, focus_item: &items::ItemRc) {
|
fn set_focus_item(self: Rc<Self>, focus_item: &items::ItemRc) {
|
||||||
let window = ComponentWindow::new(self.clone());
|
let window = ComponentWindow::new(self.self_weak.get().unwrap().upgrade().unwrap());
|
||||||
|
|
||||||
if let Some(old_focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
if let Some(old_focus_item) = self.as_ref().focus_item.borrow().upgrade() {
|
||||||
old_focus_item
|
old_focus_item
|
||||||
|
@ -883,7 +878,7 @@ impl GenericWindow for QtWindow {
|
||||||
|
|
||||||
/// ### Candidate to be moved in corelib as this kind of duplicate GraphicsWindow::set_focussixtyfps_
|
/// ### Candidate to be moved in corelib as this kind of duplicate GraphicsWindow::set_focussixtyfps_
|
||||||
fn set_focus(self: Rc<Self>, have_focus: bool) {
|
fn set_focus(self: Rc<Self>, have_focus: bool) {
|
||||||
let window = ComponentWindow::new(self.clone());
|
let window = ComponentWindow::new(self.self_weak.get().unwrap().upgrade().unwrap());
|
||||||
let event = if have_focus {
|
let event = if have_focus {
|
||||||
sixtyfps_corelib::input::FocusEvent::WindowReceivedFocus
|
sixtyfps_corelib::input::FocusEvent::WindowReceivedFocus
|
||||||
} else {
|
} else {
|
||||||
|
@ -896,8 +891,10 @@ impl GenericWindow for QtWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_popup(&self, popup: &sixtyfps_corelib::component::ComponentRc, position: Point) {
|
fn show_popup(&self, popup: &sixtyfps_corelib::component::ComponentRc, position: Point) {
|
||||||
let popup_window = Self::new();
|
let popup_window = QtWindow::new();
|
||||||
popup_window.clone().set_component(popup);
|
let window = Rc::new(sixtyfps_corelib::window::Window::new(popup_window.clone()));
|
||||||
|
popup_window.self_weak.set(Rc::downgrade(&window)).ok().unwrap();
|
||||||
|
window.set_component(popup);
|
||||||
let popup_ptr = popup_window.widget_ptr();
|
let popup_ptr = popup_window.widget_ptr();
|
||||||
let pos = qttypes::QPoint { x: position.x as _, y: position.y as _ };
|
let pos = qttypes::QPoint { x: position.x as _, y: position.y as _ };
|
||||||
let widget_ptr = self.widget_ptr();
|
let widget_ptr = self.widget_ptr();
|
||||||
|
@ -906,7 +903,7 @@ impl GenericWindow for QtWindow {
|
||||||
popup_ptr->move(pos + widget_ptr->pos());
|
popup_ptr->move(pos + widget_ptr->pos());
|
||||||
popup_ptr->show();
|
popup_ptr->show();
|
||||||
}};
|
}};
|
||||||
self.popup_window.replace(Some((popup_window, popup.clone())));
|
self.popup_window.replace(Some((window, popup.clone())));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_popup(&self) {
|
fn close_popup(&self) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue