TransientPlacement
Popup sides, alignment, flip-shift-constrain policy, and dismissal.
Placement
use incular::prelude::*;
use incular::widgets::{
TransientAlignment, TransientPlacement, TransientPlacementInput, TransientSide,
place_transient,
};
fn main() {
let placement = TransientPlacement::new()
.side(TransientSide::Bottom)
.alignment(TransientAlignment::Center)
.side_offset(4.0)
.safe_margin(EdgeInsets::all(8.0));
let input = TransientPlacementInput {
anchor_rect: Rect::from_origin_size(
Offset::new(100.0, 100.0),
Size::new(80.0, 32.0),
),
desired_size: Size::new(160.0, 96.0),
available_rect: Rect::from_origin_size(
Offset::ZERO,
Size::new(800.0, 600.0),
),
role: TransientRole::Popover,
text_direction: TextDirection::Ltr,
placement,
};
let result = place_transient(input);
println!("side: {:?}, flipped: {}", result.side, result.flipped);
}TransientSide: Top / Right / Bottom (default) / Left with
opposite(). TransientAlignment: Start / Center (enum default) / End
— but TransientPlacement::default() uses Start.
TransientPlacementMode: Anchored (default) / Submenu (LTR defaults
Right, RTL defaults Left).
Policy order: flip → shift → constrain. Flip only when the opposite side has strictly less primary overflow; shift moves cross-axis into the safe area; constrain clamps while preserving the anchor edge.
place_transient takes a TransientPlacementInput (anchor, desired size,
available rect, role, direction, placement) and returns a
TransientPlacementResult with rect, side, alignment, and flipped/shifted/
constrained flags.
Dismissal
use incular::prelude::*;
use incular::widgets::{TransientDismissPolicy, TransientDismissReason};
fn main() {
let policy = TransientDismissPolicy::tooltip();
println!(
"escape: {}",
policy.allows(TransientDismissReason::Escape)
);
println!("for role popover: {:?}", TransientDismissPolicy::for_role(TransientRole::Popover));
}Reasons: OutsidePointer / Escape / FocusLost / ParentDeactivated /
ExplicitSelection.
Related: OverlayPortal.