mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-14 19:27:01 -04:00
Merge PR #696
This commit is contained in:
4 files changed
+54
-1
No files matched your search
@@ -175,6 +175,19 @@ impl HeadlessView {
|
||||
}
|
||||
|
||||
/// Every piece of text the last frame painted (labels, tooltips, values), in paint order.
|
||||
/// Every shape of the last frame, with `Shape::Vec` flattened.
|
||||
pub fn painted_shapes(&self) -> Vec<egui::epaint::Shape> {
|
||||
fn flat(shape: &egui::epaint::Shape, out: &mut Vec<egui::epaint::Shape>) {
|
||||
match shape {
|
||||
egui::epaint::Shape::Vec(shapes) => shapes.iter().for_each(|shape| flat(shape, out)),
|
||||
other => out.push(other.clone()),
|
||||
}
|
||||
}
|
||||
let mut out = Vec::new();
|
||||
self.shapes.iter().for_each(|s| flat(&s.shape, &mut out));
|
||||
out
|
||||
}
|
||||
|
||||
pub fn painted_text(&self) -> Vec<String> {
|
||||
fn texts(shape: &egui::epaint::Shape, out: &mut Vec<String>) {
|
||||
match shape {
|
||||
|
||||
@@ -86,10 +86,14 @@ pub fn level(ui: &mut Ui, depth: usize, bar_bottom: Option<f32>, rows: impl FnOn
|
||||
// The popup's `Ui` is only as tall as the popup was last frame (egui's default area size on
|
||||
// the first), and a scroll area never grows past that. Ask for the room the window has;
|
||||
// auto-shrink then fits the area to its rows, so a menu scrolls only when they don't fit.
|
||||
// No scrollbar: the ▲ / ▼ strips, the wheel and dragging scroll a menu, like native menus.
|
||||
// egui's floating bar is drawn over the rows' right edge, where the shortcut text ends, and in
|
||||
// its wide (hovered) state its background hides the last character (issue #691).
|
||||
let out = egui::ScrollArea::vertical()
|
||||
.id_salt(("menu-level", depth))
|
||||
.max_height(height)
|
||||
.min_scrolled_height(height)
|
||||
.scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysHidden)
|
||||
.scroll_source(egui::containers::scroll_area::ScrollSource::ALL)
|
||||
.show(ui, rows);
|
||||
let down = over.then(|| ui.allocate_exact_size(vec2(0.0, ARROW), Sense::hover()).0);
|
||||
|
||||
@@ -145,3 +145,39 @@ fn click_outside_and_escape_close_the_open_menu() {
|
||||
h.settle(SETTLE);
|
||||
assert_eq!(open_menu(&h), None, "Escape");
|
||||
}
|
||||
|
||||
// ---- a scrolled menu draws no scrollbar over its rows (issue #691)
|
||||
|
||||
/// egui's floating scrollbar sat on the rows' right edge, where the shortcut text ends, and in
|
||||
/// its wide (hovered) state its background hid the last character. With the pointer resting on
|
||||
/// the menu, no tall narrow rectangle (a bar's handle or track) is painted along the level's
|
||||
/// right edge, in a menu that scrolls as in one that fits, and the level is as wide in both.
|
||||
#[test]
|
||||
fn a_scrolled_menu_draws_no_scrollbar_over_its_shortcuts() {
|
||||
let mut widths = Vec::new();
|
||||
for (size, scrolls) in [([1600.0, 700.0], true), ([1600.0, 1400.0], false)] {
|
||||
let what = format!("{} pt window", size[1]);
|
||||
let mut h = app(size);
|
||||
go(&mut h, "ui.clickWidget", "menu:View");
|
||||
go(&mut h, "ui.hoverWidget", "menu-level:1");
|
||||
let level = widget(&h, "menu-level:1").unwrap_or_else(|| panic!("{what}: no View menu"));
|
||||
let rows = widgets_with(&h, "menusub:");
|
||||
assert!(!rows.is_empty(), "{what}: no submenu rows registered");
|
||||
assert_eq!(rows.iter().any(|(_, r)| !level.contains_rect(*r)), scrolls, "{what}: scrolls = {scrolls}, level {level:?}");
|
||||
widths.push(level.width());
|
||||
// a row's hover highlight spans the level; a separator is one point tall; the ▸ of a
|
||||
// submenu row and the text are not rectangles: only a scrollbar is tall and narrow there
|
||||
let bars: Vec<egui::Rect> = h
|
||||
.view
|
||||
.painted_shapes()
|
||||
.iter()
|
||||
.filter_map(|s| match s {
|
||||
egui::epaint::Shape::Rect(r) => Some(r.rect),
|
||||
_ => None,
|
||||
})
|
||||
.filter(|r| r.width() <= 14.0 && r.height() > 30.0 && r.left() >= level.right() - 16.0 && r.right() <= level.right() + 0.5)
|
||||
.collect();
|
||||
assert!(bars.is_empty(), "{what}: a scrollbar is drawn along the menu's right edge: {bars:?}");
|
||||
}
|
||||
assert!((widths[0] - widths[1]).abs() < 0.5, "a scrolled menu is as wide as one that fits: {widths:?}");
|
||||
}
|
||||
@@ -481,7 +481,7 @@ visible menu bar yet: the menu model is only exposed through the control channel
|
||||
|
||||
| Id | Feature | Tier | Status | Evidence | Missing / notes |
|
||||
|---|---|---|---|---|---|
|
||||
| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu |
|
||||
| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu; a scrolled menu draws no scrollbar over its rows: the ▲ / ▼ strips, the wheel and dragging scroll it (issue #691: egui's floating bar hid the shortcut text's last character; `crates/ui-egui/src/tests_menubar.rs`) |
|
||||
| MENU-APP-ABOUT | About | P2 | ✅ | `cmd:app.about` | |
|
||||
| MENU-APP-SETTINGS | Settings… | P0 | ✅ | `cmd:app.settings` | app menu on macOS, Edit menu elsewhere |
|
||||
| MENU-APP-UPDATES | Check for updates | P2 | ⬜ | | |
|
||||
|
||||
Reference in new issue
Block a user