gfx/popup_overlay.h
A PopupMenu shown INSIDE the editor, and driven from the keyboard.
#include <sonore/gfx/popup_overlay.h>- 1type
- Guides: The native editor
On this page
Design notes
Why there is a second way to show a menu
native_editor.h's PopupWindow puts a menu in a real top-level window, which is right for a ComboBox: the menu may hang past the editor's edge, and the peer holds the grab that closes it. It is the wrong shape for a menu BAR. A bar's menus are entered with F10 and walked with the arrows -- Left and Right move to the neighbouring menu, which means the bar has to hear keys while its menu is open -- and moving the mouse along the bar with a menu open switches menus without a click. A separate window with its own grab makes both of those a conversation between two peers.
So this is alert.h's arrangement instead: an Overlay over the editor's root that swallows every event, with the list drawn where the menu goes. The owner (a menu bar, a toolbar's overflow, a file field's recent list) hears what happens OUTSIDE the list through three callbacks, which is all a bar needs to switch menus.
The cost is the one alert.h names: an overlay cannot extend past the editor's edge. A menu taller than the editor scrolls instead of running off it, so its last items stay reachable -- which is the rule popup.h's placeOnScreen exists to keep.
Choosing on release
A menu opened by pressing a bar item and dragged down is chosen by letting go over an item, in every desktop toolkit. The press belongs to the bar -- the router captured it before the menu existed -- so the bar forwards the drag and the release here (trackPointer, releasePointer). A release over nothing leaves the menu open, which is what turns the same press into a click-to-open.
Types 1
class PopupMenuOverlay : public Overlay
A PopupMenu drawn inside the editor, over its root, and walked from the keyboard -- what a menu bar opens, where a ComboBox uses a real popup window. The file comment says why there are two, and how choosing on release works.
The OWNER keeps one of these as a member and calls show() against itself; the overlay adds itself to the owner's root while open and takes itself out on dismiss(), so it must outlive every menu it shows. The answer arrives on the show() call's handler, exactly once, after the overlay is down. It cannot reach past the editor's edge: a long menu scrolls. Message thread only.