mirror of
https://github.com/danbulant/cushy
synced 2026-06-24 17:12:11 +00:00
MakeWindow + easy window centering
This commit is contained in:
parent
dd4c544ba6
commit
14d2069fec
5 changed files with 209 additions and 94 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -23,6 +23,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
initial value of the dynamic or whether to let the operating system perform
|
initial value of the dynamic or whether to let the operating system perform
|
||||||
the initial positioning.
|
the initial positioning.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `Open` is now implemented for most types via a blanket implementation for a
|
||||||
|
new trait, `MakeWindow`. `MakeWindow` splits the process of creating a
|
||||||
|
`Window<Behavior>` from the process of opening a window.
|
||||||
|
|
||||||
|
The new `MakeWindow` trait adds some new functionality:
|
||||||
|
`open_centered`/`run_centered`/`run_centered_in`. These functions present a
|
||||||
|
window centered on the screen where the window initially is shown.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- `Collapse`, `OverlayLayer`, and `Progress` all honor the theme components
|
- `Collapse`, `OverlayLayer`, and `Progress` all honor the theme components
|
||||||
|
|
|
||||||
28
src/debug.rs
28
src/debug.rs
|
|
@ -7,8 +7,7 @@ use alot::OrderedLots;
|
||||||
use crate::value::{Dynamic, DynamicReader, ForEach, Source, WeakDynamic};
|
use crate::value::{Dynamic, DynamicReader, ForEach, Source, WeakDynamic};
|
||||||
use crate::widget::{MakeWidget, WidgetInstance, WidgetList};
|
use crate::widget::{MakeWidget, WidgetInstance, WidgetList};
|
||||||
use crate::widgets::grid::{Grid, GridWidgets};
|
use crate::widgets::grid::{Grid, GridWidgets};
|
||||||
use crate::window::Window;
|
use crate::window::{MakeWindow, Window};
|
||||||
use crate::{Application, 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)]
|
||||||
|
|
@ -96,14 +95,6 @@ impl DebugContext {
|
||||||
Self { section }
|
Self { section }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_window(self) -> Window {
|
|
||||||
self.section
|
|
||||||
.map_ref(|section| section.widget.clone())
|
|
||||||
// .vertical_scroll()
|
|
||||||
.into_window()
|
|
||||||
.titled("Cushy Debugger")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if this debug context has no child sections or observed
|
/// Returns true if this debug context has no child sections or observed
|
||||||
/// values.
|
/// values.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -114,16 +105,15 @@ impl DebugContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Open for DebugContext {
|
impl MakeWindow for DebugContext {
|
||||||
fn open<App>(self, app: &mut App) -> crate::Result<crate::window::WindowHandle>
|
type Behavior = WidgetInstance;
|
||||||
where
|
|
||||||
App: Application + ?Sized,
|
|
||||||
{
|
|
||||||
self.into_window().open(app)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_in(self, app: PendingApp) -> crate::Result {
|
fn make_window(self) -> Window<Self::Behavior> {
|
||||||
self.into_window().run_in(app)
|
self.section
|
||||||
|
.map_ref(|section| section.widget.clone())
|
||||||
|
// .vertical_scroll()
|
||||||
|
.make_window()
|
||||||
|
.titled("Cushy Debugger")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
30
src/value.rs
30
src/value.rs
|
|
@ -550,7 +550,6 @@ pub trait Destination<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]
|
|
||||||
fn take(&self) -> T
|
fn take(&self) -> T
|
||||||
where
|
where
|
||||||
Self: Source<T>,
|
Self: Source<T>,
|
||||||
|
|
@ -1919,17 +1918,29 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct ChangeCallbacksExecutor {
|
||||||
|
thread: Option<ThreadId>,
|
||||||
|
callbacks_to_remove: Vec<LotId>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ChangeCallbacksData {
|
struct ChangeCallbacksData {
|
||||||
callbacks: Mutex<CallbacksList>,
|
callbacks: Mutex<CallbacksList>,
|
||||||
currently_executing: Mutex<Option<ThreadId>>,
|
currently_executing: Mutex<ChangeCallbacksExecutor>,
|
||||||
sync: Condvar,
|
sync: Condvar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallbackCollection for ChangeCallbacksData {
|
impl CallbackCollection for ChangeCallbacksData {
|
||||||
fn remove(&self, id: LotId) {
|
fn remove(&self, id: LotId) {
|
||||||
let mut data = self.callbacks.lock();
|
let mut currently_executing = self.currently_executing.lock();
|
||||||
data.callbacks.remove(id);
|
if currently_executing.thread == Some(thread::current().id()) {
|
||||||
|
currently_executing.callbacks_to_remove.push(id);
|
||||||
|
} else {
|
||||||
|
drop(currently_executing);
|
||||||
|
let mut data = self.callbacks.lock();
|
||||||
|
data.callbacks.remove(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1957,12 +1968,12 @@ impl Drop for ChangeCallbacks {
|
||||||
let mut currently_executing = self.data.currently_executing.lock();
|
let mut currently_executing = self.data.currently_executing.lock();
|
||||||
let current_thread = thread::current().id();
|
let current_thread = thread::current().id();
|
||||||
loop {
|
loop {
|
||||||
match &*currently_executing {
|
match ¤tly_executing.thread {
|
||||||
None => {
|
None => {
|
||||||
// No other thread is executing these callbacks. Set this
|
// No other thread is executing these callbacks. Set this
|
||||||
// thread as the current executor so that we can prevent
|
// thread as the current executor so that we can prevent
|
||||||
// infinite cycles.
|
// infinite cycles.
|
||||||
*currently_executing = Some(current_thread);
|
currently_executing.thread = Some(current_thread);
|
||||||
drop(currently_executing);
|
drop(currently_executing);
|
||||||
|
|
||||||
// Invoke the callbacks
|
// Invoke the callbacks
|
||||||
|
|
@ -1978,12 +1989,15 @@ impl Drop for ChangeCallbacks {
|
||||||
.callbacks
|
.callbacks
|
||||||
.drain_filter(|callback| callback.changed().is_err());
|
.drain_filter(|callback| callback.changed().is_err());
|
||||||
}
|
}
|
||||||
drop(state);
|
|
||||||
|
|
||||||
// Remove ourselves as the current executor, notifying any
|
// Remove ourselves as the current executor, notifying any
|
||||||
// other threads that are waiting.
|
// other threads that are waiting.
|
||||||
currently_executing = self.data.currently_executing.lock();
|
currently_executing = self.data.currently_executing.lock();
|
||||||
*currently_executing = None;
|
currently_executing.thread = None;
|
||||||
|
for callback in currently_executing.callbacks_to_remove.drain(..) {
|
||||||
|
state.callbacks.remove(callback);
|
||||||
|
}
|
||||||
|
drop(state);
|
||||||
drop(currently_executing);
|
drop(currently_executing);
|
||||||
self.data.sync.notify_all();
|
self.data.sync.notify_all();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use kludgine::app::winit::window::CursorIcon;
|
||||||
use kludgine::Color;
|
use kludgine::Color;
|
||||||
use parking_lot::{Mutex, MutexGuard};
|
use parking_lot::{Mutex, MutexGuard};
|
||||||
|
|
||||||
use crate::app::{Application, Open, PendingApp, Run};
|
use crate::app::Run;
|
||||||
use crate::context::sealed::Trackable as _;
|
use crate::context::sealed::Trackable as _;
|
||||||
use crate::context::{
|
use crate::context::{
|
||||||
AsEventContext, EventContext, GraphicsContext, LayoutContext, ManageWidget, WidgetContext,
|
AsEventContext, EventContext, GraphicsContext, LayoutContext, ManageWidget, WidgetContext,
|
||||||
|
|
@ -46,7 +46,7 @@ use crate::widgets::{
|
||||||
};
|
};
|
||||||
use crate::window::sealed::WindowCommand;
|
use crate::window::sealed::WindowCommand;
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
DeviceId, KeyEvent, Rgb8, RunningWindow, StandaloneWindowBuilder, ThemeMode,
|
DeviceId, KeyEvent, MakeWindow, Rgb8, RunningWindow, StandaloneWindowBuilder, ThemeMode,
|
||||||
VirtualRecorderBuilder, Window, WindowBehavior, WindowHandle, WindowLocal,
|
VirtualRecorderBuilder, Window, WindowBehavior, WindowHandle, WindowLocal,
|
||||||
};
|
};
|
||||||
use crate::ConstraintLimit;
|
use crate::ConstraintLimit;
|
||||||
|
|
@ -470,23 +470,6 @@ where
|
||||||
}
|
}
|
||||||
// ANCHOR_END: run
|
// ANCHOR_END: run
|
||||||
|
|
||||||
impl<T> Open for T
|
|
||||||
where
|
|
||||||
T: MakeWidget,
|
|
||||||
{
|
|
||||||
fn open<App>(self, app: &mut App) -> crate::Result<crate::window::WindowHandle>
|
|
||||||
where
|
|
||||||
App: Application + ?Sized,
|
|
||||||
{
|
|
||||||
Window::<WidgetInstance>::new(self.make_widget()).open(app)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_in(self, mut app: PendingApp) -> crate::Result {
|
|
||||||
Window::<WidgetInstance>::new(self.make_widget()).open(&mut app)?;
|
|
||||||
app.run()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A behavior that should be applied to a root widget.
|
/// A behavior that should be applied to a root widget.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum RootBehavior {
|
pub enum RootBehavior {
|
||||||
|
|
@ -918,8 +901,8 @@ pub trait MakeWidget: Sized {
|
||||||
fn make_widget(self) -> WidgetInstance;
|
fn make_widget(self) -> WidgetInstance;
|
||||||
|
|
||||||
/// Returns a new window containing `self` as the root widget.
|
/// Returns a new window containing `self` as the root widget.
|
||||||
fn into_window(self) -> Window<WidgetInstance> {
|
fn into_window(self) -> Window {
|
||||||
Window::new(self.make_widget())
|
self.make_window()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a builder for a standalone window.
|
/// Returns a builder for a standalone window.
|
||||||
|
|
@ -1611,7 +1594,7 @@ impl WidgetInstance {
|
||||||
where
|
where
|
||||||
Self: Clone,
|
Self: Clone,
|
||||||
{
|
{
|
||||||
self.clone().into_window()
|
self.clone().make_window()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
208
src/window.rs
208
src/window.rs
|
|
@ -562,7 +562,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window<WidgetInstance> {
|
impl Window {
|
||||||
/// Returns a new instance using `widget` as its contents.
|
/// Returns a new instance using `widget` as its contents.
|
||||||
pub fn for_widget<W>(widget: W) -> Self
|
pub fn for_widget<W>(widget: W) -> Self
|
||||||
where
|
where
|
||||||
|
|
@ -645,6 +645,63 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the handle to this window.
|
||||||
|
pub const fn handle(&self) -> &WindowHandle {
|
||||||
|
&self.pending.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Opens `self` in the center of the monitor the window initially appears
|
||||||
|
/// on.
|
||||||
|
pub fn open_centered<App>(mut self, app: &mut App) -> crate::Result<WindowHandle>
|
||||||
|
where
|
||||||
|
App: Application + ?Sized,
|
||||||
|
{
|
||||||
|
// We want to ensure that if the user has customized any of these
|
||||||
|
// properties that we keep their dynamic.
|
||||||
|
let outer_position = self.outer_position.clone().unwrap_or_else(|| {
|
||||||
|
let outer_position = Dynamic::new(Point::default());
|
||||||
|
self.outer_position = Some(outer_position.clone());
|
||||||
|
outer_position
|
||||||
|
});
|
||||||
|
let outer_size = self.outer_size.clone().unwrap_or_else(|| {
|
||||||
|
let outer_size = Dynamic::new(Size::default());
|
||||||
|
self.outer_size = Some(outer_size.clone());
|
||||||
|
outer_size
|
||||||
|
});
|
||||||
|
let visible = self.visible.clone().unwrap_or_else(|| {
|
||||||
|
let visible = Dynamic::new(false);
|
||||||
|
self.visible = Some(visible.clone());
|
||||||
|
visible
|
||||||
|
});
|
||||||
|
visible.set(false);
|
||||||
|
|
||||||
|
let callback_handle = Dynamic::new(None);
|
||||||
|
callback_handle.set(Some(outer_size.for_each_subsequent({
|
||||||
|
let visible = visible.clone();
|
||||||
|
let app = app.as_app();
|
||||||
|
let callback_handle = callback_handle.clone();
|
||||||
|
move |new_size| {
|
||||||
|
if let Some(monitor) = app.monitors().and_then(|monitors| {
|
||||||
|
let initial_position = outer_position.get();
|
||||||
|
monitors
|
||||||
|
.available
|
||||||
|
.into_iter()
|
||||||
|
.find(|m| m.region().contains(initial_position))
|
||||||
|
.or(monitors.primary)
|
||||||
|
}) {
|
||||||
|
let region = monitor.region();
|
||||||
|
let margin = region.size - new_size.into_signed();
|
||||||
|
outer_position.set(region.origin + margin / 2);
|
||||||
|
}
|
||||||
|
visible.set(true);
|
||||||
|
// Uninstall this callback to ensure it doesn't fire again.
|
||||||
|
let _ = callback_handle.take();
|
||||||
|
}
|
||||||
|
})));
|
||||||
|
|
||||||
|
self.open(app)
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets `focused` to be the dynamic updated when this window's focus status
|
/// Sets `focused` to be the dynamic updated when this window's focus status
|
||||||
/// is changed.
|
/// is changed.
|
||||||
///
|
///
|
||||||
|
|
@ -936,61 +993,62 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Behavior> Open for Window<Behavior>
|
impl<T> Open for T
|
||||||
where
|
where
|
||||||
Behavior: WindowBehavior,
|
T: MakeWindow,
|
||||||
{
|
{
|
||||||
fn open<App>(self, app: &mut App) -> crate::Result<WindowHandle>
|
fn open<App>(self, app: &mut App) -> crate::Result<WindowHandle>
|
||||||
where
|
where
|
||||||
App: Application + ?Sized,
|
App: Application + ?Sized,
|
||||||
{
|
{
|
||||||
|
let this = self.make_window();
|
||||||
let cushy = app.cushy().clone();
|
let cushy = app.cushy().clone();
|
||||||
let handle = self.pending.handle();
|
let handle = this.pending.handle();
|
||||||
OpenWindow::<Behavior>::open_with(
|
OpenWindow::<T::Behavior>::open_with(
|
||||||
app,
|
app,
|
||||||
sealed::Context {
|
sealed::Context {
|
||||||
user: self.context,
|
user: this.context,
|
||||||
settings: RefCell::new(sealed::WindowSettings {
|
settings: RefCell::new(sealed::WindowSettings {
|
||||||
cushy,
|
cushy,
|
||||||
title: self.title,
|
title: this.title,
|
||||||
redraw_status: self.pending.0.redraw_status.clone(),
|
redraw_status: this.pending.0.redraw_status.clone(),
|
||||||
on_open: self.on_open,
|
on_open: this.on_open,
|
||||||
on_closed: self.on_closed,
|
on_closed: this.on_closed,
|
||||||
transparent: self.attributes.transparent,
|
transparent: this.attributes.transparent,
|
||||||
attributes: Some(self.attributes),
|
attributes: Some(this.attributes),
|
||||||
occluded: self.occluded.unwrap_or_default(),
|
occluded: this.occluded.unwrap_or_default(),
|
||||||
focused: self.focused.unwrap_or_default(),
|
focused: this.focused.unwrap_or_default(),
|
||||||
inner_size: self.inner_size.unwrap_or_default(),
|
inner_size: this.inner_size.unwrap_or_default(),
|
||||||
theme: Some(self.theme),
|
theme: Some(this.theme),
|
||||||
theme_mode: self.theme_mode,
|
theme_mode: this.theme_mode,
|
||||||
font_data_to_load: self.fonts,
|
font_data_to_load: this.fonts,
|
||||||
serif_font_family: self.serif_font_family,
|
serif_font_family: this.serif_font_family,
|
||||||
sans_serif_font_family: self.sans_serif_font_family,
|
sans_serif_font_family: this.sans_serif_font_family,
|
||||||
fantasy_font_family: self.fantasy_font_family,
|
fantasy_font_family: this.fantasy_font_family,
|
||||||
monospace_font_family: self.monospace_font_family,
|
monospace_font_family: this.monospace_font_family,
|
||||||
cursive_font_family: self.cursive_font_family,
|
cursive_font_family: this.cursive_font_family,
|
||||||
vsync: self.vsync,
|
vsync: this.vsync,
|
||||||
multisample_count: self.multisample_count,
|
multisample_count: this.multisample_count,
|
||||||
close_requested: self.close_requested.map(|cb| Arc::new(Mutex::new(cb))),
|
close_requested: this.close_requested.map(|cb| Arc::new(Mutex::new(cb))),
|
||||||
zoom: self.zoom.unwrap_or_else(|| Dynamic::new(Fraction::ONE)),
|
zoom: this.zoom.unwrap_or_else(|| Dynamic::new(Fraction::ONE)),
|
||||||
resize_to_fit: self.resize_to_fit,
|
resize_to_fit: this.resize_to_fit,
|
||||||
content_protected: self.content_protected.unwrap_or_default(),
|
content_protected: this.content_protected.unwrap_or_default(),
|
||||||
cursor_hittest: self.cursor_hittest.unwrap_or_else(|| Value::Constant(true)),
|
cursor_hittest: this.cursor_hittest.unwrap_or_else(|| Value::Constant(true)),
|
||||||
cursor_visible: self.cursor_visible.unwrap_or_else(|| Value::Constant(true)),
|
cursor_visible: this.cursor_visible.unwrap_or_else(|| Value::Constant(true)),
|
||||||
cursor_position: self.cursor_position.unwrap_or_default(),
|
cursor_position: this.cursor_position.unwrap_or_default(),
|
||||||
window_level: self.window_level.unwrap_or_default(),
|
window_level: this.window_level.unwrap_or_default(),
|
||||||
decorated: self.decorated.unwrap_or_else(|| Value::Constant(true)),
|
decorated: this.decorated.unwrap_or_else(|| Value::Constant(true)),
|
||||||
maximized: self.maximized.unwrap_or_default(),
|
maximized: this.maximized.unwrap_or_default(),
|
||||||
minimized: self.minimized.unwrap_or_default(),
|
minimized: this.minimized.unwrap_or_default(),
|
||||||
resizable: self.resizable.unwrap_or_else(|| Value::Constant(true)),
|
resizable: this.resizable.unwrap_or_else(|| Value::Constant(true)),
|
||||||
resize_increments: self.resize_increments.unwrap_or_default(),
|
resize_increments: this.resize_increments.unwrap_or_default(),
|
||||||
visible: self.visible.unwrap_or_default(),
|
visible: this.visible.unwrap_or_default(),
|
||||||
inner_position: self.inner_position.unwrap_or_default(),
|
inner_position: this.inner_position.unwrap_or_default(),
|
||||||
outer_position: self.outer_position.unwrap_or_default(),
|
outer_position: this.outer_position.unwrap_or_default(),
|
||||||
outer_size: self.outer_size.unwrap_or_default(),
|
outer_size: this.outer_size.unwrap_or_default(),
|
||||||
window_icon: self.icon.unwrap_or_default(),
|
window_icon: this.icon.unwrap_or_default(),
|
||||||
}),
|
}),
|
||||||
pending: self.pending,
|
pending: this.pending,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
@ -1003,6 +1061,66 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A type that can be made into a [`Window`].
|
||||||
|
pub trait MakeWindow {
|
||||||
|
/// The behavior associated with this window.
|
||||||
|
type Behavior: WindowBehavior;
|
||||||
|
|
||||||
|
/// Returns a new window from `self`.
|
||||||
|
fn make_window(self) -> Window<Self::Behavior>;
|
||||||
|
|
||||||
|
/// Opens `self` in the center of the monitor the window initially appears
|
||||||
|
/// on.
|
||||||
|
fn open_centered<App>(self, app: &mut App) -> crate::Result<WindowHandle>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
App: Application + ?Sized,
|
||||||
|
{
|
||||||
|
self.make_window().open_centered(app)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs `self` in the center of the monitor the window
|
||||||
|
/// initially appears on.
|
||||||
|
fn run_centered(self) -> crate::Result
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.make_window().run()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs `app` after opening `self` in the center of the monitor the window
|
||||||
|
/// initially appears on.
|
||||||
|
fn run_centered_in(self, mut app: PendingApp) -> crate::Result
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.make_window().open_centered(&mut app)?;
|
||||||
|
app.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Behavior> MakeWindow for Window<Behavior>
|
||||||
|
where
|
||||||
|
Behavior: WindowBehavior,
|
||||||
|
{
|
||||||
|
type Behavior = Behavior;
|
||||||
|
|
||||||
|
fn make_window(self) -> Window<Self::Behavior> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MakeWindow for T
|
||||||
|
where
|
||||||
|
T: MakeWidget,
|
||||||
|
{
|
||||||
|
type Behavior = WidgetInstance;
|
||||||
|
|
||||||
|
fn make_window(self) -> Window<Self::Behavior> {
|
||||||
|
Window::for_widget(self.make_widget())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The behavior of a Cushy window.
|
/// The behavior of a Cushy window.
|
||||||
pub trait WindowBehavior: Sized + 'static {
|
pub trait WindowBehavior: Sized + 'static {
|
||||||
/// The type that is provided when initializing this window.
|
/// The type that is provided when initializing this window.
|
||||||
|
|
@ -2863,7 +2981,7 @@ impl PendingWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [`Window`] containing `root`.
|
/// Returns a [`Window`] containing `root`.
|
||||||
pub fn with_root(self, root: impl MakeWidget) -> Window<WidgetInstance> {
|
pub fn with_root(self, root: impl MakeWidget) -> Window {
|
||||||
Window::new_with_pending(root.make_widget(), self)
|
Window::new_with_pending(root.make_widget(), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue