mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
Rename viewports example to test_viewports, and hide drag-and-drop
This commit is contained in:
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -3707,6 +3707,14 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "test_viewports"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"eframe",
|
||||||
|
"env_logger",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.16.0"
|
version = "0.16.0"
|
||||||
@@ -4059,14 +4067,6 @@ version = "0.9.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "viewports"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"eframe",
|
|
||||||
"env_logger",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "waker-fn"
|
name = "waker-fn"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "viewports"
|
name = "test_viewports"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["konkitoman"]
|
authors = ["konkitoman"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
1
examples/test_viewports/README.md
Normal file
1
examples/test_viewports/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
This is a test of the viewports feature of eframe and egui, where we show off using multiple windows.
|
||||||
@@ -3,6 +3,9 @@ use std::sync::Arc;
|
|||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use egui::{mutex::RwLock, Id, InnerResponse, ViewportBuilder, ViewportId};
|
use egui::{mutex::RwLock, Id, InnerResponse, ViewportBuilder, ViewportId};
|
||||||
|
|
||||||
|
// Drag-and-drop between windows is not yet implemented, but if you wanna work on it, enable this:
|
||||||
|
pub const DRAG_AND_DROP_TEST: bool = false;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init(); // Use `RUST_LOG=debug` to see logs.
|
env_logger::init(); // Use `RUST_LOG=debug` to see logs.
|
||||||
|
|
||||||
@@ -109,7 +112,7 @@ impl eframe::App for App {
|
|||||||
ctx.set_force_embedding(force_embedding);
|
ctx.set_force_embedding(force_embedding);
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_ui(ui, Id::new("root_viewport"), &self.top);
|
generic_ui(ui, &self.top);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +133,7 @@ fn show_async_viewport(
|
|||||||
let mut vp_state = vp_state.write();
|
let mut vp_state = vp_state.write();
|
||||||
show_as_popup(ctx, &title, id, move |ui: &mut egui::Ui| {
|
show_as_popup(ctx, &title, id, move |ui: &mut egui::Ui| {
|
||||||
ui.add(egui::DragValue::new(&mut vp_state.count).prefix("Count: "));
|
ui.add(egui::DragValue::new(&mut vp_state.count).prefix("Count: "));
|
||||||
generic_ui(ui, id, &vp_state.children);
|
generic_ui(ui, &vp_state.children);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -146,82 +149,12 @@ fn show_sync_viewport(ctx: &egui::Context, vp_id: ViewportId, vp_state: &mut Vie
|
|||||||
move |ctx| {
|
move |ctx| {
|
||||||
show_as_popup(ctx, &vp_state.title, id, |ui: &mut egui::Ui| {
|
show_as_popup(ctx, &vp_state.title, id, |ui: &mut egui::Ui| {
|
||||||
ui.add(egui::DragValue::new(&mut vp_state.count).prefix("Count: "));
|
ui.add(egui::DragValue::new(&mut vp_state.count).prefix("Count: "));
|
||||||
generic_ui(ui, id, &vp_state.children);
|
generic_ui(ui, &vp_state.children);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is taken from crates/egui_demo_lib/src/debo/drag_and_drop.rs
|
|
||||||
fn drag_source<R>(
|
|
||||||
ui: &mut egui::Ui,
|
|
||||||
id: egui::Id,
|
|
||||||
body: impl FnOnce(&mut egui::Ui) -> R,
|
|
||||||
) -> InnerResponse<R> {
|
|
||||||
let is_being_dragged = ui.memory(|mem| mem.is_being_dragged(id));
|
|
||||||
|
|
||||||
if !is_being_dragged {
|
|
||||||
let res = ui.scope(body);
|
|
||||||
|
|
||||||
// Check for drags:
|
|
||||||
let response = ui.interact(res.response.rect, id, egui::Sense::drag());
|
|
||||||
if response.hovered() {
|
|
||||||
ui.ctx().set_cursor_icon(egui::CursorIcon::Grab);
|
|
||||||
}
|
|
||||||
res
|
|
||||||
} else {
|
|
||||||
ui.ctx().set_cursor_icon(egui::CursorIcon::Grabbing);
|
|
||||||
|
|
||||||
// Paint the body to a new layer:
|
|
||||||
let layer_id = egui::LayerId::new(egui::Order::Tooltip, id);
|
|
||||||
let res = ui.with_layer_id(layer_id, body);
|
|
||||||
|
|
||||||
if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
|
|
||||||
let delta = pointer_pos - res.response.rect.center();
|
|
||||||
ui.ctx().translate_layer(layer_id, delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is taken from crates/egui_demo_lib/src/debo/drag_and_drop.rs
|
|
||||||
fn drop_target<R>(
|
|
||||||
ui: &mut egui::Ui,
|
|
||||||
body: impl FnOnce(&mut egui::Ui) -> R,
|
|
||||||
) -> egui::InnerResponse<R> {
|
|
||||||
let is_being_dragged = ui.memory(|mem| mem.is_anything_being_dragged());
|
|
||||||
|
|
||||||
let margin = egui::Vec2::splat(ui.visuals().clip_rect_margin); // 3.0
|
|
||||||
|
|
||||||
let background_id = ui.painter().add(egui::Shape::Noop);
|
|
||||||
|
|
||||||
let available_rect = ui.available_rect_before_wrap();
|
|
||||||
let inner_rect = available_rect.shrink2(margin);
|
|
||||||
let mut content_ui = ui.child_ui(inner_rect, *ui.layout());
|
|
||||||
let ret = body(&mut content_ui);
|
|
||||||
|
|
||||||
let outer_rect =
|
|
||||||
egui::Rect::from_min_max(available_rect.min, content_ui.min_rect().max + margin);
|
|
||||||
let (rect, response) = ui.allocate_at_least(outer_rect.size(), egui::Sense::hover());
|
|
||||||
|
|
||||||
let style = if is_being_dragged && response.hovered() {
|
|
||||||
ui.visuals().widgets.active
|
|
||||||
} else {
|
|
||||||
ui.visuals().widgets.inactive
|
|
||||||
};
|
|
||||||
|
|
||||||
let fill = style.bg_fill;
|
|
||||||
let stroke = style.bg_stroke;
|
|
||||||
|
|
||||||
ui.painter().set(
|
|
||||||
background_id,
|
|
||||||
egui::epaint::RectShape::new(rect, style.rounding, fill, stroke),
|
|
||||||
);
|
|
||||||
|
|
||||||
egui::InnerResponse::new(ret, response)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This will make the content as a popup if cannot has his own native window
|
/// This will make the content as a popup if cannot has his own native window
|
||||||
fn show_as_popup(ctx: &egui::Context, title: &str, id: Id, content: impl FnOnce(&mut egui::Ui)) {
|
fn show_as_popup(ctx: &egui::Context, title: &str, id: Id, content: impl FnOnce(&mut egui::Ui)) {
|
||||||
if ctx.viewport_id() == ctx.parent_viewport_id() {
|
if ctx.viewport_id() == ctx.parent_viewport_id() {
|
||||||
@@ -231,7 +164,9 @@ fn show_as_popup(ctx: &egui::Context, title: &str, id: Id, content: impl FnOnce(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generic_ui(ui: &mut egui::Ui, container_id: Id, children: &[Arc<RwLock<ViewportState>>]) {
|
fn generic_ui(ui: &mut egui::Ui, children: &[Arc<RwLock<ViewportState>>]) {
|
||||||
|
let container_id = ui.id();
|
||||||
|
|
||||||
let ctx = ui.ctx().clone();
|
let ctx = ui.ctx().clone();
|
||||||
ui.label(format!(
|
ui.label(format!(
|
||||||
"Frame nr: {} (this increases when this viewport is being rendered)",
|
"Frame nr: {} (this increases when this viewport is being rendered)",
|
||||||
@@ -304,7 +239,9 @@ fn generic_ui(ui: &mut egui::Ui, container_id: Id, children: &[Arc<RwLock<Viewpo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drag_and_drop_test(ui, container_id);
|
if DRAG_AND_DROP_TEST {
|
||||||
|
drag_and_drop_test(ui);
|
||||||
|
}
|
||||||
|
|
||||||
if !children.is_empty() {
|
if !children.is_empty() {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
@@ -325,10 +262,15 @@ fn generic_ui(ui: &mut egui::Ui, container_id: Id, children: &[Arc<RwLock<Viewpo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drag_and_drop_test(ui: &mut egui::Ui, container_id: Id) {
|
// ----------------------------------------------------------------------------
|
||||||
|
// Drag-and-drop between windows is not yet implemented, but there is some test code for it here:
|
||||||
|
|
||||||
|
fn drag_and_drop_test(ui: &mut egui::Ui) {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
let container_id = ui.id();
|
||||||
|
|
||||||
const COLS: usize = 2;
|
const COLS: usize = 2;
|
||||||
static DATA: OnceLock<RwLock<DragAndDrop>> = OnceLock::new();
|
static DATA: OnceLock<RwLock<DragAndDrop>> = OnceLock::new();
|
||||||
let data = DATA.get_or_init(Default::default);
|
let data = DATA.get_or_init(Default::default);
|
||||||
@@ -431,3 +373,73 @@ fn drag_and_drop_test(ui: &mut egui::Ui, container_id: Id) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is taken from crates/egui_demo_lib/src/debo/drag_and_drop.rs
|
||||||
|
fn drag_source<R>(
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
id: egui::Id,
|
||||||
|
body: impl FnOnce(&mut egui::Ui) -> R,
|
||||||
|
) -> InnerResponse<R> {
|
||||||
|
let is_being_dragged = ui.memory(|mem| mem.is_being_dragged(id));
|
||||||
|
|
||||||
|
if !is_being_dragged {
|
||||||
|
let res = ui.scope(body);
|
||||||
|
|
||||||
|
// Check for drags:
|
||||||
|
let response = ui.interact(res.response.rect, id, egui::Sense::drag());
|
||||||
|
if response.hovered() {
|
||||||
|
ui.ctx().set_cursor_icon(egui::CursorIcon::Grab);
|
||||||
|
}
|
||||||
|
res
|
||||||
|
} else {
|
||||||
|
ui.ctx().set_cursor_icon(egui::CursorIcon::Grabbing);
|
||||||
|
|
||||||
|
// Paint the body to a new layer:
|
||||||
|
let layer_id = egui::LayerId::new(egui::Order::Tooltip, id);
|
||||||
|
let res = ui.with_layer_id(layer_id, body);
|
||||||
|
|
||||||
|
if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
|
||||||
|
let delta = pointer_pos - res.response.rect.center();
|
||||||
|
ui.ctx().translate_layer(layer_id, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is taken from crates/egui_demo_lib/src/debo/drag_and_drop.rs
|
||||||
|
fn drop_target<R>(
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
body: impl FnOnce(&mut egui::Ui) -> R,
|
||||||
|
) -> egui::InnerResponse<R> {
|
||||||
|
let is_being_dragged = ui.memory(|mem| mem.is_anything_being_dragged());
|
||||||
|
|
||||||
|
let margin = egui::Vec2::splat(ui.visuals().clip_rect_margin); // 3.0
|
||||||
|
|
||||||
|
let background_id = ui.painter().add(egui::Shape::Noop);
|
||||||
|
|
||||||
|
let available_rect = ui.available_rect_before_wrap();
|
||||||
|
let inner_rect = available_rect.shrink2(margin);
|
||||||
|
let mut content_ui = ui.child_ui(inner_rect, *ui.layout());
|
||||||
|
let ret = body(&mut content_ui);
|
||||||
|
|
||||||
|
let outer_rect =
|
||||||
|
egui::Rect::from_min_max(available_rect.min, content_ui.min_rect().max + margin);
|
||||||
|
let (rect, response) = ui.allocate_at_least(outer_rect.size(), egui::Sense::hover());
|
||||||
|
|
||||||
|
let style = if is_being_dragged && response.hovered() {
|
||||||
|
ui.visuals().widgets.active
|
||||||
|
} else {
|
||||||
|
ui.visuals().widgets.inactive
|
||||||
|
};
|
||||||
|
|
||||||
|
let fill = style.bg_fill;
|
||||||
|
let stroke = style.bg_stroke;
|
||||||
|
|
||||||
|
ui.painter().set(
|
||||||
|
background_id,
|
||||||
|
egui::epaint::RectShape::new(rect, style.rounding, fill, stroke),
|
||||||
|
);
|
||||||
|
|
||||||
|
egui::InnerResponse::new(ret, response)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user