Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gpui: Use local coordinates & add scale property #24699

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions crates/collab/src/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6248,6 +6248,7 @@ async fn test_right_click_menu_behind_collab_panel(cx: &mut TestAppContext) {
cx.simulate_event(MouseDownEvent {
button: MouseButton::Right,
position: new_tab_button_bounds.center(),
absolute_position: new_tab_button_bounds.center(),
modifiers: Modifiers::default(),
click_count: 1,
first_mouse: false,
Expand All @@ -6260,6 +6261,7 @@ async fn test_right_click_menu_behind_collab_panel(cx: &mut TestAppContext) {
cx.simulate_event(MouseDownEvent {
button: MouseButton::Right,
position: tab_bounds.center(),
absolute_position: new_tab_button_bounds.center(),
modifiers: Modifiers::default(),
click_count: 1,
first_mouse: false,
Expand Down
13 changes: 9 additions & 4 deletions crates/collab_ui/src/collab_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ impl CollabPanel {
el.on_secondary_mouse_down(cx.listener(
move |this, event: &MouseDownEvent, window, cx| {
this.deploy_participant_context_menu(
event.position,
event.absolute_position,
user_id,
role,
window,
Expand Down Expand Up @@ -2438,7 +2438,7 @@ impl CollabPanel {
let contact = contact.clone();
move |this, event: &ClickEvent, window, cx| {
this.deploy_contact_context_menu(
event.down.position,
event.down.absolute_position,
contact.clone(),
window,
cx,
Expand All @@ -2451,7 +2451,12 @@ impl CollabPanel {
.on_secondary_mouse_down(cx.listener({
let contact = contact.clone();
move |this, event: &MouseDownEvent, window, cx| {
this.deploy_contact_context_menu(event.position, contact.clone(), window, cx);
this.deploy_contact_context_menu(
event.absolute_position,
contact.clone(),
window,
cx,
);
}
}))
.start_slot(
Expand Down Expand Up @@ -2711,7 +2716,7 @@ impl CollabPanel {
.on_secondary_mouse_down(cx.listener(
move |this, event: &MouseDownEvent, window, cx| {
this.deploy_channel_context_menu(
event.position,
event.absolute_position,
channel_id,
ix,
window,
Expand Down
6 changes: 3 additions & 3 deletions crates/editor/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,10 +671,10 @@ impl EditorElement {
if !position_map.text_hitbox.is_hovered(window) {
return;
}
let point_for_position = position_map.point_for_position(event.position);
let point_for_position = position_map.point_for_position(event.absolute_position);
mouse_context_menu::deploy_context_menu(
editor,
Some(event.position),
Some(event.absolute_position),
point_for_position.previous_valid,
window,
cx,
Expand Down Expand Up @@ -5102,7 +5102,7 @@ impl EditorElement {

let hitbox = hitbox.clone();

let mut mouse_position = window.mouse_position();
let mut mouse_position = window.mouse_position() - window.element_origin();
move |event: &MouseMoveEvent, phase, window, cx| {
if phase == DispatchPhase::Capture {
return;
Expand Down
4 changes: 4 additions & 0 deletions crates/gpui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@ path = "examples/opacity.rs"
name = "pattern"
path = "examples/pattern.rs"

[[example]]
name = "scale"
path = "examples/scale.rs"

[[example]]
name = "set_menus"
path = "examples/set_menus.rs"
Expand Down
68 changes: 68 additions & 0 deletions crates/gpui/examples/scale.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::{f32::consts::PI, time::Duration};

use gpui::{
div, prelude::*, px, rgb, size, white, Animation, AnimationExt, App, Application, Bounds,
Window,
};

struct MainView {}

impl Render for MainView {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<'_, Self>) -> impl IntoElement {
div()
.flex()
.size_full()
.bg(rgb(0x202020))
.font_family("Sans")
.items_center()
.justify_between()
.child(ChildElement { scale: 1.0 })
.child(ChildElement { scale: 0.75 })
.child(ChildElement { scale: 0.5 })
.with_animation(
"animation",
Animation::new(Duration::from_millis(5000)).repeat(),
|el, delta| {
el.child(ChildElement {
scale: (2.0 * delta * PI).sin() * 0.5 + 1.0,
})
},
)
}
}

#[derive(IntoElement)]
struct ChildElement {
pub scale: f32,
}

impl RenderOnce for ChildElement {
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
div()
.flex()
.min_h(px(120.0))
.min_w(px(120.0))
.max_h(px(120.0))
.max_w(px(120.0))
.scale(self.scale)
.bg(white())
.items_center()
.justify_center()
.overflow_hidden()
.child(format!("Scale: {:.2}x", self.scale))
}
}

fn main() {
Application::new().run(|cx: &mut App| {
let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
cx.open_window(
gpui::WindowOptions {
window_bounds: Some(gpui::WindowBounds::Windowed(bounds)),
..Default::default()
},
|_, cx| cx.new(|_| MainView {}),
)
.unwrap();
});
}
4 changes: 3 additions & 1 deletion crates/gpui/examples/window_shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ impl Render for WindowShadow {
)
.on_click(|e, window, _| {
if e.down.button == MouseButton::Right {
window.show_window_menu(e.up.position);
window.show_window_menu(
e.up.absolute_position,
);
}
})
.text_color(black())
Expand Down
7 changes: 6 additions & 1 deletion crates/gpui/src/app/test_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ impl VisualTestContext {
) {
self.simulate_event(MouseMoveEvent {
position,
absolute_position: position,
modifiers,
pressed_button: button.into(),
})
Expand All @@ -721,6 +722,7 @@ impl VisualTestContext {
) {
self.simulate_event(MouseDownEvent {
position,
absolute_position: position,
modifiers,
button,
click_count: 1,
Expand All @@ -737,6 +739,7 @@ impl VisualTestContext {
) {
self.simulate_event(MouseUpEvent {
position,
absolute_position: position,
modifiers,
button,
click_count: 1,
Expand All @@ -747,13 +750,15 @@ impl VisualTestContext {
pub fn simulate_click(&mut self, position: Point<Pixels>, modifiers: Modifiers) {
self.simulate_event(MouseDownEvent {
position,
absolute_position: position,
modifiers,
button: MouseButton::Left,
click_count: 1,
first_mouse: false,
});
self.simulate_event(MouseUpEvent {
position,
absolute_position: position,
modifiers,
button: MouseButton::Left,
click_count: 1,
Expand Down Expand Up @@ -789,7 +794,7 @@ impl VisualTestContext {
window.invalidator.set_phase(DrawPhase::Prepaint);
let mut element = Drawable::new(f(window, cx));
element.layout_as_root(space.into(), window, cx);
window.with_absolute_element_offset(origin, |window| element.prepaint(window, cx));
window.with_element_origin(origin, |window| element.prepaint(window, cx));

window.invalidator.set_phase(DrawPhase::Paint);
let (request_layout_state, prepaint_state) = element.paint(window, cx);
Expand Down
75 changes: 54 additions & 21 deletions crates/gpui/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ enum ElementDrawPhase<RequestLayoutState, PrepaintState> {
node_id: DispatchNodeId,
global_id: Option<GlobalElementId>,
bounds: Bounds<Pixels>,
scale: f32,
request_layout: RequestLayoutState,
prepaint: PrepaintState,
},
Expand Down Expand Up @@ -333,15 +334,26 @@ impl<E: Element> Drawable<E> {
debug_assert_eq!(global_id.as_ref().unwrap().0, window.element_id_stack);
}

let bounds = window.layout_bounds(layout_id);
let mut bounds = window.layout_bounds(layout_id);
let scale = window.layout_scale(layout_id);
bounds.size *= 1.0 / scale;
window.element_layout_id = Some(layout_id);

let node_id = window.next_frame.dispatch_tree.push_node();
let prepaint = self.element.prepaint(
global_id.as_ref(),
bounds,
&mut request_layout,
window,
cx,
);
let prepaint = window.with_element_origin(bounds.origin, |window| {
window.with_element_scale(scale, |window| {
self.element.prepaint(
global_id.as_ref(),
Bounds {
origin: Point::default(),
size: bounds.size,
},
&mut request_layout,
window,
cx,
)
})
});
window.next_frame.dispatch_tree.pop_node();

if global_id.is_some() {
Expand All @@ -352,6 +364,7 @@ impl<E: Element> Drawable<E> {
node_id,
global_id,
bounds,
scale,
request_layout,
prepaint,
};
Expand All @@ -370,6 +383,7 @@ impl<E: Element> Drawable<E> {
node_id,
global_id,
bounds,
scale,
mut request_layout,
mut prepaint,
..
Expand All @@ -380,14 +394,21 @@ impl<E: Element> Drawable<E> {
}

window.next_frame.dispatch_tree.set_active_node(node_id);
self.element.paint(
global_id.as_ref(),
bounds,
&mut request_layout,
&mut prepaint,
window,
cx,
);
window.with_element_origin(bounds.origin, |window| {
window.with_element_scale(scale, |window| {
self.element.paint(
global_id.as_ref(),
Bounds {
origin: Point::default(),
size: bounds.size,
},
&mut request_layout,
&mut prepaint,
window,
cx,
);
})
});

if global_id.is_some() {
window.element_id_stack.pop();
Expand All @@ -402,12 +423,21 @@ impl<E: Element> Drawable<E> {

pub(crate) fn layout_as_root(
&mut self,
available_space: Size<AvailableSpace>,
mut available_space: Size<AvailableSpace>,
window: &mut Window,
cx: &mut App,
) -> Size<Pixels> {
available_space = available_space.map(|space| match space {
AvailableSpace::Definite(pixels) => {
AvailableSpace::Definite(pixels * window.element_scale())
}
x => x,
});

if matches!(&self.phase, ElementDrawPhase::Start) {
self.request_layout(window, cx);
window.with_element_origin(Point::default(), |window| {
self.request_layout(window, cx);
});
}

let layout_id = match mem::take(&mut self.phase) {
Expand Down Expand Up @@ -445,7 +475,7 @@ impl<E: Element> Drawable<E> {
_ => panic!("cannot measure after painting"),
};

window.layout_bounds(layout_id).size
window.layout_bounds(layout_id).size / window.element_scale()
}
}

Expand Down Expand Up @@ -545,7 +575,10 @@ impl AnyElement {
window: &mut Window,
cx: &mut App,
) -> Option<FocusHandle> {
window.with_absolute_element_offset(origin, |window| self.prepaint(window, cx))
window.with_element_origin(
origin * window.element_scale() + window.element_origin(),
|window| self.prepaint(window, cx),
)
}

/// Performs layout on this element in the available space, then prepaints it at the given absolute origin.
Expand All @@ -558,7 +591,7 @@ impl AnyElement {
cx: &mut App,
) -> Option<FocusHandle> {
self.layout_as_root(available_space, window, cx);
window.with_absolute_element_offset(origin, |window| self.prepaint(window, cx))
self.prepaint_at(origin, window, cx)
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/gpui/src/elements/anchored.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl Element for Anchored {
let offset = desired.origin - bounds.origin;
let offset = point(offset.x.round(), offset.y.round());

window.with_element_offset(offset, |window| {
window.with_element_origin(offset, |window| {
for child in &mut self.children {
child.prepaint(window, cx);
}
Expand Down
5 changes: 2 additions & 3 deletions crates/gpui/src/elements/deferred.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
AnyElement, App, Bounds, Element, GlobalElementId, IntoElement, LayoutId, Pixels, Window,
AnyElement, App, Bounds, Element, GlobalElementId, IntoElement, LayoutId, Pixels, Point, Window,
};

/// Builds a `Deferred` element, which delays the layout and paint of its child.
Expand Down Expand Up @@ -54,8 +54,7 @@ impl Element for Deferred {
_cx: &mut App,
) {
let child = self.child.take().unwrap();
let element_offset = window.element_offset();
window.defer_draw(child, element_offset, self.priority)
window.defer_draw(child, Point::default(), self.priority)
}

fn paint(
Expand Down
Loading
Loading