Update area struct to allow force resizing (#7114)
This is a really small PR so I am skipping the issue (based on contributing.md). This change adds an optional field and thus non breaking for the API. I ran into an issue during my development of an alerts manager widget ([see PR](https://github.com/blackberryfloat/egui_widget_ext/pull/2)) where I needed a scrollable overlay that did not block clicking areas of a parent widget when my alerts did not take up the entire parent. To achieve this I detect the sizing pass via the invisible flag and only render the alerts content and then on the next pass I add the scroll bar in around the alert content. Whenever the alert content changed though I would need to create a new Area with a new id to get proper sizing. That is a memory leak so I wanted to reset the size state to trigger a sizing pass. Memory is rightfully protected enough that the path to remove memory was dropped and I just added a hook to set a resize flag. I am sure there are better ways but this is what made sense to me. Looking forward to thoughts. ~~Logistics wise, I have proposed it as a patch because I was based off 0.31.1 for testing. I was also thinking it could be released quickly. I am happy to cherry pick onto main after. If that is not allowed I can rebase to main and pull against that.~~ (rebased on main) --------- Co-authored-by: Wesley Murray <murraywj97@gmail.com>
This commit is contained in:
parent
6d312cc4c7
commit
db3543d034
|
|
@ -121,6 +121,7 @@ pub struct Area {
|
|||
new_pos: Option<Pos2>,
|
||||
fade_in: bool,
|
||||
layout: Layout,
|
||||
sizing_pass: bool,
|
||||
}
|
||||
|
||||
impl WidgetWithState for Area {
|
||||
|
|
@ -147,6 +148,7 @@ impl Area {
|
|||
anchor: None,
|
||||
fade_in: true,
|
||||
layout: Layout::default(),
|
||||
sizing_pass: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -357,6 +359,27 @@ impl Area {
|
|||
self.layout = layout;
|
||||
self
|
||||
}
|
||||
|
||||
/// While true, a sizing pass will be done. This means the area will be invisible
|
||||
/// and the contents will be laid out to estimate the proper containing size of the area.
|
||||
/// If false, there will be no change to the default area behavior. This is useful if the
|
||||
/// area contents area dynamic and you need to need to make sure the area adjusts its size
|
||||
/// accordingly.
|
||||
///
|
||||
/// This should only be set to true during the specific frames you want force a sizing pass.
|
||||
/// Do NOT hard-code this as `.sizing_pass(true)`, as it will cause the area to never be
|
||||
/// visible.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - resize: If true, the area will be resized to fit its contents. False will keep the
|
||||
/// default area resizing behavior.
|
||||
///
|
||||
/// Default: `false`.
|
||||
#[inline]
|
||||
pub fn sizing_pass(mut self, resize: bool) -> Self {
|
||||
self.sizing_pass = resize;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Prepared {
|
||||
|
|
@ -410,6 +433,7 @@ impl Area {
|
|||
constrain_rect,
|
||||
fade_in,
|
||||
layout,
|
||||
sizing_pass: force_sizing_pass,
|
||||
} = self;
|
||||
|
||||
let constrain_rect = constrain_rect.unwrap_or_else(|| ctx.screen_rect());
|
||||
|
|
@ -425,6 +449,10 @@ impl Area {
|
|||
interactable,
|
||||
last_became_visible_at: None,
|
||||
});
|
||||
if force_sizing_pass {
|
||||
sizing_pass = true;
|
||||
state.size = None;
|
||||
}
|
||||
state.pivot = pivot;
|
||||
state.interactable = interactable;
|
||||
if let Some(new_pos) = new_pos {
|
||||
|
|
|
|||
Loading…
Reference in New Issue