mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 07:03:14 -04:00
Improve dragging around tab labels
This commit is contained in:
@@ -122,7 +122,7 @@ impl Linear {
|
||||
}
|
||||
}
|
||||
|
||||
drop_zones(ui.ctx(), nodes, &self.children, self.dir, |rect, i| {
|
||||
linear_drop_zones(ui.ctx(), nodes, &self.children, self.dir, |rect, i| {
|
||||
drop_context.suggest_rect(
|
||||
InsertionPoint::new(parent_id, LayoutInsertion::Horizontal(i)),
|
||||
rect,
|
||||
@@ -185,7 +185,7 @@ impl Linear {
|
||||
}
|
||||
}
|
||||
|
||||
drop_zones(ui.ctx(), nodes, &self.children, self.dir, |rect, i| {
|
||||
linear_drop_zones(ui.ctx(), nodes, &self.children, self.dir, |rect, i| {
|
||||
drop_context.suggest_rect(
|
||||
InsertionPoint::new(parent_id, LayoutInsertion::Vertical(i)),
|
||||
rect,
|
||||
@@ -315,25 +315,18 @@ fn shrink_shares<Leaf>(
|
||||
total_shares_lost
|
||||
}
|
||||
|
||||
fn drop_zones<Leaf>(
|
||||
fn linear_drop_zones<Leaf>(
|
||||
egui_ctx: &egui::Context,
|
||||
nodes: &Nodes<Leaf>,
|
||||
children: &[NodeId],
|
||||
dir: LinearDir,
|
||||
mut add_drop_drect: impl FnMut(Rect, usize),
|
||||
add_drop_drect: impl FnMut(Rect, usize),
|
||||
) {
|
||||
let preview_thickness = 12.0;
|
||||
let dragged_index = children
|
||||
.iter()
|
||||
.position(|&child| is_being_dragged(egui_ctx, child));
|
||||
|
||||
let before_rect = |rect: Rect| match dir {
|
||||
LinearDir::Horizontal => Rect::from_min_max(
|
||||
rect.left_top(),
|
||||
rect.left_bottom() + vec2(preview_thickness, 0.0),
|
||||
),
|
||||
LinearDir::Vertical => Rect::from_min_max(
|
||||
rect.left_top(),
|
||||
rect.right_top() + vec2(0.0, preview_thickness),
|
||||
),
|
||||
};
|
||||
let afer_rect = |rect: Rect| match dir {
|
||||
LinearDir::Horizontal => Rect::from_min_max(
|
||||
rect.right_top() - vec2(preview_thickness, 0.0),
|
||||
@@ -344,6 +337,37 @@ fn drop_zones<Leaf>(
|
||||
rect.right_bottom(),
|
||||
),
|
||||
};
|
||||
|
||||
drop_zones(
|
||||
preview_thickness,
|
||||
children,
|
||||
dragged_index,
|
||||
dir,
|
||||
|node_id| nodes.rect(node_id),
|
||||
add_drop_drect,
|
||||
afer_rect,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn drop_zones(
|
||||
preview_thickness: f32,
|
||||
children: &[NodeId],
|
||||
dragged_index: Option<usize>,
|
||||
dir: LinearDir,
|
||||
get_rect: impl Fn(NodeId) -> Rect,
|
||||
mut add_drop_drect: impl FnMut(Rect, usize),
|
||||
afer_rect: impl Fn(Rect) -> Rect,
|
||||
) {
|
||||
let before_rect = |rect: Rect| match dir {
|
||||
LinearDir::Horizontal => Rect::from_min_max(
|
||||
rect.left_top(),
|
||||
rect.left_bottom() + vec2(preview_thickness, 0.0),
|
||||
),
|
||||
LinearDir::Vertical => Rect::from_min_max(
|
||||
rect.left_top(),
|
||||
rect.right_top() + vec2(0.0, preview_thickness),
|
||||
),
|
||||
};
|
||||
let between_rects = |a: Rect, b: Rect| match dir {
|
||||
LinearDir::Horizontal => Rect::from_center_size(
|
||||
a.right_center().lerp(b.left_center(), 0.5),
|
||||
@@ -355,15 +379,11 @@ fn drop_zones<Leaf>(
|
||||
),
|
||||
};
|
||||
|
||||
let dragged_index = children
|
||||
.iter()
|
||||
.position(|&child| is_being_dragged(egui_ctx, child));
|
||||
|
||||
let mut prev_rect: Option<Rect> = None;
|
||||
let mut insertion_index = 0; // skips over drag-source, if any, beacuse it will be removed before its re-inserted
|
||||
|
||||
for (i, &child) in children.iter().enumerate() {
|
||||
let rect = nodes.rect(child);
|
||||
let rect = get_rect(child);
|
||||
|
||||
if Some(i) == dragged_index {
|
||||
// Suggest hole as a drop-target:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use egui::{vec2, Rect};
|
||||
|
||||
use crate::dock::{
|
||||
@@ -54,8 +56,8 @@ impl Tabs {
|
||||
|
||||
// Show tab bar:
|
||||
tab_bar_ui.horizontal(|ui| {
|
||||
let mut prev_tab_rect: Option<Rect> = None;
|
||||
let mut insertion_index = 0; // skips over drag-source, if any, beacuse it will be removed then re-inserted
|
||||
let mut button_rects = HashMap::new();
|
||||
let mut dragged_index = None;
|
||||
|
||||
for (i, &child_id) in self.children.iter().enumerate() {
|
||||
let is_being_dragged = is_being_dragged(ui.ctx(), child_id);
|
||||
@@ -76,38 +78,37 @@ impl Tabs {
|
||||
}
|
||||
}
|
||||
|
||||
let rect = response.rect;
|
||||
|
||||
{
|
||||
// suggest dropping before this tab:
|
||||
let before_point = if let Some(prev_tab_rect) = prev_tab_rect {
|
||||
// between
|
||||
prev_tab_rect.right_center().lerp(rect.left_center(), 0.5)
|
||||
} else {
|
||||
// before first
|
||||
rect.left_center()
|
||||
};
|
||||
|
||||
drop_context.suggest_rect(
|
||||
InsertionPoint::new(node_id, LayoutInsertion::Tabs(insertion_index)),
|
||||
Rect::from_center_size(before_point, vec2(4.0, rect.height())),
|
||||
);
|
||||
}
|
||||
|
||||
if i + 1 == self.children.len() {
|
||||
// suggest dropping after last tab:
|
||||
drop_context.suggest_rect(
|
||||
InsertionPoint::new(node_id, LayoutInsertion::Tabs(insertion_index + 1)),
|
||||
Rect::from_center_size(rect.right_center(), vec2(4.0, rect.height())),
|
||||
);
|
||||
}
|
||||
|
||||
prev_tab_rect = Some(rect);
|
||||
|
||||
if !is_being_dragged {
|
||||
insertion_index += 1;
|
||||
button_rects.insert(child_id, response.rect);
|
||||
if is_being_dragged {
|
||||
dragged_index = Some(i);
|
||||
}
|
||||
}
|
||||
|
||||
let preview_thickness = 6.0;
|
||||
let afer_rect = |rect: Rect| {
|
||||
let dragged_size = if let Some(dragged_index) = dragged_index {
|
||||
// We actually know the size of this thing
|
||||
button_rects[&self.children[dragged_index]].size()
|
||||
} else {
|
||||
rect.size() // guess that the size is the same as the last button
|
||||
};
|
||||
Rect::from_min_size(
|
||||
rect.right_top() + vec2(ui.spacing().item_spacing.x, 0.0),
|
||||
dragged_size,
|
||||
)
|
||||
};
|
||||
super::linear::drop_zones(
|
||||
preview_thickness,
|
||||
&self.children,
|
||||
dragged_index,
|
||||
super::LinearDir::Horizontal,
|
||||
|node_id| button_rects[&node_id],
|
||||
|rect, i| {
|
||||
drop_context
|
||||
.suggest_rect(InsertionPoint::new(node_id, LayoutInsertion::Tabs(i)), rect);
|
||||
},
|
||||
afer_rect,
|
||||
);
|
||||
});
|
||||
|
||||
// When dragged, don't show it (it is "being held")
|
||||
|
||||
Reference in New Issue
Block a user