[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` * Add ability to override text color with `visuals.override_text_color`
* Refactored the interface for `egui::app::App` * Refactored the interface for `egui::app::App`
* Demo App: Add slider to scale all of Egui * 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`). * Fix a bug where some regions would slowly grow for non-integral scales (`pixels_per_point`).
## 0.2.0 - 2020-10-10 ## 0.2.0 - 2020-10-10

View file

@ -175,8 +175,8 @@ impl Prepared {
state.size = content_ui.min_rect().size(); state.size = content_ui.min_rect().size();
let rect = Rect::from_min_size(state.pos, state.size); let area_rect = Rect::from_min_size(state.pos, state.size);
let clip_rect = Rect::everything(); // TODO: get from context let clip_rect = ctx.rect();
let interact_id = if movable { let interact_id = if movable {
Some(layer_id.id.with("move")) Some(layer_id.id.with("move"))
@ -186,7 +186,7 @@ impl Prepared {
let move_response = ctx.interact( let move_response = ctx.interact(
layer_id, layer_id,
clip_rect, clip_rect,
rect, area_rect,
interact_id, interact_id,
Sense::click_and_drag(), Sense::click_and_drag(),
); );
@ -210,14 +210,7 @@ impl Prepared {
} }
} }
// Constrain to screen: state.pos = ctx.constrain_window_rect(area_rect).min;
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);
if move_response.active if move_response.active
|| mouse_pressed_on_area(ctx, layer_id) || mouse_pressed_on_area(ctx, layer_id)

View file

@ -384,11 +384,11 @@ fn interact(
area_state: &mut area::State, area_state: &mut area::State,
resize_id: Id, resize_id: Id,
) -> Option<WindowInteraction> { ) -> 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); 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; area_state.pos = new_rect.min;
if window_interaction.is_resize() { if window_interaction.is_resize() {
@ -401,7 +401,7 @@ fn interact(
Some(window_interaction) 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); window_interaction.set_cursor(ctx);
let mouse_pos = ctx.input().mouse.pos?; let mouse_pos = ctx.input().mouse.pos?;
let mut rect = window_interaction.start_rect; // prevent drift 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. /// Call at the start of every frame.
/// Returns a master fullscreen UI, covering the entire screen. /// Returns a master fullscreen UI, covering the entire screen.
pub fn begin_frame(self: &mut Arc<Self>, new_input: RawInput) -> Ui { pub fn begin_frame(self: &mut Arc<Self>, new_input: RawInput) -> Ui {