diff --git a/CHANGELOG.md b/CHANGELOG.md index ebdee56..697ad49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -215,6 +215,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Delimiter` is a new widget that is similar to html's `hr` tag. - `List` is a new widget that creates lists similar to HTML's `ol` and `ul` tags. +- `Dynamic::try_lock()` is a panic-free version of `Dynamic::lock()`. [plotters]: https://github.com/plotters-rs/plotters diff --git a/src/context.rs b/src/context.rs index ccc8747..7281075 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1363,7 +1363,7 @@ pub(crate) mod sealed { fn inner_invalidate_when_changed(&self, handle: WindowHandle, id: WidgetId); } - #[derive(Default, Clone)] + #[derive(Debug, Default, Clone)] pub struct InvalidationStatus { refresh_sent: Arc, invalidated: Arc>>, diff --git a/src/value.rs b/src/value.rs index c037ae1..29313d7 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1089,6 +1089,23 @@ impl Dynamic { self.lock_inner() } + /// Returns an exclusive reference to the contents of this dynamic. + /// + /// This call will block until all other guards for this dynamic have been + /// dropped. + /// + /// # Errors + /// + /// Returns an error if the current thread already holds a lock to this + /// dynamic. + pub fn try_lock(&self) -> Result, DeadlockError> { + Ok(DynamicGuard { + guard: self.0.state()?, + accessed_mut: false, + prevent_notifications: false, + }) + } + fn lock_inner(&self) -> DynamicGuard<'_, T, READONLY> { DynamicGuard { guard: self.0.state().expect("deadlocked"), diff --git a/src/widget.rs b/src/widget.rs index 971a8b8..f771c08 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -2129,6 +2129,18 @@ impl Dynamic { self.clone().into_layers() } + /// Returns `self` as an unordered [`List`]. + #[must_use] + pub fn into_list(self) -> List { + List::new(self) + } + + /// Returns `self` as an unordered [`List`]. + #[must_use] + pub fn to_list(self) -> List { + self.clone().into_list() + } + /// Returns a [`Wrap`] that lays the children out horizontally, wrapping /// into additional rows as needed. #[must_use] diff --git a/src/widgets/expand.rs b/src/widgets/expand.rs index 819235d..76ba945 100644 --- a/src/widgets/expand.rs +++ b/src/widgets/expand.rs @@ -9,7 +9,7 @@ use crate::ConstraintLimit; /// /// Some parent widgets support weighting children when there is more than one /// [`Expand`]ed widget. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Expand { kind: ExpandKind, child: WidgetRef, diff --git a/src/widgets/list.rs b/src/widgets/list.rs index 64e5673..4e3ba51 100644 --- a/src/widgets/list.rs +++ b/src/widgets/list.rs @@ -476,7 +476,8 @@ fn build_grid_widgets(style: &ListStyle, children: &WidgetList) -> GridWidgets<2 .list_indicator(index.wrapping_add(1)) .unwrap_or_default(), ) - .align_right(), + .align_right() + .align_top(), child.clone().align_left().make_widget(), ) }) diff --git a/src/window.rs b/src/window.rs index a9029a4..d6c8a01 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1964,7 +1964,7 @@ pub(crate) mod sealed { pub on_closed: Option, } - #[derive(Clone)] + #[derive(Debug, Clone)] pub enum WindowCommand { Redraw, RequestClose, @@ -2079,7 +2079,7 @@ fn default_family(query: Family<'_>) -> Option { } /// A handle to an open Cushy window. -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct WindowHandle { inner: InnerWindowHandle, pub(crate) redraw_status: InvalidationStatus, @@ -2140,7 +2140,7 @@ impl Hash for WindowHandle { } } -#[derive(Clone)] +#[derive(Debug, Clone)] enum InnerWindowHandle { Pending(Arc), Known(kludgine::app::WindowHandle), @@ -2233,7 +2233,7 @@ impl PendingWindow { } } -#[derive(Default)] +#[derive(Debug, Default)] struct PendingWindowHandle { handle: OnceLock>, commands: Mutex>,