Skip to content

Commit c37125f

Browse files
authored
Tweak window resize handles (emilk#5524)
This makes it easier to hit the corners. Previously the corner response-area was covered by the response-areas of the edges. * Related to emilk#5523
1 parent 4d945f7 commit c37125f

File tree

1 file changed

+85
-37
lines changed

1 file changed

+85
-37
lines changed

crates/egui/src/containers/window.rs

+85-37
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ impl<'open> Window<'open> {
583583
outer_rect,
584584
frame_stroke,
585585
window_frame.rounding,
586+
resize_interaction,
586587
);
587588

588589
// END FRAME --------------------------------
@@ -651,29 +652,30 @@ fn paint_resize_corner(
651652
outer_rect: Rect,
652653
stroke: impl Into<Stroke>,
653654
rounding: impl Into<Rounding>,
655+
i: ResizeInteraction,
654656
) {
655-
let stroke = stroke.into();
657+
let inactive_stroke = stroke.into();
656658
let rounding = rounding.into();
657-
let (corner, radius) = if possible.resize_right && possible.resize_bottom {
658-
(Align2::RIGHT_BOTTOM, rounding.se)
659+
let (corner, radius, corner_response) = if possible.resize_right && possible.resize_bottom {
660+
(Align2::RIGHT_BOTTOM, rounding.se, i.right & i.bottom)
659661
} else if possible.resize_left && possible.resize_bottom {
660-
(Align2::LEFT_BOTTOM, rounding.sw)
662+
(Align2::LEFT_BOTTOM, rounding.sw, i.left & i.bottom)
661663
} else if possible.resize_left && possible.resize_top {
662-
(Align2::LEFT_TOP, rounding.nw)
664+
(Align2::LEFT_TOP, rounding.nw, i.left & i.top)
663665
} else if possible.resize_right && possible.resize_top {
664-
(Align2::RIGHT_TOP, rounding.ne)
666+
(Align2::RIGHT_TOP, rounding.ne, i.right & i.top)
665667
} else {
666668
// We're not in two directions, but it is still nice to tell the user
667669
// we're resizable by painting the resize corner in the expected place
668670
// (i.e. for windows only resizable in one direction):
669671
if possible.resize_right || possible.resize_bottom {
670-
(Align2::RIGHT_BOTTOM, rounding.se)
672+
(Align2::RIGHT_BOTTOM, rounding.se, i.right & i.bottom)
671673
} else if possible.resize_left || possible.resize_bottom {
672-
(Align2::LEFT_BOTTOM, rounding.sw)
674+
(Align2::LEFT_BOTTOM, rounding.sw, i.left & i.bottom)
673675
} else if possible.resize_left || possible.resize_top {
674-
(Align2::LEFT_TOP, rounding.nw)
676+
(Align2::LEFT_TOP, rounding.nw, i.left & i.top)
675677
} else if possible.resize_right || possible.resize_top {
676-
(Align2::RIGHT_TOP, rounding.ne)
678+
(Align2::RIGHT_TOP, rounding.ne, i.right & i.top)
677679
} else {
678680
return;
679681
}
@@ -683,6 +685,14 @@ fn paint_resize_corner(
683685
let offset =
684686
((2.0_f32.sqrt() * (1.0 + radius) - radius) * 45.0_f32.to_radians().cos()).max(2.0);
685687

688+
let stroke = if corner_response.drag {
689+
ui.visuals().widgets.active.fg_stroke
690+
} else if corner_response.hover {
691+
ui.visuals().widgets.hovered.fg_stroke
692+
} else {
693+
inactive_stroke
694+
};
695+
686696
let corner_size = Vec2::splat(ui.visuals().resize_corner_size);
687697
let corner_rect = corner.align_size_within_rect(corner_size, outer_rect);
688698
let corner_rect = corner_rect.translate(-offset * corner.to_sign()); // move away from corner
@@ -744,6 +754,17 @@ impl SideResponse {
744754
}
745755
}
746756

757+
impl std::ops::BitAnd for SideResponse {
758+
type Output = Self;
759+
760+
fn bitand(self, rhs: Self) -> Self::Output {
761+
Self {
762+
hover: self.hover && rhs.hover,
763+
drag: self.drag && rhs.drag,
764+
}
765+
}
766+
}
767+
747768
impl std::ops::BitOrAssign for SideResponse {
748769
fn bitor_assign(&mut self, rhs: Self) {
749770
*self = Self {
@@ -849,7 +870,7 @@ fn resize_interaction(
849870
};
850871
}
851872

852-
let is_dragging = |rect, id| {
873+
let side_response = |rect, id| {
853874
let response = ctx.create_widget(
854875
WidgetRect {
855876
layer_id,
@@ -872,6 +893,12 @@ fn resize_interaction(
872893
let side_grab_radius = ctx.style().interaction.resize_grab_radius_side;
873894
let corner_grab_radius = ctx.style().interaction.resize_grab_radius_corner;
874895

896+
let vetrtical_rect = |a: Pos2, b: Pos2| {
897+
Rect::from_min_max(a, b).expand2(vec2(side_grab_radius, -corner_grab_radius))
898+
};
899+
let horizontal_rect = |a: Pos2, b: Pos2| {
900+
Rect::from_min_max(a, b).expand2(vec2(-corner_grab_radius, side_grab_radius))
901+
};
875902
let corner_rect =
876903
|center: Pos2| Rect::from_center_size(center, Vec2::splat(2.0 * corner_grab_radius));
877904

@@ -882,59 +909,80 @@ fn resize_interaction(
882909
// Check sides first, so that corners are on top, covering the sides (i.e. corners have priority)
883910

884911
if possible.resize_right {
885-
let response = is_dragging(
886-
Rect::from_min_max(rect.right_top(), rect.right_bottom()).expand(side_grab_radius),
912+
let response = side_response(
913+
vetrtical_rect(rect.right_top(), rect.right_bottom()),
887914
id.with("right"),
888915
);
889916
right |= response;
890917
}
891918
if possible.resize_left {
892-
let response = is_dragging(
893-
Rect::from_min_max(rect.left_top(), rect.left_bottom()).expand(side_grab_radius),
919+
let response = side_response(
920+
vetrtical_rect(rect.left_top(), rect.left_bottom()),
894921
id.with("left"),
895922
);
896923
left |= response;
897924
}
898925
if possible.resize_bottom {
899-
let response = is_dragging(
900-
Rect::from_min_max(rect.left_bottom(), rect.right_bottom()).expand(side_grab_radius),
926+
let response = side_response(
927+
horizontal_rect(rect.left_bottom(), rect.right_bottom()),
901928
id.with("bottom"),
902929
);
903930
bottom |= response;
904931
}
905932
if possible.resize_top {
906-
let response = is_dragging(
907-
Rect::from_min_max(rect.left_top(), rect.right_top()).expand(side_grab_radius),
933+
let response = side_response(
934+
horizontal_rect(rect.left_top(), rect.right_top()),
908935
id.with("top"),
909936
);
910937
top |= response;
911938
}
912939

913940
// ----------------------------------------
914-
// Now check corners:
915-
916-
if possible.resize_right && possible.resize_bottom {
917-
let response = is_dragging(corner_rect(rect.right_bottom()), id.with("right_bottom"));
918-
right |= response;
919-
bottom |= response;
941+
// Now check corners.
942+
// We check any corner that has either side resizable,
943+
// because we shrink the side resize handled by the corner width.
944+
// Also, even if we can only change the width (or height) of a window,
945+
// we show one of the corners as a grab-handle, so it makes sense that
946+
// the whole corner is grabbable:
947+
948+
if possible.resize_right || possible.resize_bottom {
949+
let response = side_response(corner_rect(rect.right_bottom()), id.with("right_bottom"));
950+
if possible.resize_right {
951+
right |= response;
952+
}
953+
if possible.resize_bottom {
954+
bottom |= response;
955+
}
920956
}
921957

922-
if possible.resize_right && possible.resize_top {
923-
let response = is_dragging(corner_rect(rect.right_top()), id.with("right_top"));
924-
right |= response;
925-
top |= response;
958+
if possible.resize_right || possible.resize_top {
959+
let response = side_response(corner_rect(rect.right_top()), id.with("right_top"));
960+
if possible.resize_right {
961+
right |= response;
962+
}
963+
if possible.resize_top {
964+
top |= response;
965+
}
926966
}
927967

928-
if possible.resize_left && possible.resize_bottom {
929-
let response = is_dragging(corner_rect(rect.left_bottom()), id.with("left_bottom"));
930-
left |= response;
931-
bottom |= response;
968+
if possible.resize_left || possible.resize_bottom {
969+
let response = side_response(corner_rect(rect.left_bottom()), id.with("left_bottom"));
970+
if possible.resize_left {
971+
left |= response;
972+
}
973+
if possible.resize_bottom {
974+
bottom |= response;
975+
}
932976
}
933977

934-
if possible.resize_left && possible.resize_top {
935-
let response = is_dragging(corner_rect(rect.left_top()), id.with("left_top"));
936-
left |= response;
937-
top |= response;
978+
if possible.resize_left || possible.resize_top {
979+
let response = side_response(corner_rect(rect.left_top()), id.with("left_top"));
980+
if possible.resize_left {
981+
left |= response;
982+
}
983+
if possible.resize_top {
984+
top |= response;
985+
}
938986
}
939987

940988
let interaction = ResizeInteraction {

0 commit comments

Comments
 (0)