chore: Upgrade to GPUI3 (#6)

* wip: gpui3

* wip: gpui3

* chore: fix clippy
This commit is contained in:
reya
2025-01-28 08:25:49 +07:00
committed by GitHub
parent 3c15e74e56
commit 72a6d79bc5
62 changed files with 2572 additions and 2511 deletions

View File

@@ -1,16 +1,22 @@
use gpui::{Axis, ViewContext};
use gpui::{Axis, Context, Window};
mod panel;
mod resize_handle;
pub use panel::*;
pub(crate) use resize_handle::*;
pub fn h_resizable(cx: &mut ViewContext<ResizablePanelGroup>) -> ResizablePanelGroup {
ResizablePanelGroup::new(cx).axis(Axis::Horizontal)
pub fn h_resizable(
window: &mut Window,
cx: &mut Context<ResizablePanelGroup>,
) -> ResizablePanelGroup {
ResizablePanelGroup::new(window, cx).axis(Axis::Horizontal)
}
pub fn v_resizable(cx: &mut ViewContext<ResizablePanelGroup>) -> ResizablePanelGroup {
ResizablePanelGroup::new(cx).axis(Axis::Vertical)
pub fn v_resizable(
window: &mut Window,
cx: &mut Context<ResizablePanelGroup>,
) -> ResizablePanelGroup {
ResizablePanelGroup::new(window, cx).axis(Axis::Vertical)
}
pub fn resizable_panel() -> ResizablePanel {

View File

@@ -1,10 +1,10 @@
use super::resize_handle;
use crate::{h_flex, v_flex, AxisExt};
use gpui::{
canvas, div, prelude::FluentBuilder, px, relative, Along, AnyElement, AnyView, Axis, Bounds,
Element, Entity, EntityId, EventEmitter, IntoElement, IsZero, MouseMoveEvent, MouseUpEvent,
ParentElement, Pixels, Render, StatefulInteractiveElement as _, Style, Styled, View,
ViewContext, VisualContext as _, WeakView, WindowContext,
canvas, div, prelude::FluentBuilder, px, relative, Along, AnyElement, AnyView, App, AppContext,
Axis, Bounds, Context, Element, Entity, EntityId, EventEmitter, IntoElement, IsZero,
MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Render, StatefulInteractiveElement as _,
Style, Styled, WeakEntity, Window,
};
use std::rc::Rc;
@@ -19,7 +19,7 @@ pub struct DragPanel(pub (EntityId, usize, Axis));
#[derive(Clone)]
pub struct ResizablePanelGroup {
panels: Vec<View<ResizablePanel>>,
panels: Vec<Entity<ResizablePanel>>,
sizes: Vec<Pixels>,
axis: Axis,
size: Option<Pixels>,
@@ -28,7 +28,7 @@ pub struct ResizablePanelGroup {
}
impl ResizablePanelGroup {
pub(super) fn new(_cx: &mut ViewContext<Self>) -> Self {
pub(super) fn new(_window: &mut Window, _cx: &mut Context<Self>) -> Self {
Self {
axis: Axis::Horizontal,
sizes: Vec::new(),
@@ -39,7 +39,7 @@ impl ResizablePanelGroup {
}
}
pub fn load(&mut self, sizes: Vec<Pixels>, panels: Vec<View<ResizablePanel>>) {
pub fn load(&mut self, sizes: Vec<Pixels>, panels: Vec<Entity<ResizablePanel>>) {
self.sizes = sizes;
self.panels = panels;
}
@@ -50,25 +50,35 @@ impl ResizablePanelGroup {
self
}
pub(crate) fn set_axis(&mut self, axis: Axis, cx: &mut ViewContext<Self>) {
pub(crate) fn set_axis(&mut self, axis: Axis, _window: &mut Window, cx: &mut Context<Self>) {
self.axis = axis;
cx.notify();
}
/// Add a resizable panel to the group.
pub fn child(mut self, panel: ResizablePanel, cx: &mut ViewContext<Self>) -> Self {
self.add_child(panel, cx);
pub fn child(
mut self,
panel: ResizablePanel,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
self.add_child(panel, window, cx);
self
}
/// Add a ResizablePanelGroup as a child to the group.
pub fn group(self, group: ResizablePanelGroup, cx: &mut ViewContext<Self>) -> Self {
pub fn group(
self,
group: ResizablePanelGroup,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let group: ResizablePanelGroup = group;
let size = group.size;
let panel = ResizablePanel::new()
.content_view(cx.new_view(|_| group).into())
.content_view(cx.new(|_| group).into())
.when_some(size, |this, size| this.size(size));
self.child(panel, cx)
self.child(panel, window, cx)
}
/// Set size of the resizable panel group
@@ -90,22 +100,34 @@ impl ResizablePanelGroup {
self.sizes.iter().fold(px(0.0), |acc, &size| acc + size)
}
pub fn add_child(&mut self, panel: ResizablePanel, cx: &mut ViewContext<Self>) {
pub fn add_child(
&mut self,
panel: ResizablePanel,
_window: &mut Window,
cx: &mut Context<Self>,
) {
let mut panel = panel;
panel.axis = self.axis;
panel.group = Some(cx.view().downgrade());
panel.group = Some(cx.model().downgrade());
self.sizes.push(panel.initial_size.unwrap_or_default());
self.panels.push(cx.new_view(|_| panel));
self.panels.push(cx.new(|_| panel));
}
pub fn insert_child(&mut self, panel: ResizablePanel, ix: usize, cx: &mut ViewContext<Self>) {
pub fn insert_child(
&mut self,
panel: ResizablePanel,
ix: usize,
_window: &mut Window,
cx: &mut Context<Self>,
) {
let mut panel = panel;
panel.axis = self.axis;
panel.group = Some(cx.view().downgrade());
panel.group = Some(cx.model().downgrade());
self.sizes
.insert(ix, panel.initial_size.unwrap_or_default());
self.panels.insert(ix, cx.new_view(|_| panel));
self.panels.insert(ix, cx.new(|_| panel));
cx.notify()
}
@@ -114,7 +136,8 @@ impl ResizablePanelGroup {
&mut self,
panel: ResizablePanel,
ix: usize,
cx: &mut ViewContext<Self>,
_window: &mut Window,
cx: &mut Context<Self>,
) {
let mut panel = panel;
@@ -125,45 +148,50 @@ impl ResizablePanelGroup {
panel.initial_size = old_panel_initial_size;
panel.size_ratio = old_panel_size_ratio;
panel.axis = self.axis;
panel.group = Some(cx.view().downgrade());
panel.group = Some(cx.model().downgrade());
self.sizes[ix] = panel.initial_size.unwrap_or_default();
self.panels[ix] = cx.new_view(|_| panel);
self.panels[ix] = cx.new(|_| panel);
cx.notify()
}
pub fn remove_child(&mut self, ix: usize, cx: &mut ViewContext<Self>) {
pub fn remove_child(&mut self, ix: usize, _window: &mut Window, cx: &mut Context<Self>) {
self.sizes.remove(ix);
self.panels.remove(ix);
cx.notify()
}
pub(crate) fn remove_all_children(&mut self, cx: &mut ViewContext<Self>) {
pub(crate) fn remove_all_children(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
self.sizes.clear();
self.panels.clear();
cx.notify()
}
fn render_resize_handle(&self, ix: usize, cx: &mut ViewContext<Self>) -> impl IntoElement {
let view = cx.view().clone();
fn render_resize_handle(
&self,
ix: usize,
_window: &mut Window,
cx: &mut Context<Self>,
) -> impl IntoElement {
let view = cx.model().clone();
resize_handle(("resizable-handle", ix), self.axis).on_drag(
DragPanel((cx.entity_id(), ix, self.axis)),
move |drag_panel, _, cx| {
move |drag_panel, _, _window, cx| {
cx.stop_propagation();
// Set current resizing panel ix
view.update(cx, |view, _| {
view.resizing_panel_ix = Some(ix);
});
cx.new_view(|_| drag_panel.clone())
cx.new(|_| drag_panel.clone())
},
)
}
fn done_resizing(&mut self, cx: &mut ViewContext<Self>) {
fn done_resizing(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
cx.emit(ResizablePanelEvent::Resized);
self.resizing_panel_ix = None;
}
fn sync_real_panel_sizes(&mut self, cx: &WindowContext) {
fn sync_real_panel_sizes(&mut self, _window: &Window, cx: &App) {
for (i, panel) in self.panels.iter().enumerate() {
self.sizes[i] = panel.read(cx).bounds.size.along(self.axis)
}
@@ -171,7 +199,13 @@ impl ResizablePanelGroup {
/// The `ix`` is the index of the panel to resize,
/// and the `size` is the new size for the panel.
fn resize_panels(&mut self, ix: usize, size: Pixels, cx: &mut ViewContext<Self>) {
fn resize_panels(
&mut self,
ix: usize,
size: Pixels,
window: &mut Window,
cx: &mut Context<Self>,
) {
let mut ix = ix;
// Only resize the left panels.
if ix >= self.panels.len() - 1 {
@@ -180,7 +214,7 @@ impl ResizablePanelGroup {
let size = size.floor();
let container_size = self.bounds.size.along(self.axis);
self.sync_real_panel_sizes(cx);
self.sync_real_panel_sizes(window, cx);
let mut changed = size - self.sizes[ix];
let is_expand = changed > px(0.);
@@ -238,8 +272,8 @@ impl ResizablePanelGroup {
impl EventEmitter<ResizablePanelEvent> for ResizablePanelGroup {}
impl Render for ResizablePanelGroup {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let view = cx.view().clone();
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let view = cx.model().clone();
let container = if self.axis.is_horizontal() {
h_flex()
} else {
@@ -250,7 +284,7 @@ impl Render for ResizablePanelGroup {
.size_full()
.children(self.panels.iter().enumerate().map(|(ix, panel)| {
if ix > 0 {
let handle = self.render_resize_handle(ix - 1, cx);
let handle = self.render_resize_handle(ix - 1, window, cx);
panel.update(cx, |view, _| {
view.resize_handle = Some(handle.into_any_element())
});
@@ -260,23 +294,23 @@ impl Render for ResizablePanelGroup {
}))
.child({
canvas(
move |bounds, cx| view.update(cx, |r, _| r.bounds = bounds),
|_, _, _| {},
move |bounds, _, cx| view.update(cx, |r, _| r.bounds = bounds),
|_, _, _, _| {},
)
.absolute()
.size_full()
})
.child(ResizePanelGroupElement {
view: cx.view().clone(),
view: cx.model().clone(),
axis: self.axis,
})
}
}
type ContentBuilder = Option<Rc<dyn Fn(&mut WindowContext) -> AnyElement>>;
type ContentBuilder = Option<Rc<dyn Fn(&mut Window, &mut App) -> AnyElement>>;
pub struct ResizablePanel {
group: Option<WeakView<ResizablePanelGroup>>,
group: Option<WeakEntity<ResizablePanelGroup>>,
/// Initial size is the size that the panel has when it is created.
initial_size: Option<Pixels>,
/// size is the size that the panel has when it is resized or adjusted by flex layout.
@@ -308,7 +342,7 @@ impl ResizablePanel {
pub fn content<F>(mut self, content: F) -> Self
where
F: Fn(&mut WindowContext) -> AnyElement + 'static,
F: Fn(&mut Window, &mut App) -> AnyElement + 'static,
{
self.content_builder = Some(Rc::new(content));
self
@@ -326,12 +360,17 @@ impl ResizablePanel {
}
/// Save the real panel size, and update group sizes
fn update_size(&mut self, bounds: Bounds<Pixels>, cx: &mut ViewContext<Self>) {
fn update_size(
&mut self,
bounds: Bounds<Pixels>,
_window: &mut Window,
cx: &mut Context<Self>,
) {
let new_size = bounds.size.along(self.axis);
self.bounds = bounds;
self.size = Some(new_size);
let panel_view = cx.view().clone();
let panel_view = cx.model().clone();
if let Some(group) = self.group.as_ref() {
_ = group.update(cx, |view, _| {
if let Some(ix) = view
@@ -350,8 +389,8 @@ impl ResizablePanel {
impl FluentBuilder for ResizablePanel {}
impl Render for ResizablePanel {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let view = cx.view().clone();
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let view = cx.model().clone();
let total_size = self
.group
.as_ref()
@@ -388,13 +427,17 @@ impl Render for ResizablePanel {
})
.child({
canvas(
move |bounds, cx| view.update(cx, |r, cx| r.update_size(bounds, cx)),
|_, _, _| {},
move |bounds, window, cx| {
view.update(cx, |r, cx| r.update_size(bounds, window, cx))
},
|_, _, _, _| {},
)
.absolute()
.size_full()
})
.when_some(self.content_builder.clone(), |this, c| this.child(c(cx)))
.when_some(self.content_builder.clone(), |this, c| {
this.child(c(window, cx))
})
.when_some(self.content_view.clone(), |this, c| this.child(c))
.when_some(self.resize_handle.take(), |this, c| this.child(c))
}
@@ -402,7 +445,7 @@ impl Render for ResizablePanel {
struct ResizePanelGroupElement {
axis: Axis,
view: View<ResizablePanelGroup>,
view: Entity<ResizablePanelGroup>,
}
impl IntoElement for ResizePanelGroupElement {
@@ -424,9 +467,10 @@ impl Element for ResizePanelGroupElement {
fn request_layout(
&mut self,
_: Option<&gpui::GlobalElementId>,
cx: &mut WindowContext,
window: &mut Window,
cx: &mut App,
) -> (gpui::LayoutId, Self::RequestLayoutState) {
(cx.request_layout(Style::default(), None), ())
(window.request_layout(Style::default(), None, cx), ())
}
fn prepaint(
@@ -434,7 +478,8 @@ impl Element for ResizePanelGroupElement {
_: Option<&gpui::GlobalElementId>,
_: Bounds<Pixels>,
_: &mut Self::RequestLayoutState,
_: &mut WindowContext,
_window: &mut Window,
_cx: &mut App,
) -> Self::PrepaintState {
}
@@ -444,13 +489,14 @@ impl Element for ResizePanelGroupElement {
_: Bounds<Pixels>,
_: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState,
cx: &mut WindowContext,
window: &mut Window,
cx: &mut App,
) {
cx.on_mouse_event({
window.on_mouse_event({
let view = self.view.clone();
let axis = self.axis;
let current_ix = view.read(cx).resizing_panel_ix;
move |e: &MouseMoveEvent, phase, cx| {
move |e: &MouseMoveEvent, phase, window, cx| {
if phase.bubble() {
if let Some(ix) = current_ix {
view.update(cx, |view, cx| {
@@ -461,11 +507,19 @@ impl Element for ResizePanelGroupElement {
.read(cx);
match axis {
Axis::Horizontal => {
view.resize_panels(ix, e.position.x - panel.bounds.left(), cx)
}
Axis::Horizontal => view.resize_panels(
ix,
e.position.x - panel.bounds.left(),
window,
cx,
),
Axis::Vertical => {
view.resize_panels(ix, e.position.y - panel.bounds.top(), cx);
view.resize_panels(
ix,
e.position.y - panel.bounds.top(),
window,
cx,
);
}
}
})
@@ -475,11 +529,11 @@ impl Element for ResizePanelGroupElement {
});
// When any mouse up, stop dragging
cx.on_mouse_event({
window.on_mouse_event({
let view = self.view.clone();
move |_: &MouseUpEvent, phase, cx| {
move |_: &MouseUpEvent, phase, window, cx| {
if phase.bubble() {
view.update(cx, |view, cx| view.done_resizing(cx));
view.update(cx, |view, cx| view.done_resizing(window, cx));
}
}
})

View File

@@ -3,9 +3,9 @@ use crate::{
AxisExt as _,
};
use gpui::{
div, prelude::FluentBuilder as _, px, Axis, Div, ElementId, InteractiveElement, IntoElement,
ParentElement as _, Pixels, RenderOnce, Stateful, StatefulInteractiveElement, Styled as _,
WindowContext,
div, prelude::FluentBuilder as _, px, App, Axis, Div, ElementId, InteractiveElement,
IntoElement, ParentElement as _, Pixels, RenderOnce, Stateful, StatefulInteractiveElement,
Styled as _, Window,
};
pub(crate) const HANDLE_PADDING: Pixels = px(8.);
@@ -40,7 +40,7 @@ impl InteractiveElement for ResizeHandle {
impl StatefulInteractiveElement for ResizeHandle {}
impl RenderOnce for ResizeHandle {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
self.base
.occlude()
.absolute()