A sketch dialog and the Sketch Palette on screen at the same time (#791)

A command dialog opened while sketching no longer hides the Sketch Palette: the dialog docks at the left of the viewport and the palette keeps the right. A view too narrow for both keeps the dialog alone.
This commit is contained in:
William Dunn authored and GitHub committed 2026-10-13 13:41:46 -04:00
1 parent 16766bdbc7
commit de1479029d
6 files changed
+168 -26

No files matched your search

+46 -1
View File
@@ -3,6 +3,8 @@
//! other file creates an `egui::Window`, and that every dialog stays within the limits).
//!
//! - [`docked`]: command dialogs and command panels, flush to the right edge of the viewport.
//! - [`docked_on`]: the same, against either edge ([`Side`]), with [`dock_frame`] for its
//! chrome. A dialog opened while the Sketch Palette holds the right edge takes the left.
//! - [`window`]: floating windows (Preferences, Parameters, prompts…), centred by default.
//! - [`right_aligned`]: right-align a row's last items without widening the window (a
//! right-to-left layout would stretch it to its maximum width).
@@ -28,17 +30,60 @@ pub enum Width {
Wide,
}
/// Which edge of the viewport a docked panel sits against. The Sketch Palette holds the right
/// edge while a sketch is open, so a dialog started there takes the left.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Side {
Right,
Left,
}
impl Side {
/// The x of the viewport edge this side docks against.
pub fn anchor_x(self, viewport: egui::Rect) -> f32 {
match self {
Side::Right => viewport.right(),
Side::Left => viewport.left(),
}
}
}
/// The window frame of a docked panel: the two corners away from its edge are rounded, and the
/// shadow falls the same way, so a left dock mirrors a right one.
pub fn dock_frame(ctx: &egui::Context, side: Side) -> egui::Frame {
let t = crate::theme::Tokens::get();
let (corner_radius, shadow_x) = match side {
Side::Right => (egui::CornerRadius { nw: 4, sw: 4, ne: 0, se: 0 }, -2),
Side::Left => (egui::CornerRadius { nw: 0, sw: 0, ne: 4, se: 4 }, 2),
};
egui::Frame::window(&ctx.global_style())
.fill(t.dialog_bg)
.stroke(egui::Stroke::new(1.0, t.dialog_border))
.corner_radius(corner_radius)
.shadow(egui::Shadow { offset: [shadow_x, 2], blur: 8, spread: 0, color: egui::Color32::from_black_alpha(40) })
}
/// A command dialog docked at `anchor` (its top right corner), shrink-wrapped to its content.
pub fn docked<'a>(title: impl Into<WidgetText>, id: egui::Id, anchor: Pos2, max_height: f32, width: Width) -> egui::Window<'a> {
docked_on(title, id, anchor, max_height, width, Side::Right)
}
/// A command dialog docked against `side` at `anchor` (its top corner on that side),
/// shrink-wrapped to its content.
pub fn docked_on<'a>(title: impl Into<WidgetText>, id: egui::Id, anchor: Pos2, max_height: f32, width: Width, side: Side) -> egui::Window<'a> {
let max = match width {
Width::Normal => DIALOG_MAX_W,
Width::Wide => DIALOG_WIDE_MAX_W,
};
let pivot = match side {
Side::Right => Align2::RIGHT_TOP,
Side::Left => Align2::LEFT_TOP,
};
egui::Window::new(title)
.enabled(!crate::issue_report::cad_input_blocked())
.id(id)
.title_bar(false)
.pivot(Align2::RIGHT_TOP)
.pivot(pivot)
.fixed_pos(anchor)
.constrain(false)
.auto_sized()