mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #2499 from vangel76/fix/2421-floating-panel-opaque
Panels: floating panel groups paint an opaque background (#2421)
This commit is contained in:
@@ -625,6 +625,17 @@ pub(crate) fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) -> bool {
|
||||
display
|
||||
.floating
|
||||
.retain(|group| !app.ui.floating_panels.iter().any(|native| decorated(native) && native.panels.iter().any(|id| group.panels.contains(id))));
|
||||
// Floating groups lie on the canvas, not on the dock's card: reserve a fill under each one
|
||||
// before the dock draws it, sized once it is placed, so the canvas doesn't show through (#2421).
|
||||
let fills: Vec<_> = display
|
||||
.floating
|
||||
.iter()
|
||||
.filter_map(|group| group.panels.first())
|
||||
.map(|first| {
|
||||
let layer = egui::LayerId::new(egui::Order::Middle, area.with(("floating", first)));
|
||||
(layer, ui.ctx().layer_painter(layer).add(egui::Shape::Noop))
|
||||
})
|
||||
.collect();
|
||||
let mut draw = |ui: &mut egui::Ui| {
|
||||
if layout.root.is_some() && crate::dock::collapse_header(ui, collapsed) {
|
||||
let _ = app.run("window.collapseDock", json!({"collapsed":!collapsed}));
|
||||
@@ -644,7 +655,8 @@ pub(crate) fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) -> bool {
|
||||
}
|
||||
let mut style = craft_ui::docking::DockStyle::from_ui(ui);
|
||||
style.tab_height = 33.0;
|
||||
// The dock is a card (`theme::card`): its panes and tab strip lie on the card's colour.
|
||||
// The dock is a card (`theme::card`): its panes and tab strip lie on the card's colour
|
||||
// (square fills would cover its rounded corners). Floating groups get the fills below.
|
||||
style.background = egui::Color32::TRANSPARENT;
|
||||
style.tab_background = egui::Color32::TRANSPARENT;
|
||||
style.active_background = t.button;
|
||||
@@ -659,7 +671,7 @@ pub(crate) fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) -> bool {
|
||||
style.resize_label = tl!("Resize panels").to_string();
|
||||
style.resize_window_label = tl!("Resize panel window").to_string();
|
||||
let mut content = PanelContent { app, commands: Vec::new() };
|
||||
let output = craft_ui::docking::DockArea::new(egui::Id::new("vectorcraft-panel-docking")).show_customized(
|
||||
let output = craft_ui::docking::DockArea::new(area).show_customized(
|
||||
ui,
|
||||
&display,
|
||||
&style,
|
||||
@@ -754,6 +766,11 @@ pub(crate) fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) -> bool {
|
||||
ui.ctx().data_mut(|data| data.insert_temp(crate::floating::group_rect_id(first), rect));
|
||||
}
|
||||
}
|
||||
for (layer, fill) in fills {
|
||||
if let Some(rect) = ui.ctx().memory(|memory| memory.area_rect(layer.id)) {
|
||||
ui.ctx().layer_painter(layer).set(fill, egui::Shape::rect_filled(rect, 0.0, t.panel));
|
||||
}
|
||||
}
|
||||
icon_rail(app, ui);
|
||||
crate::floating::docked_columns(app, ui);
|
||||
true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::*;
|
||||
use egui::{Event, Modifiers, PointerButton, Pos2, vec2};
|
||||
use egui::{Event, Modifiers, PointerButton, Pos2, pos2, vec2};
|
||||
use egui_kittest::{Harness, kittest::Queryable};
|
||||
|
||||
fn app() -> VectorcraftApp {
|
||||
@@ -614,3 +614,29 @@ fn the_window_menu_item_hides_a_shown_panel_and_shows_it_again() {
|
||||
app.run("window.panel", json!({"panel":"properties"})).unwrap();
|
||||
assert!(shown(&app), "without the menu's toggle the command only shows the panel");
|
||||
}
|
||||
|
||||
/// A floating group lies on the canvas, not on the dock's card, so its tab strip and body paint
|
||||
/// their own opaque background (#2421).
|
||||
#[test]
|
||||
fn floating_group_paints_an_opaque_background() {
|
||||
let mut app = app();
|
||||
app.run("window.panel.float", json!({"panel":"properties","x":400,"y":200,"width":300,"height":420})).unwrap();
|
||||
let h = harness(app, vec2(1280.0, 800.0));
|
||||
// Paint order: the last big filled rectangle over a point decides what the user sees there
|
||||
// (outlines, small widgets and fully transparent fills, which paint nothing, don't count).
|
||||
fn topmost(shape: &egui::Shape, p: Pos2, found: &mut Option<egui::Color32>) {
|
||||
match shape {
|
||||
egui::Shape::Rect(r) if r.rect.contains(p) && r.rect.width() >= 200.0 && r.stroke.is_empty() && r.fill.a() > 0 => *found = Some(r.fill),
|
||||
egui::Shape::Vec(v) => v.iter().for_each(|s| topmost(s, p, found)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let opaque_at = |p: Pos2| {
|
||||
let mut found = None;
|
||||
h.output().shapes.iter().for_each(|s| topmost(&s.shape, p, &mut found));
|
||||
found.is_some_and(|c| c.a() == 255)
|
||||
};
|
||||
// Tab strip to the right of the tabs, and the body's empty bottom-right corner.
|
||||
assert!(opaque_at(pos2(690.0, 210.0)), "tab strip is transparent");
|
||||
assert!(opaque_at(pos2(690.0, 610.0)), "body is transparent");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user