Open new windows with a default size and position (#9204)

This PR changes GPUI to open windows with a default size and location,
and to otherwise inherit from their spawning window.

Note: The linux build now crashes on startup.

Release Notes:

- N/A

---------

Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Ezekiel Warren <zaucy@users.noreply.github.com>
This commit is contained in:
Mikayla Maki 2024-03-12 21:19:51 -07:00 committed by GitHub
parent 9a2dceeea1
commit e792c1a5c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 443 additions and 347 deletions

View file

@ -9,9 +9,12 @@ use serde_derive::{Deserialize, Serialize};
use std::{
cmp::{self, PartialOrd},
fmt,
hash::Hash,
ops::{Add, Div, Mul, MulAssign, Sub},
};
use crate::AppContext;
/// An axis along which a measurement can be made.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Axis {
@ -84,7 +87,7 @@ pub struct Point<T: Default + Clone + Debug> {
/// assert_eq!(p.x, 10);
/// assert_eq!(p.y, 20);
/// ```
pub fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {
pub const fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {
Point { x, y }
}
@ -354,6 +357,15 @@ pub struct Size<T: Clone + Default + Debug> {
pub height: T,
}
impl From<Size<GlobalPixels>> for Size<Pixels> {
fn from(size: Size<GlobalPixels>) -> Self {
Size {
width: Pixels(size.width.0),
height: Pixels(size.height.0),
}
}
}
/// Constructs a new `Size<T>` with the provided width and height.
///
/// # Arguments
@ -369,7 +381,7 @@ pub struct Size<T: Clone + Default + Debug> {
/// assert_eq!(my_size.width, 10);
/// assert_eq!(my_size.height, 20);
/// ```
pub fn size<T>(width: T, height: T) -> Size<T>
pub const fn size<T>(width: T, height: T) -> Size<T>
where
T: Clone + Default + Debug,
{
@ -662,6 +674,35 @@ pub struct Bounds<T: Clone + Default + Debug> {
pub size: Size<T>,
}
impl Bounds<GlobalPixels> {
/// Generate a centered bounds for the primary display
pub fn centered(size: impl Into<Size<GlobalPixels>>, cx: &mut AppContext) -> Self {
let size = size.into();
cx.primary_display()
.map(|display| {
let center = display.bounds().center();
Bounds {
origin: point(center.x - size.width / 2.0, center.y - size.height / 2.0),
size,
}
})
.unwrap_or_else(|| Bounds {
origin: point(GlobalPixels(0.0), GlobalPixels(0.0)),
size,
})
}
/// Generate maximized bounds for the primary display
pub fn maximized(cx: &mut AppContext) -> Self {
cx.primary_display()
.map(|display| display.bounds())
.unwrap_or_else(|| Bounds {
origin: point(GlobalPixels(0.0), GlobalPixels(0.0)),
size: size(GlobalPixels(1024.0), GlobalPixels(768.0)),
})
}
}
impl<T> Bounds<T>
where
T: Clone + Debug + Sub<Output = T> + Default,
@ -1165,6 +1206,29 @@ where
size: self.size.map(f),
}
}
/// Applies a function to the origin of the bounds, producing a new `Bounds` with the new origin
///
/// # Examples
///
/// ```
/// # use zed::{Bounds, Point, Size};
/// let bounds = Bounds {
/// origin: Point { x: 10.0, y: 10.0 },
/// size: Size { width: 10.0, height: 20.0 },
/// };
/// let new_bounds = bounds.map_origin(|value| value * 1.5);
///
/// assert_eq!(new_bounds, Bounds {
/// origin: Point { x: 15.0, y: 15.0 },
/// size: Size { width: 10.0, height: 20.0 },
/// });
pub fn map_origin(self, f: impl Fn(Point<T>) -> Point<T>) -> Bounds<T> {
Bounds {
origin: f(self.origin),
size: self.size,
}
}
}
/// Checks if the bounds represent an empty area.