Initial implementation of offscreen rendering

This commit is contained in:
Jonathan Johnson 2024-01-03 11:35:43 -08:00
parent 244797110e
commit be0399279c
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
43 changed files with 1617 additions and 638 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
target/ target/
examples/offscreen*.png

39
Cargo.lock generated
View file

@ -574,6 +574,7 @@ dependencies = [
"ahash", "ahash",
"alot", "alot",
"arboard", "arboard",
"bytemuck",
"cushy-macros", "cushy-macros",
"figures", "figures",
"image", "image",
@ -1179,7 +1180,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]] [[package]]
name = "kludgine" name = "kludgine"
version = "0.7.0" version = "0.7.0"
source = "git+https://github.com/khonsulabs/kludgine#0bda2a6dc273aa49338f23ea5190aefdf037d740" source = "git+https://github.com/khonsulabs/kludgine#9999ff4a323a6dec1deebb9a0a1825d561559478"
dependencies = [ dependencies = [
"ahash", "ahash",
"alot", "alot",
@ -1827,9 +1828,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
[[package]] [[package]]
name = "prettyplease" name = "prettyplease"
version = "0.2.15" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn", "syn",
@ -1858,9 +1859,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.71" version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -1891,9 +1892,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.33" version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -2173,18 +2174,18 @@ checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.193" version = "1.0.194"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.193" version = "1.0.194"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2331,9 +2332,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.43" version = "2.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2360,18 +2361,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.52" version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d" checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.52" version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3" checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3185,9 +3186,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.29.7" version = "0.29.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fd430cd4560ee9c48885a4ef473b609a56796e37b1e18222abee146143f7457" checksum = "0dc1a7ae1076890701c7dd71ea35b2aebaf9aeb7b8868ac2d33b1c7e8ef93c00"
dependencies = [ dependencies = [
"ahash", "ahash",
"android-activity", "android-activity",

View file

@ -39,6 +39,8 @@ cushy-macros = { version = "0.2.0", path = "cushy-macros" }
arboard = "3.2.1" arboard = "3.2.1"
zeroize = "1.6.1" zeroize = "1.6.1"
unicode-segmentation = "1.10.1" unicode-segmentation = "1.10.1"
pollster = "0.3.0"
bytemuck = "1.14.0"
# [patch.crates-io] # [patch.crates-io]
@ -57,7 +59,6 @@ unicode-segmentation = "1.10.1"
opt-level = 2 opt-level = 2
[dev-dependencies] [dev-dependencies]
pollster = "0.3.0"
rand = "0.8.5" rand = "0.8.5"
image = { version = "0.24.7", features = ["png"] } image = { version = "0.24.7", features = ["png"] }

View file

@ -90,14 +90,14 @@ impl Default for Toggle {
} }
impl Widget for Toggle { impl Widget for Toggle {
fn redraw(&mut self, context: &mut cushy::context::GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut cushy::context::GraphicsContext<'_, '_, '_, '_>) {
context.fill(self.color.get_tracking_redraw(context)); context.fill(self.color.get_tracking_redraw(context));
} }
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<cushy::ConstraintLimit>, available_space: Size<cushy::ConstraintLimit>,
context: &mut cushy::context::LayoutContext<'_, '_, '_, '_, '_>, context: &mut cushy::context::LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
Size::new( Size::new(
available_space.width.min(), available_space.width.min(),
@ -108,7 +108,7 @@ impl Widget for Toggle {
fn hit_test( fn hit_test(
&mut self, &mut self,
_location: figures::Point<figures::units::Px>, _location: figures::Point<figures::units::Px>,
_context: &mut cushy::context::EventContext<'_, '_>, _context: &mut cushy::context::EventContext<'_>,
) -> bool { ) -> bool {
true true
} }
@ -118,7 +118,7 @@ impl Widget for Toggle {
_location: figures::Point<figures::units::Px>, _location: figures::Point<figures::units::Px>,
_device_id: kludgine::app::winit::event::DeviceId, _device_id: kludgine::app::winit::event::DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
_context: &mut cushy::context::EventContext<'_, '_>, _context: &mut cushy::context::EventContext<'_>,
) -> cushy::widget::EventHandling { ) -> cushy::widget::EventHandling {
self.value.toggle(); self.value.toggle();

46
examples/offscreen.rs Normal file
View file

@ -0,0 +1,46 @@
use cushy::widget::MakeWidget;
use figures::Size;
fn ui() -> impl MakeWidget {
"Hello World".into_button().centered()
}
fn main() {
// The default recorder generated solid, rgb images.
let recorder = ui()
.build_recorder()
.size(Size::new(320, 240))
.finish()
.unwrap();
image::save_buffer_with_format(
"examples/offscreen.png",
recorder.bytes(),
recorder.size().width.get(),
recorder.size().height.get(),
image::ColorType::Rgb8,
image::ImageFormat::Png,
)
.unwrap();
// Creating a recorder with alpha makes the virtual window transparent.
let recorder = ui()
.build_recorder()
.with_alpha()
.size(Size::new(320, 240))
.finish()
.unwrap();
image::save_buffer_with_format(
"examples/offscreen-transparent.png",
recorder.bytes(),
recorder.size().width.get(),
recorder.size().height.get(),
image::ColorType::Rgba8,
image::ImageFormat::Png,
)
.unwrap();
}
#[test]
fn runs() {
main();
}

View file

@ -30,11 +30,7 @@ impl Default for PendingApp {
fn default() -> Self { fn default() -> Self {
Self { Self {
app: kludgine::app::PendingApp::default(), app: kludgine::app::PendingApp::default(),
cushy: Cushy { cushy: Cushy::new(),
clipboard: Clipboard::new()
.ok()
.map(|clipboard| Arc::new(Mutex::new(clipboard))),
},
} }
} }
} }
@ -52,6 +48,14 @@ pub struct Cushy {
} }
impl Cushy { impl Cushy {
pub(crate) fn new() -> Self {
Self {
clipboard: Clipboard::new()
.ok()
.map(|clipboard| Arc::new(Mutex::new(clipboard))),
}
}
/// Returns a locked mutex guard to the OS's clipboard, if one was able to be /// Returns a locked mutex guard to the OS's clipboard, if one was able to be
/// initialized when the window opened. /// initialized when the window opened.
#[must_use] #[must_use]
@ -77,7 +81,7 @@ impl Application for PendingApp {
fn as_app(&self) -> App { fn as_app(&self) -> App {
App { App {
app: self.app.as_app(), app: Some(self.app.as_app()),
cushy: self.cushy.clone(), cushy: self.cushy.clone(),
} }
} }
@ -86,7 +90,7 @@ impl Application for PendingApp {
/// A handle to a Cushy application. /// A handle to a Cushy application.
#[derive(Clone)] #[derive(Clone)]
pub struct App { pub struct App {
app: kludgine::app::App<WindowCommand>, app: Option<kludgine::app::App<WindowCommand>>,
cushy: Cushy, cushy: Cushy,
} }
@ -102,7 +106,10 @@ impl Application for App {
impl AsApplication<AppEvent<WindowCommand>> for App { impl AsApplication<AppEvent<WindowCommand>> for App {
fn as_application(&self) -> &dyn kludgine::app::Application<AppEvent<WindowCommand>> { fn as_application(&self) -> &dyn kludgine::app::Application<AppEvent<WindowCommand>> {
self.app.as_application() self.app
.as_ref()
.map(AsApplication::as_application)
.expect("no app")
} }
} }

View file

@ -21,16 +21,16 @@ use crate::styles::{ComponentDefinition, Styles, Theme, ThemePair};
use crate::tree::Tree; use crate::tree::Tree;
use crate::value::{IntoValue, Source, Value}; use crate::value::{IntoValue, Source, Value};
use crate::widget::{EventHandling, MountedWidget, RootBehavior, WidgetId, WidgetInstance}; use crate::widget::{EventHandling, MountedWidget, RootBehavior, WidgetId, WidgetInstance};
use crate::window::{CursorState, RunningWindow, ThemeMode}; use crate::window::{CursorState, PlatformWindow, ThemeMode};
use crate::ConstraintLimit; use crate::ConstraintLimit;
/// A context to an event function. /// A context to an event function.
/// ///
/// This type is a combination of a reference to the rendering library, /// This type is a combination of a reference to the rendering library,
/// [`Kludgine`], and a [`WidgetContext`]. /// [`Kludgine`], and a [`WidgetContext`].
pub struct EventContext<'context, 'window> { pub struct EventContext<'context> {
/// The context for the widget receiving the event. /// The context for the widget receiving the event.
pub widget: WidgetContext<'context, 'window>, pub widget: WidgetContext<'context>,
/// The rendering library's state. /// The rendering library's state.
/// ///
/// This is useful for accessing the current [scale](Kludgine::scale) or /// This is useful for accessing the current [scale](Kludgine::scale) or
@ -38,13 +38,10 @@ pub struct EventContext<'context, 'window> {
pub kludgine: &'context mut Kludgine, pub kludgine: &'context mut Kludgine,
} }
impl<'context, 'window> EventContext<'context, 'window> { impl<'context> EventContext<'context> {
const MAX_PENDING_CHANGE_CYCLES: u8 = 100; const MAX_PENDING_CHANGE_CYCLES: u8 = 100;
pub(crate) fn new( pub(crate) fn new(widget: WidgetContext<'context>, kludgine: &'context mut Kludgine) -> Self {
widget: WidgetContext<'context, 'window>,
kludgine: &'context mut Kludgine,
) -> Self {
Self { widget, kludgine } Self { widget, kludgine }
} }
@ -58,10 +55,10 @@ impl<'context, 'window> EventContext<'context, 'window> {
pub fn for_other<'child, Widget>( pub fn for_other<'child, Widget>(
&'child mut self, &'child mut self,
widget: &Widget, widget: &Widget,
) -> <Widget::Managed as MapManagedWidget<EventContext<'child, 'window>>>::Result ) -> <Widget::Managed as MapManagedWidget<EventContext<'child>>>::Result
where where
Widget: ManageWidget, Widget: ManageWidget,
Widget::Managed: MapManagedWidget<EventContext<'child, 'window>>, Widget::Managed: MapManagedWidget<EventContext<'child>>,
{ {
widget widget
.manage(self) .manage(self)
@ -177,7 +174,8 @@ impl<'context, 'window> EventContext<'context, 'window> {
cursor = widget_cursor; cursor = widget_cursor;
} }
} }
self.winit().set_cursor_icon(cursor.unwrap_or_default()); self.window_mut()
.set_cursor_icon(cursor.unwrap_or_default());
} }
pub(crate) fn clear_hover(&mut self) { pub(crate) fn clear_hover(&mut self) {
@ -189,7 +187,7 @@ impl<'context, 'window> EventContext<'context, 'window> {
old_hover.lock().as_widget().unhover(&mut old_hover_context); old_hover.lock().as_widget().unhover(&mut old_hover_context);
} }
self.winit().set_cursor_icon(CursorIcon::Default); self.window_mut().set_cursor_icon(CursorIcon::Default);
} }
fn apply_pending_activation(&mut self) { fn apply_pending_activation(&mut self) {
@ -480,15 +478,15 @@ impl<'context, 'window> EventContext<'context, 'window> {
} }
} }
impl<'context, 'window> Deref for EventContext<'context, 'window> { impl<'context> Deref for EventContext<'context> {
type Target = WidgetContext<'context, 'window>; type Target = WidgetContext<'context>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.widget &self.widget
} }
} }
impl<'context, 'window> DerefMut for EventContext<'context, 'window> { impl<'context> DerefMut for EventContext<'context> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.widget &mut self.widget
} }
@ -523,18 +521,18 @@ impl<T> DerefMut for Exclusive<'_, T> {
} }
/// A context to a function that is rendering a widget. /// A context to a function that is rendering a widget.
pub struct GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass> { pub struct GraphicsContext<'context, 'clip, 'gfx, 'pass> {
/// The context of the widget being rendered. /// The context of the widget being rendered.
pub widget: WidgetContext<'context, 'window>, pub widget: WidgetContext<'context>,
/// The graphics context clipped and offset to the area of the widget being /// The graphics context clipped and offset to the area of the widget being
/// rendered. Drawing at 0,0 will draw at the top-left pixel of the laid-out /// rendered. Drawing at 0,0 will draw at the top-left pixel of the laid-out
/// widget region. /// widget region.
pub gfx: Exclusive<'context, Graphics<'clip, 'gfx, 'pass>>, pub gfx: Exclusive<'context, Graphics<'clip, 'gfx, 'pass>>,
} }
impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass> { impl<'context, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'clip, 'gfx, 'pass> {
/// Returns a new instance that borrows from `self`. /// Returns a new instance that borrows from `self`.
pub fn borrowed(&mut self) -> GraphicsContext<'_, 'window, 'clip, 'gfx, 'pass> { pub fn borrowed(&mut self) -> GraphicsContext<'_, 'clip, 'gfx, 'pass> {
GraphicsContext { GraphicsContext {
widget: self.widget.borrowed(), widget: self.widget.borrowed(),
gfx: Exclusive::Borrowed(&mut self.gfx), gfx: Exclusive::Borrowed(&mut self.gfx),
@ -546,12 +544,10 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, '
pub fn for_other<'child, Widget>( pub fn for_other<'child, Widget>(
&'child mut self, &'child mut self,
widget: &Widget, widget: &Widget,
) -> <Widget::Managed as MapManagedWidget< ) -> <Widget::Managed as MapManagedWidget<GraphicsContext<'child, 'child, 'gfx, 'pass>>>::Result
GraphicsContext<'child, 'window, 'child, 'gfx, 'pass>,
>>::Result
where where
Widget: ManageWidget, Widget: ManageWidget,
Widget::Managed: MapManagedWidget<GraphicsContext<'child, 'window, 'child, 'gfx, 'pass>>, Widget::Managed: MapManagedWidget<GraphicsContext<'child, 'child, 'gfx, 'pass>>,
{ {
let opacity = self.get(&Opacity); let opacity = self.get(&Opacity);
widget.manage(self).map(|widget| { widget.manage(self).map(|widget| {
@ -577,7 +573,7 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, '
} }
/// Returns a new graphics context that renders to the `clip` rectangle. /// Returns a new graphics context that renders to the `clip` rectangle.
pub fn clipped_to(&mut self, clip: Rect<Px>) -> GraphicsContext<'_, 'window, '_, 'gfx, 'pass> { pub fn clipped_to(&mut self, clip: Rect<Px>) -> GraphicsContext<'_, '_, 'gfx, 'pass> {
GraphicsContext { GraphicsContext {
widget: self.widget.borrowed(), widget: self.widget.borrowed(),
gfx: Exclusive::Owned(self.gfx.clipped_to(clip)), gfx: Exclusive::Owned(self.gfx.clipped_to(clip)),
@ -675,7 +671,7 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> GraphicsContext<'context, 'window, '
} }
} }
impl Drop for GraphicsContext<'_, '_, '_, '_, '_> { impl Drop for GraphicsContext<'_, '_, '_, '_> {
fn drop(&mut self) { fn drop(&mut self) {
if matches!(self.widget.pending_state, PendingState::Owned(_)) { if matches!(self.widget.pending_state, PendingState::Owned(_)) {
self.as_event_context().apply_pending_state(); self.as_event_context().apply_pending_state();
@ -683,36 +679,30 @@ impl Drop for GraphicsContext<'_, '_, '_, '_, '_> {
} }
} }
impl<'context, 'window, 'clip, 'gfx, 'pass> Deref impl<'context, 'clip, 'gfx, 'pass> Deref for GraphicsContext<'context, 'clip, 'gfx, 'pass> {
for GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass> type Target = WidgetContext<'context>;
{
type Target = WidgetContext<'context, 'window>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.widget &self.widget
} }
} }
impl<'context, 'window, 'clip, 'gfx, 'pass> DerefMut impl<'context, 'clip, 'gfx, 'pass> DerefMut for GraphicsContext<'context, 'clip, 'gfx, 'pass> {
for GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>
{
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.widget &mut self.widget
} }
} }
/// A context to a function that is rendering a widget. /// A context to a function that is rendering a widget.
pub struct LayoutContext<'context, 'window, 'clip, 'gfx, 'pass> { pub struct LayoutContext<'context, 'clip, 'gfx, 'pass> {
/// The graphics context that this layout operation is being performed /// The graphics context that this layout operation is being performed
/// within. /// within.
pub graphics: GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, pub graphics: GraphicsContext<'context, 'clip, 'gfx, 'pass>,
persist_layout: bool, persist_layout: bool,
} }
impl<'context, 'window, 'clip, 'gfx, 'pass> LayoutContext<'context, 'window, 'clip, 'gfx, 'pass> { impl<'context, 'clip, 'gfx, 'pass> LayoutContext<'context, 'clip, 'gfx, 'pass> {
pub(crate) fn new( pub(crate) fn new(graphics: &'context mut GraphicsContext<'_, 'clip, 'gfx, 'pass>) -> Self {
graphics: &'context mut GraphicsContext<'_, 'window, 'clip, 'gfx, 'pass>,
) -> Self {
Self { Self {
graphics: graphics.borrowed(), graphics: graphics.borrowed(),
persist_layout: true, persist_layout: true,
@ -736,10 +726,10 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> LayoutContext<'context, 'window, 'cl
pub fn for_other<'child, Widget>( pub fn for_other<'child, Widget>(
&'child mut self, &'child mut self,
widget: &Widget, widget: &Widget,
) -> <Widget::Managed as MapManagedWidget<LayoutContext<'child, 'window, 'child, 'gfx, 'pass>>>::Result ) -> <Widget::Managed as MapManagedWidget<LayoutContext<'child, 'child, 'gfx, 'pass>>>::Result
where where
Widget: ManageWidget, Widget: ManageWidget,
Widget::Managed: MapManagedWidget<LayoutContext<'child, 'window, 'child, 'gfx, 'pass>>, Widget::Managed: MapManagedWidget<LayoutContext<'child, 'child, 'gfx, 'pass>>,
{ {
widget.manage(self).map(|widget| LayoutContext { widget.manage(self).map(|widget| LayoutContext {
graphics: self.graphics.for_other(&widget), graphics: self.graphics.for_other(&widget),
@ -782,36 +772,30 @@ impl<'context, 'window, 'clip, 'gfx, 'pass> LayoutContext<'context, 'window, 'cl
} }
} }
impl<'context, 'window, 'clip, 'gfx, 'pass> AsEventContext<'window> impl<'context, 'clip, 'gfx, 'pass> AsEventContext for LayoutContext<'context, 'clip, 'gfx, 'pass> {
for LayoutContext<'context, 'window, 'clip, 'gfx, 'pass> fn as_event_context(&mut self) -> EventContext<'_> {
{
fn as_event_context(&mut self) -> EventContext<'_, 'window> {
self.graphics.as_event_context() self.graphics.as_event_context()
} }
} }
impl<'context, 'window, 'clip, 'gfx, 'pass> Deref impl<'context, 'clip, 'gfx, 'pass> Deref for LayoutContext<'context, 'clip, 'gfx, 'pass> {
for LayoutContext<'context, 'window, 'clip, 'gfx, 'pass> type Target = GraphicsContext<'context, 'clip, 'gfx, 'pass>;
{
type Target = GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.graphics &self.graphics
} }
} }
impl<'context, 'window, 'clip, 'gfx, 'pass> DerefMut impl<'context, 'clip, 'gfx, 'pass> DerefMut for LayoutContext<'context, 'clip, 'gfx, 'pass> {
for LayoutContext<'context, 'window, 'clip, 'gfx, 'pass>
{
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.graphics &mut self.graphics
} }
} }
/// Converts from one context to an [`EventContext`]. /// Converts from one context to an [`EventContext`].
pub trait AsEventContext<'window> { pub trait AsEventContext {
/// Returns this context as an [`EventContext`]. /// Returns this context as an [`EventContext`].
fn as_event_context(&mut self) -> EventContext<'_, 'window>; fn as_event_context(&mut self) -> EventContext<'_>;
/// Pushes a new child widget into the widget hierarchy beneathq the /// Pushes a new child widget into the widget hierarchy beneathq the
/// context's widget. /// context's widget.
@ -837,14 +821,14 @@ pub trait AsEventContext<'window> {
} }
} }
impl<'window> AsEventContext<'window> for EventContext<'_, 'window> { impl AsEventContext for EventContext<'_> {
fn as_event_context(&mut self) -> EventContext<'_, 'window> { fn as_event_context(&mut self) -> EventContext<'_> {
EventContext::new(self.widget.borrowed(), self.kludgine) EventContext::new(self.widget.borrowed(), self.kludgine)
} }
} }
impl<'window> AsEventContext<'window> for GraphicsContext<'_, 'window, '_, '_, '_> { impl AsEventContext for GraphicsContext<'_, '_, '_, '_> {
fn as_event_context(&mut self) -> EventContext<'_, 'window> { fn as_event_context(&mut self) -> EventContext<'_> {
EventContext::new(self.widget.borrowed(), &mut self.gfx) EventContext::new(self.widget.borrowed(), &mut self.gfx)
} }
} }
@ -853,10 +837,10 @@ impl<'window> AsEventContext<'window> for GraphicsContext<'_, 'window, '_, '_, '
/// ///
/// This type provides access to the widget hierarchy from the perspective of a /// This type provides access to the widget hierarchy from the perspective of a
/// specific widget. /// specific widget.
pub struct WidgetContext<'context, 'window> { pub struct WidgetContext<'context> {
current_node: MountedWidget, current_node: MountedWidget,
pub(crate) tree: Tree, pub(crate) tree: Tree,
window: &'context mut RunningWindow<'window>, window: &'context mut dyn PlatformWindow,
theme: Cow<'context, ThemePair>, theme: Cow<'context, ThemePair>,
cursor: &'context mut CursorState, cursor: &'context mut CursorState,
pending_state: PendingState<'context>, pending_state: PendingState<'context>,
@ -864,11 +848,11 @@ pub struct WidgetContext<'context, 'window> {
cache: WidgetCacheKey, cache: WidgetCacheKey,
} }
impl<'context, 'window> WidgetContext<'context, 'window> { impl<'context> WidgetContext<'context> {
pub(crate) fn new( pub(crate) fn new(
current_node: MountedWidget, current_node: MountedWidget,
theme: &'context ThemePair, theme: &'context ThemePair,
window: &'context mut RunningWindow<'window>, window: &'context mut dyn PlatformWindow,
theme_mode: ThemeMode, theme_mode: ThemeMode,
cursor: &'context mut CursorState, cursor: &'context mut CursorState,
) -> Self { ) -> Self {
@ -899,7 +883,7 @@ impl<'context, 'window> WidgetContext<'context, 'window> {
} }
/// Returns a new instance that borrows from `self`. /// Returns a new instance that borrows from `self`.
pub fn borrowed(&mut self) -> WidgetContext<'_, 'window> { pub fn borrowed(&mut self) -> WidgetContext<'_> {
WidgetContext { WidgetContext {
tree: self.tree.clone(), tree: self.tree.clone(),
current_node: self.current_node.clone(), current_node: self.current_node.clone(),
@ -916,10 +900,10 @@ impl<'context, 'window> WidgetContext<'context, 'window> {
pub fn for_other<'child, Widget>( pub fn for_other<'child, Widget>(
&'child mut self, &'child mut self,
widget: &Widget, widget: &Widget,
) -> <Widget::Managed as MapManagedWidget<WidgetContext<'child, 'window>>>::Result ) -> <Widget::Managed as MapManagedWidget<WidgetContext<'child>>>::Result
where where
Widget: ManageWidget, Widget: ManageWidget,
Widget::Managed: MapManagedWidget<WidgetContext<'child, 'window>>, Widget::Managed: MapManagedWidget<WidgetContext<'child>>,
{ {
widget.manage(self).map(|current_node| { widget.manage(self).map(|current_node| {
let (effective_styles, theme, theme_mode) = current_node.overidden_theme(); let (effective_styles, theme, theme_mode) = current_node.overidden_theme();
@ -1159,13 +1143,13 @@ impl<'context, 'window> WidgetContext<'context, 'window> {
/// Returns the window containing this widget. /// Returns the window containing this widget.
#[must_use] #[must_use]
pub fn window(&self) -> &RunningWindow<'window> { pub fn window(&self) -> &dyn PlatformWindow {
self.window self.window
} }
/// Returns an exclusive reference to the window containing this widget. /// Returns an exclusive reference to the window containing this widget.
#[must_use] #[must_use]
pub fn window_mut(&mut self) -> &mut RunningWindow<'window> { pub fn window_mut(&mut self) -> &mut dyn PlatformWindow {
self.window self.window
} }
@ -1201,9 +1185,7 @@ impl<'context, 'window> WidgetContext<'context, 'window> {
} }
} }
impl dyn AsEventContext<'_> {} impl Drop for EventContext<'_> {
impl Drop for EventContext<'_, '_> {
fn drop(&mut self) { fn drop(&mut self) {
if matches!(self.widget.pending_state, PendingState::Owned(_)) { if matches!(self.widget.pending_state, PendingState::Owned(_)) {
self.apply_pending_state(); self.apply_pending_state();
@ -1211,17 +1193,17 @@ impl Drop for EventContext<'_, '_> {
} }
} }
impl<'window> Deref for WidgetContext<'_, 'window> { impl<'context> Deref for WidgetContext<'context> {
type Target = RunningWindow<'window>; type Target = &'context mut dyn PlatformWindow;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.window &self.window
} }
} }
impl<'window> DerefMut for WidgetContext<'_, 'window> { impl DerefMut for WidgetContext<'_> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
self.window &mut self.window
} }
} }
@ -1270,13 +1252,13 @@ pub trait ManageWidget {
type Managed: MapManagedWidget<MountedWidget>; type Managed: MapManagedWidget<MountedWidget>;
/// Resolve `self` into a [`MountedWidget`]. /// Resolve `self` into a [`MountedWidget`].
fn manage(&self, context: &WidgetContext<'_, '_>) -> Self::Managed; fn manage(&self, context: &WidgetContext<'_>) -> Self::Managed;
} }
impl ManageWidget for WidgetId { impl ManageWidget for WidgetId {
type Managed = Option<MountedWidget>; type Managed = Option<MountedWidget>;
fn manage(&self, context: &WidgetContext<'_, '_>) -> Self::Managed { fn manage(&self, context: &WidgetContext<'_>) -> Self::Managed {
context.tree.widget(*self) context.tree.widget(*self)
} }
} }
@ -1284,7 +1266,7 @@ impl ManageWidget for WidgetId {
impl ManageWidget for WidgetInstance { impl ManageWidget for WidgetInstance {
type Managed = Option<MountedWidget>; type Managed = Option<MountedWidget>;
fn manage(&self, context: &WidgetContext<'_, '_>) -> Self::Managed { fn manage(&self, context: &WidgetContext<'_>) -> Self::Managed {
context.tree.widget(self.id()) context.tree.widget(self.id())
} }
} }
@ -1292,7 +1274,7 @@ impl ManageWidget for WidgetInstance {
impl ManageWidget for MountedWidget { impl ManageWidget for MountedWidget {
type Managed = Self; type Managed = Self;
fn manage(&self, _context: &WidgetContext<'_, '_>) -> Self::Managed { fn manage(&self, _context: &WidgetContext<'_>) -> Self::Managed {
self.clone() self.clone()
} }
} }
@ -1348,7 +1330,7 @@ pub trait Trackable: sealed::Trackable {
/// Marks the widget for redraw when this value is updated. /// Marks the widget for redraw when this value is updated.
/// ///
/// This function has no effect if the value is constant. /// This function has no effect if the value is constant.
fn redraw_when_changed(&self, context: &WidgetContext<'_, '_>) fn redraw_when_changed(&self, context: &WidgetContext<'_>)
where where
Self: Sized, Self: Sized,
{ {
@ -1358,7 +1340,7 @@ pub trait Trackable: sealed::Trackable {
/// Marks the widget for redraw when this value is updated. /// Marks the widget for redraw when this value is updated.
/// ///
/// This function has no effect if the value is constant. /// This function has no effect if the value is constant.
fn invalidate_when_changed(&self, context: &WidgetContext<'_, '_>) fn invalidate_when_changed(&self, context: &WidgetContext<'_>)
where where
Self: Sized, Self: Sized,
{ {

View file

@ -8,7 +8,7 @@ use crate::value::{Dynamic, DynamicReader, ForEach, Source, WeakDynamic};
use crate::widget::{Children, MakeWidget, WidgetInstance}; use crate::widget::{Children, MakeWidget, WidgetInstance};
use crate::widgets::grid::{Grid, GridWidgets}; use crate::widgets::grid::{Grid, GridWidgets};
use crate::window::Window; use crate::window::Window;
use crate::Open; use crate::{Open, PendingApp};
/// A widget that can provide extra information when debugging. /// A widget that can provide extra information when debugging.
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -122,7 +122,7 @@ impl Open for DebugContext {
self.into_window().open(app) self.into_window().open(app)
} }
fn run_in(self, app: crate::PendingApp) -> crate::Result { fn run_in(self, app: PendingApp) -> crate::Result {
self.into_window().run_in(app) self.into_window().run_in(app)
} }
} }

View file

@ -114,7 +114,7 @@ impl Styles {
&self, &self,
component: &impl NamedComponent, component: &impl NamedComponent,
fallback: &Fallback, fallback: &Fallback,
context: &WidgetContext<'_, '_>, context: &WidgetContext<'_>,
) -> Fallback::ComponentType ) -> Fallback::ComponentType
where where
Fallback: ComponentDefinition + ?Sized, Fallback: ComponentDefinition + ?Sized,
@ -127,10 +127,7 @@ impl Styles {
.unwrap_or_else(|| fallback.default_value(context)) .unwrap_or_else(|| fallback.default_value(context))
} }
fn resolve_component<T>( fn resolve_component<T>(component: &Value<Component>, context: &WidgetContext<'_>) -> Option<T>
component: &Value<Component>,
context: &WidgetContext<'_, '_>,
) -> Option<T>
where where
T: ComponentType, T: ComponentType,
{ {
@ -162,7 +159,7 @@ impl Styles {
pub fn try_get<Named>( pub fn try_get<Named>(
&self, &self,
component: &Named, component: &Named,
context: &WidgetContext<'_, '_>, context: &WidgetContext<'_>,
) -> Option<Named::ComponentType> ) -> Option<Named::ComponentType>
where where
Named: ComponentDefinition + ?Sized, Named: ComponentDefinition + ?Sized,
@ -176,11 +173,7 @@ impl Styles {
/// Returns the component associated with the given name, or if not found, /// Returns the component associated with the given name, or if not found,
/// returns the default value provided by the definition. /// returns the default value provided by the definition.
#[must_use] #[must_use]
pub fn get<Named>( pub fn get<Named>(&self, component: &Named, context: &WidgetContext<'_>) -> Named::ComponentType
&self,
component: &Named,
context: &WidgetContext<'_, '_>,
) -> Named::ComponentType
where where
Named: ComponentDefinition + ?Sized, Named: ComponentDefinition + ?Sized,
{ {
@ -440,10 +433,8 @@ impl Component {
#[must_use] #[must_use]
pub fn dynamic<T, Func>(resolve: Func) -> Self pub fn dynamic<T, Func>(resolve: Func) -> Self
where where
Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<T> Func:
+ Send for<'a, 'context> Fn(&'a WidgetContext<'context>) -> Option<T> + Send + Sync + 'static,
+ Sync
+ 'static,
T: ComponentType, T: ComponentType,
{ {
Self::Dynamic(DynamicComponent::new(move |context| { Self::Dynamic(DynamicComponent::new(move |context| {
@ -1099,7 +1090,7 @@ pub trait ComponentDefinition: NamedComponent {
type ComponentType: ComponentType; type ComponentType: ComponentType;
/// Returns the default value to use for this component. /// Returns the default value to use for this component.
fn default_value(&self, context: &WidgetContext<'_, '_>) -> Self::ComponentType; fn default_value(&self, context: &WidgetContext<'_>) -> Self::ComponentType;
} }
/// Describes whether a type should invalidate a widget. /// Describes whether a type should invalidate a widget.
@ -2535,19 +2526,19 @@ impl PartialEq for DynamicComponent {
/// A type that resolves to a [`Component`] at runtime. /// A type that resolves to a [`Component`] at runtime.
pub trait DynamicComponentResolver: Send + Sync + 'static { pub trait DynamicComponentResolver: Send + Sync + 'static {
/// Returns the effective component, if one should be applied. /// Returns the effective component, if one should be applied.
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component>; fn resolve_component(&self, context: &WidgetContext<'_>) -> Option<Component>;
} }
struct DynamicFunctionWrapper<F>(F); struct DynamicFunctionWrapper<F>(F);
impl<T> DynamicComponentResolver for DynamicFunctionWrapper<T> impl<T> DynamicComponentResolver for DynamicFunctionWrapper<T>
where where
T: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component> T: for<'a, 'context> Fn(&'a WidgetContext<'context>) -> Option<Component>
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
{ {
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component> { fn resolve_component(&self, context: &WidgetContext<'_>) -> Option<Component> {
self.0(context) self.0(context)
} }
} }
@ -2556,7 +2547,7 @@ impl<T> DynamicComponentResolver for T
where where
T: ComponentDefinition + Clone + Send + Sync + 'static, T: ComponentDefinition + Clone + Send + Sync + 'static,
{ {
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component> { fn resolve_component(&self, context: &WidgetContext<'_>) -> Option<Component> {
Some(context.get(self).into_component()) Some(context.get(self).into_component())
} }
} }
@ -2576,7 +2567,7 @@ impl DynamicComponent {
#[must_use] #[must_use]
pub fn new<Func>(resolve: Func) -> Self pub fn new<Func>(resolve: Func) -> Self
where where
Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component> Func: for<'a, 'context> Fn(&'a WidgetContext<'context>) -> Option<Component>
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
@ -2587,7 +2578,7 @@ impl DynamicComponent {
/// Invokes the resolver function, optionally returning a resolved /// Invokes the resolver function, optionally returning a resolved
/// component. /// component.
#[must_use] #[must_use]
pub fn resolve(&self, context: &WidgetContext<'_, '_>) -> Option<Component> { pub fn resolve(&self, context: &WidgetContext<'_>) -> Option<Component> {
self.0.resolve_component(context) self.0.resolve_component(context)
} }
} }

View file

@ -69,7 +69,7 @@ macro_rules! define_components {
define_components!($type, |context| context.theme().$($path)*); define_components!($type, |context| context.theme().$($path)*);
}; };
($type:ty, |$context:ident| $($expr:tt)*) => { ($type:ty, |$context:ident| $($expr:tt)*) => {
fn default_value(&self, $context: &WidgetContext<'_, '_>) -> $type { fn default_value(&self, $context: &WidgetContext<'_>) -> $type {
$($expr)* $($expr)*
} }
}; };

View file

@ -25,7 +25,7 @@ pub struct Tick {
impl Tick { impl Tick {
/// Signals that this widget has been redrawn. /// Signals that this widget has been redrawn.
pub fn rendered(&self, context: &WidgetContext<'_, '_>) { pub fn rendered(&self, context: &WidgetContext<'_>) {
context.redraw_when_changed(&self.data.tick_number); context.redraw_when_changed(&self.data.tick_number);
self.data.sync.notify_one(); self.data.sync.notify_one();

View file

@ -103,7 +103,7 @@ pub trait Source<T> {
/// This function panics if this value is already locked by the current /// This function panics if this value is already locked by the current
/// thread. /// thread.
#[must_use] #[must_use]
fn get_tracking_redraw(&self, context: &WidgetContext<'_, '_>) -> T fn get_tracking_redraw(&self, context: &WidgetContext<'_>) -> T
where where
T: Clone, T: Clone,
Self: Trackable + Sized, Self: Trackable + Sized,
@ -121,7 +121,7 @@ pub trait Source<T> {
/// This function panics if this value is already locked by the current /// This function panics if this value is already locked by the current
/// thread. /// thread.
#[must_use] #[must_use]
fn get_tracking_invalidate(&self, context: &WidgetContext<'_, '_>) -> T fn get_tracking_invalidate(&self, context: &WidgetContext<'_>) -> T
where where
T: Clone, T: Clone,
Self: Trackable + Sized, Self: Trackable + Sized,
@ -2508,7 +2508,7 @@ impl<T> Value<T> {
/// updated. /// updated.
pub fn map_tracking_redraw<R>( pub fn map_tracking_redraw<R>(
&self, &self,
context: &WidgetContext<'_, '_>, context: &WidgetContext<'_>,
map: impl FnOnce(&T) -> R, map: impl FnOnce(&T) -> R,
) -> R { ) -> R {
match self { match self {
@ -2526,7 +2526,7 @@ impl<T> Value<T> {
/// updated. /// updated.
pub fn map_tracking_invalidate<R>( pub fn map_tracking_invalidate<R>(
&self, &self,
context: &WidgetContext<'_, '_>, context: &WidgetContext<'_>,
map: impl FnOnce(&T) -> R, map: impl FnOnce(&T) -> R,
) -> R { ) -> R {
match self { match self {
@ -2573,7 +2573,7 @@ impl<T> Value<T> {
/// ///
/// If `self` is a dynamic, `context` will be refreshed when the value is /// If `self` is a dynamic, `context` will be refreshed when the value is
/// updated. /// updated.
pub fn get_tracking_redraw(&self, context: &WidgetContext<'_, '_>) -> T pub fn get_tracking_redraw(&self, context: &WidgetContext<'_>) -> T
where where
T: Clone, T: Clone,
{ {
@ -2584,7 +2584,7 @@ impl<T> Value<T> {
/// ///
/// If `self` is a dynamic, `context` will be invalidated when the value is /// If `self` is a dynamic, `context` will be invalidated when the value is
/// updated. /// updated.
pub fn get_tracking_invalidate(&self, context: &WidgetContext<'_, '_>) -> T pub fn get_tracking_invalidate(&self, context: &WidgetContext<'_>) -> T
where where
T: Clone, T: Clone,
{ {

View file

@ -45,7 +45,11 @@ use crate::widgets::{
Align, Button, Checkbox, Collapse, Container, Disclose, Expand, Layers, Resize, Scroll, Space, Align, Button, Checkbox, Collapse, Container, Disclose, Expand, Layers, Resize, Scroll, Space,
Stack, Style, Themed, ThemedMode, Validated, Wrap, Stack, Style, Themed, ThemedMode, Validated, Wrap,
}; };
use crate::window::{RunningWindow, ThemeMode, Window, WindowBehavior, WindowHandle, WindowLocal}; use crate::window::sealed::WindowCommand;
use crate::window::{
Rgb8, RunningWindow, ThemeMode, VirtualRecorderBuilder, VirtualWindowBuilder, Window,
WindowBehavior, WindowHandle, WindowLocal,
};
use crate::ConstraintLimit; use crate::ConstraintLimit;
/// A type that makes up a graphical user interface. /// A type that makes up a graphical user interface.
@ -264,7 +268,7 @@ use crate::ConstraintLimit;
/// [repo]: https://github.com/khonsulabs/cushy /// [repo]: https://github.com/khonsulabs/cushy
pub trait Widget: Send + Debug + 'static { pub trait Widget: Send + Debug + 'static {
/// Redraw the contents of this widget. /// Redraw the contents of this widget.
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>); fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>);
/// Writes a summary of this widget into `fmt`. /// Writes a summary of this widget into `fmt`.
/// ///
@ -297,50 +301,46 @@ pub trait Widget: Send + Debug + 'static {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
available_space.map(ConstraintLimit::min) available_space.map(ConstraintLimit::min)
} }
/// The widget has been mounted into a parent widget. /// The widget has been mounted into a parent widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn mounted(&mut self, context: &mut EventContext<'_, '_>) {} fn mounted(&mut self, context: &mut EventContext<'_>) {}
/// The widget has been removed from its parent widget. /// The widget has been removed from its parent widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) {} fn unmounted(&mut self, context: &mut EventContext<'_>) {}
/// Returns true if this widget should respond to mouse input at `location`. /// Returns true if this widget should respond to mouse input at `location`.
#[allow(unused_variables)] #[allow(unused_variables)]
fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> bool {
false false
} }
/// The widget is currently has a cursor hovering it at `location`. /// The widget is currently has a cursor hovering it at `location`.
#[allow(unused_variables)] #[allow(unused_variables)]
fn hover( fn hover(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> Option<CursorIcon> {
&mut self,
location: Point<Px>,
context: &mut EventContext<'_, '_>,
) -> Option<CursorIcon> {
None None
} }
/// The widget is no longer being hovered. /// The widget is no longer being hovered.
#[allow(unused_variables)] #[allow(unused_variables)]
fn unhover(&mut self, context: &mut EventContext<'_, '_>) {} fn unhover(&mut self, context: &mut EventContext<'_>) {}
/// This widget has been targeted to be focused. If this function returns /// This widget has been targeted to be focused. If this function returns
/// true, the widget will be focused. If false, Cushy will continue /// true, the widget will be focused. If false, Cushy will continue
/// searching for another focus target. /// searching for another focus target.
#[allow(unused_variables)] #[allow(unused_variables)]
fn accept_focus(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, context: &mut EventContext<'_>) -> bool {
false false
} }
/// The widget has received focus for user input. /// The widget has received focus for user input.
#[allow(unused_variables)] #[allow(unused_variables)]
fn focus(&mut self, context: &mut EventContext<'_, '_>) {} fn focus(&mut self, context: &mut EventContext<'_>) {}
/// The widget should switch to the next focusable area within this widget, /// The widget should switch to the next focusable area within this widget,
/// honoring `direction` in a consistent manner. Returning `HANDLED` will /// honoring `direction` in a consistent manner. Returning `HANDLED` will
@ -349,7 +349,7 @@ pub trait Widget: Send + Debug + 'static {
fn advance_focus( fn advance_focus(
&mut self, &mut self,
direction: VisualOrder, direction: VisualOrder,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
@ -357,21 +357,21 @@ pub trait Widget: Send + Debug + 'static {
/// The widget is about to lose focus. Returning true allows the focus to /// The widget is about to lose focus. Returning true allows the focus to
/// switch away from this widget. /// switch away from this widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn allow_blur(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn allow_blur(&mut self, context: &mut EventContext<'_>) -> bool {
true true
} }
/// The widget is no longer focused for user input. /// The widget is no longer focused for user input.
#[allow(unused_variables)] #[allow(unused_variables)]
fn blur(&mut self, context: &mut EventContext<'_, '_>) {} fn blur(&mut self, context: &mut EventContext<'_>) {}
/// The widget has become the active widget. /// The widget has become the active widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn activate(&mut self, context: &mut EventContext<'_, '_>) {} fn activate(&mut self, context: &mut EventContext<'_>) {}
/// The widget is no longer active. /// The widget is no longer active.
#[allow(unused_variables)] #[allow(unused_variables)]
fn deactivate(&mut self, context: &mut EventContext<'_, '_>) {} fn deactivate(&mut self, context: &mut EventContext<'_>) {}
/// A mouse button event has occurred at `location`. Returns whether the /// A mouse button event has occurred at `location`. Returns whether the
/// event has been handled or not. /// event has been handled or not.
@ -384,7 +384,7 @@ pub trait Widget: Send + Debug + 'static {
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
@ -397,7 +397,7 @@ pub trait Widget: Send + Debug + 'static {
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
} }
@ -408,7 +408,7 @@ pub trait Widget: Send + Debug + 'static {
location: Option<Point<Px>>, location: Option<Point<Px>>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
} }
@ -420,7 +420,7 @@ pub trait Widget: Send + Debug + 'static {
device_id: DeviceId, device_id: DeviceId,
input: KeyEvent, input: KeyEvent,
is_synthetic: bool, is_synthetic: bool,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
@ -428,7 +428,7 @@ pub trait Widget: Send + Debug + 'static {
/// An input manager event has been sent to this widget. Returns whether the /// An input manager event has been sent to this widget. Returns whether the
/// event has been handled or not. /// event has been handled or not.
#[allow(unused_variables)] #[allow(unused_variables)]
fn ime(&mut self, ime: Ime, context: &mut EventContext<'_, '_>) -> EventHandling { fn ime(&mut self, ime: Ime, context: &mut EventContext<'_>) -> EventHandling {
IGNORED IGNORED
} }
@ -440,7 +440,7 @@ pub trait Widget: Send + Debug + 'static {
device_id: DeviceId, device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
phase: TouchPhase, phase: TouchPhase,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
@ -451,7 +451,7 @@ pub trait Widget: Send + Debug + 'static {
#[allow(unused_variables)] #[allow(unused_variables)]
fn root_behavior( fn root_behavior(
&mut self, &mut self,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<(RootBehavior, WidgetInstance)> { ) -> Option<(RootBehavior, WidgetInstance)> {
None None
} }
@ -544,7 +544,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
/// Returns the behavior this widget should apply when positioned at the /// Returns the behavior this widget should apply when positioned at the
/// root of the window. /// root of the window.
#[allow(unused_variables)] #[allow(unused_variables)]
fn root_behavior(&mut self, context: &mut EventContext<'_, '_>) -> Option<RootBehavior> { fn root_behavior(&mut self, context: &mut EventContext<'_>) -> Option<RootBehavior> {
None None
} }
@ -552,13 +552,13 @@ pub trait WrapperWidget: Debug + Send + 'static {
/// ///
/// This is invoked before the wrapped widget is drawn. /// This is invoked before the wrapped widget is drawn.
#[allow(unused_variables)] #[allow(unused_variables)]
fn redraw_background(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {} fn redraw_background(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {}
/// Draws the foreground of the widget. /// Draws the foreground of the widget.
/// ///
/// This is invoked after the wrapped widget is drawn. /// This is invoked after the wrapped widget is drawn.
#[allow(unused_variables)] #[allow(unused_variables)]
fn redraw_foreground(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {} fn redraw_foreground(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {}
/// Returns the rectangle that the child widget should occupy given /// Returns the rectangle that the child widget should occupy given
/// `available_space`. /// `available_space`.
@ -566,7 +566,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
fn layout_child( fn layout_child(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
let adjusted_space = self.adjust_child_constraints(available_space, context); let adjusted_space = self.adjust_child_constraints(available_space, context);
let child = self.child_mut().mounted(&mut context.as_event_context()); let child = self.child_mut().mounted(&mut context.as_event_context());
@ -584,7 +584,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
fn adjust_child_constraints( fn adjust_child_constraints(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<ConstraintLimit> { ) -> Size<ConstraintLimit> {
available_space available_space
} }
@ -596,7 +596,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
&mut self, &mut self,
size: Size<Px>, size: Size<Px>,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
Size::new( Size::new(
available_space available_space
@ -612,7 +612,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
/// Returns the background color to render behind the wrapped widget. /// Returns the background color to render behind the wrapped widget.
#[allow(unused_variables)] #[allow(unused_variables)]
#[must_use] #[must_use]
fn background_color(&mut self, context: &WidgetContext<'_, '_>) -> Option<Color> { fn background_color(&mut self, context: &WidgetContext<'_>) -> Option<Color> {
// WidgetBackground is already filled, so we don't need to do anything // WidgetBackground is already filled, so we don't need to do anything
// else by default. // else by default.
None None
@ -620,39 +620,35 @@ pub trait WrapperWidget: Debug + Send + 'static {
/// The widget has been mounted into a parent widget. /// The widget has been mounted into a parent widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn mounted(&mut self, context: &mut EventContext<'_, '_>) {} fn mounted(&mut self, context: &mut EventContext<'_>) {}
/// The widget has been removed from its parent widget. /// The widget has been removed from its parent widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
self.child_mut().unmount_in(context); self.child_mut().unmount_in(context);
} }
/// Returns true if this widget should respond to mouse input at `location`. /// Returns true if this widget should respond to mouse input at `location`.
#[allow(unused_variables)] #[allow(unused_variables)]
fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> bool {
false false
} }
/// The widget is currently has a cursor hovering it at `location`. /// The widget is currently has a cursor hovering it at `location`.
#[allow(unused_variables)] #[allow(unused_variables)]
fn hover( fn hover(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> Option<CursorIcon> {
&mut self,
location: Point<Px>,
context: &mut EventContext<'_, '_>,
) -> Option<CursorIcon> {
None None
} }
/// The widget is no longer being hovered. /// The widget is no longer being hovered.
#[allow(unused_variables)] #[allow(unused_variables)]
fn unhover(&mut self, context: &mut EventContext<'_, '_>) {} fn unhover(&mut self, context: &mut EventContext<'_>) {}
/// This widget has been targeted to be focused. If this function returns /// This widget has been targeted to be focused. If this function returns
/// true, the widget will be focused. If false, Cushy will continue /// true, the widget will be focused. If false, Cushy will continue
/// searching for another focus target. /// searching for another focus target.
#[allow(unused_variables)] #[allow(unused_variables)]
fn accept_focus(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, context: &mut EventContext<'_>) -> bool {
false false
} }
@ -663,33 +659,33 @@ pub trait WrapperWidget: Debug + Send + 'static {
fn advance_focus( fn advance_focus(
&mut self, &mut self,
direction: VisualOrder, direction: VisualOrder,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
/// The widget has received focus for user input. /// The widget has received focus for user input.
#[allow(unused_variables)] #[allow(unused_variables)]
fn focus(&mut self, context: &mut EventContext<'_, '_>) {} fn focus(&mut self, context: &mut EventContext<'_>) {}
/// The widget is about to lose focus. Returning true allows the focus to /// The widget is about to lose focus. Returning true allows the focus to
/// switch away from this widget. /// switch away from this widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn allow_blur(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn allow_blur(&mut self, context: &mut EventContext<'_>) -> bool {
true true
} }
/// The widget is no longer focused for user input. /// The widget is no longer focused for user input.
#[allow(unused_variables)] #[allow(unused_variables)]
fn blur(&mut self, context: &mut EventContext<'_, '_>) {} fn blur(&mut self, context: &mut EventContext<'_>) {}
/// The widget has become the active widget. /// The widget has become the active widget.
#[allow(unused_variables)] #[allow(unused_variables)]
fn activate(&mut self, context: &mut EventContext<'_, '_>) {} fn activate(&mut self, context: &mut EventContext<'_>) {}
/// The widget is no longer active. /// The widget is no longer active.
#[allow(unused_variables)] #[allow(unused_variables)]
fn deactivate(&mut self, context: &mut EventContext<'_, '_>) {} fn deactivate(&mut self, context: &mut EventContext<'_>) {}
/// A mouse button event has occurred at `location`. Returns whether the /// A mouse button event has occurred at `location`. Returns whether the
/// event has been handled or not. /// event has been handled or not.
@ -702,7 +698,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
@ -715,7 +711,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
} }
@ -726,7 +722,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
location: Option<Point<Px>>, location: Option<Point<Px>>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
} }
@ -738,7 +734,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
device_id: DeviceId, device_id: DeviceId,
input: KeyEvent, input: KeyEvent,
is_synthetic: bool, is_synthetic: bool,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
@ -746,7 +742,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
/// An input manager event has been sent to this widget. Returns whether the /// An input manager event has been sent to this widget. Returns whether the
/// event has been handled or not. /// event has been handled or not.
#[allow(unused_variables)] #[allow(unused_variables)]
fn ime(&mut self, ime: Ime, context: &mut EventContext<'_, '_>) -> EventHandling { fn ime(&mut self, ime: Ime, context: &mut EventContext<'_>) -> EventHandling {
IGNORED IGNORED
} }
@ -758,7 +754,7 @@ pub trait WrapperWidget: Debug + Send + 'static {
device_id: DeviceId, device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
phase: TouchPhase, phase: TouchPhase,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
IGNORED IGNORED
} }
@ -770,13 +766,13 @@ where
{ {
fn root_behavior( fn root_behavior(
&mut self, &mut self,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<(RootBehavior, WidgetInstance)> { ) -> Option<(RootBehavior, WidgetInstance)> {
T::root_behavior(self, context) T::root_behavior(self, context)
.map(|behavior| (behavior, T::child_mut(self).widget().clone())) .map(|behavior| (behavior, T::child_mut(self).widget().clone()))
} }
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let background_color = self.background_color(context); let background_color = self.background_color(context);
if let Some(color) = background_color { if let Some(color) = background_color {
context.fill(color); context.fill(color);
@ -793,7 +789,7 @@ where
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
let layout = self.layout_child(available_space, context); let layout = self.layout_child(available_space, context);
let child = self.child_mut().mounted(&mut context.as_event_context()); let child = self.child_mut().mounted(&mut context.as_event_context());
@ -801,47 +797,43 @@ where
layout.size layout.size
} }
fn mounted(&mut self, context: &mut EventContext<'_, '_>) { fn mounted(&mut self, context: &mut EventContext<'_>) {
T::mounted(self, context); T::mounted(self, context);
} }
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
T::unmounted(self, context); T::unmounted(self, context);
} }
fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> bool {
T::hit_test(self, location, context) T::hit_test(self, location, context)
} }
fn hover( fn hover(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> Option<CursorIcon> {
&mut self,
location: Point<Px>,
context: &mut EventContext<'_, '_>,
) -> Option<CursorIcon> {
T::hover(self, location, context) T::hover(self, location, context)
} }
fn unhover(&mut self, context: &mut EventContext<'_, '_>) { fn unhover(&mut self, context: &mut EventContext<'_>) {
T::unhover(self, context); T::unhover(self, context);
} }
fn accept_focus(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, context: &mut EventContext<'_>) -> bool {
T::accept_focus(self, context) T::accept_focus(self, context)
} }
fn focus(&mut self, context: &mut EventContext<'_, '_>) { fn focus(&mut self, context: &mut EventContext<'_>) {
T::focus(self, context); T::focus(self, context);
} }
fn blur(&mut self, context: &mut EventContext<'_, '_>) { fn blur(&mut self, context: &mut EventContext<'_>) {
T::blur(self, context); T::blur(self, context);
} }
fn activate(&mut self, context: &mut EventContext<'_, '_>) { fn activate(&mut self, context: &mut EventContext<'_>) {
T::activate(self, context); T::activate(self, context);
} }
fn deactivate(&mut self, context: &mut EventContext<'_, '_>) { fn deactivate(&mut self, context: &mut EventContext<'_>) {
T::deactivate(self, context); T::deactivate(self, context);
} }
@ -850,7 +842,7 @@ where
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
T::mouse_down(self, location, device_id, button, context) T::mouse_down(self, location, device_id, button, context)
} }
@ -860,7 +852,7 @@ where
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
T::mouse_drag(self, location, device_id, button, context); T::mouse_drag(self, location, device_id, button, context);
} }
@ -870,7 +862,7 @@ where
location: Option<Point<Px>>, location: Option<Point<Px>>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
T::mouse_up(self, location, device_id, button, context); T::mouse_up(self, location, device_id, button, context);
} }
@ -880,12 +872,12 @@ where
device_id: DeviceId, device_id: DeviceId,
input: KeyEvent, input: KeyEvent,
is_synthetic: bool, is_synthetic: bool,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
T::keyboard_input(self, device_id, input, is_synthetic, context) T::keyboard_input(self, device_id, input, is_synthetic, context)
} }
fn ime(&mut self, ime: Ime, context: &mut EventContext<'_, '_>) -> EventHandling { fn ime(&mut self, ime: Ime, context: &mut EventContext<'_>) -> EventHandling {
T::ime(self, ime, context) T::ime(self, ime, context)
} }
@ -894,7 +886,7 @@ where
device_id: DeviceId, device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
phase: TouchPhase, phase: TouchPhase,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
T::mouse_wheel(self, device_id, delta, phase, context) T::mouse_wheel(self, device_id, delta, phase, context)
} }
@ -902,12 +894,12 @@ where
fn advance_focus( fn advance_focus(
&mut self, &mut self,
direction: VisualOrder, direction: VisualOrder,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
T::advance_focus(self, direction, context) T::advance_focus(self, direction, context)
} }
fn allow_blur(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn allow_blur(&mut self, context: &mut EventContext<'_>) -> bool {
T::allow_blur(self, context) T::allow_blur(self, context)
} }
@ -926,6 +918,16 @@ pub trait MakeWidget: Sized {
Window::new(self.make_widget()) Window::new(self.make_widget())
} }
/// Returns a builder for a [`VirtualWindow`](crate::window::VirtualWindow).
fn build_virtual_window(self) -> VirtualWindowBuilder {
VirtualWindowBuilder::new(self)
}
/// Returns a builder for a [`VirtualRecorder`](crate::window::VirtualRecorder)
fn build_recorder(self) -> VirtualRecorderBuilder<Rgb8> {
VirtualRecorderBuilder::new(self)
}
/// Associates `styles` with this widget. /// Associates `styles` with this widget.
/// ///
/// This is equivalent to `Style::new(styles, self)`. /// This is equivalent to `Style::new(styles, self)`.
@ -1589,7 +1591,10 @@ impl PartialEq for WidgetInstance {
impl WindowBehavior for WidgetInstance { impl WindowBehavior for WidgetInstance {
type Context = Self; type Context = Self;
fn initialize(_window: &mut RunningWindow<'_>, context: Self::Context) -> Self { fn initialize(
_window: &mut RunningWindow<kludgine::app::Window<'_, WindowCommand>>,
context: Self::Context,
) -> Self {
context context
} }
@ -2181,11 +2186,7 @@ where
T: MountableChild, T: MountableChild,
{ {
/// Mounts and unmounts all children needed to be in sync with `children`. /// Mounts and unmounts all children needed to be in sync with `children`.
pub fn synchronize_with( pub fn synchronize_with(&mut self, children: &Value<Children>, context: &mut EventContext<'_>) {
&mut self,
children: &Value<Children>,
context: &mut EventContext<'_, '_>,
) {
let current_generation = children.generation(); let current_generation = children.generation();
if current_generation.map_or_else( if current_generation.map_or_else(
|| children.map(Children::len) != self.children.len(), || children.map(Children::len) != self.children.len(),
@ -2284,10 +2285,7 @@ impl WidgetRef {
} }
/// Returns this child, mounting it in the process if necessary. /// Returns this child, mounting it in the process if necessary.
fn mounted_for_context<'window>( fn mounted_for_context(&mut self, context: &mut impl AsEventContext) -> &MountedWidget {
&mut self,
context: &mut impl AsEventContext<'window>,
) -> &MountedWidget {
let mut context = context.as_event_context(); let mut context = context.as_event_context();
self.mounted self.mounted
.entry(&context) .entry(&context)
@ -2295,21 +2293,18 @@ impl WidgetRef {
} }
/// Returns this child, mounting it in the process if necessary. /// Returns this child, mounting it in the process if necessary.
pub fn mount_if_needed<'window>(&mut self, context: &mut impl AsEventContext<'window>) { pub fn mount_if_needed(&mut self, context: &mut impl AsEventContext) {
self.mounted_for_context(context); self.mounted_for_context(context);
} }
/// Returns this child, mounting it in the process if necessary. /// Returns this child, mounting it in the process if necessary.
pub fn mounted<'window>( pub fn mounted(&mut self, context: &mut impl AsEventContext) -> MountedWidget {
&mut self,
context: &mut impl AsEventContext<'window>,
) -> MountedWidget {
self.mounted_for_context(context).clone() self.mounted_for_context(context).clone()
} }
/// Returns this child, mounting it in the process if necessary. /// Returns this child, mounting it in the process if necessary.
#[must_use] #[must_use]
pub fn as_mounted(&self, context: &WidgetContext<'_, '_>) -> Option<&MountedWidget> { pub fn as_mounted(&self, context: &WidgetContext<'_>) -> Option<&MountedWidget> {
self.mounted.get(context) self.mounted.get(context)
} }
@ -2320,7 +2315,7 @@ impl WidgetRef {
} }
/// Unmounts this widget from the window belonging to `context`, if needed. /// Unmounts this widget from the window belonging to `context`, if needed.
pub fn unmount_in<'window>(&mut self, context: &mut impl AsEventContext<'window>) { pub fn unmount_in(&mut self, context: &mut impl AsEventContext) {
let mut context = context.as_event_context(); let mut context = context.as_event_context();
if let Some(mounted) = self.mounted.clear_for(&context) { if let Some(mounted) = self.mounted.clear_for(&context) {
context.remove_child(&mounted); context.remove_child(&mounted);
@ -2351,7 +2346,7 @@ impl PartialEq for WidgetRef {
impl ManageWidget for WidgetRef { impl ManageWidget for WidgetRef {
type Managed = Option<MountedWidget>; type Managed = Option<MountedWidget>;
fn manage(&self, context: &WidgetContext<'_, '_>) -> Self::Managed { fn manage(&self, context: &WidgetContext<'_>) -> Self::Managed {
self.mounted self.mounted
.get(context) .get(context)
.cloned() .cloned()
@ -2374,7 +2369,7 @@ impl WidgetId {
/// Finds this widget mounted in this window, if present. /// Finds this widget mounted in this window, if present.
#[must_use] #[must_use]
pub fn find_in(self, context: &WidgetContext<'_, '_>) -> Option<MountedWidget> { pub fn find_in(self, context: &WidgetContext<'_>) -> Option<MountedWidget> {
context.tree.widget(self) context.tree.widget(self)
} }
} }

View file

@ -87,7 +87,7 @@ impl Align {
fn measure( fn measure(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Layout { ) -> Layout {
let margin = self.edges.get(); let margin = self.edges.get();
let vertical = FrameInfo::new(context.gfx.scale(), margin.top, margin.bottom); let vertical = FrameInfo::new(context.gfx.scale(), margin.top, margin.bottom);
@ -179,14 +179,14 @@ impl WrapperWidget for Align {
&mut self.child &mut self.child
} }
fn root_behavior(&mut self, _context: &mut EventContext<'_, '_>) -> Option<RootBehavior> { fn root_behavior(&mut self, _context: &mut EventContext<'_>) -> Option<RootBehavior> {
Some(RootBehavior::Align) Some(RootBehavior::Align)
} }
fn layout_child( fn layout_child(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
let layout = self.measure(available_space, context); let layout = self.measure(available_space, context);

View file

@ -71,7 +71,7 @@ impl ButtonKind {
pub fn colors_for_default( pub fn colors_for_default(
self, self,
visual_state: VisualState, visual_state: VisualState,
context: &WidgetContext<'_, '_>, context: &WidgetContext<'_>,
) -> ButtonColors { ) -> ButtonColors {
match self { match self {
ButtonKind::Solid => match visual_state { ButtonKind::Solid => match visual_state {
@ -171,7 +171,7 @@ impl Button {
self self
} }
fn invoke_on_click(&mut self, context: &WidgetContext<'_, '_>) { fn invoke_on_click(&mut self, context: &WidgetContext<'_>) {
if context.enabled() { if context.enabled() {
if let Some(on_click) = self.on_click.as_mut() { if let Some(on_click) = self.on_click.as_mut() {
on_click.invoke(()); on_click.invoke(());
@ -179,7 +179,7 @@ impl Button {
} }
} }
fn visual_style(context: &WidgetContext<'_, '_>) -> VisualState { fn visual_style(context: &WidgetContext<'_>) -> VisualState {
if !context.enabled() { if !context.enabled() {
VisualState::Disabled VisualState::Disabled
} else if context.active() { } else if context.active() {
@ -195,7 +195,7 @@ impl Button {
#[must_use] #[must_use]
pub fn colors_for_transparent( pub fn colors_for_transparent(
visual_state: VisualState, visual_state: VisualState,
context: &WidgetContext<'_, '_>, context: &WidgetContext<'_>,
) -> ButtonColors { ) -> ButtonColors {
match visual_state { match visual_state {
VisualState::Normal => ButtonColors { VisualState::Normal => ButtonColors {
@ -225,7 +225,7 @@ impl Button {
} }
} }
fn determine_stateful_colors(&mut self, context: &mut WidgetContext<'_, '_>) -> ButtonColors { fn determine_stateful_colors(&mut self, context: &mut WidgetContext<'_>) -> ButtonColors {
let kind = self.kind.get_tracking_redraw(context); let kind = self.kind.get_tracking_redraw(context);
let visual_state = Self::visual_style(context); let visual_state = Self::visual_style(context);
@ -247,7 +247,7 @@ impl Button {
} }
} }
fn update_colors(&mut self, context: &mut WidgetContext<'_, '_>, immediate: bool) { fn update_colors(&mut self, context: &mut WidgetContext<'_>, immediate: bool) {
let new_style = self.determine_stateful_colors(context); let new_style = self.determine_stateful_colors(context);
let window_local = self.per_window.entry(context).or_default(); let window_local = self.per_window.entry(context).or_default();
@ -271,7 +271,7 @@ impl Button {
} }
} }
fn current_style(&mut self, context: &mut WidgetContext<'_, '_>) -> ButtonColors { fn current_style(&mut self, context: &mut WidgetContext<'_>) -> ButtonColors {
if self if self
.per_window .per_window
.entry(context) .entry(context)
@ -318,7 +318,7 @@ impl VisualState {
/// Returns the colors to apply to a [`ButtonKind::Solid`] [`Button`] or /// Returns the colors to apply to a [`ButtonKind::Solid`] [`Button`] or
/// button-like widget. /// button-like widget.
#[must_use] #[must_use]
pub fn solid_colors(self, context: &WidgetContext<'_, '_>) -> ButtonColors { pub fn solid_colors(self, context: &WidgetContext<'_>) -> ButtonColors {
match self { match self {
VisualState::Normal => ButtonColors { VisualState::Normal => ButtonColors {
background: context.get(&ButtonBackground), background: context.get(&ButtonBackground),
@ -346,7 +346,7 @@ impl VisualState {
/// Returns the colors to apply to a [`ButtonKind::Outline`] [`Button`] or /// Returns the colors to apply to a [`ButtonKind::Outline`] [`Button`] or
/// button-like widget. /// button-like widget.
#[must_use] #[must_use]
pub fn outline_colors(self, context: &WidgetContext<'_, '_>) -> ButtonColors { pub fn outline_colors(self, context: &WidgetContext<'_>) -> ButtonColors {
let solid = self.solid_colors(context); let solid = self.solid_colors(context);
ButtonColors { ButtonColors {
background: solid.outline, background: solid.outline,
@ -364,7 +364,7 @@ impl Widget for Button {
.finish() .finish()
} }
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
#![allow(clippy::similar_names)] #![allow(clippy::similar_names)]
let current_style = self.kind.get_tracking_redraw(context); let current_style = self.kind.get_tracking_redraw(context);
@ -417,11 +417,11 @@ impl Widget for Button {
context.for_other(&content).redraw(); context.for_other(&content).redraw();
} }
fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_>) -> bool {
true true
} }
fn accept_focus(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, context: &mut EventContext<'_>) -> bool {
self.focusable && context.enabled() && context.get(&AutoFocusableControls).is_all() self.focusable && context.enabled() && context.get(&AutoFocusableControls).is_all()
} }
@ -430,7 +430,7 @@ impl Widget for Button {
_location: Point<Px>, _location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
self.per_window.entry(context).or_default().buttons_pressed += 1; self.per_window.entry(context).or_default().buttons_pressed += 1;
context.activate(); context.activate();
@ -442,7 +442,7 @@ impl Widget for Button {
location: Point<Px>, location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
let changed = if Rect::from(context.last_layout().expect("must have been rendered").size) let changed = if Rect::from(context.last_layout().expect("must have been rendered").size)
.contains(location) .contains(location)
@ -462,7 +462,7 @@ impl Widget for Button {
location: Option<Point<Px>>, location: Option<Point<Px>>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
let window_local = self.per_window.entry(context).or_default(); let window_local = self.per_window.entry(context).or_default();
window_local.buttons_pressed -= 1; window_local.buttons_pressed -= 1;
@ -484,7 +484,7 @@ impl Widget for Button {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<crate::ConstraintLimit>, available_space: Size<crate::ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
let padding = context let padding = context
.get(&IntrinsicPadding) .get(&IntrinsicPadding)
@ -502,14 +502,14 @@ impl Widget for Button {
size + double_padding size + double_padding
} }
fn unhover(&mut self, context: &mut EventContext<'_, '_>) { fn unhover(&mut self, context: &mut EventContext<'_>) {
self.update_colors(context, false); self.update_colors(context, false);
} }
fn hover( fn hover(
&mut self, &mut self,
_location: Point<Px>, _location: Point<Px>,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<CursorIcon> { ) -> Option<CursorIcon> {
self.update_colors(context, false); self.update_colors(context, false);
@ -520,15 +520,15 @@ impl Widget for Button {
} }
} }
fn focus(&mut self, context: &mut EventContext<'_, '_>) { fn focus(&mut self, context: &mut EventContext<'_>) {
context.set_needs_redraw(); context.set_needs_redraw();
} }
fn blur(&mut self, context: &mut EventContext<'_, '_>) { fn blur(&mut self, context: &mut EventContext<'_>) {
context.set_needs_redraw(); context.set_needs_redraw();
} }
fn activate(&mut self, context: &mut EventContext<'_, '_>) { fn activate(&mut self, context: &mut EventContext<'_>) {
let window_local = self.per_window.entry(context).or_default(); let window_local = self.per_window.entry(context).or_default();
// If we have no buttons pressed, the event should fire on activate not // If we have no buttons pressed, the event should fire on activate not
// on deactivate. // on deactivate.
@ -538,11 +538,11 @@ impl Widget for Button {
self.update_colors(context, true); self.update_colors(context, true);
} }
fn deactivate(&mut self, context: &mut EventContext<'_, '_>) { fn deactivate(&mut self, context: &mut EventContext<'_>) {
self.update_colors(context, false); self.update_colors(context, false);
} }
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
self.content.unmount_in(context); self.content.unmount_in(context);
} }
} }

View file

@ -20,8 +20,8 @@ impl Canvas {
/// Returns a new canvas that draws its contents by invoking `render`. /// Returns a new canvas that draws its contents by invoking `render`.
pub fn new<F>(render: F) -> Self pub fn new<F>(render: F) -> Self
where where
F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut( F: for<'clip, 'gfx, 'pass, 'context> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'clip, 'gfx, 'pass>,
) + Send ) + Send
+ 'static, + 'static,
{ {
@ -40,7 +40,7 @@ impl Canvas {
} }
impl Widget for Canvas { impl Widget for Canvas {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
context.redraw_when_changed(&self.redraw); context.redraw_when_changed(&self.redraw);
self.render.render(context); self.render.render(context);
if let Some(tick) = &self.tick { if let Some(tick) = &self.tick {
@ -51,7 +51,7 @@ impl Widget for Canvas {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<crate::ConstraintLimit>, available_space: Size<crate::ConstraintLimit>,
_context: &mut LayoutContext<'_, '_, '_, '_, '_>, _context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
available_space.map(ConstraintLimit::max) available_space.map(ConstraintLimit::max)
} }
@ -64,17 +64,16 @@ impl Debug for Canvas {
} }
trait RenderFunction: Send + 'static { trait RenderFunction: Send + 'static {
fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>); fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>);
} }
impl<F> RenderFunction for F impl<F> RenderFunction for F
where where
F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut( F: for<'clip, 'gfx, 'pass, 'context> FnMut(&mut GraphicsContext<'context, 'clip, 'gfx, 'pass>)
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, + Send
) + Send
+ 'static, + 'static,
{ {
fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
self(context); self(context);
} }
} }

View file

@ -175,7 +175,7 @@ struct CheckboxOrnament {
} }
impl Widget for CheckboxOrnament { impl Widget for CheckboxOrnament {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let checkbox_size = context let checkbox_size = context
.gfx .gfx
.region() .region()
@ -244,7 +244,7 @@ impl Widget for CheckboxOrnament {
fn layout( fn layout(
&mut self, &mut self,
_available_space: Size<ConstraintLimit>, _available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<figures::units::UPx> { ) -> Size<figures::units::UPx> {
let checkbox_size = context.get(&CheckboxSize).into_upx(context.gfx.scale()); let checkbox_size = context.get(&CheckboxSize).into_upx(context.gfx.scale());
Size::squared(checkbox_size) Size::squared(checkbox_size)

View file

@ -51,7 +51,7 @@ impl Collapse {
} }
} }
fn note_child_size(&mut self, size: Px, context: &mut LayoutContext<'_, '_, '_, '_, '_>) { fn note_child_size(&mut self, size: Px, context: &mut LayoutContext<'_, '_, '_, '_>) {
let (easing, target) = if self.collapse.get_tracking_invalidate(context) { let (easing, target) = if self.collapse.get_tracking_invalidate(context) {
(EasingFunction::from(EaseOutQuadradic), Px::ZERO) (EasingFunction::from(EaseOutQuadradic), Px::ZERO)
} else { } else {
@ -90,7 +90,7 @@ impl WrapperWidget for Collapse {
&mut self, &mut self,
size: Size<Px>, size: Size<Px>,
_available_space: Size<ConstraintLimit>, _available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
let clip_size = self.size.get_tracking_invalidate(context); let clip_size = self.size.get_tracking_invalidate(context);
if self.vertical { if self.vertical {

View file

@ -69,7 +69,7 @@ impl ColorSourcePicker {
} }
impl Widget for ColorSourcePicker { impl Widget for ColorSourcePicker {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let loupe_size = Lp::mm(3).into_px(context.gfx.scale()); let loupe_size = Lp::mm(3).into_px(context.gfx.scale());
let size = context.gfx.region().size; let size = context.gfx.region().size;
@ -148,7 +148,7 @@ impl Widget for ColorSourcePicker {
); );
} }
fn hit_test(&mut self, location: Point<Px>, _context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, location: Point<Px>, _context: &mut EventContext<'_>) -> bool {
self.visible_rect.contains(location) self.visible_rect.contains(location)
} }
@ -157,7 +157,7 @@ impl Widget for ColorSourcePicker {
location: Point<Px>, location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
self.update_from_mouse(location); self.update_from_mouse(location);
HANDLED HANDLED
@ -168,7 +168,7 @@ impl Widget for ColorSourcePicker {
location: Point<Px>, location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) { ) {
self.update_from_mouse(location); self.update_from_mouse(location);
} }
@ -180,7 +180,7 @@ fn draw_gradient_segment(
height: Px, height: Px,
hue: Range<f32>, hue: Range<f32>,
lightness: ZeroToOne, lightness: ZeroToOne,
context: &mut GraphicsContext<'_, '_, '_, '_, '_>, context: &mut GraphicsContext<'_, '_, '_, '_>,
) { ) {
let mid_left = ( let mid_left = (
Point::new(start.x, start.y + height / 2), Point::new(start.x, start.y + height / 2),

View file

@ -158,7 +158,7 @@ impl Container {
self self
} }
fn padding(&self, context: &GraphicsContext<'_, '_, '_, '_, '_>) -> Edges<Px> { fn padding(&self, context: &GraphicsContext<'_, '_, '_, '_>) -> Edges<Px> {
match &self.padding { match &self.padding {
Some(padding) => padding.get(), Some(padding) => padding.get(),
None => Edges::from(context.get(&IntrinsicPadding)), None => Edges::from(context.get(&IntrinsicPadding)),
@ -166,7 +166,7 @@ impl Container {
.map(|dim| dim.into_px(context.gfx.scale()).round()) .map(|dim| dim.into_px(context.gfx.scale()).round())
} }
fn effective_background_color(&mut self, context: &WidgetContext<'_, '_>) -> kludgine::Color { fn effective_background_color(&mut self, context: &WidgetContext<'_>) -> kludgine::Color {
let background = match self.background.get() { let background = match self.background.get() {
ContainerBackground::Color(color) => EffectiveBackground::Color(color), ContainerBackground::Color(color) => EffectiveBackground::Color(color),
ContainerBackground::Level(level) => EffectiveBackground::Level(level), ContainerBackground::Level(level) => EffectiveBackground::Level(level),
@ -206,7 +206,7 @@ impl Widget for Container {
.finish() .finish()
} }
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
self.child.unmount_in(context); self.child.unmount_in(context);
} }
@ -215,7 +215,7 @@ impl Widget for Container {
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let opacity = context.get(&Opacity); let opacity = context.get(&Opacity);
let background = self.effective_background_color(context); let background = self.effective_background_color(context);
@ -251,7 +251,7 @@ impl Widget for Container {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
let child = self.child.mounted(context); let child = self.child.mounted(context);
@ -308,7 +308,7 @@ impl Widget for Container {
fn root_behavior( fn root_behavior(
&mut self, &mut self,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<(RootBehavior, WidgetInstance)> { ) -> Option<(RootBehavior, WidgetInstance)> {
let mut padding = self let mut padding = self
.padding .padding
@ -345,7 +345,7 @@ fn render_shadow(
mut corner_radii: CornerRadii<Px>, mut corner_radii: CornerRadii<Px>,
shadow: &ContainerShadow<Px>, shadow: &ContainerShadow<Px>,
background: Color, background: Color,
context: &mut GraphicsContext<'_, '_, '_, '_, '_>, context: &mut GraphicsContext<'_, '_, '_, '_>,
) { ) {
let shadow_color = shadow.color.unwrap_or_else(|| context.theme_pair().shadow); let shadow_color = shadow.color.unwrap_or_else(|| context.theme_pair().shadow);
let shadow_color = let shadow_color =
@ -588,7 +588,7 @@ fn shadow_arc(
solid_color: Color, solid_color: Color,
transparent_color: Color, transparent_color: Color,
start_angle: Angle, start_angle: Angle,
context: &mut GraphicsContext<'_, '_, '_, '_, '_>, context: &mut GraphicsContext<'_, '_, '_, '_>,
) { ) {
let full_radius = radius + gradient; let full_radius = radius + gradient;
let mut current_outer_arc = origin + Point::new(full_radius, Px::ZERO).rotate_by(start_angle); let mut current_outer_arc = origin + Point::new(full_radius, Px::ZERO).rotate_by(start_angle);

View file

@ -121,8 +121,8 @@ impl Custom {
where where
Redraw: Send Redraw: Send
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'clip, 'gfx, 'pass> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'clip, 'gfx, 'pass>,
), ),
{ {
self.redraw_background = Some(Box::new(redraw)); self.redraw_background = Some(Box::new(redraw));
@ -143,8 +143,8 @@ impl Custom {
where where
Redraw: Send Redraw: Send
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'clip, 'gfx, 'pass> FnMut(
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut GraphicsContext<'context, 'clip, 'gfx, 'pass>,
), ),
{ {
self.redraw_foreground = Some(Box::new(redraw)); self.redraw_foreground = Some(Box::new(redraw));
@ -156,8 +156,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::mounted`]. /// This callback corresponds to [`WrapperWidget::mounted`].
pub fn on_mounted<Mounted>(mut self, mounted: Mounted) -> Self pub fn on_mounted<Mounted>(mut self, mounted: Mounted) -> Self
where where
Mounted: Mounted: Send + 'static + for<'context> FnMut(&mut EventContext<'context>),
Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.mounted = Some(Box::new(mounted)); self.mounted = Some(Box::new(mounted));
self self
@ -169,8 +168,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::unmounted`]. /// This callback corresponds to [`WrapperWidget::unmounted`].
pub fn on_unmounted<Mounted>(mut self, mounted: Mounted) -> Self pub fn on_unmounted<Mounted>(mut self, mounted: Mounted) -> Self
where where
Mounted: Mounted: Send + 'static + for<'context> FnMut(&mut EventContext<'context>),
Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.unmounted = Some(Box::new(mounted)); self.unmounted = Some(Box::new(mounted));
self self
@ -181,8 +179,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::unhover`]. /// This callback corresponds to [`WrapperWidget::unhover`].
pub fn on_unhover<Unhover>(mut self, unhovered: Unhover) -> Self pub fn on_unhover<Unhover>(mut self, unhovered: Unhover) -> Self
where where
Unhover: Unhover: Send + 'static + for<'context> FnMut(&mut EventContext<'context>),
Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.unhover = Some(Box::new(unhovered)); self.unhover = Some(Box::new(unhovered));
self self
@ -193,8 +190,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::focus`]. /// This callback corresponds to [`WrapperWidget::focus`].
pub fn on_focus<Focused>(mut self, focus: Focused) -> Self pub fn on_focus<Focused>(mut self, focus: Focused) -> Self
where where
Focused: Focused: Send + 'static + for<'context> FnMut(&mut EventContext<'context>),
Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.focus = Some(Box::new(focus)); self.focus = Some(Box::new(focus));
self self
@ -205,7 +201,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::blur`]. /// This callback corresponds to [`WrapperWidget::blur`].
pub fn on_blur<Blur>(mut self, blur: Blur) -> Self pub fn on_blur<Blur>(mut self, blur: Blur) -> Self
where where
Blur: Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>), Blur: Send + 'static + for<'context> FnMut(&mut EventContext<'context>),
{ {
self.blur = Some(Box::new(blur)); self.blur = Some(Box::new(blur));
self self
@ -216,8 +212,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::activate`]. /// This callback corresponds to [`WrapperWidget::activate`].
pub fn on_activate<Activated>(mut self, activated: Activated) -> Self pub fn on_activate<Activated>(mut self, activated: Activated) -> Self
where where
Activated: Activated: Send + 'static + for<'context> FnMut(&mut EventContext<'context>),
Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.activate = Some(Box::new(activated)); self.activate = Some(Box::new(activated));
self self
@ -228,8 +223,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::deactivate`]. /// This callback corresponds to [`WrapperWidget::deactivate`].
pub fn on_deactivate<Deactivated>(mut self, deactivated: Deactivated) -> Self pub fn on_deactivate<Deactivated>(mut self, deactivated: Deactivated) -> Self
where where
Deactivated: Deactivated: Send + 'static + for<'context> FnMut(&mut EventContext<'context>),
Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>),
{ {
self.deactivate = Some(Box::new(deactivated)); self.deactivate = Some(Box::new(deactivated));
self self
@ -241,9 +235,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::accept_focus`]. /// This callback corresponds to [`WrapperWidget::accept_focus`].
pub fn on_accept_focus<AcceptFocus>(mut self, accept: AcceptFocus) -> Self pub fn on_accept_focus<AcceptFocus>(mut self, accept: AcceptFocus) -> Self
where where
AcceptFocus: Send AcceptFocus: Send + 'static + for<'context> FnMut(&mut EventContext<'context>) -> bool,
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> bool,
{ {
self.accept_focus = Some(Box::new(accept)); self.accept_focus = Some(Box::new(accept));
self self
@ -256,9 +248,7 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::allow_blur`]. /// This callback corresponds to [`WrapperWidget::allow_blur`].
pub fn on_allow_blur<AllowBlur>(mut self, allow_blur: AllowBlur) -> Self pub fn on_allow_blur<AllowBlur>(mut self, allow_blur: AllowBlur) -> Self
where where
AllowBlur: Send AllowBlur: Send + 'static + for<'context> FnMut(&mut EventContext<'context>) -> bool,
+ 'static
+ for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> bool,
{ {
self.allow_blur = Some(Box::new(allow_blur)); self.allow_blur = Some(Box::new(allow_blur));
self self
@ -274,10 +264,7 @@ impl Custom {
where where
AdvanceFocus: Send AdvanceFocus: Send
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context> FnMut(VisualOrder, &mut EventContext<'context>) -> EventHandling,
VisualOrder,
&mut EventContext<'context, 'window>,
) -> EventHandling,
{ {
self.advance_focus = Some(Box::new(advance_focus)); self.advance_focus = Some(Box::new(advance_focus));
self self
@ -295,9 +282,9 @@ impl Custom {
where where
AdjustChildConstraints: Send AdjustChildConstraints: Send
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'clip, 'gfx, 'pass> FnMut(
Size<ConstraintLimit>, Size<ConstraintLimit>,
&mut LayoutContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut LayoutContext<'context, 'clip, 'gfx, 'pass>,
) -> Size<ConstraintLimit>, ) -> Size<ConstraintLimit>,
{ {
self.adjust_child = Some(Box::new(adjust_child_constraints)); self.adjust_child = Some(Box::new(adjust_child_constraints));
@ -311,10 +298,10 @@ impl Custom {
where where
PositionChild: Send PositionChild: Send
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'clip, 'gfx, 'pass> FnMut(
Size<Px>, Size<Px>,
Size<ConstraintLimit>, Size<ConstraintLimit>,
&mut LayoutContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut LayoutContext<'context, 'clip, 'gfx, 'pass>,
) -> WrappedLayout, ) -> WrappedLayout,
{ {
self.position_child = Some(Box::new(position_child)); self.position_child = Some(Box::new(position_child));
@ -327,9 +314,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::hit_test`]. /// This callback corresponds to [`WrapperWidget::hit_test`].
pub fn on_hit_test<HitTest>(mut self, hit_test: HitTest) -> Self pub fn on_hit_test<HitTest>(mut self, hit_test: HitTest) -> Self
where where
HitTest: Send HitTest:
+ 'static Send + 'static + for<'context> FnMut(Point<Px>, &mut EventContext<'context>) -> bool,
+ for<'context, 'window> FnMut(Point<Px>, &mut EventContext<'context, 'window>) -> bool,
{ {
self.hit_test = Some(Box::new(hit_test)); self.hit_test = Some(Box::new(hit_test));
self self
@ -342,10 +328,7 @@ impl Custom {
where where
Hover: Send Hover: Send
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context> FnMut(Point<Px>, &mut EventContext<'context>) -> Option<CursorIcon>,
Point<Px>,
&mut EventContext<'context, 'window>,
) -> Option<CursorIcon>,
{ {
self.hover = Some(Box::new(hover)); self.hover = Some(Box::new(hover));
self self
@ -364,11 +347,11 @@ impl Custom {
where where
MouseDown: Send MouseDown: Send
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context> FnMut(
Point<Px>, Point<Px>,
DeviceId, DeviceId,
MouseButton, MouseButton,
&mut EventContext<'context, 'window>, &mut EventContext<'context>,
) -> EventHandling, ) -> EventHandling,
{ {
self.mouse_down = Some(Box::new(mouse_down)); self.mouse_down = Some(Box::new(mouse_down));
@ -383,12 +366,7 @@ impl Custom {
where where
MouseDrag: Send MouseDrag: Send
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context> FnMut(Point<Px>, DeviceId, MouseButton, &mut EventContext<'context>),
Point<Px>,
DeviceId,
MouseButton,
&mut EventContext<'context, 'window>,
),
{ {
self.mouse_drag = Some(Box::new(mouse_drag)); self.mouse_drag = Some(Box::new(mouse_drag));
self self
@ -401,11 +379,11 @@ impl Custom {
where where
MouseUp: Send MouseUp: Send
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context> FnMut(
Option<Point<Px>>, Option<Point<Px>>,
DeviceId, DeviceId,
MouseButton, MouseButton,
&mut EventContext<'context, 'window>, &mut EventContext<'context>,
), ),
{ {
self.mouse_up = Some(Box::new(mouse_up)); self.mouse_up = Some(Box::new(mouse_up));
@ -417,9 +395,8 @@ impl Custom {
/// This callback corresponds to [`WrapperWidget::ime`]. /// This callback corresponds to [`WrapperWidget::ime`].
pub fn on_ime<OnIme>(mut self, ime: OnIme) -> Self pub fn on_ime<OnIme>(mut self, ime: OnIme) -> Self
where where
OnIme: Send OnIme:
+ 'static Send + 'static + for<'context> FnMut(Ime, &mut EventContext<'context>) -> EventHandling,
+ for<'context, 'window> FnMut(Ime, &mut EventContext<'context, 'window>) -> EventHandling,
{ {
self.ime = Some(Box::new(ime)); self.ime = Some(Box::new(ime));
self self
@ -432,11 +409,11 @@ impl Custom {
where where
KeyboardInput: Send KeyboardInput: Send
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context> FnMut(
DeviceId, DeviceId,
KeyEvent, KeyEvent,
bool, bool,
&mut EventContext<'context, 'window>, &mut EventContext<'context>,
) -> EventHandling, ) -> EventHandling,
{ {
self.keyboard_input = Some(Box::new(keyboard_input)); self.keyboard_input = Some(Box::new(keyboard_input));
@ -450,11 +427,11 @@ impl Custom {
where where
MouseWheel: Send MouseWheel: Send
+ 'static + 'static
+ for<'context, 'window> FnMut( + for<'context> FnMut(
DeviceId, DeviceId,
MouseScrollDelta, MouseScrollDelta,
TouchPhase, TouchPhase,
&mut EventContext<'context, 'window>, &mut EventContext<'context>,
) -> EventHandling, ) -> EventHandling,
{ {
self.mouse_wheel = Some(Box::new(mouse_wheel)); self.mouse_wheel = Some(Box::new(mouse_wheel));
@ -467,13 +444,13 @@ impl WrapperWidget for Custom {
&mut self.child &mut self.child
} }
fn redraw_background(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw_background(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
if let Some(redraw) = &mut self.redraw_background { if let Some(redraw) = &mut self.redraw_background {
redraw.invoke(context); redraw.invoke(context);
} }
} }
fn redraw_foreground(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw_foreground(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
if let Some(redraw) = &mut self.redraw_foreground { if let Some(redraw) = &mut self.redraw_foreground {
redraw.invoke(context); redraw.invoke(context);
} }
@ -482,7 +459,7 @@ impl WrapperWidget for Custom {
fn adjust_child_constraints( fn adjust_child_constraints(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<ConstraintLimit> { ) -> Size<ConstraintLimit> {
if let Some(adjust_child) = &mut self.adjust_child { if let Some(adjust_child) = &mut self.adjust_child {
adjust_child.invoke(available_space, context) adjust_child.invoke(available_space, context)
@ -495,7 +472,7 @@ impl WrapperWidget for Custom {
&mut self, &mut self,
size: Size<Px>, size: Size<Px>,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
if let Some(position_child) = &mut self.position_child { if let Some(position_child) = &mut self.position_child {
position_child.invoke(size, available_space, context) position_child.invoke(size, available_space, context)
@ -512,19 +489,19 @@ impl WrapperWidget for Custom {
} }
} }
fn background_color(&mut self, context: &WidgetContext<'_, '_>) -> Option<Color> { fn background_color(&mut self, context: &WidgetContext<'_>) -> Option<Color> {
self.background self.background
.as_ref() .as_ref()
.map(|bg| bg.get_tracking_redraw(context)) .map(|bg| bg.get_tracking_redraw(context))
} }
fn mounted(&mut self, context: &mut EventContext<'_, '_>) { fn mounted(&mut self, context: &mut EventContext<'_>) {
if let Some(mounted) = &mut self.mounted { if let Some(mounted) = &mut self.mounted {
mounted.invoke(context); mounted.invoke(context);
} }
} }
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
if let Some(unmounted) = &mut self.unmounted { if let Some(unmounted) = &mut self.unmounted {
unmounted.invoke(context); unmounted.invoke(context);
} else { } else {
@ -532,7 +509,7 @@ impl WrapperWidget for Custom {
} }
} }
fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> bool {
if let Some(hit_test) = &mut self.hit_test { if let Some(hit_test) = &mut self.hit_test {
hit_test.invoke(location, context) hit_test.invoke(location, context)
} else { } else {
@ -540,22 +517,18 @@ impl WrapperWidget for Custom {
} }
} }
fn hover( fn hover(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> Option<CursorIcon> {
&mut self,
location: Point<Px>,
context: &mut EventContext<'_, '_>,
) -> Option<CursorIcon> {
let hover = self.hover.as_mut()?; let hover = self.hover.as_mut()?;
hover.invoke(location, context) hover.invoke(location, context)
} }
fn unhover(&mut self, context: &mut EventContext<'_, '_>) { fn unhover(&mut self, context: &mut EventContext<'_>) {
if let Some(unhover) = &mut self.unhover { if let Some(unhover) = &mut self.unhover {
unhover.invoke(context); unhover.invoke(context);
} }
} }
fn accept_focus(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, context: &mut EventContext<'_>) -> bool {
if let Some(accept_focus) = &mut self.accept_focus { if let Some(accept_focus) = &mut self.accept_focus {
accept_focus.invoke(context) accept_focus.invoke(context)
} else { } else {
@ -563,25 +536,25 @@ impl WrapperWidget for Custom {
} }
} }
fn focus(&mut self, context: &mut EventContext<'_, '_>) { fn focus(&mut self, context: &mut EventContext<'_>) {
if let Some(focus) = &mut self.focus { if let Some(focus) = &mut self.focus {
focus.invoke(context); focus.invoke(context);
} }
} }
fn blur(&mut self, context: &mut EventContext<'_, '_>) { fn blur(&mut self, context: &mut EventContext<'_>) {
if let Some(blur) = &mut self.blur { if let Some(blur) = &mut self.blur {
blur.invoke(context); blur.invoke(context);
} }
} }
fn activate(&mut self, context: &mut EventContext<'_, '_>) { fn activate(&mut self, context: &mut EventContext<'_>) {
if let Some(activate) = &mut self.activate { if let Some(activate) = &mut self.activate {
activate.invoke(context); activate.invoke(context);
} }
} }
fn deactivate(&mut self, context: &mut EventContext<'_, '_>) { fn deactivate(&mut self, context: &mut EventContext<'_>) {
if let Some(deactivate) = &mut self.deactivate { if let Some(deactivate) = &mut self.deactivate {
deactivate.invoke(context); deactivate.invoke(context);
} }
@ -592,7 +565,7 @@ impl WrapperWidget for Custom {
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if let Some(mouse_down) = &mut self.mouse_down { if let Some(mouse_down) = &mut self.mouse_down {
mouse_down.invoke(location, device_id, button, context) mouse_down.invoke(location, device_id, button, context)
@ -606,7 +579,7 @@ impl WrapperWidget for Custom {
location: Point<Px>, location: Point<Px>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
if let Some(mouse_drag) = &mut self.mouse_drag { if let Some(mouse_drag) = &mut self.mouse_drag {
mouse_drag.invoke(location, device_id, button, context); mouse_drag.invoke(location, device_id, button, context);
@ -618,7 +591,7 @@ impl WrapperWidget for Custom {
location: Option<Point<Px>>, location: Option<Point<Px>>,
device_id: DeviceId, device_id: DeviceId,
button: MouseButton, button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
if let Some(mouse_up) = &mut self.mouse_up { if let Some(mouse_up) = &mut self.mouse_up {
mouse_up.invoke(location, device_id, button, context); mouse_up.invoke(location, device_id, button, context);
@ -630,7 +603,7 @@ impl WrapperWidget for Custom {
device_id: DeviceId, device_id: DeviceId,
input: KeyEvent, input: KeyEvent,
is_synthetic: bool, is_synthetic: bool,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if let Some(keyboard_input) = &mut self.keyboard_input { if let Some(keyboard_input) = &mut self.keyboard_input {
keyboard_input.invoke(device_id, input, is_synthetic, context) keyboard_input.invoke(device_id, input, is_synthetic, context)
@ -639,7 +612,7 @@ impl WrapperWidget for Custom {
} }
} }
fn ime(&mut self, ime: Ime, context: &mut EventContext<'_, '_>) -> EventHandling { fn ime(&mut self, ime: Ime, context: &mut EventContext<'_>) -> EventHandling {
if let Some(f) = &mut self.ime { if let Some(f) = &mut self.ime {
f.invoke(ime, context) f.invoke(ime, context)
} else { } else {
@ -652,7 +625,7 @@ impl WrapperWidget for Custom {
device_id: DeviceId, device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
phase: TouchPhase, phase: TouchPhase,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if let Some(mouse_wheel) = &mut self.mouse_wheel { if let Some(mouse_wheel) = &mut self.mouse_wheel {
mouse_wheel.invoke(device_id, delta, phase, context) mouse_wheel.invoke(device_id, delta, phase, context)
@ -664,7 +637,7 @@ impl WrapperWidget for Custom {
fn advance_focus( fn advance_focus(
&mut self, &mut self,
direction: VisualOrder, direction: VisualOrder,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if let Some(advance_focus) = &mut self.advance_focus { if let Some(advance_focus) = &mut self.advance_focus {
advance_focus.invoke(direction, context) advance_focus.invoke(direction, context)
@ -673,7 +646,7 @@ impl WrapperWidget for Custom {
} }
} }
fn allow_blur(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn allow_blur(&mut self, context: &mut EventContext<'_>) -> bool {
if let Some(allow_blur) = &mut self.allow_blur { if let Some(allow_blur) = &mut self.allow_blur {
allow_blur.invoke(context) allow_blur.invoke(context)
} else { } else {
@ -683,18 +656,16 @@ impl WrapperWidget for Custom {
} }
trait RedrawFunc: Send { trait RedrawFunc: Send {
fn invoke(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>); fn invoke(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>);
} }
impl<Func> RedrawFunc for Func impl<Func> RedrawFunc for Func
where where
Func: Send Func: Send
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'clip, 'gfx, 'pass> FnMut(&mut GraphicsContext<'context, 'clip, 'gfx, 'pass>),
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
),
{ {
fn invoke(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn invoke(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
self(context); self(context);
} }
} }
@ -703,7 +674,7 @@ trait AdjustChildConstraintsFunc: Send {
fn invoke( fn invoke(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<ConstraintLimit>; ) -> Size<ConstraintLimit>;
} }
@ -711,15 +682,15 @@ impl<Func> AdjustChildConstraintsFunc for Func
where where
Func: Send Func: Send
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'clip, 'gfx, 'pass> FnMut(
Size<ConstraintLimit>, Size<ConstraintLimit>,
&mut LayoutContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut LayoutContext<'context, 'clip, 'gfx, 'pass>,
) -> Size<ConstraintLimit>, ) -> Size<ConstraintLimit>,
{ {
fn invoke( fn invoke(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<ConstraintLimit> { ) -> Size<ConstraintLimit> {
self(available_space, context) self(available_space, context)
} }
@ -730,7 +701,7 @@ trait PositionChildFunc: Send {
&mut self, &mut self,
size: Size<Px>, size: Size<Px>,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout; ) -> WrappedLayout;
} }
@ -738,45 +709,44 @@ impl<Func> PositionChildFunc for Func
where where
Func: Send Func: Send
+ 'static + 'static
+ for<'context, 'window, 'clip, 'gfx, 'pass> FnMut( + for<'context, 'clip, 'gfx, 'pass> FnMut(
Size<Px>, Size<Px>,
Size<ConstraintLimit>, Size<ConstraintLimit>,
&mut LayoutContext<'context, 'window, 'clip, 'gfx, 'pass>, &mut LayoutContext<'context, 'clip, 'gfx, 'pass>,
) -> WrappedLayout, ) -> WrappedLayout,
{ {
fn invoke( fn invoke(
&mut self, &mut self,
size: Size<Px>, size: Size<Px>,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
self(size, available_space, context) self(size, available_space, context)
} }
} }
trait EventFunc<R = ()>: Send { trait EventFunc<R = ()>: Send {
fn invoke(&mut self, context: &mut EventContext<'_, '_>) -> R; fn invoke(&mut self, context: &mut EventContext<'_>) -> R;
} }
impl<R, Func> EventFunc<R> for Func impl<R, Func> EventFunc<R> for Func
where where
Func: Send + 'static + for<'context, 'window> FnMut(&mut EventContext<'context, 'window>) -> R, Func: Send + 'static + for<'context> FnMut(&mut EventContext<'context>) -> R,
{ {
fn invoke(&mut self, context: &mut EventContext<'_, '_>) -> R { fn invoke(&mut self, context: &mut EventContext<'_>) -> R {
self(context) self(context)
} }
} }
trait OneParamEventFunc<P, R = ()>: Send { trait OneParamEventFunc<P, R = ()>: Send {
fn invoke(&mut self, param: P, context: &mut EventContext<'_, '_>) -> R; fn invoke(&mut self, param: P, context: &mut EventContext<'_>) -> R;
} }
impl<P, R, Func> OneParamEventFunc<P, R> for Func impl<P, R, Func> OneParamEventFunc<P, R> for Func
where where
Func: Func: Send + 'static + for<'context> FnMut(P, &mut EventContext<'context>) -> R,
Send + 'static + for<'context, 'window> FnMut(P, &mut EventContext<'context, 'window>) -> R,
{ {
fn invoke(&mut self, location: P, context: &mut EventContext<'_, '_>) -> R { fn invoke(&mut self, location: P, context: &mut EventContext<'_>) -> R {
self(location, context) self(location, context)
} }
} }
@ -787,7 +757,7 @@ trait ThreeParamEventFunc<P1, P2, P3, R = ()>: Send {
location: P1, location: P1,
device_id: P2, device_id: P2,
button: P3, button: P3,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> R; ) -> R;
} }
@ -795,16 +765,14 @@ type MouseUpFunc = dyn ThreeParamEventFunc<Option<Point<Px>>, DeviceId, MouseBut
impl<P1, P2, P3, R, Func> ThreeParamEventFunc<P1, P2, P3, R> for Func impl<P1, P2, P3, R, Func> ThreeParamEventFunc<P1, P2, P3, R> for Func
where where
Func: Send Func: Send + 'static + for<'context> FnMut(P1, P2, P3, &mut EventContext<'context>) -> R,
+ 'static
+ for<'context, 'window> FnMut(P1, P2, P3, &mut EventContext<'context, 'window>) -> R,
{ {
fn invoke( fn invoke(
&mut self, &mut self,
location: P1, location: P1,
device_id: P2, device_id: P2,
button: P3, button: P3,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> R { ) -> R {
self(location, device_id, button, context) self(location, device_id, button, context)
} }

View file

@ -122,7 +122,7 @@ impl DiscloseIndicator {
fn effective_colors( fn effective_colors(
&mut self, &mut self,
context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>,
) -> (Color, Color) { ) -> (Color, Color) {
let current_color = if context.active() { let current_color = if context.active() {
context.get(&ButtonActiveBackground) context.get(&ButtonActiveBackground)
@ -161,14 +161,14 @@ impl DiscloseIndicator {
} }
impl Widget for DiscloseIndicator { impl Widget for DiscloseIndicator {
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
if let Some(label) = &mut self.label { if let Some(label) = &mut self.label {
label.unmount_in(context); label.unmount_in(context);
} }
self.contents.unmount_in(context); self.contents.unmount_in(context);
} }
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) {
let angle = self.angle.get_tracking_redraw(context); let angle = self.angle.get_tracking_redraw(context);
let (color, stroke_color) = self.effective_colors(context); let (color, stroke_color) = self.effective_colors(context);
let size = context let size = context
@ -217,7 +217,7 @@ impl Widget for DiscloseIndicator {
fn layout( fn layout(
&mut self, &mut self,
mut available_space: Size<ConstraintLimit>, mut available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
let indicator_size = context let indicator_size = context
.get(&IndicatorSize) .get(&IndicatorSize)
@ -270,19 +270,19 @@ impl Widget for DiscloseIndicator {
) )
} }
fn accept_focus(&mut self, _context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, _context: &mut EventContext<'_>) -> bool {
true true
} }
fn focus(&mut self, context: &mut EventContext<'_, '_>) { fn focus(&mut self, context: &mut EventContext<'_>) {
context.set_needs_redraw(); context.set_needs_redraw();
} }
fn blur(&mut self, context: &mut EventContext<'_, '_>) { fn blur(&mut self, context: &mut EventContext<'_>) {
context.set_needs_redraw(); context.set_needs_redraw();
} }
fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> bool {
let size = context let size = context
.get(&IndicatorSize) .get(&IndicatorSize)
.into_px(context.kludgine.scale()) .into_px(context.kludgine.scale())
@ -296,11 +296,7 @@ impl Widget for DiscloseIndicator {
} }
} }
fn hover( fn hover(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> Option<CursorIcon> {
&mut self,
location: Point<Px>,
context: &mut EventContext<'_, '_>,
) -> Option<CursorIcon> {
let hovering = self.hit_test(location, context); let hovering = self.hit_test(location, context);
if self.hovering_indicator != hovering { if self.hovering_indicator != hovering {
context.set_needs_redraw(); context.set_needs_redraw();
@ -310,7 +306,7 @@ impl Widget for DiscloseIndicator {
hovering.then_some(CursorIcon::Pointer) hovering.then_some(CursorIcon::Pointer)
} }
fn unhover(&mut self, context: &mut EventContext<'_, '_>) { fn unhover(&mut self, context: &mut EventContext<'_>) {
if self.hovering_indicator { if self.hovering_indicator {
self.hovering_indicator = false; self.hovering_indicator = false;
context.set_needs_redraw(); context.set_needs_redraw();
@ -322,7 +318,7 @@ impl Widget for DiscloseIndicator {
location: Point<Px>, location: Point<Px>,
_device_id: kludgine::app::winit::event::DeviceId, _device_id: kludgine::app::winit::event::DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if self.hit_test(location, context) { if self.hit_test(location, context) {
self.mouse_buttons_pressed += 1; self.mouse_buttons_pressed += 1;
@ -339,7 +335,7 @@ impl Widget for DiscloseIndicator {
_location: Option<Point<Px>>, _location: Option<Point<Px>>,
_device_id: kludgine::app::winit::event::DeviceId, _device_id: kludgine::app::winit::event::DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
self.mouse_buttons_pressed -= 1; self.mouse_buttons_pressed -= 1;
if self.mouse_buttons_pressed == 0 { if self.mouse_buttons_pressed == 0 {
@ -348,7 +344,7 @@ impl Widget for DiscloseIndicator {
} }
} }
fn activate(&mut self, _context: &mut EventContext<'_, '_>) { fn activate(&mut self, _context: &mut EventContext<'_>) {
if self.mouse_buttons_pressed == 0 { if self.mouse_buttons_pressed == 0 {
self.collapsed.toggle(); self.collapsed.toggle();
} }

View file

@ -98,14 +98,14 @@ impl WrapperWidget for Expand {
&mut self.child &mut self.child
} }
fn root_behavior(&mut self, _context: &mut EventContext<'_, '_>) -> Option<RootBehavior> { fn root_behavior(&mut self, _context: &mut EventContext<'_>) -> Option<RootBehavior> {
Some(RootBehavior::Expand) Some(RootBehavior::Expand)
} }
fn layout_child( fn layout_child(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
let available_space = available_space.map(|lim| ConstraintLimit::Fill(lim.max())); let available_space = available_space.map(|lim| ConstraintLimit::Fill(lim.max()));
let child = self.child.mounted(&mut context.as_event_context()); let child = self.child.mounted(&mut context.as_event_context());

View file

@ -67,7 +67,7 @@ impl<const ELEMENTS: usize> Grid<ELEMENTS> {
self self
} }
fn synchronize_specs(&mut self, context: &mut EventContext<'_, '_>) { fn synchronize_specs(&mut self, context: &mut EventContext<'_>) {
let current_generation = self.columns.generation(); let current_generation = self.columns.generation();
let count_changed = self.layout.children.len() != ELEMENTS; let count_changed = self.layout.children.len() != ELEMENTS;
if count_changed if count_changed
@ -84,7 +84,7 @@ impl<const ELEMENTS: usize> Grid<ELEMENTS> {
} }
} }
fn synchronize_children(&mut self, context: &mut EventContext<'_, '_>) { fn synchronize_children(&mut self, context: &mut EventContext<'_>) {
self.synchronize_specs(context); self.synchronize_specs(context);
let current_generation = self.rows.generation(); let current_generation = self.rows.generation();
self.rows.invalidate_when_changed(context); self.rows.invalidate_when_changed(context);
@ -132,7 +132,7 @@ impl<const ELEMENTS: usize> Grid<ELEMENTS> {
} }
impl<const COLUMNS: usize> Widget for Grid<COLUMNS> { impl<const COLUMNS: usize> Widget for Grid<COLUMNS> {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
for (row, widgets) in self.live_rows.iter_mut().enumerate() { for (row, widgets) in self.live_rows.iter_mut().enumerate() {
if self.layout.others[row] > 0 { if self.layout.others[row] > 0 {
for (column, cell) in widgets.iter().enumerate() { for (column, cell) in widgets.iter().enumerate() {
@ -147,7 +147,7 @@ impl<const COLUMNS: usize> Widget for Grid<COLUMNS> {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
self.synchronize_children(&mut context.as_event_context()); self.synchronize_children(&mut context.as_event_context());

View file

@ -112,7 +112,7 @@ impl Image {
} }
impl Widget for Image { impl Widget for Image {
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) {
self.contents.map(|texture| { self.contents.map(|texture| {
let size = texture.size().into_signed(); let size = texture.size().into_signed();
let rect = match self.scaling.get() { let rect = match self.scaling.get() {
@ -147,7 +147,7 @@ impl Widget for Image {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
match self.scaling.get_tracking_invalidate(context) { match self.scaling.get_tracking_invalidate(context) {
ImageScaling::Aspect { .. } | ImageScaling::Stretch => { ImageScaling::Aspect { .. } | ImageScaling::Stretch => {

View file

@ -166,7 +166,7 @@ where
}); });
} }
fn forward_delete(&mut self, context: &mut EventContext<'_, '_>) { fn forward_delete(&mut self, context: &mut EventContext<'_>) {
if !context.enabled() { if !context.enabled() {
return; return;
} }
@ -200,7 +200,7 @@ where
}); });
} }
fn delete(&mut self, context: &mut EventContext<'_, '_>) { fn delete(&mut self, context: &mut EventContext<'_>) {
if !context.enabled() { if !context.enabled() {
return; return;
} }
@ -231,7 +231,7 @@ where
&mut self, &mut self,
direction: Affinity, direction: Affinity,
mode: CursorNavigationMode, mode: CursorNavigationMode,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
if !matches!(mode, CursorNavigationMode::Line) { if !matches!(mode, CursorNavigationMode::Line) {
self.line_navigation_x_target = None; self.line_navigation_x_target = None;
@ -315,11 +315,7 @@ where
} }
} }
fn move_cursor_by_line_extent( fn move_cursor_by_line_extent(&mut self, affinity: Affinity, context: &mut EventContext<'_>) {
&mut self,
affinity: Affinity,
context: &mut EventContext<'_, '_>,
) {
let Some(cache) = self.cache.as_ref() else { let Some(cache) = self.cache.as_ref() else {
return; return;
}; };
@ -339,7 +335,7 @@ where
self.selection.cursor = self.cursor_from_point(position, context); self.selection.cursor = self.cursor_from_point(position, context);
} }
fn move_cursor_by_line(&mut self, affinity: Affinity, context: &mut EventContext<'_, '_>) { fn move_cursor_by_line(&mut self, affinity: Affinity, context: &mut EventContext<'_>) {
let Some(cache) = self.cache.as_ref() else { let Some(cache) = self.cache.as_ref() else {
return; return;
}; };
@ -406,13 +402,13 @@ where
self.mask_symbol.map(|mask| !mask.is_empty()) self.mask_symbol.map(|mask| !mask.is_empty())
} }
fn copy_selection_to_clipboard(&mut self, context: &mut EventContext<'_, '_>) { fn copy_selection_to_clipboard(&mut self, context: &mut EventContext<'_>) {
if self.is_masked() { if self.is_masked() {
return; return;
} }
self.map_selected_text(|text| { self.map_selected_text(|text| {
if let Some(mut clipboard) = context.clipboard_guard() { if let Some(mut clipboard) = context.cushy().clipboard_guard() {
match clipboard.set_text(text) { match clipboard.set_text(text) {
Ok(()) => {} Ok(()) => {}
Err(err) => tracing::error!("error copying to clipboard: {err}"), Err(err) => tracing::error!("error copying to clipboard: {err}"),
@ -421,7 +417,7 @@ where
}); });
} }
fn replace_selection(&mut self, new_text: &str, context: &mut EventContext<'_, '_>) { fn replace_selection(&mut self, new_text: &str, context: &mut EventContext<'_>) {
if !context.enabled() { if !context.enabled() {
return; return;
} }
@ -444,12 +440,13 @@ where
}; };
} }
fn paste_from_clipboard(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn paste_from_clipboard(&mut self, context: &mut EventContext<'_>) -> bool {
if !context.enabled() { if !context.enabled() {
return false; return false;
} }
match context match context
.cushy()
.clipboard_guard() .clipboard_guard()
.map(|mut clipboard| clipboard.get_text()) .map(|mut clipboard| clipboard.get_text())
{ {
@ -465,7 +462,7 @@ where
} }
} }
fn handle_key(&mut self, input: KeyEvent, context: &mut EventContext<'_, '_>) -> EventHandling { fn handle_key(&mut self, input: KeyEvent, context: &mut EventContext<'_>) -> EventHandling {
match (input.state, input.logical_key, input.text.as_deref()) { match (input.state, input.logical_key, input.text.as_deref()) {
(ElementState::Pressed, Key::Named(key @ (NamedKey::Backspace| NamedKey::Delete)), _) => { (ElementState::Pressed, Key::Named(key @ (NamedKey::Backspace| NamedKey::Delete)), _) => {
match key { match key {
@ -547,11 +544,7 @@ where
} }
} }
fn layout_text( fn layout_text(&mut self, width: Option<Px>, context: &mut GraphicsContext<'_, '_, '_, '_>) {
&mut self,
width: Option<Px>,
context: &mut GraphicsContext<'_, '_, '_, '_, '_>,
) {
context.invalidate_when_changed(&self.value); context.invalidate_when_changed(&self.value);
let mut key = { let mut key = {
@ -808,11 +801,7 @@ where
} }
} }
fn cursor_from_point( fn cursor_from_point(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> Cursor {
&mut self,
location: Point<Px>,
context: &mut EventContext<'_, '_>,
) -> Cursor {
let mut cursor = self.cached_cursor_from_point(location, context); let mut cursor = self.cached_cursor_from_point(location, context);
if let Some(symbol) = self.mask.graphemes(true).next() { if let Some(symbol) = self.mask.graphemes(true).next() {
let grapheme_offset = cursor.offset / symbol.len(); let grapheme_offset = cursor.offset / symbol.len();
@ -831,7 +820,7 @@ where
fn cached_cursor_from_point( fn cached_cursor_from_point(
&mut self, &mut self,
location: Point<Px>, location: Point<Px>,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Cursor { ) -> Cursor {
let Some(cache) = &self.cache else { let Some(cache) = &self.cache else {
return Cursor::default(); return Cursor::default();
@ -973,11 +962,11 @@ impl<Storage> Widget for Input<Storage>
where where
Storage: InputStorage + Debug, Storage: InputStorage + Debug,
{ {
fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_>) -> bool {
true true
} }
fn accept_focus(&mut self, _context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, _context: &mut EventContext<'_>) -> bool {
true true
} }
@ -986,7 +975,7 @@ where
location: Point<Px>, location: Point<Px>,
_device_id: kludgine::app::winit::event::DeviceId, _device_id: kludgine::app::winit::event::DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
self.mouse_buttons_down += 1; self.mouse_buttons_down += 1;
context.focus(); context.focus();
@ -1000,7 +989,7 @@ where
fn hover( fn hover(
&mut self, &mut self,
_location: Point<Px>, _location: Point<Px>,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) -> Option<CursorIcon> { ) -> Option<CursorIcon> {
Some(CursorIcon::Text) Some(CursorIcon::Text)
} }
@ -1010,7 +999,7 @@ where
location: Point<Px>, location: Point<Px>,
_device_id: kludgine::app::winit::event::DeviceId, _device_id: kludgine::app::winit::event::DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
let cursor_location = self.cursor_from_point(location, context); let cursor_location = self.cursor_from_point(location, context);
if self.selection.cursor != cursor_location { if self.selection.cursor != cursor_location {
@ -1025,13 +1014,13 @@ where
_location: Option<Point<Px>>, _location: Option<Point<Px>>,
_device_id: kludgine::app::winit::event::DeviceId, _device_id: kludgine::app::winit::event::DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) { ) {
self.mouse_buttons_down -= 1; self.mouse_buttons_down -= 1;
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) {
if self.needs_to_select_all { if self.needs_to_select_all {
self.needs_to_select_all = false; self.needs_to_select_all = false;
self.select_all(); self.select_all();
@ -1177,7 +1166,7 @@ where
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
let padding = context let padding = context
.get(&IntrinsicPadding) .get(&IntrinsicPadding)
@ -1202,7 +1191,7 @@ where
_device_id: kludgine::app::winit::event::DeviceId, _device_id: kludgine::app::winit::event::DeviceId,
input: kludgine::app::winit::event::KeyEvent, input: kludgine::app::winit::event::KeyEvent,
_is_synthetic: bool, _is_synthetic: bool,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if let Some(on_key) = &mut self.on_key { if let Some(on_key) = &mut self.on_key {
on_key.invoke(input.clone())?; on_key.invoke(input.clone())?;
@ -1219,7 +1208,7 @@ where
handled handled
} }
fn ime(&mut self, ime: Ime, context: &mut EventContext<'_, '_>) -> EventHandling { fn ime(&mut self, ime: Ime, context: &mut EventContext<'_>) -> EventHandling {
match ime { match ime {
Ime::Enabled | Ime::Disabled => {} Ime::Enabled | Ime::Disabled => {}
Ime::Preedit(text, cursor) => { Ime::Preedit(text, cursor) => {
@ -1234,7 +1223,7 @@ where
HANDLED HANDLED
} }
fn focus(&mut self, context: &mut EventContext<'_, '_>) { fn focus(&mut self, context: &mut EventContext<'_>) {
if self.mouse_buttons_down == 0 { if self.mouse_buttons_down == 0 {
self.needs_to_select_all = true; self.needs_to_select_all = true;
} }
@ -1248,7 +1237,7 @@ where
context.set_needs_redraw(); context.set_needs_redraw();
} }
fn blur(&mut self, context: &mut EventContext<'_, '_>) { fn blur(&mut self, context: &mut EventContext<'_>) {
context.set_ime_allowed(false); context.set_ime_allowed(false);
context.set_needs_redraw(); context.set_needs_redraw();
} }

View file

@ -38,7 +38,7 @@ where
fn prepared_text( fn prepared_text(
&mut self, &mut self,
context: &mut GraphicsContext<'_, '_, '_, '_, '_>, context: &mut GraphicsContext<'_, '_, '_, '_>,
color: Color, color: Color,
width: Px, width: Px,
) -> &MeasuredText<Px> { ) -> &MeasuredText<Px> {
@ -76,7 +76,7 @@ impl<T> Widget for Label<T>
where where
T: std::fmt::Debug + std::fmt::Display + Send + 'static, T: std::fmt::Debug + std::fmt::Display + Send + 'static,
{ {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
self.display.invalidate_when_changed(context); self.display.invalidate_when_changed(context);
let size = context.gfx.region().size; let size = context.gfx.region().size;
@ -94,7 +94,7 @@ where
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
let color = context.get(&TextColor); let color = context.get(&TextColor);
let width = available_space.width.max().try_into().unwrap_or(Px::MAX); let width = available_space.width.max().try_into().unwrap_or(Px::MAX);
@ -107,7 +107,7 @@ where
fmt.debug_tuple("Label").field(&self.display).finish() fmt.debug_tuple("Label").field(&self.display).finish()
} }
fn unmounted(&mut self, context: &mut crate::context::EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut crate::context::EventContext<'_>) {
self.prepared_text.clear_for(context); self.prepared_text.clear_for(context);
} }
} }

View file

@ -39,14 +39,14 @@ impl Layers {
} }
} }
fn synchronize_children(&mut self, context: &mut EventContext<'_, '_>) { fn synchronize_children(&mut self, context: &mut EventContext<'_>) {
self.children.invalidate_when_changed(context); self.children.invalidate_when_changed(context);
self.mounted.synchronize_with(&self.children, context); self.mounted.synchronize_with(&self.children, context);
} }
} }
impl Widget for Layers { impl Widget for Layers {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
self.synchronize_children(&mut context.as_event_context()); self.synchronize_children(&mut context.as_event_context());
for mounted in self.mounted.children() { for mounted in self.mounted.children() {
@ -68,7 +68,7 @@ impl Widget for Layers {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
self.synchronize_children(&mut context.as_event_context()); self.synchronize_children(&mut context.as_event_context());
@ -104,11 +104,11 @@ impl Widget for Layers {
size size
} }
fn mounted(&mut self, context: &mut EventContext<'_, '_>) { fn mounted(&mut self, context: &mut EventContext<'_>) {
self.synchronize_children(context); self.synchronize_children(context);
} }
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
for child in self.mounted.drain() { for child in self.mounted.drain() {
context.remove_child(&child); context.remove_child(&child);
} }
@ -116,7 +116,7 @@ impl Widget for Layers {
fn root_behavior( fn root_behavior(
&mut self, &mut self,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<(RootBehavior, WidgetInstance)> { ) -> Option<(RootBehavior, WidgetInstance)> {
self.synchronize_children(context); self.synchronize_children(context);
@ -174,7 +174,7 @@ impl OverlayLayer {
} }
impl Widget for OverlayLayer { impl Widget for OverlayLayer {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let state = self.state.lock(); let state = self.state.lock();
for child in &state.overlays { for child in &state.overlays {
@ -192,7 +192,7 @@ impl Widget for OverlayLayer {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
let mut state = self.state.lock(); let mut state = self.state.lock();
state.prevent_notifications(); state.prevent_notifications();
@ -233,7 +233,7 @@ impl Widget for OverlayLayer {
Size::ZERO Size::ZERO
} }
fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, location: Point<Px>, context: &mut EventContext<'_>) -> bool {
let state = self.state.lock(); let state = self.state.lock();
state.test_point(location, false, context).is_some() state.test_point(location, false, context).is_some()
} }
@ -241,7 +241,7 @@ impl Widget for OverlayLayer {
fn hover( fn hover(
&mut self, &mut self,
location: Point<Px>, location: Point<Px>,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<kludgine::app::winit::window::CursorIcon> { ) -> Option<kludgine::app::winit::window::CursorIcon> {
let mut state = self.state.lock(); let mut state = self.state.lock();
@ -259,7 +259,7 @@ impl Widget for OverlayLayer {
None None
} }
fn unhover(&mut self, _context: &mut EventContext<'_, '_>) { fn unhover(&mut self, _context: &mut EventContext<'_>) {
let mut state = self.state.lock(); let mut state = self.state.lock();
state.hovering = None; state.hovering = None;
@ -301,7 +301,7 @@ impl OverlayState {
&self, &self,
location: Point<Px>, location: Point<Px>,
check_original_relative: bool, check_original_relative: bool,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<usize> { ) -> Option<usize> {
for (index, overlay) in self.overlays.iter().enumerate() { for (index, overlay) in self.overlays.iter().enumerate() {
if overlay.requires_hover if overlay.requires_hover
@ -326,7 +326,7 @@ impl OverlayState {
fn point_is_in_root_relative( fn point_is_in_root_relative(
&self, &self,
location: Point<Px>, location: Point<Px>,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> bool { ) -> bool {
if let Some(relative_to) = self if let Some(relative_to) = self
.overlays .overlays
@ -342,7 +342,7 @@ impl OverlayState {
false false
} }
fn process_new_overlays(&mut self, context: &mut EventContext<'_, '_>) { fn process_new_overlays(&mut self, context: &mut EventContext<'_>) {
while self.new_overlays > 0 { while self.new_overlays > 0 {
let new_index = self.overlays.len() - self.new_overlays; let new_index = self.overlays.len() - self.new_overlays;
self.new_overlays -= 1; self.new_overlays -= 1;
@ -378,7 +378,7 @@ impl OverlayState {
index: usize, index: usize,
widget: &MountedWidget, widget: &MountedWidget,
available_space: Size<UPx>, available_space: Size<UPx>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
relative_to: WidgetId, relative_to: WidgetId,
) -> Option<Rect<Px>> { ) -> Option<Rect<Px>> {
let direction = self.overlays[index].direction; let direction = self.overlays[index].direction;
@ -465,7 +465,7 @@ impl OverlayState {
&self, &self,
checking_index: usize, checking_index: usize,
layout: &Rect<Px>, layout: &Rect<Px>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> bool { ) -> bool {
for index in (0..self.overlays.len()).filter(|&i| i != checking_index) { for index in (0..self.overlays.len()).filter(|&i| i != checking_index) {
if self.overlays[index] if self.overlays[index]
@ -497,7 +497,7 @@ impl OverlayState {
index: usize, index: usize,
widget: &MountedWidget, widget: &MountedWidget,
available_space: Size<UPx>, available_space: Size<UPx>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Option<Rect<Px>> { ) -> Option<Rect<Px>> {
if let Some(relative_to) = self.overlays[index].relative_to { if let Some(relative_to) = self.overlays[index].relative_to {
self.layout_overlay_relative(index, widget, available_space, context, relative_to) self.layout_overlay_relative(index, widget, available_space, context, relative_to)
@ -747,7 +747,7 @@ impl WrapperWidget for Tooltipped {
fn hover( fn hover(
&mut self, &mut self,
_location: Point<Px>, _location: Point<Px>,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<kludgine::app::winit::window::CursorIcon> { ) -> Option<kludgine::app::winit::window::CursorIcon> {
let background_color = context.theme().surface.highest_container; let background_color = context.theme().surface.highest_container;
@ -779,7 +779,7 @@ impl WrapperWidget for Tooltipped {
None None
} }
fn unhover(&mut self, _context: &mut EventContext<'_, '_>) { fn unhover(&mut self, _context: &mut EventContext<'_>) {
self.show_animation = None; self.show_animation = None;
self.data.shown_tooltip.set(None); self.data.shown_tooltip.set(None);
} }

View file

@ -25,7 +25,7 @@ impl WrapperWidget for ThemedMode {
&mut self.child &mut self.child
} }
fn mounted(&mut self, context: &mut EventContext<'_, '_>) { fn mounted(&mut self, context: &mut EventContext<'_>) {
context.attach_theme_mode(self.mode.clone()); context.attach_theme_mode(self.mode.clone());
} }
} }

View file

@ -318,7 +318,7 @@ impl Spinner {
start: ZeroToOne, start: ZeroToOne,
sweep: ZeroToOne, sweep: ZeroToOne,
color: Color, color: Color,
context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>,
) { ) {
if sweep > 0. { if sweep > 0. {
context.gfx.draw_shape( context.gfx.draw_shape(
@ -335,7 +335,7 @@ impl Spinner {
} }
impl Widget for Spinner { impl Widget for Spinner {
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) {
let track_size = context.get(&TrackSize).into_px(context.gfx.scale()); let track_size = context.get(&TrackSize).into_px(context.gfx.scale());
let start = self.start.get_tracking_redraw(context); let start = self.start.get_tracking_redraw(context);
let end = self.end.get_tracking_redraw(context); let end = self.end.get_tracking_redraw(context);
@ -384,7 +384,7 @@ impl Widget for Spinner {
fn layout( fn layout(
&mut self, &mut self,
available_space: figures::Size<crate::ConstraintLimit>, available_space: figures::Size<crate::ConstraintLimit>,
context: &mut crate::context::LayoutContext<'_, '_, '_, '_, '_>, context: &mut crate::context::LayoutContext<'_, '_, '_, '_>,
) -> figures::Size<figures::units::UPx> { ) -> figures::Size<figures::units::UPx> {
let track_size = context.get(&TrackSize).into_px(context.gfx.scale()); let track_size = context.get(&TrackSize).into_px(context.gfx.scale());
let minimum_size = track_size * 4; let minimum_size = track_size * 4;

View file

@ -80,7 +80,7 @@ impl<T> Widget for RadioOrnament<T>
where where
T: Debug + Eq + Send + 'static, T: Debug + Eq + Send + 'static,
{ {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let radio_size = context let radio_size = context
.gfx .gfx
.region() .region()
@ -118,7 +118,7 @@ where
fn layout( fn layout(
&mut self, &mut self,
_available_space: Size<ConstraintLimit>, _available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<figures::units::UPx> { ) -> Size<figures::units::UPx> {
let radio_size = context.get(&RadioSize).into_upx(context.gfx.scale()); let radio_size = context.get(&RadioSize).into_upx(context.gfx.scale());
Size::squared(radio_size) Size::squared(radio_size)

View file

@ -89,14 +89,14 @@ impl WrapperWidget for Resize {
&mut self.child &mut self.child
} }
fn root_behavior(&mut self, _context: &mut EventContext<'_, '_>) -> Option<RootBehavior> { fn root_behavior(&mut self, _context: &mut EventContext<'_>) -> Option<RootBehavior> {
Some(RootBehavior::Resize(Size::new(self.width, self.height))) Some(RootBehavior::Resize(Size::new(self.width, self.height)))
} }
fn layout_child( fn layout_child(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> WrappedLayout { ) -> WrappedLayout {
let child = self.child.mounted(&mut context.as_event_context()); let child = self.child.mounted(&mut context.as_event_context());
let size = if let (Some(width), Some(height)) = let size = if let (Some(width), Some(height)) =

View file

@ -97,7 +97,7 @@ impl Scroll {
(clamped, max_scroll) (clamped, max_scroll)
} }
fn show_scrollbars(&mut self, context: &mut EventContext<'_, '_>) { fn show_scrollbars(&mut self, context: &mut EventContext<'_>) {
let should_hide = self.drag.mouse_buttons_down == 0; let should_hide = self.drag.mouse_buttons_down == 0;
if should_hide != self.scrollbar_opacity_animation.will_hide if should_hide != self.scrollbar_opacity_animation.will_hide
|| self.scrollbar_opacity_animation.handle.is_complete() || self.scrollbar_opacity_animation.handle.is_complete()
@ -130,7 +130,7 @@ impl Scroll {
} }
} }
fn hide_scrollbars(&mut self, context: &mut EventContext<'_, '_>) { fn hide_scrollbars(&mut self, context: &mut EventContext<'_>) {
if self.drag.mouse_buttons_down == 0 && !self.scrollbar_opacity_animation.will_hide { if self.drag.mouse_buttons_down == 0 && !self.scrollbar_opacity_animation.will_hide {
self.scrollbar_opacity_animation.will_hide = true; self.scrollbar_opacity_animation.will_hide = true;
self.scrollbar_opacity_animation.handle = self self.scrollbar_opacity_animation.handle = self
@ -144,29 +144,29 @@ impl Scroll {
} }
impl Widget for Scroll { impl Widget for Scroll {
fn unmounted(&mut self, context: &mut EventContext<'_, '_>) { fn unmounted(&mut self, context: &mut EventContext<'_>) {
self.contents.unmount_in(context); self.contents.unmount_in(context);
} }
fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_>) -> bool {
true true
} }
fn hover( fn hover(
&mut self, &mut self,
_location: Point<Px>, _location: Point<Px>,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<CursorIcon> { ) -> Option<CursorIcon> {
self.show_scrollbars(context); self.show_scrollbars(context);
None None
} }
fn unhover(&mut self, context: &mut EventContext<'_, '_>) { fn unhover(&mut self, context: &mut EventContext<'_>) {
self.hide_scrollbars(context); self.hide_scrollbars(context);
} }
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) {
context.redraw_when_changed(&self.scrollbar_opacity); context.redraw_when_changed(&self.scrollbar_opacity);
let managed = self.contents.mounted(&mut context.as_event_context()); let managed = self.contents.mounted(&mut context.as_event_context());
@ -198,7 +198,7 @@ impl Widget for Scroll {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
self.bar_width = context self.bar_width = context
.get(&ScrollBarThickness) .get(&ScrollBarThickness)
@ -302,7 +302,7 @@ impl Widget for Scroll {
_device_id: DeviceId, _device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
_phase: TouchPhase, _phase: TouchPhase,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
let amount = match delta { let amount = match delta {
MouseScrollDelta::LineDelta(x, y) => Point::new(x, y) * self.line_height.into_float(), MouseScrollDelta::LineDelta(x, y) => Point::new(x, y) * self.line_height.into_float(),
@ -330,7 +330,7 @@ impl Widget for Scroll {
location: Point<Px>, location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
let relative_x = (self.control_size.width - location.x).max(Px::ZERO); let relative_x = (self.control_size.width - location.x).max(Px::ZERO);
let in_vertical_area = self.enabled.y && relative_x <= self.bar_width; let in_vertical_area = self.enabled.y && relative_x <= self.bar_width;
@ -380,7 +380,7 @@ impl Widget for Scroll {
location: Point<Px>, location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) { ) {
self.drag.update( self.drag.update(
location, location,
@ -397,7 +397,7 @@ impl Widget for Scroll {
location: Option<Point<Px>>, location: Option<Point<Px>>,
_device_id: DeviceId, _device_id: DeviceId,
_button: kludgine::app::winit::event::MouseButton, _button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
self.drag.mouse_buttons_down -= 1; self.drag.mouse_buttons_down -= 1;

View file

@ -144,7 +144,7 @@ where
self self
} }
fn draw_track(&mut self, spec: &TrackSpec, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn draw_track(&mut self, spec: &TrackSpec, context: &mut GraphicsContext<'_, '_, '_, '_>) {
if self.horizontal { if self.horizontal {
self.rendered_size = spec.size.width; self.rendered_size = spec.size.width;
} else { } else {
@ -238,7 +238,7 @@ where
focus: Option<Knob>, focus: Option<Knob>,
focus_ring_width: Px, focus_ring_width: Px,
spec: &TrackSpec, spec: &TrackSpec,
context: &mut GraphicsContext<'_, '_, '_, '_, '_>, context: &mut GraphicsContext<'_, '_, '_, '_>,
) { ) {
let (a, a_is_focused, b) = match (start_knob, focus) { let (a, a_is_focused, b) = match (start_knob, focus) {
(Some(start_knob), Some(Knob::Start)) => (end_knob, false, Some((start_knob, true))), (Some(start_knob), Some(Knob::Start)) => (end_knob, false, Some((start_knob, true))),
@ -257,7 +257,7 @@ where
is_focused: bool, is_focused: bool,
focus_ring_width: Px, focus_ring_width: Px,
spec: &TrackSpec, spec: &TrackSpec,
context: &mut GraphicsContext<'_, '_, '_, '_, '_>, context: &mut GraphicsContext<'_, '_, '_, '_>,
) { ) {
context.gfx.draw_shape( context.gfx.draw_shape(
Shape::filled_circle(spec.half_knob, spec.knob_color, Origin::Center) Shape::filled_circle(spec.half_knob, spec.knob_color, Origin::Center)
@ -417,7 +417,7 @@ impl<T> Widget for Slider<T>
where where
T: SliderValue, T: SliderValue,
{ {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let (track_color, inactive_track_color, knob_color) = if context.enabled() { let (track_color, inactive_track_color, knob_color) = if context.enabled() {
( (
context.get(&TrackColor), context.get(&TrackColor),
@ -500,7 +500,7 @@ where
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
self.knob_size = if self.knob_visible { self.knob_size = if self.knob_visible {
context.get(&KnobSize).into_upx(context.gfx.scale()) context.get(&KnobSize).into_upx(context.gfx.scale())
@ -552,14 +552,14 @@ where
} }
} }
fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_, '_>) -> bool { fn hit_test(&mut self, _location: Point<Px>, _context: &mut EventContext<'_>) -> bool {
self.interactive self.interactive
} }
fn hover( fn hover(
&mut self, &mut self,
_location: Point<Px>, _location: Point<Px>,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> Option<CursorIcon> { ) -> Option<CursorIcon> {
(self.interactive && self.knob_visible).then_some({ (self.interactive && self.knob_visible).then_some({
if context.enabled() { if context.enabled() {
@ -574,14 +574,14 @@ where
}) })
} }
fn accept_focus(&mut self, context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, context: &mut EventContext<'_>) -> bool {
context.enabled() context.enabled()
&& self.interactive && self.interactive
&& self.knob_visible && self.knob_visible
&& context.get(&AutoFocusableControls).is_all() && context.get(&AutoFocusableControls).is_all()
} }
fn focus(&mut self, context: &mut EventContext<'_, '_>) { fn focus(&mut self, context: &mut EventContext<'_>) {
if self.mouse_buttons_down == 0 { if self.mouse_buttons_down == 0 {
self.focused_knob = Some(if T::RANGED && !context.focus_is_advancing() { self.focused_knob = Some(if T::RANGED && !context.focus_is_advancing() {
Knob::End Knob::End
@ -595,7 +595,7 @@ where
fn advance_focus( fn advance_focus(
&mut self, &mut self,
direction: VisualOrder, direction: VisualOrder,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
let (true, Some(focused)) = (T::RANGED, self.focused_knob) else { let (true, Some(focused)) = (T::RANGED, self.focused_knob) else {
return IGNORED; return IGNORED;
@ -619,7 +619,7 @@ where
HANDLED HANDLED
} }
fn blur(&mut self, context: &mut EventContext<'_, '_>) { fn blur(&mut self, context: &mut EventContext<'_>) {
self.previous_focus = self.focused_knob.take(); self.previous_focus = self.focused_knob.take();
context.set_needs_redraw(); context.set_needs_redraw();
} }
@ -629,7 +629,7 @@ where
location: Point<Px>, location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
let true = self.interactive else { let true = self.interactive else {
return IGNORED; return IGNORED;
@ -652,7 +652,7 @@ where
location: Point<Px>, location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) { ) {
if context.enabled() { if context.enabled() {
self.update_from_click(location, None); self.update_from_click(location, None);
@ -664,7 +664,7 @@ where
_location: Option<Point<Px>>, _location: Option<Point<Px>>,
_device_id: DeviceId, _device_id: DeviceId,
_button: MouseButton, _button: MouseButton,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) { ) {
self.mouse_buttons_down -= 1; self.mouse_buttons_down -= 1;
} }
@ -674,7 +674,7 @@ where
_device_id: DeviceId, _device_id: DeviceId,
input: kludgine::app::winit::event::KeyEvent, input: kludgine::app::winit::event::KeyEvent,
_is_synthetic: bool, _is_synthetic: bool,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
let true = self.interactive else { let true = self.interactive else {
return IGNORED; return IGNORED;
@ -699,7 +699,7 @@ where
_device_id: DeviceId, _device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
_phase: TouchPhase, _phase: TouchPhase,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
let true = self.interactive else { let true = self.interactive else {
return IGNORED; return IGNORED;

View file

@ -38,7 +38,7 @@ impl Space {
} }
impl Widget for Space { impl Widget for Space {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let color = self.color.get_tracking_redraw(context); let color = self.color.get_tracking_redraw(context);
context.fill(color); context.fill(color);
} }
@ -46,7 +46,7 @@ impl Widget for Space {
fn layout( fn layout(
&mut self, &mut self,
_available_space: Size<ConstraintLimit>, _available_space: Size<ConstraintLimit>,
_context: &mut LayoutContext<'_, '_, '_, '_, '_>, _context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
Size::default() Size::default()
} }

View file

@ -56,7 +56,7 @@ impl Stack {
self self
} }
fn synchronize_children(&mut self, context: &mut EventContext<'_, '_>) { fn synchronize_children(&mut self, context: &mut EventContext<'_>) {
let current_generation = self.children.generation(); let current_generation = self.children.generation();
self.children.invalidate_when_changed(context); self.children.invalidate_when_changed(context);
if current_generation.map_or_else( if current_generation.map_or_else(
@ -118,7 +118,7 @@ impl Stack {
} }
impl Widget for Stack { impl Widget for Stack {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
for (layout, child) in self.layout.iter().zip(&self.synced_children) { for (layout, child) in self.layout.iter().zip(&self.synced_children) {
if layout.size > 0 { if layout.size > 0 {
context.for_other(child).redraw(); context.for_other(child).redraw();
@ -129,7 +129,7 @@ impl Widget for Stack {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
self.synchronize_children(&mut context.as_event_context()); self.synchronize_children(&mut context.as_event_context());

View file

@ -206,7 +206,7 @@ impl WrapperWidget for Style {
&mut self.child &mut self.child
} }
fn mounted(&mut self, context: &mut EventContext<'_, '_>) { fn mounted(&mut self, context: &mut EventContext<'_>) {
context.attach_styles(self.styles.clone()); context.attach_styles(self.styles.clone());
} }
} }

View file

@ -52,7 +52,7 @@ impl WrapperWidget for Switcher {
fn adjust_child_constraints( fn adjust_child_constraints(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<ConstraintLimit> { ) -> Size<ConstraintLimit> {
if self.source.has_updated() { if self.source.has_updated() {
self.child = WidgetRef::new(self.source.get()); self.child = WidgetRef::new(self.source.get());

View file

@ -25,7 +25,7 @@ impl WrapperWidget for Themed {
&mut self.child &mut self.child
} }
fn mounted(&mut self, context: &mut EventContext<'_, '_>) { fn mounted(&mut self, context: &mut EventContext<'_>) {
context.attach_theme(self.theme.clone()); context.attach_theme(self.theme.clone());
} }
} }

View file

@ -64,7 +64,7 @@ impl<Layers> Widget for TileMap<Layers>
where where
Layers: tilemap::Layers, Layers: tilemap::Layers,
{ {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
let focus = self.focus.get(); let focus = self.focus.get();
// TODO this needs to be updated to support being placed in side of a scroll view. // TODO this needs to be updated to support being placed in side of a scroll view.
let redraw_after = match &mut self.layers { let redraw_after = match &mut self.layers {
@ -103,14 +103,14 @@ where
} }
} }
fn accept_focus(&mut self, _context: &mut EventContext<'_, '_>) -> bool { fn accept_focus(&mut self, _context: &mut EventContext<'_>) -> bool {
true true
} }
fn hit_test( fn hit_test(
&mut self, &mut self,
_location: figures::Point<figures::units::Px>, _location: figures::Point<figures::units::Px>,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) -> bool { ) -> bool {
true true
} }
@ -118,7 +118,7 @@ where
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
_context: &mut LayoutContext<'_, '_, '_, '_, '_>, _context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
Size::new(available_space.width.max(), available_space.height.max()) Size::new(available_space.width.max(), available_space.height.max())
} }
@ -128,7 +128,7 @@ where
_device_id: DeviceId, _device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
_phase: TouchPhase, _phase: TouchPhase,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
let amount = match delta { let amount = match delta {
MouseScrollDelta::LineDelta(_, lines) => lines, MouseScrollDelta::LineDelta(_, lines) => lines,
@ -141,11 +141,7 @@ where
HANDLED HANDLED
} }
fn hover( fn hover(&mut self, local: Point<Px>, context: &mut EventContext<'_>) -> Option<CursorIcon> {
&mut self,
local: Point<Px>,
context: &mut EventContext<'_, '_>,
) -> Option<CursorIcon> {
if let Some(tick) = &self.tick { if let Some(tick) = &self.tick {
let Some(size) = context.last_layout().map(|rect| rect.size) else { let Some(size) = context.last_layout().map(|rect| rect.size) else {
return None; return None;
@ -163,7 +159,7 @@ where
None None
} }
fn unhover(&mut self, _context: &mut EventContext<'_, '_>) { fn unhover(&mut self, _context: &mut EventContext<'_>) {
if let Some(tick) = &self.tick { if let Some(tick) = &self.tick {
tick.set_cursor_position(None); tick.set_cursor_position(None);
} }
@ -174,7 +170,7 @@ where
_device_id: DeviceId, _device_id: DeviceId,
input: KeyEvent, input: KeyEvent,
_is_synthetic: bool, _is_synthetic: bool,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if let Some(tick) = &self.tick { if let Some(tick) = &self.tick {
tick.key_input(&input)?; tick.key_input(&input)?;
@ -188,7 +184,7 @@ where
_location: Point<Px>, _location: Point<Px>,
_device_id: DeviceId, _device_id: DeviceId,
button: kludgine::app::winit::event::MouseButton, button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_, '_>, context: &mut EventContext<'_>,
) -> EventHandling { ) -> EventHandling {
if let Some(tick) = &self.tick { if let Some(tick) = &self.tick {
tick.mouse_button(button, ElementState::Pressed); tick.mouse_button(button, ElementState::Pressed);
@ -204,7 +200,7 @@ where
_location: Option<Point<Px>>, _location: Option<Point<Px>>,
_device_id: DeviceId, _device_id: DeviceId,
button: kludgine::app::winit::event::MouseButton, button: kludgine::app::winit::event::MouseButton,
_context: &mut EventContext<'_, '_>, _context: &mut EventContext<'_>,
) { ) {
if let Some(tick) = &self.tick { if let Some(tick) = &self.tick {
tick.mouse_button(button, ElementState::Released); tick.mouse_button(button, ElementState::Released);

View file

@ -102,10 +102,7 @@ impl WrapperWidget for ValidatedWidget {
&mut self.contents &mut self.contents
} }
fn redraw_background( fn redraw_background(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) {
&mut self,
context: &mut crate::context::GraphicsContext<'_, '_, '_, '_, '_>,
) {
self.error_color.set(context.get(&InvalidTextColor)); self.error_color.set(context.get(&InvalidTextColor));
self.default_color.set(context.get(&HintTextColor)); self.default_color.set(context.get(&HintTextColor));
} }

View file

@ -97,7 +97,7 @@ impl Wrap {
} }
impl Widget for Wrap { impl Widget for Wrap {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_>) {
for child in self.mounted.children() { for child in self.mounted.children() {
context.for_other(child).redraw(); context.for_other(child).redraw();
} }
@ -107,7 +107,7 @@ impl Widget for Wrap {
fn layout( fn layout(
&mut self, &mut self,
available_space: Size<ConstraintLimit>, available_space: Size<ConstraintLimit>,
context: &mut LayoutContext<'_, '_, '_, '_, '_>, context: &mut LayoutContext<'_, '_, '_, '_>,
) -> Size<UPx> { ) -> Size<UPx> {
struct RowChild { struct RowChild {
index: usize, index: usize,

File diff suppressed because it is too large Load diff