Skip to main content

truce_gui/
lib.rs

1//! Built-in GPU-free GUI for truce plugins (heavyweight runtime).
2//!
3//! Uses a [`truce_gui_types::RenderBackend`] trait to abstract over
4//! rendering implementations. The default [`backend_cpu::CpuBackend`]
5//! uses tiny-skia for software rasterization. The non-runtime data
6//! types (layout, widget regions, interaction state, theme, render
7//! trait, plugin-logic trait) live in `truce-gui-types` and
8//! `truce-plugin`; this crate re-exports them so existing
9//! `truce_gui::...` paths keep working.
10
11// Widget-drawing helpers, `RenderBackend` trait methods, and interaction
12// dispatch all take many independent geometry / state / theme arguments.
13// The long signatures are intentional; bundling them into builder
14// structs would obscure call sites without simplifying any single
15// call.
16#![allow(clippy::too_many_arguments)]
17
18pub mod backend_cpu;
19pub mod blit;
20// baseview-bound editor is macOS / Windows / Linux only. iOS
21// embeds the editor in a UIView managed by the AUv3 view
22// controller - see [`editor_ios`].
23#[cfg(not(target_os = "ios"))]
24pub mod editor;
25#[cfg(target_os = "ios")]
26pub mod editor_ios;
27#[cfg(target_os = "ios")]
28pub use editor_ios as editor;
29pub mod font;
30pub mod interaction;
31pub mod platform;
32mod render_core;
33
34// Re-export the lightweight data + trait surface from `truce-gui-types`
35// so old `truce_gui::layout::*` / `truce_gui::widgets::*` /
36// `truce_gui::theme::*` paths continue to resolve. New code can import
37// directly from `truce_gui_types`.
38#[cfg(target_os = "ios")]
39pub use truce_gui_types::ios;
40pub use truce_gui_types::{ImageId, ParamSnapshot, RenderBackend, Theme};
41pub use truce_gui_types::{layout, render, snapshot, theme, widgets};
42
43// Re-export plugin-logic traits from `truce-plugin` for the same
44// backward-compat reason.
45pub use truce_plugin::{PluginLogic, PluginLogic64, PluginLogicCore, default_hit_test};
46
47#[doc(hidden)]
48pub use truce_plugin::__plugin_logic_deps;
49
50pub use editor::BuiltinEditor;
51pub use platform::{EditorScale, to_physical_px};
52
53/// Get the display scale factor used to size the next editor.
54///
55/// Screenshot rendering pins this to a deterministic value via
56/// [`truce_core::screenshot::override_scale`] (default 2.0) so a
57/// reference PNG baked on one host renders at the same physical
58/// dimensions on any other. Outside screenshot rendering the
59/// override is unset and we return the platform's main-screen DPI
60/// query (Retina = 2.0, normal = 1.0).
61#[must_use]
62pub fn backing_scale() -> f64 {
63    if let Some(s) = truce_core::screenshot::override_scale() {
64        return s;
65    }
66    platform::main_screen_scale()
67}
68
69// ---------------------------------------------------------------------------
70// tiny-skia conversions for the light `Color` type
71//
72// `truce-gui-types::theme::Color` doesn't pull in `tiny-skia` (the
73// whole point of the split). The conversion helpers live here so
74// the CPU backend and screenshot pipeline can call them without
75// reimplementing the f32→u8 saturation logic at each site.
76// ---------------------------------------------------------------------------
77
78/// Extension trait giving [`truce_gui_types::theme::Color`] the
79/// `to_skia` / `to_premultiplied` methods that used to live on the
80/// inherent impl, now relocated here so `truce-gui-types` stays
81/// rasterizer-free.
82pub trait ColorExt {
83    fn to_skia(&self) -> tiny_skia::Color;
84    fn to_premultiplied(&self) -> tiny_skia::PremultipliedColorU8;
85}
86
87impl ColorExt for truce_gui_types::theme::Color {
88    fn to_skia(&self) -> tiny_skia::Color {
89        tiny_skia::Color::from_rgba(self.r, self.g, self.b, self.a)
90            .unwrap_or(tiny_skia::Color::BLACK)
91    }
92
93    fn to_premultiplied(&self) -> tiny_skia::PremultipliedColorU8 {
94        self.to_skia().premultiply().to_color_u8()
95    }
96}