slint/internal/core/backend.rs
Simon Hausmann 67a2f0ce3f WIP: Make image decoding a feature of the core library
This includes the cache of decoded images, the HTMLImage element support
and the SVG rendering adapter.

The objective is that Image holds an ImageInner, which is not a path
anymore that the backend has to process, but instead always either
decoded image data, a pointer to a static texture or an SVG tree that
can be rendered to the desired size.
2022-07-20 12:57:37 +02:00

104 lines
3.5 KiB
Rust

// Copyright © SixtyFPS GmbH <info@slint-ui.com>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
/*!
The backend is the abstraction for crates that need to do the actual drawing and event loop
*/
use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::string::String;
use crate::window::Window;
#[cfg(feature = "std")]
use once_cell::sync::OnceCell;
#[cfg(all(not(feature = "std"), feature = "unsafe_single_core"))]
use crate::unsafe_single_core::OnceCell;
#[derive(Copy, Clone)]
/// Behavior describing how the event loop should terminate.
pub enum EventLoopQuitBehavior {
/// Terminate the event loop when the last window was closed.
QuitOnLastWindowClosed,
/// Keep the event loop running until [`Backend::quit_event_loop()`] is called.
QuitOnlyExplicitly,
}
/// Interface implemented by back-ends
pub trait Backend: Send + Sync {
/// Instantiate a window for a component.
/// FIXME: should return a Box<dyn PlatformWindow>
fn create_window(&'static self) -> Rc<Window>;
/// Spins an event loop and renders the visible windows.
fn run_event_loop(&'static self, behavior: EventLoopQuitBehavior);
/// Exits the event loop.
fn quit_event_loop(&'static self);
#[cfg(feature = "std")] // FIXME: just because of the Error
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided slice must be a valid TrueType
/// font.
fn register_font_from_memory(
&'static self,
data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>>;
#[cfg(feature = "std")]
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided path must refer to a valid TrueType
/// font.
fn register_font_from_path(
&'static self,
path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>>;
fn register_bitmap_font(&'static self, _font_data: &'static crate::graphics::BitmapFont) {
unimplemented!()
}
fn set_clipboard_text(&'static self, text: String);
fn clipboard_text(&'static self) -> Option<String>;
/// Send an user event to from another thread that should be run in the GUI event loop
fn post_event(&'static self, event: Box<dyn FnOnce() + Send>);
fn duration_since_start(&'static self) -> core::time::Duration {
#[cfg(feature = "std")]
{
let the_beginning = *INITIAL_INSTANT.get_or_init(instant::Instant::now);
instant::Instant::now() - the_beginning
}
#[cfg(not(feature = "std"))]
core::time::Duration::ZERO
}
}
#[cfg(feature = "std")]
static INITIAL_INSTANT: once_cell::sync::OnceCell<instant::Instant> =
once_cell::sync::OnceCell::new();
#[cfg(feature = "std")]
impl std::convert::From<crate::animations::Instant> for instant::Instant {
fn from(our_instant: crate::animations::Instant) -> Self {
let the_beginning = *INITIAL_INSTANT.get_or_init(instant::Instant::now);
the_beginning + core::time::Duration::from_millis(our_instant.0)
}
}
static PRIVATE_BACKEND_INSTANCE: OnceCell<Box<dyn Backend + 'static>> = OnceCell::new();
pub fn instance() -> Option<&'static dyn Backend> {
use core::ops::Deref;
PRIVATE_BACKEND_INSTANCE.get().map(|backend_box| backend_box.deref())
}
pub fn instance_or_init(
factory_fn: impl FnOnce() -> Box<dyn Backend + 'static>,
) -> &'static dyn Backend {
use core::ops::Deref;
PRIVATE_BACKEND_INSTANCE.get_or_init(factory_fn).deref()
}