mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 07:03:14 -04:00
Code cleanup
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
use egui::{vec2, Color32, Id, Response, Rgba, Sense, Stroke, TextStyle, Ui, Visuals, WidgetText};
|
||||
use egui::{
|
||||
vec2, Color32, Id, Rect, Response, Rgba, Sense, Stroke, TextStyle, Ui, Visuals, WidgetText,
|
||||
};
|
||||
|
||||
use super::{Node, NodeId, Nodes, ResizeState, SimplificationOptions, UiResponse};
|
||||
|
||||
@@ -7,14 +9,22 @@ pub trait Behavior<Leaf> {
|
||||
/// Show this leaf node in the given [`egui::Ui`].
|
||||
///
|
||||
/// If this is an unknown node, return [`NodeAction::Remove`] and the node will be removed.
|
||||
///
|
||||
/// You can make the leaf draggable by returning [`UiResponse::DragStarted`]
|
||||
/// when the user drags some handle.
|
||||
fn leaf_ui(&mut self, _ui: &mut Ui, _node_id: NodeId, _leaf: &mut Leaf) -> UiResponse;
|
||||
|
||||
fn tab_text_for_leaf(&mut self, leaf: &Leaf) -> WidgetText;
|
||||
/// The title of a leaf tab.
|
||||
fn tab_title_for_leaf(&mut self, leaf: &Leaf) -> WidgetText;
|
||||
|
||||
fn tab_text_for_node(&mut self, nodes: &Nodes<Leaf>, node_id: NodeId) -> WidgetText {
|
||||
/// The title of a general tab.
|
||||
///
|
||||
/// The default implementation uses the name of the layout for branches, and
|
||||
/// calls [`Self::tab_text_for_leaf`] for leaves.
|
||||
fn tab_title_for_node(&mut self, nodes: &Nodes<Leaf>, node_id: NodeId) -> WidgetText {
|
||||
if let Some(node) = nodes.nodes.get(&node_id) {
|
||||
match node {
|
||||
Node::Leaf(leaf) => self.tab_text_for_leaf(leaf),
|
||||
Node::Leaf(leaf) => self.tab_title_for_leaf(leaf),
|
||||
Node::Branch(branch) => format!("{:?}", branch.get_layout()).into(),
|
||||
}
|
||||
} else {
|
||||
@@ -23,6 +33,8 @@ pub trait Behavior<Leaf> {
|
||||
}
|
||||
|
||||
/// Show the title of a tab as a button.
|
||||
///
|
||||
/// You can override the default implementation to add e.g. a close button.
|
||||
fn tab_ui(
|
||||
&mut self,
|
||||
nodes: &Nodes<Leaf>,
|
||||
@@ -32,7 +44,7 @@ pub trait Behavior<Leaf> {
|
||||
active: bool,
|
||||
is_being_dragged: bool,
|
||||
) -> Response {
|
||||
let text = self.tab_text_for_node(nodes, node_id);
|
||||
let text = self.tab_title_for_node(nodes, node_id);
|
||||
let font_id = TextStyle::Button.resolve(ui.style());
|
||||
let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
|
||||
|
||||
@@ -45,8 +57,8 @@ pub trait Behavior<Leaf> {
|
||||
|
||||
// Show a gap when dragged
|
||||
if ui.is_rect_visible(rect) && !is_being_dragged {
|
||||
let bg_color = self.tab_bg_color(ui.visuals(), active);
|
||||
let stroke = self.tab_outline_stroke(ui.visuals(), active);
|
||||
let bg_color = self.tab_bg_color(ui.visuals(), node_id, active);
|
||||
let stroke = self.tab_outline_stroke(ui.visuals(), node_id, active);
|
||||
ui.painter().rect(rect.shrink(0.5), 0.0, bg_color, stroke);
|
||||
|
||||
if active {
|
||||
@@ -58,7 +70,7 @@ pub trait Behavior<Leaf> {
|
||||
);
|
||||
}
|
||||
|
||||
let text_color = self.tab_text_color(ui.visuals(), active);
|
||||
let text_color = self.tab_text_color(ui.visuals(), node_id, active);
|
||||
ui.painter().galley_with_color(
|
||||
egui::Align2::CENTER_CENTER
|
||||
.align_size_within_rect(galley.size(), rect)
|
||||
@@ -76,7 +88,7 @@ pub trait Behavior<Leaf> {
|
||||
true
|
||||
}
|
||||
|
||||
/// Adds some UI to the top right of the tab bar.
|
||||
/// Adds some UI to the top right of each tab bar.
|
||||
///
|
||||
/// You can use this to, for instance, add a button for adding new tabs.
|
||||
///
|
||||
@@ -89,7 +101,7 @@ pub trait Behavior<Leaf> {
|
||||
// --------
|
||||
// Settings:
|
||||
|
||||
/// The height of the bar holding tab names.
|
||||
/// The height of the bar holding tab titles.
|
||||
fn tab_bar_height(&self, _style: &egui::Style) -> f32 {
|
||||
24.0
|
||||
}
|
||||
@@ -100,15 +112,17 @@ pub trait Behavior<Leaf> {
|
||||
1.0
|
||||
}
|
||||
|
||||
// No child should shrink below this size
|
||||
/// No child should shrink below this width nor height.
|
||||
fn min_size(&self) -> f32 {
|
||||
32.0
|
||||
}
|
||||
|
||||
/// What are the rules for simplifying the tree?
|
||||
fn simplification_options(&self) -> SimplificationOptions {
|
||||
SimplificationOptions::default()
|
||||
}
|
||||
|
||||
/// The stroke used for the lines in horizontal, vertical, and grid layouts.
|
||||
fn resize_stroke(&self, style: &egui::Style, resize_state: ResizeState) -> egui::Stroke {
|
||||
match resize_state {
|
||||
ResizeState::Idle => egui::Stroke::NONE, // Let the gap speak for itself
|
||||
@@ -122,7 +136,7 @@ pub trait Behavior<Leaf> {
|
||||
8.0
|
||||
}
|
||||
|
||||
/// The background color of the tab bar
|
||||
/// The background color of the tab bar.
|
||||
fn tab_bar_color(&self, visuals: &Visuals) -> Color32 {
|
||||
if visuals.dark_mode {
|
||||
Color32::BLACK
|
||||
@@ -131,7 +145,8 @@ pub trait Behavior<Leaf> {
|
||||
}
|
||||
}
|
||||
|
||||
fn tab_bg_color(&self, visuals: &Visuals, active: bool) -> Color32 {
|
||||
/// The background color of a tab.
|
||||
fn tab_bg_color(&self, visuals: &Visuals, _node_id: NodeId, active: bool) -> Color32 {
|
||||
if active {
|
||||
visuals.window_fill() // same as the tab contents
|
||||
} else {
|
||||
@@ -140,7 +155,7 @@ pub trait Behavior<Leaf> {
|
||||
}
|
||||
|
||||
/// Stroke of the outline around a tab title.
|
||||
fn tab_outline_stroke(&self, visuals: &Visuals, active: bool) -> Stroke {
|
||||
fn tab_outline_stroke(&self, visuals: &Visuals, _node_id: NodeId, active: bool) -> Stroke {
|
||||
if active {
|
||||
Stroke::new(1.0, visuals.widgets.active.bg_fill)
|
||||
} else {
|
||||
@@ -153,11 +168,42 @@ pub trait Behavior<Leaf> {
|
||||
Stroke::new(1.0, visuals.widgets.noninteractive.bg_stroke.color)
|
||||
}
|
||||
|
||||
fn tab_text_color(&self, visuals: &Visuals, active: bool) -> Color32 {
|
||||
/// The color of the title text of the tab.
|
||||
fn tab_text_color(&self, visuals: &Visuals, _node_id: NodeId, active: bool) -> Color32 {
|
||||
if active {
|
||||
visuals.widgets.active.text_color()
|
||||
} else {
|
||||
visuals.widgets.noninteractive.text_color()
|
||||
}
|
||||
}
|
||||
|
||||
/// When drag-and-dropping a node, how do we preview what is about to happen?
|
||||
fn paint_drag_preview(
|
||||
&self,
|
||||
visuals: &Visuals,
|
||||
painter: &egui::Painter,
|
||||
parent_rect: Option<Rect>,
|
||||
preview_rect: Rect,
|
||||
) {
|
||||
let preview_stroke = visuals.selection.stroke;
|
||||
let preview_color = preview_stroke.color;
|
||||
|
||||
if let Some(parent_rect) = parent_rect {
|
||||
// Show which parent we will be dropped into
|
||||
painter.rect_stroke(parent_rect, 1.0, preview_stroke);
|
||||
}
|
||||
|
||||
painter.rect(
|
||||
preview_rect,
|
||||
1.0,
|
||||
preview_color.gamma_multiply(0.5),
|
||||
preview_stroke,
|
||||
);
|
||||
}
|
||||
|
||||
/// Show we preview leaves that are being dragged,
|
||||
/// i.e. show their ui in the region where they will end up?
|
||||
fn preview_dragged_leaves(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +68,6 @@ impl<Leaf: std::fmt::Debug> std::fmt::Debug for Dock<Leaf> {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Construction
|
||||
|
||||
impl<Leaf> Dock<Leaf> {
|
||||
pub fn new(root: NodeId, nodes: Nodes<Leaf>) -> Self {
|
||||
Self {
|
||||
@@ -79,6 +77,10 @@ impl<Leaf> Dock<Leaf> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn root(&self) -> NodeId {
|
||||
self.root
|
||||
}
|
||||
|
||||
pub fn parent_of(&self, node_id: NodeId) -> Option<NodeId> {
|
||||
self.nodes
|
||||
.nodes
|
||||
@@ -92,15 +94,10 @@ impl<Leaf> Dock<Leaf> {
|
||||
})
|
||||
.map(|(id, _)| *id)
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
impl<Leaf> Dock<Leaf> {
|
||||
pub fn root(&self) -> NodeId {
|
||||
self.root
|
||||
}
|
||||
|
||||
/// Show all the leaves in the dock.
|
||||
/// Show the dock in the given [`Ui`].
|
||||
///
|
||||
/// The dock will use upp all the avilable space - nothing more, nothing less.
|
||||
pub fn ui(&mut self, behavior: &mut dyn Behavior<Leaf>, ui: &mut Ui) {
|
||||
let options = behavior.simplification_options();
|
||||
self.simplify(&options);
|
||||
@@ -133,6 +130,15 @@ impl<Leaf> Dock<Leaf> {
|
||||
self.nodes
|
||||
.node_ui(behavior, &mut drop_context, ui, self.root);
|
||||
|
||||
self.preview_dragged_node(behavior, &drop_context, ui);
|
||||
}
|
||||
|
||||
fn preview_dragged_node(
|
||||
&mut self,
|
||||
behavior: &mut dyn Behavior<Leaf>,
|
||||
drop_context: &DropContext,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
if let (Some(mouse_pos), Some(dragged_node_id)) =
|
||||
(drop_context.mouse_pos, drop_context.dragged_node_id)
|
||||
{
|
||||
@@ -147,8 +153,8 @@ impl<Leaf> Dock<Leaf> {
|
||||
let mut frame = egui::Frame::popup(ui.style());
|
||||
frame.fill = frame.fill.gamma_multiply(0.5); // Make see-through
|
||||
frame.show(ui, |ui| {
|
||||
// TODO: preview contents
|
||||
let text = behavior.tab_text_for_node(&self.nodes, dragged_node_id);
|
||||
// TODO(emilk): preview contents?
|
||||
let text = behavior.tab_title_for_node(&self.nodes, dragged_node_id);
|
||||
ui.label(text);
|
||||
});
|
||||
});
|
||||
@@ -156,26 +162,14 @@ impl<Leaf> Dock<Leaf> {
|
||||
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;
|
||||
let parent_rect = drop_context
|
||||
.best_insertion
|
||||
.and_then(|insertion_point| self.nodes.try_rect(insertion_point.parent_id));
|
||||
|
||||
if let Some(insertion_point) = &drop_context.best_insertion {
|
||||
if let Some(parent_rect) = self.nodes.try_rect(insertion_point.parent_id) {
|
||||
// Show which parent we will be dropped into
|
||||
ui.painter().rect_stroke(parent_rect, 1.0, preview_stroke);
|
||||
}
|
||||
}
|
||||
behavior.paint_drag_preview(ui.visuals(), ui.painter(), parent_rect, preview_rect);
|
||||
|
||||
ui.painter().rect(
|
||||
preview_rect,
|
||||
1.0,
|
||||
preview_color.gamma_multiply(0.5),
|
||||
preview_stroke,
|
||||
);
|
||||
|
||||
let preview_child = false;
|
||||
if preview_child {
|
||||
// Preview actual child?
|
||||
if behavior.preview_dragged_leaves() {
|
||||
// TODO(emilk): add support for previewing branches too.
|
||||
if preview_rect.width() > 32.0 && preview_rect.height() > 32.0 {
|
||||
if let Some(Node::Leaf(leaf)) = self.nodes.get_mut(dragged_node_id) {
|
||||
let _ = behavior.leaf_ui(
|
||||
@@ -200,6 +194,7 @@ impl<Leaf> Dock<Leaf> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Take the preview rectangle and smooth it over time.
|
||||
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);
|
||||
@@ -228,7 +223,8 @@ impl<Leaf> Dock<Leaf> {
|
||||
}
|
||||
}
|
||||
|
||||
fn move_node(&mut self, moved_node_id: NodeId, insertion_point: InsertionPoint) {
|
||||
/// Move the given node to the given insertion point.
|
||||
pub fn move_node(&mut self, moved_node_id: NodeId, insertion_point: InsertionPoint) {
|
||||
log::debug!(
|
||||
"Moving {moved_node_id:?} into {:?}",
|
||||
insertion_point.insertion
|
||||
@@ -238,7 +234,7 @@ impl<Leaf> Dock<Leaf> {
|
||||
}
|
||||
|
||||
/// Find the currently dragged node, if any.
|
||||
fn dragged_id(&self, ctx: &egui::Context) -> Option<NodeId> {
|
||||
pub fn dragged_id(&self, ctx: &egui::Context) -> Option<NodeId> {
|
||||
if !is_possible_drag(ctx) {
|
||||
// We're not sure we're dragging _at all_ yet.
|
||||
return None;
|
||||
@@ -246,7 +242,7 @@ impl<Leaf> Dock<Leaf> {
|
||||
|
||||
for &node_id in self.nodes.nodes.keys() {
|
||||
if node_id == self.root {
|
||||
continue; // now allowed to drag root
|
||||
continue; // not allowed to drag root
|
||||
}
|
||||
|
||||
let id = node_id.id();
|
||||
@@ -264,9 +260,12 @@ impl<Leaf> Dock<Leaf> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Performs no simplifcations!
|
||||
fn remove_node_id_from_parent(&mut self, dragged_node_id: NodeId) {
|
||||
self.nodes
|
||||
.remove_node_id_from_parent(self.root, dragged_node_id);
|
||||
/// Performs no simplifcations, nor does it remove the actual [`Node`].
|
||||
pub fn remove_node_id_from_parent(&mut self, remove_me: NodeId) {
|
||||
for parent in self.nodes.nodes.values_mut() {
|
||||
if let Node::Branch(branch) = parent {
|
||||
branch.retain(|child| child != remove_me);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,21 +16,36 @@
|
||||
//! The user needs to implement this in order to specify the `ui` of each `Leaf` and
|
||||
//! the tab name of leaves (if there are tab nodes).
|
||||
//!
|
||||
//! ## Implementation notes
|
||||
//! In many places we want to recursively visit all noted, while also mutating them.
|
||||
//! In order to not get into trouble with the borrow checker a trick is used:
|
||||
//! each [`Node`] is removed, mutated, recursed, and then re-added.
|
||||
//! You'll see this pattern many times reading the following code.
|
||||
//!
|
||||
//! ## Shortcomings
|
||||
//! We use real recursion, so if your trees get too deep you will get a stack overflow.
|
||||
//!
|
||||
//!
|
||||
//! ## Future improvements
|
||||
//! * A new ui for each node, nested
|
||||
//! * Per-tab close-buttons
|
||||
//! * Easy per-tab close-buttons
|
||||
//! * Scrolling of tab-bar
|
||||
//! * Vertical tab bar
|
||||
//! * Auto-grid layouts (re-arange as parent is resized)
|
||||
//! * Auto-join nested horizontal/vertical layouts in the simplify step
|
||||
|
||||
// ## Implementation notes
|
||||
// In many places we want to recursively visit all noted, while also mutating them.
|
||||
// In order to not get into trouble with the borrow checker a trick is used:
|
||||
// each [`Node`] is removed, mutated, recursed, and then re-added.
|
||||
// You'll see this pattern many times reading the following code.
|
||||
//
|
||||
// Each frame consists of two passes: layout, and ui.
|
||||
// The layout pass figures out where each node should be placed.
|
||||
// The ui pass does all the painting.
|
||||
// These two passes could be combined into one pass if we wanted to,
|
||||
// but having them split up makes the code slightly simpler, and
|
||||
// leaves the door open for more complex layout (e.g. min/max sizes per node).
|
||||
//
|
||||
// Everything is quite dynamic, so we have a bunch of defensive coding that call `warn!` on failure.
|
||||
// These situations should not happen in normal use, but could happen if the user messes with
|
||||
// the internals of the tree, putting it in an invalid state.
|
||||
//
|
||||
// ## TODO before release:
|
||||
// * Auto-grid layouts (re-arange as parent is resized)
|
||||
// * Clip tab titles to not cover "add new tab" button
|
||||
|
||||
use egui::{Id, Pos2, Rect};
|
||||
|
||||
@@ -96,6 +111,7 @@ pub enum UiResponse {
|
||||
DragStarted,
|
||||
}
|
||||
|
||||
/// What are the rules for simplifying the tree?
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct SimplificationOptions {
|
||||
pub prune_empty_tabs: bool,
|
||||
@@ -143,7 +159,7 @@ pub struct InsertionPoint {
|
||||
}
|
||||
|
||||
impl InsertionPoint {
|
||||
fn new(parent_id: NodeId, insertion: LayoutInsertion) -> Self {
|
||||
pub fn new(parent_id: NodeId, insertion: LayoutInsertion) -> Self {
|
||||
Self {
|
||||
parent_id,
|
||||
insertion,
|
||||
@@ -185,7 +201,14 @@ struct DropContext {
|
||||
}
|
||||
|
||||
impl DropContext {
|
||||
fn on_node<Leaf>(&mut self, parent_id: NodeId, rect: Rect, node: &Node<Leaf>) {
|
||||
fn on_node<Leaf>(
|
||||
&mut self,
|
||||
behavior: &mut dyn Behavior<Leaf>,
|
||||
style: &egui::Style,
|
||||
parent_id: NodeId,
|
||||
rect: Rect,
|
||||
node: &Node<Leaf>,
|
||||
) {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
@@ -212,17 +235,18 @@ impl DropContext {
|
||||
);
|
||||
}
|
||||
|
||||
// self.suggest_rect(InsertionPoint::new(parent_id, LayoutType::Tabs, 1), rect);
|
||||
self.suggest_rect(
|
||||
InsertionPoint::new(parent_id, LayoutInsertion::Tabs(usize::MAX)),
|
||||
rect.split_top_bottom_at_y(rect.top() + behavior.tab_bar_height(style))
|
||||
.1,
|
||||
);
|
||||
}
|
||||
|
||||
fn suggest_rect(&mut self, insertion: InsertionPoint, preview_rect: Rect) {
|
||||
self.suggest_point(insertion, preview_rect.center(), preview_rect);
|
||||
}
|
||||
|
||||
fn suggest_point(&mut self, insertion: InsertionPoint, target_point: Pos2, preview_rect: Rect) {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
let target_point = preview_rect.center();
|
||||
if let Some(mouse_pos) = self.mouse_pos {
|
||||
let dist_sq = mouse_pos.distance_sq(target_point);
|
||||
if dist_sq < self.best_dist_sq {
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct Nodes<Leaf> {
|
||||
|
||||
/// Filled in by the layout step at the start of each frame.
|
||||
#[serde(default, skip)]
|
||||
pub rects: HashMap<NodeId, Rect>,
|
||||
pub(super) rects: HashMap<NodeId, Rect>,
|
||||
}
|
||||
|
||||
impl<Leaf> Default for Nodes<Leaf> {
|
||||
@@ -29,11 +29,11 @@ impl<Leaf> Default for Nodes<Leaf> {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
impl<Leaf> Nodes<Leaf> {
|
||||
pub fn try_rect(&self, node_id: NodeId) -> Option<Rect> {
|
||||
pub(super) fn try_rect(&self, node_id: NodeId) -> Option<Rect> {
|
||||
self.rects.get(&node_id).copied()
|
||||
}
|
||||
|
||||
pub fn rect(&self, node_id: NodeId) -> Rect {
|
||||
pub(super) fn rect(&self, node_id: NodeId) -> Rect {
|
||||
let rect = self.try_rect(node_id);
|
||||
debug_assert!(rect.is_some(), "Failed to find rect for {node_id:?}");
|
||||
rect.unwrap_or(egui::Rect::from_min_max(Pos2::ZERO, Pos2::ZERO))
|
||||
@@ -90,23 +90,6 @@ impl<Leaf> Nodes<Leaf> {
|
||||
self.insert_node(Node::Branch(Branch::new_grid(children)))
|
||||
}
|
||||
|
||||
/// Performs no simplifcations!
|
||||
/// // TODO: remove ?
|
||||
pub(super) fn remove_node_id_from_parent(&mut self, it: NodeId, remove: NodeId) -> GcAction {
|
||||
if it == remove {
|
||||
return GcAction::Remove;
|
||||
}
|
||||
let Some(mut node) = self.nodes.remove(&it) else {
|
||||
log::warn!("Unexpected missing node during removal");
|
||||
return GcAction::Remove;
|
||||
};
|
||||
if let Node::Branch(branch) = &mut node {
|
||||
branch.retain(|child| self.remove_node_id_from_parent(child, remove) == GcAction::Keep);
|
||||
}
|
||||
self.nodes.insert(it, node);
|
||||
GcAction::Keep
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, insertion_point: InsertionPoint, child_id: NodeId) {
|
||||
let InsertionPoint {
|
||||
parent_id,
|
||||
@@ -257,7 +240,7 @@ impl<Leaf> Nodes<Leaf> {
|
||||
ui: &mut Ui,
|
||||
node_id: NodeId,
|
||||
) {
|
||||
// NOTE: important that we get thr rect and node in two steps,
|
||||
// NOTE: important that we get the rect and node in two steps,
|
||||
// otherwise we could loose the node when there is no rect.
|
||||
let Some(rect) = self.try_rect(node_id) else {
|
||||
log::warn!("Failed to find rect for node {node_id:?} during ui");
|
||||
@@ -273,14 +256,9 @@ impl<Leaf> Nodes<Leaf> {
|
||||
// Can't drag a node onto self or any children
|
||||
drop_context.enabled = false;
|
||||
}
|
||||
drop_context.on_node(node_id, rect, &node);
|
||||
|
||||
drop_context.suggest_rect(
|
||||
InsertionPoint::new(node_id, LayoutInsertion::Tabs(usize::MAX)),
|
||||
rect.split_top_bottom_at_y(rect.top() + behavior.tab_bar_height(ui.style()))
|
||||
.1,
|
||||
);
|
||||
drop_context.on_node(behavior, ui.style(), node_id, rect, &node);
|
||||
|
||||
// Each node gets its own `Ui`, nested inside each other, with proper clip rectangles.
|
||||
let mut ui = egui::Ui::new(
|
||||
ui.ctx().clone(),
|
||||
ui.layer_id(),
|
||||
@@ -314,7 +292,7 @@ impl<Leaf> Nodes<Leaf> {
|
||||
};
|
||||
|
||||
if let Node::Branch(branch) = &mut node {
|
||||
// TODO: join nested versions of the same horizontal/vertical layouts
|
||||
// TODO(emilk): join nested versions of the same horizontal/vertical layouts
|
||||
|
||||
branch.simplify_children(|child| self.simplify(options, child));
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ impl dock::Behavior<View> for DockBehavior {
|
||||
view.ui(ui)
|
||||
}
|
||||
|
||||
fn tab_text_for_leaf(&mut self, view: &View) -> egui::WidgetText {
|
||||
fn tab_title_for_leaf(&mut self, view: &View) -> egui::WidgetText {
|
||||
format!("View {}", view.nr).into()
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ fn tree_ui(
|
||||
// Get the name BEFORE we remove the node below!
|
||||
let text = format!(
|
||||
"{} - {node_id:?}",
|
||||
behavior.tab_text_for_node(nodes, node_id).text()
|
||||
behavior.tab_title_for_node(nodes, node_id).text()
|
||||
);
|
||||
|
||||
let Some(mut node) = nodes.nodes.remove(&node_id) else {
|
||||
|
||||
Reference in New Issue
Block a user