Started to make the dock better, major issue's resizing child elements
This commit is contained in:
parent
f2b72eb6d2
commit
31a3fdb23e
2 changed files with 53 additions and 67 deletions
|
@ -1,14 +1,14 @@
|
||||||
use std::{cell::Cell, rc::Rc};
|
use std::{cell::Cell, rc::Rc};
|
||||||
|
|
||||||
use pathfinder_geometry::vector::Vector2F;
|
use pathfinder_geometry::vector::{vec2f, Vector2F};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
color::Color, scene::DragRegionEvent, Axis, Border, CursorStyle, Element, ElementBox,
|
geometry::rect::RectF, scene::DragRegionEvent, Axis, CursorStyle, Element, ElementBox,
|
||||||
ElementStateHandle, MouseButton, RenderContext, View, MouseRegion,
|
ElementStateHandle, MouseButton, MouseRegion, RenderContext, View,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{ConstrainedBox, Empty, Flex, Hook, MouseEventHandler, Padding, ParentElement};
|
use super::{ConstrainedBox, Flex, Hook, ParentElement};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum Side {
|
pub enum Side {
|
||||||
|
@ -35,13 +35,6 @@ impl Side {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize_padding(&self, padding_size: f32) -> Padding {
|
|
||||||
match self.axis() {
|
|
||||||
Axis::Horizontal => Padding::horizontal(padding_size),
|
|
||||||
Axis::Vertical => Padding::vertical(padding_size),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relevant_component(&self, vector: Vector2F) -> f32 {
|
fn relevant_component(&self, vector: Vector2F) -> f32 {
|
||||||
match self.axis() {
|
match self.axis() {
|
||||||
Axis::Horizontal => vector.x(),
|
Axis::Horizontal => vector.x(),
|
||||||
|
@ -56,6 +49,19 @@ impl Side {
|
||||||
self.relevant_component(e.position) - self.relevant_component(e.prev_mouse_position)
|
self.relevant_component(e.position) - self.relevant_component(e.prev_mouse_position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn of_rect(&self, bounds: RectF, handle_size: f32) -> RectF {
|
||||||
|
match self {
|
||||||
|
Side::Top => RectF::new(bounds.origin(), vec2f(bounds.width(), handle_size)),
|
||||||
|
Side::Bottom => RectF::new(bounds.lower_left(), vec2f(bounds.width(), handle_size)),
|
||||||
|
Side::Left => RectF::new(bounds.origin(), vec2f(handle_size, bounds.height())),
|
||||||
|
Side::Right => {
|
||||||
|
let mut origin = bounds.upper_right();
|
||||||
|
origin.set_x(origin.x() - handle_size);
|
||||||
|
RectF::new(origin, vec2f(handle_size, bounds.height()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResizeHandleState {
|
struct ResizeHandleState {
|
||||||
|
@ -65,6 +71,7 @@ struct ResizeHandleState {
|
||||||
|
|
||||||
pub struct Resizable {
|
pub struct Resizable {
|
||||||
side: Side,
|
side: Side,
|
||||||
|
handle_size: f32,
|
||||||
child: ElementBox,
|
child: ElementBox,
|
||||||
state: Rc<ResizeHandleState>,
|
state: Rc<ResizeHandleState>,
|
||||||
_state_handle: ElementStateHandle<Rc<ResizeHandleState>>,
|
_state_handle: ElementStateHandle<Rc<ResizeHandleState>>,
|
||||||
|
@ -91,11 +98,6 @@ impl Resizable {
|
||||||
|
|
||||||
let mut flex = Flex::new(side.axis());
|
let mut flex = Flex::new(side.axis());
|
||||||
|
|
||||||
if side.before_content() {
|
|
||||||
dbg!("HANDLE BEING RENDERED BEFORE");
|
|
||||||
flex.add_child(render_resize_handle(state.clone(), side, handle_size, cx))
|
|
||||||
}
|
|
||||||
|
|
||||||
flex.add_child(
|
flex.add_child(
|
||||||
Hook::new({
|
Hook::new({
|
||||||
let constrained = ConstrainedBox::new(child);
|
let constrained = ConstrainedBox::new(child);
|
||||||
|
@ -114,57 +116,18 @@ impl Resizable {
|
||||||
.boxed(),
|
.boxed(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if !side.before_content() {
|
|
||||||
dbg!("HANDLE BEING RENDERED AFTER");
|
|
||||||
flex.add_child(render_resize_handle(state.clone(), side, handle_size, cx))
|
|
||||||
}
|
|
||||||
|
|
||||||
let child = flex.boxed();
|
let child = flex.boxed();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
side,
|
side,
|
||||||
child,
|
child,
|
||||||
|
handle_size,
|
||||||
state,
|
state,
|
||||||
_state_handle: state_handle,
|
_state_handle: state_handle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_resize_handle<T: View>(
|
|
||||||
state: Rc<ResizeHandleState>,
|
|
||||||
side: Side,
|
|
||||||
padding_size: f32,
|
|
||||||
cx: &mut RenderContext<T>,
|
|
||||||
) -> ElementBox {
|
|
||||||
enum ResizeHandle {}
|
|
||||||
MouseEventHandler::<ResizeHandle>::new(side as usize, cx, |_, _| {
|
|
||||||
Empty::new()
|
|
||||||
// Border necessary to properly add a MouseRegion
|
|
||||||
.contained()
|
|
||||||
.with_border(Border {
|
|
||||||
width: 4.,
|
|
||||||
left: true,
|
|
||||||
color: Color::red(),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.boxed()
|
|
||||||
})
|
|
||||||
.with_padding(side.resize_padding(padding_size))
|
|
||||||
.with_cursor_style(match side.axis() {
|
|
||||||
Axis::Horizontal => CursorStyle::ResizeLeftRight,
|
|
||||||
Axis::Vertical => CursorStyle::ResizeUpDown,
|
|
||||||
})
|
|
||||||
.on_down(MouseButton::Left, |_, _| {}) // This prevents the mouse down event from being propagated elsewhere
|
|
||||||
.on_drag(MouseButton::Left, move |e, cx| {
|
|
||||||
let prev_width = state.actual_dimension.get();
|
|
||||||
state
|
|
||||||
.custom_dimension
|
|
||||||
.set(0f32.max(prev_width + side.compute_delta(e)).round());
|
|
||||||
cx.notify();
|
|
||||||
})
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Element for Resizable {
|
impl Element for Resizable {
|
||||||
type LayoutState = Vector2F;
|
type LayoutState = Vector2F;
|
||||||
type PaintState = ();
|
type PaintState = ();
|
||||||
|
@ -182,19 +145,42 @@ impl Element for Resizable {
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: pathfinder_geometry::rect::RectF,
|
bounds: pathfinder_geometry::rect::RectF,
|
||||||
visible_bounds: pathfinder_geometry::rect::RectF,
|
visible_bounds: pathfinder_geometry::rect::RectF,
|
||||||
child_size: &mut Self::LayoutState,
|
_child_size: &mut Self::LayoutState,
|
||||||
cx: &mut crate::PaintContext,
|
cx: &mut crate::PaintContext,
|
||||||
) -> Self::PaintState {
|
) -> Self::PaintState {
|
||||||
cx.scene.push_stacking_context(None);
|
cx.scene.push_stacking_context(None);
|
||||||
|
|
||||||
// Render a mouse region on the appropriate border (likely just bounds)
|
let handle_region = self.side.of_rect(bounds, self.handle_size);
|
||||||
// Use the padding in the above code to decide the size of the rect to pass to the mouse region
|
|
||||||
// Add handlers for Down and Drag like above
|
enum ResizeHandle {}
|
||||||
|
cx.scene.push_mouse_region(
|
||||||
// Maybe try pushing a quad to visually inspect where the region gets placed
|
MouseRegion::new::<ResizeHandle>(
|
||||||
// Push a cursor region
|
cx.current_view_id(),
|
||||||
cx.scene.push_mouse_region(MouseRegion::)
|
self.side as usize,
|
||||||
|
handle_region,
|
||||||
|
)
|
||||||
|
.on_down(MouseButton::Left, |_, _| {}) // This prevents the mouse down event from being propagated elsewhere
|
||||||
|
.on_drag(MouseButton::Left, {
|
||||||
|
let state = self.state.clone();
|
||||||
|
let side = self.side;
|
||||||
|
move |e, cx| {
|
||||||
|
let prev_width = state.actual_dimension.get();
|
||||||
|
state
|
||||||
|
.custom_dimension
|
||||||
|
.set(0f32.max(prev_width + side.compute_delta(e)).round());
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
cx.scene.push_cursor_region(crate::CursorRegion {
|
||||||
|
bounds: handle_region,
|
||||||
|
style: match self.side.axis() {
|
||||||
|
Axis::Horizontal => CursorStyle::ResizeLeftRight,
|
||||||
|
Axis::Vertical => CursorStyle::ResizeUpDown,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
cx.scene.pop_stacking_context();
|
cx.scene.pop_stacking_context();
|
||||||
|
|
||||||
self.child.paint(bounds.origin(), visible_bounds, cx);
|
self.child.paint(bounds.origin(), visible_bounds, cx);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::{ChildView, Container, Empty, FlexItem, Margin, MouseEventHandler, Side, Svg},
|
elements::{ChildView, Container, Empty, Margin, MouseEventHandler, Side, Svg},
|
||||||
impl_internal_actions, CursorStyle, Element, ElementBox, Entity, MouseButton,
|
impl_internal_actions, CursorStyle, Element, ElementBox, Entity, MouseButton,
|
||||||
MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle,
|
MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue