Take a strong widget to depend on, and use the question mark
`depend_on_size` took a bare `WidgetId`, which any id at all satisfies. It takes a `&StrongWidget` now, so `DrawResult` carries the handle it was drawn from rather than an id copied out of it and nothing can claim a dependency on a widget it does not hold. `UiSpan::outside` matched on a pair of `Option`s where `?` says it. It was written that way while the method was still `const`, and it is not. No call site changed. Checked: fmt, clippy and 35 tests; `tabs`, `view`, `minimal` and `text` render unchanged, and the live sway resize round trip still matches a cold start at each size.
This commit is contained in:
1 parent
53e61289f5
commit
46547563c1
2 files changed
+24
-25
No files matched your search
@@ -279,10 +279,10 @@ impl UiSpan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn outside(&self, parent: &Self) -> Option<Self> {
|
pub fn outside(&self, parent: &Self) -> Option<Self> {
|
||||||
match (self.start.outside(parent), self.end.outside(parent)) {
|
Some(Self {
|
||||||
(Some(start), Some(end)) => Some(Self { start, end }),
|
start: self.start.outside(parent)?,
|
||||||
_ => None,
|
end: self.end.outside(parent)?,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn len(&self) -> UiScalar {
|
pub const fn len(&self) -> UiScalar {
|
||||||
|
|||||||
+20
-21
@@ -71,34 +71,33 @@ impl<'a> Painter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draws a widget within this widget's region.
|
/// Draws a widget within this widget's region.
|
||||||
pub fn widget<W: ?Sized>(&mut self, id: &StrongWidget<W>) -> DrawResult<'_, 'a> {
|
pub fn widget<'s, W: ?Sized>(&'s mut self, id: &'s StrongWidget<W>) -> DrawResult<'s, 'a, W> {
|
||||||
self.widget_at(id, self.region)
|
self.widget_at(id, self.region)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draws a widget somewhere within this one. Drawing one a second time
|
/// Draws a widget somewhere within this one. Drawing one a second time
|
||||||
/// gives it a new box, keeping the drawing it already has where it can.
|
/// gives it a new box, keeping the drawing it already has where it can.
|
||||||
pub fn widget_within<W: ?Sized>(
|
pub fn widget_within<'s, W: ?Sized>(
|
||||||
&mut self,
|
&'s mut self,
|
||||||
id: &StrongWidget<W>,
|
id: &'s StrongWidget<W>,
|
||||||
region: UiRegion,
|
region: UiRegion,
|
||||||
) -> DrawResult<'_, 'a> {
|
) -> DrawResult<'s, 'a, W> {
|
||||||
let region = region.within(&self.region);
|
let region = region.within(&self.region);
|
||||||
self.widget_at(id, region)
|
self.widget_at(id, region)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn widget_at<W: ?Sized>(
|
fn widget_at<'s, W: ?Sized>(
|
||||||
&mut self,
|
&'s mut self,
|
||||||
id: &StrongWidget<W>,
|
id: &'s StrongWidget<W>,
|
||||||
region: UiRegion,
|
region: UiRegion,
|
||||||
) -> DrawResult<'_, 'a> {
|
) -> DrawResult<'s, 'a, W> {
|
||||||
let child = id.id();
|
|
||||||
// A child listed twice would be moved twice.
|
// A child listed twice would be moved twice.
|
||||||
if !self.children.contains(&child) {
|
if !self.children.contains(&id.id()) {
|
||||||
self.children.push(child);
|
self.children.push(id.id());
|
||||||
}
|
}
|
||||||
let size = self.state.draw_inner(
|
let size = self.state.draw_inner(
|
||||||
self.layer,
|
self.layer,
|
||||||
child,
|
id.id(),
|
||||||
region,
|
region,
|
||||||
Some(self.id),
|
Some(self.id),
|
||||||
self.mask,
|
self.mask,
|
||||||
@@ -106,7 +105,7 @@ impl<'a> Painter<'a> {
|
|||||||
self.rsc,
|
self.rsc,
|
||||||
);
|
);
|
||||||
DrawResult {
|
DrawResult {
|
||||||
child,
|
child: id,
|
||||||
painter: self,
|
painter: self,
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
@@ -116,13 +115,13 @@ impl<'a> Painter<'a> {
|
|||||||
/// Asking counts as reading its size.
|
/// Asking counts as reading its size.
|
||||||
pub fn size_hint<W: ?Sized>(&mut self, id: &StrongWidget<W>, axis: Axis) -> Option<Len> {
|
pub fn size_hint<W: ?Sized>(&mut self, id: &StrongWidget<W>, axis: Axis) -> Option<Len> {
|
||||||
let hint = self.rsc.widgets().get_dyn(id.id())?.size_hint(axis)?;
|
let hint = self.rsc.widgets().get_dyn(id.id())?.size_hint(axis)?;
|
||||||
self.depend_on_size(id.id());
|
self.depend_on_size(id);
|
||||||
Some(hint)
|
Some(hint)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn depend_on_size(&mut self, child: WidgetId) {
|
fn depend_on_size<W: ?Sized>(&mut self, child: &StrongWidget<W>) {
|
||||||
if !self.size_deps.contains(&child) {
|
if !self.size_deps.contains(&child.id()) {
|
||||||
self.size_deps.push(child);
|
self.size_deps.push(child.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,13 +201,13 @@ impl<'a> Painter<'a> {
|
|||||||
/// A child that has just been drawn. Reading its size records that this
|
/// A child that has just been drawn. Reading its size records that this
|
||||||
/// widget's own size depends on it; dropping it without reading draws the
|
/// widget's own size depends on it; dropping it without reading draws the
|
||||||
/// child and leaves the parent independent of what it came to.
|
/// child and leaves the parent independent of what it came to.
|
||||||
pub struct DrawResult<'p, 'a> {
|
pub struct DrawResult<'p, 'a, W: ?Sized> {
|
||||||
painter: &'p mut Painter<'a>,
|
painter: &'p mut Painter<'a>,
|
||||||
child: WidgetId,
|
child: &'p StrongWidget<W>,
|
||||||
size: Size,
|
size: Size,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawResult<'_, '_> {
|
impl<W: ?Sized> DrawResult<'_, '_, W> {
|
||||||
pub fn size(self) -> Size {
|
pub fn size(self) -> Size {
|
||||||
self.painter.depend_on_size(self.child);
|
self.painter.depend_on_size(self.child);
|
||||||
self.size
|
self.size
|
||||||
|
|||||||
Reference in new issue
Block a user