gpui: Implement dynamic window control elements (#30828)
Allows setting element as window control elements which consist of `Drag`, `Close`, `Max`, or `Min`. This allows you to implement dynamically sized elements that control the platform window, this is used for areas such as the title bar. Currently only implemented for Windows. Release Notes: - N/A
This commit is contained in:
parent
d9efa2860f
commit
ca3f46588a
11 changed files with 129 additions and 96 deletions
|
@ -418,6 +418,19 @@ pub(crate) struct HitTest {
|
|||
pub(crate) hover_hitbox_count: usize,
|
||||
}
|
||||
|
||||
/// A type of window control area that corresponds to the platform window.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum WindowControlArea {
|
||||
/// An area that allows dragging of the platform window.
|
||||
Drag,
|
||||
/// An area that allows closing of the platform window.
|
||||
Close,
|
||||
/// An area that allows maximizing of the platform window.
|
||||
Max,
|
||||
/// An area that allows minimizing of the platform window.
|
||||
Min,
|
||||
}
|
||||
|
||||
/// An identifier for a [Hitbox] which also includes [HitboxBehavior].
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct HitboxId(u64);
|
||||
|
@ -604,6 +617,7 @@ pub(crate) struct Frame {
|
|||
pub(crate) dispatch_tree: DispatchTree,
|
||||
pub(crate) scene: Scene,
|
||||
pub(crate) hitboxes: Vec<Hitbox>,
|
||||
pub(crate) window_control_hitboxes: Vec<(WindowControlArea, Hitbox)>,
|
||||
pub(crate) deferred_draws: Vec<DeferredDraw>,
|
||||
pub(crate) input_handlers: Vec<Option<PlatformInputHandler>>,
|
||||
pub(crate) tooltip_requests: Vec<Option<TooltipRequest>>,
|
||||
|
@ -647,6 +661,7 @@ impl Frame {
|
|||
dispatch_tree,
|
||||
scene: Scene::default(),
|
||||
hitboxes: Vec::new(),
|
||||
window_control_hitboxes: Vec::new(),
|
||||
deferred_draws: Vec::new(),
|
||||
input_handlers: Vec::new(),
|
||||
tooltip_requests: Vec::new(),
|
||||
|
@ -673,6 +688,7 @@ impl Frame {
|
|||
self.tooltip_requests.clear();
|
||||
self.cursor_styles.clear();
|
||||
self.hitboxes.clear();
|
||||
self.window_control_hitboxes.clear();
|
||||
self.deferred_draws.clear();
|
||||
self.focus = None;
|
||||
|
||||
|
@ -1013,6 +1029,22 @@ impl Window {
|
|||
.unwrap_or(DispatchEventResult::default())
|
||||
})
|
||||
});
|
||||
platform_window.on_hit_test_window_control({
|
||||
let mut cx = cx.to_async();
|
||||
Box::new(move || {
|
||||
handle
|
||||
.update(&mut cx, |_, window, _cx| {
|
||||
for (area, hitbox) in &window.rendered_frame.window_control_hitboxes {
|
||||
if window.mouse_hit_test.ids.contains(&hitbox.id) {
|
||||
return Some(*area);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.log_err()
|
||||
.unwrap_or(None)
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(app_id) = app_id {
|
||||
platform_window.set_app_id(&app_id);
|
||||
|
@ -3002,6 +3034,14 @@ impl Window {
|
|||
hitbox
|
||||
}
|
||||
|
||||
/// Set a hitbox which will act as a control area of the platform window.
|
||||
///
|
||||
/// This method should only be called as part of the paint phase of element drawing.
|
||||
pub fn insert_window_control_hitbox(&mut self, area: WindowControlArea, hitbox: Hitbox) {
|
||||
self.invalidator.debug_assert_paint();
|
||||
self.next_frame.window_control_hitboxes.push((area, hitbox));
|
||||
}
|
||||
|
||||
/// Sets the key context for the current element. This context will be used to translate
|
||||
/// keybindings into actions.
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue