mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 06:10:06 -04:00
Smooth preview
This commit is contained in:
@@ -37,6 +37,10 @@ impl std::fmt::Debug for NodeId {
|
|||||||
pub struct Dock<Leaf> {
|
pub struct Dock<Leaf> {
|
||||||
pub root: NodeId,
|
pub root: NodeId,
|
||||||
pub nodes: Nodes<Leaf>,
|
pub nodes: Nodes<Leaf>,
|
||||||
|
|
||||||
|
/// Smoothed avaerage of preview
|
||||||
|
#[serde(skip)]
|
||||||
|
pub smoothed_preview_rect: Option<Rect>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Leaf> Default for Dock<Leaf> {
|
impl<Leaf> Default for Dock<Leaf> {
|
||||||
@@ -44,6 +48,7 @@ impl<Leaf> Default for Dock<Leaf> {
|
|||||||
Self {
|
Self {
|
||||||
root: Default::default(),
|
root: Default::default(),
|
||||||
nodes: Default::default(),
|
nodes: Default::default(),
|
||||||
|
smoothed_preview_rect: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +262,11 @@ pub trait Behavior<Leaf> {
|
|||||||
|
|
||||||
impl<Leaf> Dock<Leaf> {
|
impl<Leaf> Dock<Leaf> {
|
||||||
pub fn new(root: NodeId, nodes: Nodes<Leaf>) -> Self {
|
pub fn new(root: NodeId, nodes: Nodes<Leaf>) -> Self {
|
||||||
Self { root, nodes }
|
Self {
|
||||||
|
root,
|
||||||
|
nodes,
|
||||||
|
smoothed_preview_rect: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,6 +421,22 @@ impl<Leaf> Dock<Leaf> {
|
|||||||
self.root
|
self.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn smooth_preview_rect(&mut self, ctx: &egui::Context, new_rect: Rect) -> Rect {
|
||||||
|
let dt = ctx.input(|input| input.stable_dt).at_most(0.1);
|
||||||
|
let t = egui::emath::exponential_smooth_factor(0.9, 0.05, dt);
|
||||||
|
|
||||||
|
let smoothed = self.smoothed_preview_rect.get_or_insert(new_rect);
|
||||||
|
*smoothed = smoothed.lerp_towards(&new_rect, t);
|
||||||
|
|
||||||
|
let diff = smoothed.min.distance(new_rect.min) + smoothed.max.distance(new_rect.max);
|
||||||
|
if diff < 0.5 {
|
||||||
|
*smoothed = new_rect;
|
||||||
|
} else {
|
||||||
|
ctx.request_repaint();
|
||||||
|
}
|
||||||
|
*smoothed
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, behavior: &mut dyn Behavior<Leaf>, ui: &mut Ui) {
|
pub fn ui(&mut self, behavior: &mut dyn Behavior<Leaf>, ui: &mut Ui) {
|
||||||
let options = behavior.simplification_options();
|
let options = behavior.simplification_options();
|
||||||
self.simplify(&options);
|
self.simplify(&options);
|
||||||
@@ -462,11 +487,23 @@ impl<Leaf> Dock<Leaf> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Some(preview_rect) = drop_context.preview_rect {
|
if let Some(preview_rect) = drop_context.preview_rect {
|
||||||
|
let preview_rect = self.smooth_preview_rect(ui.ctx(), preview_rect);
|
||||||
|
|
||||||
|
let preview_stroke = ui.visuals().selection.stroke;
|
||||||
|
let preview_color = preview_stroke.color;
|
||||||
|
|
||||||
|
if let Some(insertion_point) = &drop_context.best_insertion {
|
||||||
|
if let Some(node) = self.nodes.nodes.get(&insertion_point.parent_id) {
|
||||||
|
// Show which parent we will be dropped into
|
||||||
|
ui.painter().rect_stroke(node.rect, 1.0, preview_stroke);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui.painter().rect(
|
ui.painter().rect(
|
||||||
preview_rect,
|
preview_rect,
|
||||||
1.0,
|
1.0,
|
||||||
Color32::LIGHT_BLUE.gamma_multiply(0.5),
|
preview_color.gamma_multiply(0.5),
|
||||||
(1.0, Color32::LIGHT_BLUE),
|
preview_stroke,
|
||||||
);
|
);
|
||||||
|
|
||||||
let preview_child = false;
|
let preview_child = false;
|
||||||
@@ -489,7 +526,10 @@ impl<Leaf> Dock<Leaf> {
|
|||||||
if let Some(insertion_point) = drop_context.best_insertion {
|
if let Some(insertion_point) = drop_context.best_insertion {
|
||||||
self.move_node(dragged_node_id, insertion_point);
|
self.move_node(dragged_node_id, insertion_point);
|
||||||
}
|
}
|
||||||
|
self.smoothed_preview_rect = None;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.smoothed_preview_rect = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,12 +761,14 @@ impl<Leaf> Nodes<Leaf> {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// ui
|
// ui
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
enum LayoutType {
|
enum LayoutType {
|
||||||
Tabs,
|
Tabs,
|
||||||
Horizontal,
|
Horizontal,
|
||||||
Vertical,
|
Vertical,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct InsertionPoint {
|
struct InsertionPoint {
|
||||||
parent_id: NodeId,
|
parent_id: NodeId,
|
||||||
|
|
||||||
@@ -951,7 +993,7 @@ impl<Leaf> Nodes<Leaf> {
|
|||||||
let rect = self.nodes[&child].rect;
|
let rect = self.nodes[&child].rect;
|
||||||
|
|
||||||
if is_being_dragged(ui.ctx(), child) {
|
if is_being_dragged(ui.ctx(), child) {
|
||||||
// suggest self as drop-target:
|
// Leave a hole, and suggest that hole as drop-target:
|
||||||
drop_context.suggest_rect(
|
drop_context.suggest_rect(
|
||||||
InsertionPoint::new(parent_id, LayoutType::Horizontal, i),
|
InsertionPoint::new(parent_id, LayoutType::Horizontal, i),
|
||||||
rect,
|
rect,
|
||||||
|
|||||||
@@ -361,13 +361,28 @@ impl Rect {
|
|||||||
|
|
||||||
/// Linearly interpolate so that `[0, 0]` is [`Self::min`] and
|
/// Linearly interpolate so that `[0, 0]` is [`Self::min`] and
|
||||||
/// `[1, 1]` is [`Self::max`].
|
/// `[1, 1]` is [`Self::max`].
|
||||||
|
#[deprecated = "Use `lerp_inside` instead"]
|
||||||
pub fn lerp(&self, t: Vec2) -> Pos2 {
|
pub fn lerp(&self, t: Vec2) -> Pos2 {
|
||||||
|
self.lerp_inside(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Linearly interpolate so that `[0, 0]` is [`Self::min`] and
|
||||||
|
/// `[1, 1]` is [`Self::max`].
|
||||||
|
pub fn lerp_inside(&self, t: Vec2) -> Pos2 {
|
||||||
Pos2 {
|
Pos2 {
|
||||||
x: lerp(self.min.x..=self.max.x, t.x),
|
x: lerp(self.min.x..=self.max.x, t.x),
|
||||||
y: lerp(self.min.y..=self.max.y, t.y),
|
y: lerp(self.min.y..=self.max.y, t.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Linearly self towards other rect.
|
||||||
|
pub fn lerp_towards(&self, other: &Rect, t: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
min: self.min.lerp(other.min, t),
|
||||||
|
max: self.max.lerp(other.max, t),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn x_range(&self) -> RangeInclusive<f32> {
|
pub fn x_range(&self) -> RangeInclusive<f32> {
|
||||||
self.min.x..=self.max.x
|
self.min.x..=self.max.x
|
||||||
|
|||||||
Reference in New Issue
Block a user