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

Multi-viewport support #203

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Proof of concept with immediate viewports
Adanos020 committed Nov 25, 2023
commit ac58b84112764590ad017c631cbe3ddf4841bdfe
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ include = ["src/**/*.rs", "Cargo.toml", "LICENSE"]

[features]
default = []
multi-viewport = []

# Enable serialization of `Tree`.
serde = ["dep:serde", "egui/serde"]
35 changes: 29 additions & 6 deletions src/dock_state/window_state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use egui::{Id, Pos2, Rect, Vec2};

#[cfg(feature = "multi-viewport")]
use egui::ViewportBuilder;

#[cfg(not(feature = "multi-viewport"))]
use egui::Window;

/// The state of a [`Surface::Window`](crate::Surface::Window).
///
/// Doubles as a handle for the surface, allowing the user to set its size and position.
@@ -77,13 +83,30 @@ impl WindowState {
self.next_size.take()
}

//the 'static in this case means that the `open` field is always `None`
pub(crate) fn create_window(&mut self, id: Id, bounds: Rect) -> (egui::Window<'static>, bool) {
#[cfg(feature = "multi-viewport")]
pub(crate) fn create_window(&mut self, id: Id, bounds: Rect) -> (ViewportBuilder, bool) {
let new = self.new;
let mut viewport_builder = ViewportBuilder::default()
.with_decorations(false)
.with_resizable(true)
.with_drag_and_drop(true);

if let Some(position) = self.next_position() {
viewport_builder = viewport_builder.with_position(position);
}
if let Some(size) = self.next_size() {
viewport_builder = viewport_builder.with_inner_size(size);
}

self.new = false;
(viewport_builder, new)
}

// The 'static in this case means that the `open` field is always `None`
#[cfg(not(feature = "multi-viewport"))]
pub(crate) fn create_window(&mut self, id: Id, bounds: Rect) -> (Window<'static>, bool) {
let new = self.new;
let mut window_constructor = egui::Window::new("")
.id(id)
.constrain_to(bounds)
.title_bar(false);
let mut window_constructor = Window::new("").id(id).constrain_to(bounds).title_bar(false);

if let Some(position) = self.next_position() {
window_constructor = window_constructor.current_pos(position);
90 changes: 63 additions & 27 deletions src/widgets/dock_area/show/window_surface.rs
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@ use std::convert::identity;
use std::sync::Arc;

use egui::{
CollapsingHeader, CollapsingResponse, Frame, Galley, Id, Layout, Rect, Response, Sense,
TextStyle, Ui, Vec2, Widget,
CentralPanel, CollapsingHeader, CollapsingResponse, Frame, Galley, Id, Layout, Rect, Response,
Sense, TextStyle, Ui, Vec2, ViewportId, Widget,
};

use crate::{
@@ -25,7 +25,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
let id = format!("window {surf_index:?}").into();
let bounds = self.window_bounds.unwrap();
let mut open = true;
let (window, new) = self
let (mut window, new) = self
.dock_state
.get_window_state_mut(surf_index)
.unwrap()
@@ -91,31 +91,67 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
frame.shadow.color = frame.shadow.color.linear_multiply(fade_factor);
}

window
.frame(frame)
.min_width(min_window_width(&title, ui.spacing().indent))
.show(ui.ctx(), |ui| {
//fade inner ui (if neccesary)
if fade_factor != 1.0 {
fade_visuals(ui.visuals_mut(), fade_factor);
}
#[cfg(feature = "multi-viewport")]
{
window = window
.with_close_button(self.show_window_close_buttons && disabled.is_none())
.with_title(title.text());
ui.ctx().show_viewport_immediate(
ViewportId::from_hash_of(id),
window,
|ctx, viewport_class| {
CentralPanel::default().show(ctx, |ui| {
if fade_factor != 1.0 {
fade_visuals(ui.visuals_mut(), fade_factor);
}

let collapser_id = id.with("collapser");
let collapser_state = new.then_some(true);
let ch_res = self.show_window_body(
ui,
surf_index,
tab_viewer,
state,
fade_style,
collapser_state,
collapser_id,
title,
);
if self.show_window_close_buttons {
self.show_close_button(ui, &mut open, ch_res, disabled);
}
});
let collapser_id = id.with("collapser");
let collapser_state = new.then_some(true);
let ch_res = self.show_window_body(
ui,
surf_index,
tab_viewer,
state,
fade_style,
collapser_state,
collapser_id,
title,
);
if self.show_window_close_buttons {
self.show_close_button(ui, &mut open, ch_res, disabled);
}
});
},
)
}
#[cfg(not(feature = "multi-viewport"))]
{
window
.frame(frame)
.min_width(min_window_width(&title, ui.spacing().indent))
.show(ui.ctx(), |ui| {
//fade inner ui (if neccesary)
if fade_factor != 1.0 {
fade_visuals(ui.visuals_mut(), fade_factor);
}

let collapser_id = id.with("collapser");
let collapser_state = new.then_some(true);
let ch_res = self.show_window_body(
ui,
surf_index,
tab_viewer,
state,
fade_style,
collapser_state,
collapser_id,
title,
);
if self.show_window_close_buttons {
self.show_close_button(ui, &mut open, ch_res, disabled);
}
});
}

if !open {
self.to_remove.push(TabRemoval::Window(surf_index));