[windows] Constrain windows to screen

This commit is contained in:
Emil Ernerfeldt 2020-10-21 16:24:36 +02:00
parent 39431afd03
commit 46ce9a4f3d
4 changed files with 32 additions and 15 deletions

View file

@ -6,6 +6,7 @@
* Add ability to override text color with `visuals.override_text_color`
* Refactored the interface for `egui::app::App`
* Demo App: Add slider to scale all of Egui
* Windows are now constrained to the screen
* Fix a bug where some regions would slowly grow for non-integral scales (`pixels_per_point`).
## 0.2.0 - 2020-10-10

View file

@ -175,8 +175,8 @@ impl Prepared {
state.size = content_ui.min_rect().size();
let rect = Rect::from_min_size(state.pos, state.size);
let clip_rect = Rect::everything(); // TODO: get from context
let area_rect = Rect::from_min_size(state.pos, state.size);
let clip_rect = ctx.rect();
let interact_id = if movable {
Some(layer_id.id.with("move"))
@ -186,7 +186,7 @@ impl Prepared {
let move_response = ctx.interact(
layer_id,
clip_rect,
rect,
area_rect,
interact_id,
Sense::click_and_drag(),
);
@ -210,14 +210,7 @@ impl Prepared {
}
}
// Constrain to screen:
let margin = 32.0;
state.pos = state.pos.max(pos2(margin - state.size.x, 0.0));
state.pos = state.pos.min(pos2(
ctx.input().screen_size.x - margin,
ctx.input().screen_size.y - margin,
));
state.pos = ctx.round_pos_to_pixels(state.pos);
state.pos = ctx.constrain_window_rect(area_rect).min;
if move_response.active
|| mouse_pressed_on_area(ctx, layer_id)

View file

@ -384,11 +384,11 @@ fn interact(
area_state: &mut area::State,
resize_id: Id,
) -> Option<WindowInteraction> {
let new_rect = resize_window(ctx, &window_interaction)?;
let new_rect = move_and_resize_window(ctx, &window_interaction)?;
let new_rect = ctx.round_rect_to_pixels(new_rect);
// TODO: add this to a Window state instead as a command "move here next frame"
let new_rect = ctx.constrain_window_rect(new_rect);
// TODO: add this to a Window state instead as a command "move here next frame"
area_state.pos = new_rect.min;
if window_interaction.is_resize() {
@ -401,7 +401,7 @@ fn interact(
Some(window_interaction)
}
fn resize_window(ctx: &Context, window_interaction: &WindowInteraction) -> Option<Rect> {
fn move_and_resize_window(ctx: &Context, window_interaction: &WindowInteraction) -> Option<Rect> {
window_interaction.set_cursor(ctx);
let mouse_pos = ctx.input().mouse.pos?;
let mut rect = window_interaction.start_rect; // prevent drift

View file

@ -165,6 +165,29 @@ impl Context {
// ---------------------------------------------------------------------
/// Constraint the position of a window/area
/// so it fits within the screen.
pub(crate) fn constrain_window_rect(&self, window: Rect) -> Rect {
let screen = self.rect();
let mut pos = window.min;
// Constrain to screen, unless window is too large to fit:
let margin_x = (window.width() - screen.width()).at_least(0.0);
let margin_y = (window.height() - screen.height()).at_least(0.0);
pos.x = pos.x.at_least(screen.left() - margin_x);
pos.x = pos.x.at_most(screen.right() + margin_x - window.width());
pos.y = pos.y.at_least(screen.top() - margin_y);
pos.y = pos.y.at_most(screen.bottom() + margin_y - window.height());
pos = self.round_pos_to_pixels(pos);
Rect::from_min_size(pos, window.size())
}
// ---------------------------------------------------------------------
/// Call at the start of every frame.
/// Returns a master fullscreen UI, covering the entire screen.
pub fn begin_frame(self: &mut Arc<Self>, new_input: RawInput) -> Ui {