Merge remote-tracking branch 'origin/main' into perf-2

This commit is contained in:
Nathan Sobo 2023-12-14 14:16:59 -07:00
commit fb3382bcc5
68 changed files with 2701 additions and 1149 deletions

View file

@ -1,15 +1,15 @@
use crate::{
key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext,
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId,
Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent,
Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString, Size, Style,
SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View,
VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
key_dispatch::DispatchActionListener, px, size, transparent_black, Action, AnyDrag, AnyView,
AppContext, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners,
CursorStyle, DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity,
EntityId, EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId,
Hsla, ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent,
LayoutId, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent,
MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler,
PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
RenderImageParams, RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString,
Size, Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline,
UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::{anyhow, Context as _, Result};
use collections::FxHashMap;
@ -243,6 +243,7 @@ pub struct Window {
pub(crate) blur_listeners: SubscriberSet<(), AnyObserver>,
default_prevented: bool,
mouse_position: Point<Pixels>,
modifiers: Modifiers,
requested_cursor_style: Option<CursorStyle>,
scale_factor: f32,
bounds: WindowBounds,
@ -315,6 +316,7 @@ impl Window {
let display_id = platform_window.display().id();
let sprite_atlas = platform_window.sprite_atlas();
let mouse_position = platform_window.mouse_position();
let modifiers = platform_window.modifiers();
let content_size = platform_window.content_size();
let scale_factor = platform_window.scale_factor();
let bounds = platform_window.bounds();
@ -378,6 +380,7 @@ impl Window {
blur_listeners: SubscriberSet::new(),
default_prevented: true,
mouse_position,
modifiers,
requested_cursor_style: None,
scale_factor,
bounds,
@ -893,6 +896,11 @@ impl<'a> WindowContext<'a> {
self.window.mouse_position
}
/// The current state of the keyboard's modifiers
pub fn modifiers(&self) -> Modifiers {
self.window.modifiers
}
pub fn set_cursor_style(&mut self, style: CursorStyle) {
self.window.requested_cursor_style = Some(style)
}
@ -979,14 +987,8 @@ impl<'a> WindowContext<'a> {
/// Paint one or more quads into the scene for the next frame at the current stacking context.
/// Quads are colored rectangular regions with an optional background, border, and corner radius.
pub fn paint_quad(
&mut self,
bounds: Bounds<Pixels>,
corner_radii: Corners<Pixels>,
background: impl Into<Hsla>,
border_widths: Edges<Pixels>,
border_color: impl Into<Hsla>,
) {
/// see [`fill`], [`outline`], and [`quad`] to construct this type.
pub fn paint_quad(&mut self, quad: PaintQuad) {
let scale_factor = self.scale_factor();
let content_mask = self.content_mask();
@ -995,12 +997,12 @@ impl<'a> WindowContext<'a> {
&window.next_frame.z_index_stack,
Quad {
order: 0,
bounds: bounds.scale(scale_factor),
bounds: quad.bounds.scale(scale_factor),
content_mask: content_mask.scale(scale_factor),
background: background.into(),
border_color: border_color.into(),
corner_radii: corner_radii.scale(scale_factor),
border_widths: border_widths.scale(scale_factor),
background: quad.background,
border_color: quad.border_color,
corner_radii: quad.corner_radii.scale(scale_factor),
border_widths: quad.border_widths.scale(scale_factor),
},
);
}
@ -1363,16 +1365,34 @@ impl<'a> WindowContext<'a> {
// API for the mouse position can only occur on the main thread.
InputEvent::MouseMove(mouse_move) => {
self.window.mouse_position = mouse_move.position;
self.window.modifiers = mouse_move.modifiers;
InputEvent::MouseMove(mouse_move)
}
InputEvent::MouseDown(mouse_down) => {
self.window.mouse_position = mouse_down.position;
self.window.modifiers = mouse_down.modifiers;
InputEvent::MouseDown(mouse_down)
}
InputEvent::MouseUp(mouse_up) => {
self.window.mouse_position = mouse_up.position;
self.window.modifiers = mouse_up.modifiers;
InputEvent::MouseUp(mouse_up)
}
InputEvent::MouseExited(mouse_exited) => {
// todo!("Should we record that the mouse is outside of the window somehow? Or are these global pixels?")
self.window.modifiers = mouse_exited.modifiers;
InputEvent::MouseExited(mouse_exited)
}
InputEvent::ModifiersChanged(modifiers_changed) => {
self.window.modifiers = modifiers_changed.modifiers;
InputEvent::ModifiersChanged(modifiers_changed)
}
InputEvent::ScrollWheel(scroll_wheel) => {
self.window.mouse_position = scroll_wheel.position;
self.window.modifiers = scroll_wheel.modifiers;
InputEvent::ScrollWheel(scroll_wheel)
}
// Translate dragging and dropping of external files from the operating system
// to internal drag and drop events.
InputEvent::FileDrop(file_drop) => match file_drop {
@ -1415,7 +1435,7 @@ impl<'a> WindowContext<'a> {
click_count: 1,
}),
},
_ => event,
InputEvent::KeyDown(_) | InputEvent::KeyUp(_) => event,
};
if let Some(any_mouse_event) = event.mouse_event() {
@ -2985,3 +3005,85 @@ impl From<(&'static str, u64)> for ElementId {
ElementId::NamedInteger(name.into(), id as usize)
}
}
/// A rectangle, to be rendered on the screen by GPUI at the given position and size.
pub struct PaintQuad {
bounds: Bounds<Pixels>,
corner_radii: Corners<Pixels>,
background: Hsla,
border_widths: Edges<Pixels>,
border_color: Hsla,
}
impl PaintQuad {
/// Set the corner radii of the quad.
pub fn corner_radii(self, corner_radii: impl Into<Corners<Pixels>>) -> Self {
PaintQuad {
corner_radii: corner_radii.into(),
..self
}
}
/// Set the border widths of the quad.
pub fn border_widths(self, border_widths: impl Into<Edges<Pixels>>) -> Self {
PaintQuad {
border_widths: border_widths.into(),
..self
}
}
/// Set the border color of the quad.
pub fn border_color(self, border_color: impl Into<Hsla>) -> Self {
PaintQuad {
border_color: border_color.into(),
..self
}
}
/// Set the background color of the quad.
pub fn background(self, background: impl Into<Hsla>) -> Self {
PaintQuad {
background: background.into(),
..self
}
}
}
/// Create a quad with the given parameters.
pub fn quad(
bounds: Bounds<Pixels>,
corner_radii: impl Into<Corners<Pixels>>,
background: impl Into<Hsla>,
border_widths: impl Into<Edges<Pixels>>,
border_color: impl Into<Hsla>,
) -> PaintQuad {
PaintQuad {
bounds,
corner_radii: corner_radii.into(),
background: background.into(),
border_widths: border_widths.into(),
border_color: border_color.into(),
}
}
/// Create a filled quad with the given bounds and background color.
pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Hsla>) -> PaintQuad {
PaintQuad {
bounds: bounds.into(),
corner_radii: (0.).into(),
background: background.into(),
border_widths: (0.).into(),
border_color: transparent_black(),
}
}
/// Create a rectangle outline with the given bounds, border color, and a 1px border width
pub fn outline(bounds: impl Into<Bounds<Pixels>>, border_color: impl Into<Hsla>) -> PaintQuad {
PaintQuad {
bounds: bounds.into(),
corner_radii: (0.).into(),
background: transparent_black(),
border_widths: (1.).into(),
border_color: border_color.into(),
}
}