mirror of
https://github.com/danbulant/cushy
synced 2026-07-07 12:10:44 +00:00
Added Widget::summarize
Debug printing widgets was quite verbose. While developing a widget, you often want to see a full debug printout, but this feature assumes that debug printing a WidgetInstance should show a summary of the widget, not a full debug printout containing cached glyph information of every label. By default, summarize just calls Debug, but this extra layer allows widgets to provide a more condensed summary and exclude details like caches. Originally, adding dbg!() around the theme example's UI yielded a whopping 20,324 lines of text. The summary code only prints 3,858 lines.
This commit is contained in:
parent
d1e21178e0
commit
0e6796318b
15 changed files with 222 additions and 28 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use interner::global::{GlobalString, StringPool};
|
use interner::global::{GlobalString, StringPool};
|
||||||
|
|
@ -12,7 +13,7 @@ static NAMES: StringPool<ahash::RandomState> =
|
||||||
/// string exists. By ensuring all instances of each unique string are the same
|
/// string exists. By ensuring all instances of each unique string are the same
|
||||||
/// exact underlying instance, optimizations can be made that avoid string
|
/// exact underlying instance, optimizations can be made that avoid string
|
||||||
/// comparisons.
|
/// comparisons.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Name(GlobalString<ahash::RandomState>);
|
pub struct Name(GlobalString<ahash::RandomState>);
|
||||||
|
|
||||||
impl Name {
|
impl Name {
|
||||||
|
|
@ -22,6 +23,12 @@ impl Name {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for Name {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Debug::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for Name {
|
impl Deref for Name {
|
||||||
type Target = str;
|
type Target = str;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::hash_map;
|
use std::collections::hash_map;
|
||||||
use std::fmt::Debug;
|
use std::fmt::{Debug, Write};
|
||||||
use std::ops::{
|
use std::ops::{
|
||||||
Add, AddAssign, Bound, Deref, Div, Mul, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
|
Add, AddAssign, Bound, Deref, Div, Mul, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
|
||||||
RangeToInclusive,
|
RangeToInclusive,
|
||||||
|
|
@ -29,7 +29,7 @@ use crate::value::{Dynamic, IntoValue, Value};
|
||||||
pub mod components;
|
pub mod components;
|
||||||
|
|
||||||
/// A collection of style components organized by their name.
|
/// A collection of style components organized by their name.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Styles(Arc<StyleData>);
|
pub struct Styles(Arc<StyleData>);
|
||||||
|
|
||||||
impl Styles {
|
impl Styles {
|
||||||
|
|
@ -172,7 +172,21 @@ impl Styles {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
impl Debug for Styles {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mut map = f.debug_struct("Styles");
|
||||||
|
let mut component_name = String::new();
|
||||||
|
for (name, component) in &self.0.components {
|
||||||
|
component_name.clear();
|
||||||
|
write!(&mut component_name, "{name:?}")?;
|
||||||
|
|
||||||
|
map.field(&component_name, component);
|
||||||
|
}
|
||||||
|
map.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
struct StyleData {
|
struct StyleData {
|
||||||
components: AHashMap<ComponentName, Value<Component>>,
|
components: AHashMap<ComponentName, Value<Component>>,
|
||||||
}
|
}
|
||||||
|
|
@ -519,7 +533,7 @@ impl TryFrom<Component> for CornerRadii<Dimension> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A 1-dimensional measurement that may be automatically calculated.
|
/// A 1-dimensional measurement that may be automatically calculated.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum FlexibleDimension {
|
pub enum FlexibleDimension {
|
||||||
/// Automatically calculate this dimension.
|
/// Automatically calculate this dimension.
|
||||||
Auto,
|
Auto,
|
||||||
|
|
@ -532,6 +546,15 @@ impl FlexibleDimension {
|
||||||
pub const ZERO: Self = Self::Dimension(Dimension::ZERO);
|
pub const ZERO: Self = Self::Dimension(Dimension::ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for FlexibleDimension {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Auto => f.write_str("Auto"),
|
||||||
|
Self::Dimension(arg0) => Debug::fmt(arg0, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for FlexibleDimension {
|
impl Default for FlexibleDimension {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::ZERO
|
Self::ZERO
|
||||||
|
|
@ -557,7 +580,7 @@ impl From<Lp> for FlexibleDimension {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A 1-dimensional measurement.
|
/// A 1-dimensional measurement.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
pub enum Dimension {
|
pub enum Dimension {
|
||||||
/// Physical Pixels
|
/// Physical Pixels
|
||||||
Px(Px),
|
Px(Px),
|
||||||
|
|
@ -565,6 +588,15 @@ pub enum Dimension {
|
||||||
Lp(Lp),
|
Lp(Lp),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for Dimension {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Px(arg0) => Debug::fmt(arg0, f),
|
||||||
|
Self::Lp(arg0) => Debug::fmt(arg0, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Dimension {
|
impl Default for Dimension {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::ZERO
|
Self::ZERO
|
||||||
|
|
@ -907,7 +939,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A fully-qualified style component name.
|
/// A fully-qualified style component name.
|
||||||
#[derive(Clone, Eq, PartialEq, Debug, Hash)]
|
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct ComponentName {
|
pub struct ComponentName {
|
||||||
/// The group name.
|
/// The group name.
|
||||||
pub group: Name,
|
pub group: Name,
|
||||||
|
|
@ -925,6 +957,12 @@ impl ComponentName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for ComponentName {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{:?}.{:?}", &self.group, &self.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&'static Lazy<ComponentName>> for ComponentName {
|
impl From<&'static Lazy<ComponentName>> for ComponentName {
|
||||||
fn from(value: &'static Lazy<ComponentName>) -> Self {
|
fn from(value: &'static Lazy<ComponentName>) -> Self {
|
||||||
(**value).clone()
|
(**value).clone()
|
||||||
|
|
|
||||||
70
src/value.rs
70
src/value.rs
|
|
@ -624,14 +624,7 @@ where
|
||||||
T: Debug,
|
T: Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self.0.state() {
|
Debug::fmt(&DebugDynamicData(&self.0), f)
|
||||||
Ok(state) => f
|
|
||||||
.debug_struct("Dynamic")
|
|
||||||
.field("value", &state.wrapped.value)
|
|
||||||
.field("generation", &state.wrapped.generation)
|
|
||||||
.finish(),
|
|
||||||
Err(_) => f.debug_tuple("Dynamic").field(&"<unable to lock>").finish(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -722,12 +715,20 @@ impl From<String> for Dynamic<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct DynamicMutexGuard<'a, T> {
|
struct DynamicMutexGuard<'a, T> {
|
||||||
dynamic: &'a DynamicData<T>,
|
dynamic: &'a DynamicData<T>,
|
||||||
guard: MutexGuard<'a, State<T>>,
|
guard: MutexGuard<'a, State<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Debug for DynamicMutexGuard<'_, T>
|
||||||
|
where
|
||||||
|
T: Debug,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.guard.debug("DynamicMutexGuard", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for DynamicMutexGuard<'a, T> {
|
impl<'a, T> Drop for DynamicMutexGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut during_state = self.dynamic.during_callback_state.lock().ignore_poison();
|
let mut during_state = self.dynamic.during_callback_state.lock().ignore_poison();
|
||||||
|
|
@ -755,7 +756,6 @@ struct LockState {
|
||||||
locked_thread: ThreadId,
|
locked_thread: ThreadId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct DynamicData<T> {
|
struct DynamicData<T> {
|
||||||
state: Mutex<State<T>>,
|
state: Mutex<State<T>>,
|
||||||
during_callback_state: Mutex<Option<LockState>>,
|
during_callback_state: Mutex<Option<LockState>>,
|
||||||
|
|
@ -859,6 +859,20 @@ impl<T> DynamicData<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DebugDynamicData<'a, T>(&'a Arc<DynamicData<T>>);
|
||||||
|
|
||||||
|
impl<T> Debug for DebugDynamicData<'_, T>
|
||||||
|
where
|
||||||
|
T: Debug,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self.0.state() {
|
||||||
|
Ok(state) => state.debug("Dynamic", f),
|
||||||
|
Err(_) => f.debug_tuple("Dynamic").field(&"<unable to lock>").finish(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An error occurred while updating a value in a [`Dynamic`].
|
/// An error occurred while updating a value in a [`Dynamic`].
|
||||||
pub enum ReplaceError<T> {
|
pub enum ReplaceError<T> {
|
||||||
/// The value was already equal to the one set.
|
/// The value was already equal to the one set.
|
||||||
|
|
@ -953,6 +967,16 @@ impl<T> State<T> {
|
||||||
|
|
||||||
ChangeCallbacks(self.callbacks.clone())
|
ChangeCallbacks(self.callbacks.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn debug(&self, name: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
|
where
|
||||||
|
T: Debug,
|
||||||
|
{
|
||||||
|
f.debug_struct(name)
|
||||||
|
.field("value", &self.wrapped.value)
|
||||||
|
.field("generation", &self.wrapped.generation.0)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Debug for State<T>
|
impl<T> Debug for State<T>
|
||||||
|
|
@ -1167,7 +1191,6 @@ impl<T> PartialEq<WeakDynamic<T>> for Dynamic<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A reader that tracks the last generation accessed through this reader.
|
/// A reader that tracks the last generation accessed through this reader.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct DynamicReader<T> {
|
pub struct DynamicReader<T> {
|
||||||
source: Arc<DynamicData<T>>,
|
source: Arc<DynamicData<T>>,
|
||||||
read_generation: Generation,
|
read_generation: Generation,
|
||||||
|
|
@ -1308,6 +1331,18 @@ impl<T> context::sealed::Trackable for DynamicReader<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Debug for DynamicReader<T>
|
||||||
|
where
|
||||||
|
T: Debug,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("DynamicReader")
|
||||||
|
.field("source", &DebugDynamicData(&self.source))
|
||||||
|
.field("read_generation", &self.read_generation.0)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Clone for DynamicReader<T> {
|
impl<T> Clone for DynamicReader<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
self.source.state().expect("deadlocked").readers += 1;
|
self.source.state().expect("deadlocked").readers += 1;
|
||||||
|
|
@ -1514,7 +1549,6 @@ impl GetWidget<usize> for Vec<WidgetInstance> {
|
||||||
impl<T, W> Switchable<T> for W where W: IntoDynamic<T> {}
|
impl<T, W> Switchable<T> for W where W: IntoDynamic<T> {}
|
||||||
|
|
||||||
/// A value that may be either constant or dynamic.
|
/// A value that may be either constant or dynamic.
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Value<T> {
|
pub enum Value<T> {
|
||||||
/// A value that will not ever change externally.
|
/// A value that will not ever change externally.
|
||||||
Constant(T),
|
Constant(T),
|
||||||
|
|
@ -1651,6 +1685,18 @@ impl<T> IntoDynamic<T> for Value<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Debug for Value<T>
|
||||||
|
where
|
||||||
|
T: Debug,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Constant(arg0) => Debug::fmt(arg0, f),
|
||||||
|
Self::Dynamic(arg0) => Debug::fmt(arg0, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Clone for Value<T>
|
impl<T> Clone for Value<T>
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::fmt::Debug;
|
use std::fmt::{self, Debug};
|
||||||
use std::ops::{ControlFlow, Deref, DerefMut};
|
use std::ops::{ControlFlow, Deref, DerefMut};
|
||||||
use std::panic::UnwindSafe;
|
use std::panic::UnwindSafe;
|
||||||
use std::sync::atomic::{self, AtomicU64};
|
use std::sync::atomic::{self, AtomicU64};
|
||||||
|
|
@ -51,6 +51,15 @@ pub trait Widget: Send + UnwindSafe + 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`.
|
||||||
|
///
|
||||||
|
/// The default implementation calls [`Debug::fmt`]. This function allows
|
||||||
|
/// widget authors to print only publicly relevant information that will
|
||||||
|
/// appear when debug formatting a [`WidgetInstance`].
|
||||||
|
fn summarize(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
Debug::fmt(self, f)
|
||||||
|
}
|
||||||
|
|
||||||
/// Layout this widget and returns the ideal size based on its contents and
|
/// Layout this widget and returns the ideal size based on its contents and
|
||||||
/// the `available_space`.
|
/// the `available_space`.
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
|
|
@ -284,6 +293,15 @@ pub trait WrapperWidget: Debug + Send + UnwindSafe + 'static {
|
||||||
/// Returns the child widget.
|
/// Returns the child widget.
|
||||||
fn child_mut(&mut self) -> &mut WidgetRef;
|
fn child_mut(&mut self) -> &mut WidgetRef;
|
||||||
|
|
||||||
|
/// Writes a summary of this widget into `fmt`.
|
||||||
|
///
|
||||||
|
/// The default implementation calls [`Debug::fmt`]. This function allows
|
||||||
|
/// widget authors to print only publicly relevant information that will
|
||||||
|
/// appear when debug formatting a [`WidgetInstance`].
|
||||||
|
fn summarize(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
Debug::fmt(self, f)
|
||||||
|
}
|
||||||
|
|
||||||
/// 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)]
|
||||||
|
|
@ -650,6 +668,10 @@ where
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
T::summarize(self, fmt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type that can create a [`WidgetInstance`].
|
/// A type that can create a [`WidgetInstance`].
|
||||||
|
|
@ -1119,11 +1141,20 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An instance of a [`Widget`].
|
/// An instance of a [`Widget`].
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub struct WidgetInstance {
|
pub struct WidgetInstance {
|
||||||
data: Arc<WidgetInstanceData>,
|
data: Arc<WidgetInstanceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for WidgetInstance {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self.data.widget.try_lock() {
|
||||||
|
Ok(widget) => widget.summarize(f),
|
||||||
|
Err(_) => f.debug_struct("WidgetInstance").finish_non_exhaustive(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct WidgetInstanceData {
|
struct WidgetInstanceData {
|
||||||
id: WidgetId,
|
id: WidgetId,
|
||||||
|
|
@ -1372,9 +1403,7 @@ pub struct ManagedWidget {
|
||||||
|
|
||||||
impl Debug for ManagedWidget {
|
impl Debug for ManagedWidget {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("ManagedWidget")
|
Debug::fmt(&self.widget, f)
|
||||||
.field("widget", &self.widget)
|
|
||||||
.finish_non_exhaustive()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1567,7 +1596,7 @@ impl WidgetGuard<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A list of [`Widget`]s.
|
/// A list of [`Widget`]s.
|
||||||
#[derive(Debug, Default, Eq, PartialEq)]
|
#[derive(Default, Eq, PartialEq)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct Children {
|
pub struct Children {
|
||||||
ordered: Vec<WidgetInstance>,
|
ordered: Vec<WidgetInstance>,
|
||||||
|
|
@ -1647,6 +1676,12 @@ impl Children {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for Children {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
Debug::fmt(&self.ordered, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Dynamic<Children> {
|
impl Dynamic<Children> {
|
||||||
/// Returns `self` as a vertical [`Stack`] of rows.
|
/// Returns `self` as a vertical [`Stack`] of rows.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -1687,7 +1722,7 @@ impl DerefMut for Children {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A child widget
|
/// A child widget
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone)]
|
||||||
pub enum WidgetRef {
|
pub enum WidgetRef {
|
||||||
/// An unmounted child widget
|
/// An unmounted child widget
|
||||||
Unmounted(WidgetInstance),
|
Unmounted(WidgetInstance),
|
||||||
|
|
@ -1732,6 +1767,15 @@ impl AsRef<WidgetId> for WidgetRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for WidgetRef {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Unmounted(arg0) => Debug::fmt(arg0, f),
|
||||||
|
Self::Mounted(arg0) => Debug::fmt(arg0, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The unique id of a [`WidgetInstance`].
|
/// The unique id of a [`WidgetInstance`].
|
||||||
///
|
///
|
||||||
/// Each [`WidgetInstance`] is guaranteed to have a unique [`WidgetId`] across
|
/// Each [`WidgetInstance`] is guaranteed to have a unique [`WidgetId`] across
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,13 @@ impl VisualState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for Button {
|
impl Widget for Button {
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_struct("Button")
|
||||||
|
.field("content", &self.content)
|
||||||
|
.field("kind", &self.kind)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
|
||||||
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
|
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
|
||||||
#![allow(clippy::similar_names)]
|
#![allow(clippy::similar_names)]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,13 @@ impl WrapperWidget for Collapse {
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_struct("Collapse")
|
||||||
|
.field("collapse", &self.collapse)
|
||||||
|
.field("child", &self.child)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,14 @@ impl WrapperWidget for Container {
|
||||||
size: padded.into_unsigned(),
|
size: padded.into_unsigned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_struct("Container")
|
||||||
|
.field("background", &self.background)
|
||||||
|
.field("padding", &self.padding)
|
||||||
|
.field("child", &self.child)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The selected background configuration of a [`Container`].
|
/// The selected background configuration of a [`Container`].
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ use crate::widgets::Space;
|
||||||
/// `Slider` in a `Data` widget to store the animation handle.
|
/// `Slider` in a `Data` widget to store the animation handle.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Data<T> {
|
pub struct Data<T> {
|
||||||
_data: T,
|
#[allow(dead_code)] // This affects formatting in Debug to rename it.
|
||||||
|
data: T,
|
||||||
child: WidgetRef,
|
child: WidgetRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ impl<T> Data<T> {
|
||||||
/// Returns a new instance that wraps `widget` and stores `value`.
|
/// Returns a new instance that wraps `widget` and stores `value`.
|
||||||
pub fn new_wrapping(value: T, widget: impl MakeWidget) -> Self {
|
pub fn new_wrapping(value: T, widget: impl MakeWidget) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_data: value,
|
data: value,
|
||||||
child: WidgetRef::new(widget),
|
child: WidgetRef::new(widget),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,13 @@ impl<const COLUMNS: usize> Widget for Grid<COLUMNS> {
|
||||||
|
|
||||||
content_size
|
content_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_struct("Grid")
|
||||||
|
.field("dimensions", &self.columns)
|
||||||
|
.field("entries", &self.rows)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The orientation (Row/Column) of an [`Grid`] or
|
/// The orientation (Row/Column) of an [`Grid`] or
|
||||||
|
|
|
||||||
|
|
@ -935,6 +935,8 @@ where
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Input")
|
f.debug_struct("Input")
|
||||||
.field("text", &self.value)
|
.field("text", &self.value)
|
||||||
|
.field("mask_symbol", &self.mask_symbol)
|
||||||
|
.field("placeholder", &self.placeholder)
|
||||||
.finish_non_exhaustive()
|
.finish_non_exhaustive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,10 @@ impl Widget for Label {
|
||||||
|
|
||||||
prepared.size.try_cast().unwrap_or_default()
|
prepared.size.try_cast().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_tuple("Label").field(&self.text).finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_make_widget {
|
macro_rules! impl_make_widget {
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,13 @@ impl Widget for Scroll {
|
||||||
HANDLED
|
HANDLED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_struct("Scroll")
|
||||||
|
.field("enabled", &self.enabled)
|
||||||
|
.field("contents", &self.contents)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constrain_child(constraint: ConstraintLimit, measured: Px) -> UPx {
|
fn constrain_child(constraint: ConstraintLimit, measured: Px) -> UPx {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use crate::widget::{MakeWidget, MakeWidgetWithId, WidgetInstance};
|
||||||
use crate::widgets::button::{ButtonBackground, ButtonHoverBackground, ButtonKind};
|
use crate::widgets::button::{ButtonBackground, ButtonHoverBackground, ButtonKind};
|
||||||
|
|
||||||
/// A selectable, labeled widget representing a value.
|
/// A selectable, labeled widget representing a value.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Select<T> {
|
pub struct Select<T> {
|
||||||
/// The value this button represents.
|
/// The value this button represents.
|
||||||
pub value: T,
|
pub value: T,
|
||||||
|
|
|
||||||
|
|
@ -728,6 +728,14 @@ where
|
||||||
// using a mouse wheel as an input is annoying.
|
// using a mouse wheel as an input is annoying.
|
||||||
HANDLED
|
HANDLED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_struct("Slider")
|
||||||
|
.field("value", &self.value)
|
||||||
|
.field("min", &self.minimum)
|
||||||
|
.field("max", &self.maximum)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TrackSpec {
|
struct TrackSpec {
|
||||||
|
|
|
||||||
|
|
@ -169,4 +169,11 @@ impl Widget for Stack {
|
||||||
|
|
||||||
content_size
|
content_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
fmt.debug_struct("Stack")
|
||||||
|
.field("orientation", &self.layout.orientation)
|
||||||
|
.field("children", &self.children)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue