@@ -5,6 +5,7 @@ mod container;
mod empty;
mod event_handler;
mod flex;
+mod hooks;
mod label;
mod line_box;
mod list;
@@ -23,6 +24,7 @@ pub use container::*;
pub use empty::*;
pub use event_handler::*;
pub use flex::*;
+pub use hooks::*;
pub use label::*;
pub use line_box::*;
pub use list::*;
@@ -0,0 +1,79 @@
+use crate::{
+ geometry::{rect::RectF, vector::Vector2F},
+ json::json,
+ DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
+ SizeConstraint,
+};
+
+pub struct Hooks {
+ child: ElementBox,
+ before_layout: Option<Box<dyn FnMut(SizeConstraint, &mut LayoutContext)>>,
+}
+
+impl Hooks {
+ pub fn new(child: ElementBox) -> Self {
+ Self {
+ child,
+ before_layout: None,
+ }
+ }
+
+ pub fn on_before_layout(
+ mut self,
+ f: impl 'static + FnMut(SizeConstraint, &mut LayoutContext),
+ ) -> Self {
+ self.before_layout = Some(Box::new(f));
+ self
+ }
+}
+
+impl Element for Hooks {
+ type LayoutState = ();
+ type PaintState = ();
+
+ fn layout(
+ &mut self,
+ constraint: SizeConstraint,
+ cx: &mut LayoutContext,
+ ) -> (Vector2F, Self::LayoutState) {
+ if let Some(handler) = self.before_layout.as_mut() {
+ handler(constraint, cx);
+ }
+ let size = self.child.layout(constraint, cx);
+ (size, ())
+ }
+
+ fn paint(
+ &mut self,
+ bounds: RectF,
+ visible_bounds: RectF,
+ _: &mut Self::LayoutState,
+ cx: &mut PaintContext,
+ ) {
+ self.child.paint(bounds.origin(), visible_bounds, cx);
+ }
+
+ fn dispatch_event(
+ &mut self,
+ event: &Event,
+ _: RectF,
+ _: &mut Self::LayoutState,
+ _: &mut Self::PaintState,
+ cx: &mut EventContext,
+ ) -> bool {
+ self.child.dispatch_event(event, cx)
+ }
+
+ fn debug(
+ &self,
+ _: RectF,
+ _: &Self::LayoutState,
+ _: &Self::PaintState,
+ cx: &DebugContext,
+ ) -> serde_json::Value {
+ json!({
+ "type": "Hooks",
+ "child": self.child.debug(cx),
+ })
+ }
+}
@@ -112,12 +112,21 @@ impl Sidebar {
if matches!(self.side, Side::Right) {
container.add_child(self.render_resize_handle(settings, cx));
}
+
+ let width = self.width.clone();
container.add_child(
Flexible::new(
1.,
- ConstrainedBox::new(ChildView::new(active_item.id()).boxed())
- .with_max_width(*self.width.borrow())
- .boxed(),
+ Hooks::new(
+ ConstrainedBox::new(ChildView::new(active_item.id()).boxed())
+ .with_max_width(*self.width.borrow())
+ .boxed(),
+ )
+ .on_before_layout(move |constraint, _| {
+ let mut width = width.borrow_mut();
+ *width = width.min(constraint.max.x());
+ })
+ .boxed(),
)
.boxed(),
);