Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Basic Scrolling in Tab Menu #3

Closed
wants to merge 14 commits into from
Prev Previous commit
Next Next commit
feat: hide/show icons based on scroll type [right not positioned]
  • Loading branch information
bennjii committed Jun 1, 2023
commit ffeb56fe07757130a1e4f0d030679842eabc1b66
17 changes: 9 additions & 8 deletions examples/advanced.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use std::sync::mpsc::Sender;

use eframe::egui;

fn main() -> Result<(), eframe::Error> {
Expand Down Expand Up @@ -135,8 +136,8 @@ impl egui_tiles::Behavior<Pane> for TreeBehavior {
ui: &mut egui::Ui,
_tile_id: egui_tiles::TileId,
_tabs: &egui_tiles::Tabs,
_scroll: Sender<f32>,
_offset: Option<f32>,
_offset: f32,
_scroll: Sender<f32>
) {
if ui.button("<").clicked() {
bennjii marked this conversation as resolved.
Show resolved Hide resolved
_scroll.send(-45.0).unwrap();
Expand All @@ -147,14 +148,14 @@ impl egui_tiles::Behavior<Pane> for TreeBehavior {
&mut self,
_tiles: &egui_tiles::Tiles<Pane>,
ui: &mut egui::Ui,
tile_id: egui_tiles::TileId,
_tile_id: egui_tiles::TileId,
_tabs: &egui_tiles::Tabs,
_scroll: Sender<f32>,
_offset: Option<f32>,
_offset: f32,
_scroll: Sender<f32>
) {
if ui.button("➕").clicked() {
self.add_child_to = Some(tile_id);
}
// if ui.button("➕").clicked() {
// self.add_child_to = Some(tile_id);
// }

if ui.button(">").clicked() {
bennjii marked this conversation as resolved.
Show resolved Hide resolved
// Integer value to move scroll by
Expand Down
4 changes: 2 additions & 2 deletions src/behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ pub trait Behavior<Pane> {
_ui: &mut Ui,
_tile_id: TileId,
_tabs: &crate::Tabs,
_offset: f32,
_scroll: Sender<f32>,
_offset: Option<f32>,
) {
// if ui.button("➕").clicked() {
// }
Expand All @@ -128,8 +128,8 @@ pub trait Behavior<Pane> {
_ui: &mut Ui,
_tile_id: TileId,
_tabs: &crate::Tabs,
_offset: f32,
_scroll: Sender<f32>,
_offset: Option<f32>,
) {
// if ui.button("➕").clicked() {
// }
Expand Down
2 changes: 1 addition & 1 deletion src/container/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl Linear {
///
/// The `fraction` is the fraction of the total width that the first child should get.
pub fn new_binary(dir: LinearDir, children: [TileId; 2], fraction: f32) -> Self {
debug_assert!(0.0 <= fraction && fraction <= 1.0);
debug_assert!((0.0..=1.0).contains(&fraction));
let mut slf = Self {
children: children.into(),
dir,
Expand Down
86 changes: 53 additions & 33 deletions src/container/tabs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use egui::{scroll_area::ScrollBarVisibility, vec2, Rect};
use egui::{scroll_area::ScrollBarVisibility, vec2, Rect, Vec2};

use crate::{
is_being_dragged, Behavior, ContainerInsertion, DropContext, InsertionPoint, SimplifyAction,
Expand All @@ -15,6 +15,13 @@ pub struct Tabs {
pub active: Option<TileId>,
}

#[derive(Default, Clone)]
struct ScrollState {
pub offset: Vec2,
pub consumed: Vec2,
pub available: Vec2
}

impl Tabs {
pub fn new(children: Vec<TileId>) -> Self {
let active = children.first().copied();
Expand Down Expand Up @@ -86,13 +93,12 @@ impl Tabs {
) -> Option<TileId> {
let mut next_active = self.active;

let scroll_length: f32 = 0.0;

let scroll_state: ScrollState = ScrollState::default();
let id = ui.make_persistent_id(tile_id);

ui.ctx().memory_mut(|m| {
if m.data.get_temp::<f32>(id).is_none() {
m.data.insert_temp(id, scroll_length)
if m.data.get_temp::<ScrollState>(id).is_none() {
m.data.insert_temp(id, scroll_state)
}
});

Expand All @@ -106,22 +112,35 @@ impl Tabs {
ui.painter()
.rect_filled(ui.max_rect(), 0.0, behavior.tab_bar_color(ui.visuals()));

ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
ui.with_layout(egui::Layout::left_to_right(egui::Align::Center), |ui| {
bennjii marked this conversation as resolved.
Show resolved Hide resolved
// Add buttons such as "add new tab"
ui.spacing_mut().item_spacing.x = 0.0; // Tabs have spacing built-in

let scrolling_channel = std::sync::mpsc::channel::<f32>();
bennjii marked this conversation as resolved.
Show resolved Hide resolved
let offset = ui.ctx().memory_mut(|m| m.data.get_temp::<f32>(id));

behavior.top_bar_rtl_ui(
&tree.tiles,
ui,
tile_id,
self,
scrolling_channel.0.clone(),
offset,
);
behavior.top_bar_ltl_ui(&tree.tiles, ui, tile_id, self, scrolling_channel.0, offset);
let mut scroll_state: ScrollState = ui.ctx().memory_mut(|m| m.data.get_temp::<ScrollState>(id)).unwrap();

if scroll_state.offset.x > 0.0 {
behavior.top_bar_ltl_ui(
&tree.tiles, ui, tile_id,
self, scroll_state.offset.x,
scrolling_channel.0.clone()
);
}

// ui.allocate_space(scroll_state.available);

let should_show_scroll_right = scroll_state.consumed.x >= scroll_state.available.x;

if should_show_scroll_right {
behavior.top_bar_rtl_ui(
&tree.tiles,
ui,
tile_id,
self,
scroll_state.offset.x,
scrolling_channel.0
);
}

ui.set_clip_rect(ui.available_rect_before_wrap()); // Don't cover the `rtl_ui` buttons.

Expand All @@ -130,27 +149,22 @@ impl Tabs {
.max_width(ui.available_width());

if let Ok(new_position) = scrolling_channel.1.try_recv() {
if let Some(offset) = offset {
let mut offset = offset;

offset += new_position;
scroll_state.offset.x += new_position;

// Max is: [`ui.available_width()`]
if offset >= (ui.available_width()) {
offset = ui.available_width();
}

if offset < 0.0 {
offset = 0.0;
}

area = area.to_owned().horizontal_scroll_offset(offset);
// Max is: [`ui.available_width()`]
if scroll_state.offset.x >= (ui.available_width()) {
scroll_state.offset.x = ui.available_width();
}

ui.ctx().memory_mut(|m| m.data.insert_temp(id, offset));
if scroll_state.offset.x < 0.0 {
scroll_state.offset.x = 0.0;
}

area = area.to_owned().horizontal_scroll_offset(scroll_state.offset.x);
ui.ctx().memory_mut(|m| m.data.insert_temp(id, scroll_state.clone()));
}

area.to_owned().show(ui, |ui| {
let output = area.show_viewport(ui, |ui, _| {
// ui.interact(rect, id, Sense::)
ui.with_layout(egui::Layout::left_to_right(egui::Align::Center), |ui| {
if !tree.is_root(tile_id) {
Expand Down Expand Up @@ -204,6 +218,12 @@ impl Tabs {
}
});
});

scroll_state.offset = output.state.offset;
scroll_state.consumed = output.content_size;
scroll_state.available = output.inner_rect.size();

ui.ctx().memory_mut(|m| m.data.insert_temp(id, scroll_state));
});

// -----------
Expand Down