forked from 1b-agent/opencadstudio-upstream
Ribbon key tips: Alt shows codes on tabs, buttons and menu items
A lone Alt shows a code on every ribbon tab and quick-access button. Typing a tab code opens the tab and shows the codes of its buttons, dropdowns, slide-outs and collapsed panels; a button code runs it, a dropdown or slide-out code opens it and shows its item codes, Esc goes back one level. Codes follow the reference ribbon; buttons without a reference counterpart get none and unnamed menu items are numbered. Codes are drawn as accent pills over the widgets that reported their bounds in the current frame, with a hint bar under the ribbon. While the tips are open keys go to them only. The automation gets a keytips action and read operation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
592289f4fd
commit
86429bf439
34 files changed
+1569
-53
No files matched your search
+37
-4
@@ -34,14 +34,46 @@ use crate::app::Message;
|
||||
thread_local! {
|
||||
/// Screen bounds of every ribbon dropdown button, keyed by dropdown id, so
|
||||
/// an open dropdown's overlay can anchor directly below its widget at any
|
||||
/// size. Written by `PosReport` on draw, read by `dropdown_bounds`.
|
||||
static DD_BOUNDS: RefCell<FxHashMap<String, Rectangle>> =
|
||||
/// size. Written by `PosReport` on draw, read by `dropdown_bounds`. Each
|
||||
/// entry keeps the frame it was drawn in (see `fresh_bounds`).
|
||||
static DD_BOUNDS: RefCell<FxHashMap<String, (Rectangle, u64)>> =
|
||||
RefCell::new(FxHashMap::default());
|
||||
/// Advanced by `end_frame` once everything above the widgets has drawn.
|
||||
static FRAME: Cell<u64> = const { Cell::new(0) };
|
||||
}
|
||||
|
||||
/// Last-drawn screen bounds of the dropdown button with this id.
|
||||
pub fn dropdown_bounds(id: &str) -> Option<Rectangle> {
|
||||
DD_BOUNDS.with(|m| m.borrow().get(id).copied())
|
||||
DD_BOUNDS.with(|m| m.borrow().get(id).map(|(bounds, _)| *bounds))
|
||||
}
|
||||
|
||||
/// Bounds of the widget `id` only when it was drawn in the current frame, so
|
||||
/// a widget that left the screen does not report its old place.
|
||||
pub fn fresh_bounds(id: &str) -> Option<Rectangle> {
|
||||
let frame = FRAME.with(Cell::get);
|
||||
DD_BOUNDS.with(|m| {
|
||||
m.borrow()
|
||||
.get(id)
|
||||
.filter(|(_, drawn)| *drawn == frame)
|
||||
.map(|(bounds, _)| *bounds)
|
||||
})
|
||||
}
|
||||
|
||||
/// Bounds of the widget `id` when it was drawn in the current or the last
|
||||
/// finished frame (for use between frames).
|
||||
pub fn recent_bounds(id: &str) -> Option<Rectangle> {
|
||||
let frame = FRAME.with(Cell::get);
|
||||
DD_BOUNDS.with(|m| {
|
||||
m.borrow()
|
||||
.get(id)
|
||||
.filter(|(_, drawn)| drawn + 1 >= frame)
|
||||
.map(|(bounds, _)| *bounds)
|
||||
})
|
||||
}
|
||||
|
||||
/// Close the current frame for `fresh_bounds`.
|
||||
pub fn end_frame() {
|
||||
FRAME.with(|frame| frame.set(frame.get() + 1));
|
||||
}
|
||||
|
||||
pub struct WrapBar<'a> {
|
||||
@@ -1038,7 +1070,8 @@ impl<'a> Widget<Message, Theme, Renderer> for PosReport<'a> {
|
||||
viewport: &Rectangle,
|
||||
) {
|
||||
DD_BOUNDS.with(|m| {
|
||||
m.borrow_mut().insert(self.id.to_string(), layout.bounds());
|
||||
m.borrow_mut()
|
||||
.insert(self.id.to_string(), (layout.bounds(), FRAME.with(Cell::get)));
|
||||
});
|
||||
self.child.as_widget().draw(
|
||||
&tree.children[0],
|
||||
|
||||
Reference in new issue
Block a user