Skip to content

Commit

Permalink
Make TabViewer::{on_add,add_popup} accept corresponding surface ind…
Browse files Browse the repository at this point in the history
…ex (#167)

* Make `TabViewer::{on_add,add_popup}` accept corresponding surface index

* Fix `TabViewer::context_menu` while I'm at it

* Update changelog

* Fix examples
  • Loading branch information
Adanos020 committed Aug 28, 2023
1 parent a445121 commit f116e1a
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 66 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ provide a guide of how to use the library.
- Renamed `Style::border` to `Style::main_surface_border_stroke`.
- Moved `Style::selection_color` to `OverlayStyle::selection_color`.
- `DockArea::new` now takes in a `DockState` instead of a `Tree`.
- Removed `DockArea::scroll_area_in_tabs`. (([#160](https://github.com/Adanos020/egui_dock/pull/160)))
- Removed `DockArea::scroll_area_in_tabs`. ([#160](https://github.com/Adanos020/egui_dock/pull/160))
- `TabViewer::{context_menu,on_add,add_popup}` now take in an additional `SurfaceIndex` parameter. ([#167](https://github.com/Adanos020/egui_dock/pull/167))

## 0.6.3 - 2023-06-16

Expand Down
16 changes: 11 additions & 5 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ struct MyApp {
impl TabViewer for MyContext {
type Tab = String;

fn title(&mut self, tab: &mut Self::Tab) -> WidgetText {
tab.as_str().into()
}

fn ui(&mut self, ui: &mut Ui, tab: &mut Self::Tab) {
match tab.as_str() {
"Simple Demo" => self.simple_demo(ui),
Expand All @@ -95,7 +99,13 @@ impl TabViewer for MyContext {
}
}

fn context_menu(&mut self, ui: &mut Ui, tab: &mut Self::Tab, _node: NodeIndex) {
fn context_menu(
&mut self,
ui: &mut Ui,
tab: &mut Self::Tab,
_surface: SurfaceIndex,
_node: NodeIndex,
) {
match tab.as_str() {
"Simple Demo" => self.simple_demo_menu(ui),
_ => {
Expand All @@ -105,10 +115,6 @@ impl TabViewer for MyContext {
}
}

fn title(&mut self, tab: &mut Self::Tab) -> WidgetText {
tab.as_str().into()
}

fn closeable(&mut self, tab: &mut Self::Tab) -> bool {
["Inspector", "Style Editor"].contains(&tab.as_str())
}
Expand Down
8 changes: 4 additions & 4 deletions examples/reject_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ struct OpinionatedTab {
impl egui_dock::TabViewer for TabViewer {
type Tab = OpinionatedTab;

fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
(&tab.title).into()
}

fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
ui.label(&tab.content);
match &mut tab.can_become_window {
Expand All @@ -43,10 +47,6 @@ impl egui_dock::TabViewer for TabViewer {
}
}

fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
(&tab.title).into()
}

fn allowed_in_windows(&self, tab: &mut Self::Tab) -> bool {
match tab.can_become_window {
Ok(opinion) | Err(opinion) => opinion,
Expand Down
8 changes: 4 additions & 4 deletions examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ struct TabViewer {}
impl egui_dock::TabViewer for TabViewer {
type Tab = String;

fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
ui.label(format!("Content of {tab}"));
}

fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
(&*tab).into()
}

fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
ui.label(format!("Content of {tab}"));
}
}

struct MyApp {
Expand Down
20 changes: 10 additions & 10 deletions examples/tab_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use eframe::{egui, NativeOptions};

use egui_dock::{DockArea, DockState, NodeIndex, Style};
use egui_dock::{DockArea, DockState, NodeIndex, Style, SurfaceIndex};

fn main() -> eframe::Result<()> {
let options = NativeOptions::default();
Expand All @@ -14,22 +14,22 @@ fn main() -> eframe::Result<()> {
}

struct TabViewer<'a> {
added_nodes: &'a mut Vec<NodeIndex>,
added_nodes: &'a mut Vec<(SurfaceIndex, NodeIndex)>,
}

impl egui_dock::TabViewer for TabViewer<'_> {
type Tab = usize;

fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
ui.label(format!("Content of tab {tab}"));
}

fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
format!("Tab {tab}").into()
}

fn on_add(&mut self, node: NodeIndex) {
self.added_nodes.push(node);
fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
ui.label(format!("Content of tab {tab}"));
}

fn on_add(&mut self, surface: SurfaceIndex, node: NodeIndex) {
self.added_nodes.push((surface, node));
}
}

Expand Down Expand Up @@ -70,8 +70,8 @@ impl eframe::App for MyApp {
},
);

added_nodes.drain(..).for_each(|node| {
self.tree.main_surface_mut().set_focused_node(node);
added_nodes.drain(..).for_each(|(surface, node)| {
self.tree.set_focused_node_and_surface((surface, node));
self.tree.push_to_focused_leaf(self.counter);
self.counter += 1;
});
Expand Down
74 changes: 46 additions & 28 deletions examples/tab_add_popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use eframe::{egui, NativeOptions};

use egui::{Color32, RichText};
use egui_dock::{DockArea, DockState, NodeIndex, Style};
use egui_dock::{DockArea, DockState, NodeIndex, Style, SurfaceIndex};

fn main() -> eframe::Result<()> {
let options = NativeOptions::default();
Expand All @@ -21,20 +21,24 @@ enum MyTabKind {

struct MyTab {
kind: MyTabKind,
surface: SurfaceIndex,
node: NodeIndex,
}

impl MyTab {
fn regular(node_index: usize) -> Self {
fn regular(surface: SurfaceIndex, node: NodeIndex) -> Self {
Self {
kind: MyTabKind::Regular,
node: NodeIndex(node_index),
surface,
node,
}
}

fn fancy(node_index: usize) -> Self {
fn fancy(surface: SurfaceIndex, node: NodeIndex) -> Self {
Self {
kind: MyTabKind::Fancy,
node: NodeIndex(node_index),
surface,
node,
}
}

Expand Down Expand Up @@ -68,56 +72,68 @@ struct TabViewer<'a> {
impl egui_dock::TabViewer for TabViewer<'_> {
type Tab = MyTab;

fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
ui.label(tab.content());
}

fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
tab.title().into()
}

fn add_popup(&mut self, ui: &mut egui::Ui, node: NodeIndex) {
fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
ui.label(tab.content());
}

fn add_popup(&mut self, ui: &mut egui::Ui, surface: SurfaceIndex, node: NodeIndex) {
ui.set_min_width(120.0);
ui.style_mut().visuals.button_frame = false;

if ui.button("Regular tab").clicked() {
self.added_nodes.push(MyTab::regular(node.0));
self.added_nodes.push(MyTab::regular(surface, node));
}

if ui.button("Fancy tab").clicked() {
self.added_nodes.push(MyTab::fancy(node.0));
self.added_nodes.push(MyTab::fancy(surface, node));
}
}
}

struct MyApp {
tree: DockState<MyTab>,
dock_state: DockState<MyTab>,
counter: usize,
}

impl Default for MyApp {
fn default() -> Self {
let mut tree = DockState::new(vec![MyTab::regular(1), MyTab::fancy(2)]);
let mut tree = DockState::new(vec![
MyTab::regular(SurfaceIndex::main(), NodeIndex(1)),
MyTab::fancy(SurfaceIndex::main(), NodeIndex(2)),
]);

// You can modify the tree before constructing the dock
let [a, b] =
tree.main_surface_mut()
.split_left(NodeIndex::root(), 0.3, vec![MyTab::fancy(3)]);
let [_, _] = tree
.main_surface_mut()
.split_below(a, 0.7, vec![MyTab::fancy(4)]);
let [_, _] = tree
.main_surface_mut()
.split_below(b, 0.5, vec![MyTab::regular(5)]);

Self { tree, counter: 6 }
let [a, b] = tree.main_surface_mut().split_left(
NodeIndex::root(),
0.3,
vec![MyTab::fancy(SurfaceIndex::main(), NodeIndex(3))],
);
let [_, _] = tree.main_surface_mut().split_below(
a,
0.7,
vec![MyTab::fancy(SurfaceIndex::main(), NodeIndex(4))],
);
let [_, _] = tree.main_surface_mut().split_below(
b,
0.5,
vec![MyTab::regular(SurfaceIndex::main(), NodeIndex(5))],
);

Self {
dock_state: tree,
counter: 6,
}
}
}

impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
let mut added_nodes = Vec::new();
DockArea::new(&mut self.tree)
DockArea::new(&mut self.dock_state)
.show_add_buttons(true)
.show_add_popup(true)
.style(Style::from_egui(ctx.style().as_ref()))
Expand All @@ -129,9 +145,11 @@ impl eframe::App for MyApp {
);

added_nodes.drain(..).for_each(|node| {
self.tree.main_surface_mut().set_focused_node(node.node);
self.tree.push_to_focused_leaf(MyTab {
self.dock_state
.set_focused_node_and_surface((node.surface, node.node));
self.dock_state.push_to_focused_leaf(MyTab {
kind: node.kind,
surface: node.surface,
node: NodeIndex(self.counter),
});
self.counter += 1;
Expand Down
8 changes: 4 additions & 4 deletions examples/text_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ struct Buffers {
impl egui_dock::TabViewer for Buffers {
type Tab = Title;

fn title(&mut self, title: &mut Title) -> egui::WidgetText {
egui::WidgetText::from(&*title)
}

fn ui(&mut self, ui: &mut egui::Ui, title: &mut Title) {
let text = self.buffers.entry(title.clone()).or_default();
egui::TextEdit::multiline(text)
.desired_width(f32::INFINITY)
.show(ui);
}

fn title(&mut self, title: &mut Title) -> egui::WidgetText {
egui::WidgetText::from(&*title)
}
}

struct MyApp {
Expand Down
9 changes: 6 additions & 3 deletions src/widgets/dock_area/show/leaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
};
self.tab_plus(
ui,
surface_index,
node_index,
tab_viewer,
tabbar_outer_rect,
Expand Down Expand Up @@ -307,7 +308,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> {

if self.tab_context_menus {
response = response.context_menu(|ui| {
tab_viewer.context_menu(ui, tab, node_index);
tab_viewer.context_menu(ui, tab, surface_index, node_index);
if (surface_index.is_main() || !is_lonely_tab)
&& ui.button("Eject").clicked()
{
Expand Down Expand Up @@ -394,9 +395,11 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
}
}

#[allow(clippy::too_many_arguments)]
fn tab_plus(
&mut self,
ui: &mut Ui,
surface_index: SurfaceIndex,
node_index: NodeIndex,
tab_viewer: &mut impl TabViewer<Tab = Tab>,
tabbar_outer_rect: Rect,
Expand Down Expand Up @@ -452,14 +455,14 @@ impl<'tree, Tab> DockArea<'tree, Tab> {

let popup_id = ui.id().with("tab_add_popup");
popup_under_widget(ui, popup_id, &response, |ui| {
tab_viewer.add_popup(ui, node_index);
tab_viewer.add_popup(ui, surface_index, node_index);
});

if response.clicked() {
if self.show_add_popup {
ui.memory_mut(|mem| mem.toggle_popup(popup_id));
}
tab_viewer.on_add(node_index);
tab_viewer.on_add(surface_index, node_index);
}
}

Expand Down
22 changes: 15 additions & 7 deletions src/widgets/tab_viewer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{NodeIndex, TabStyle};
use crate::{NodeIndex, SurfaceIndex, TabStyle};
use egui::{Id, Ui, WidgetText};

/// Defines how to display a tab inside a [`Tree`](crate::Tree).
Expand All @@ -14,9 +14,16 @@ pub trait TabViewer {

/// Content inside the context menu shown when the tab is right-clicked.
///
/// The `_node` specifies which [`Node`](crate::Node) or split of the tree that this particular context menu
/// belongs to.
fn context_menu(&mut self, _ui: &mut Ui, _tab: &mut Self::Tab, _node: NodeIndex) {}
/// `_surface` and `_node` specify which [`Surface`](crate::Surface) and [`Node`](crate::Node) that this particular
/// context menu belongs to.
fn context_menu(
&mut self,
_ui: &mut Ui,
_tab: &mut Self::Tab,
_surface: SurfaceIndex,
_node: NodeIndex,
) {
}

/// Unique ID for this tab.
///
Expand Down Expand Up @@ -47,14 +54,15 @@ pub trait TabViewer {
/// This is called when the tabs add button is pressed and if the dock [`Style`](crate::Style)'s
/// `show_add_buttons` is set to `true`.
///
/// `_node` specifies which [`Node`](crate::Node) or split of the tree this particular add button was pressed on.
fn on_add(&mut self, _node: NodeIndex) {}
/// `_surface` and `_node` specify which surface and which [`Node`](crate::Node) this particular add button was
/// pressed on.
fn on_add(&mut self, _surface: SurfaceIndex, _node: NodeIndex) {}

/// Content of the popup under the add button. Useful for selecting what type of tab to add.
///
/// This requires that [`DockArea::show_add_buttons`](crate::DockArea::show_add_buttons) and
/// [`DockArea::show_add_popup`](crate::DockArea::show_add_popup) are set to `true`.
fn add_popup(&mut self, _ui: &mut Ui, _node: NodeIndex) {}
fn add_popup(&mut self, _ui: &mut Ui, _surface: SurfaceIndex, _node: NodeIndex) {}

/// This is called every frame after [`ui`](Self::ui) is called, if the `_tab` is active.
///
Expand Down

0 comments on commit f116e1a

Please sign in to comment.