* craft-ui: combo boxes whose menu grows back with its contents
egui's ComboBox lays its menu out in the height it had on the previous pass,
and its scroll area takes no more than that. A filtered list that shrinks (a
search with no matches) never grows back when the search is cleared
(emilk/egui#5225, #5138). craft_ui::combo::menu offers its contents the full
height on every pass; craft_ui::combo::combo draws the combo box button
around it. The Font Manager's Language, Script and Sample menus use it.
* craft-ui: combo and menu take the close behaviour
A menu with a search field that closes itself on a pick (DesignCraft's font
menu) closes on a click outside only.
* craft-ui: ComboBox, a drop-in for egui's combo box, with header menus
craft_ui::ComboBox has egui 0.37's ComboBox builder and button (same
atoms, style classes and icon, pixel-identical in a test) with a menu that
grows back. show_ui_with_header and show_rows_with_header keep a search
field in place and scroll only the list; combo::Menu is the same menu under
a field an app draws itself. clippy.toml disallows egui::ComboBox.
The Font Manager's Language menu, the keymap dialog's combo boxes and the
print dialog's printer and duplex choices use it.
* craft-ui: combo menus keep to the room on their side, and footers
A menu is never taller than the room on the side of its field it opens on,
so an unbounded height fits on screen and scrolls. The side is settled once
the menu is measured and kept while it is open, so a menu that shrinks or
grows while typing doesn't jump to the other side of its field.
Footer forms keep a row under the scrolling list. Menu::new takes the
field's Ui for its default height and frame, and Menu::open shows the menu
under a text field that keeps the focus while typing.
* craft-ui: combo menus open by the app keep their side, and take picks
Menu::open takes &mut bool: the menu clears it when it closes (close
behavior, Escape, ui.close(), the field losing the focus to anything but
the menu), so a click on a row under a focused text field is picked.
The side settles only once the menu was shown and measured, also for
menus the app opens (Popup::open_id). A footer that changes height
remeasures the menu before it is shown. The popup frame's margins come
from the popup style; only above/below alignments are tried.
* craft-ui: a resting pointer over a combo menu doesn't keep it open
The menu counts the pointer as having moved into it only on a press or
click. A footer height change also requests a repaint, in case the
discard is denied.
* craft-ui: a footer menu opens without a second sizing pass
A footer height change no longer discards the pass or forces another
sizing pass: the menu measures again on the next pass and settles its
side then. A forced sizing pass ran a search field's focus request in a
pass where the field can't take the focus, so a footer menu opened with
the search unfocused.
* craft-ui: tests use Ui::scope_id
* craft-ui: hide the measuring pass of a footer menu, cap remeasures
The pass that measures a menu before its side is settled is laid out but
drawn fully transparent, so no frame shows a side or height the menu then
leaves. A footer that changes height on every pass remeasures twice per
open, then settles.
* craft-ui: tests satisfy clippy
Dragging a pane (a docked pane's title or a floating pane) over another
pane docked at a side edge offers two dock zones: the outer third docks
it directly outside that pane, the inner third directly inside it. The
middle third is no target. The window-edge strip docks a pane outermost
on that edge. The new PaneRequest::Before(pane, before) asks the app to
move the pane to directly before another in its open list, which sets
its position on the edge; the drop preview is laid out from that order,
so it matches where the pane lands. With one slot per edge, a closable
pane dropped on an edge takes the slot.
DockContent::group_extra_tabs_width and group_extra_tabs draw host tabs
right after a group's panel tabs, before the drag bar and the header.
They fit with the panel tabs as one more tab that never overflows: both
shrink widest first to min_tab_width, and in a narrower row the panel
tabs overflow while the extra tabs keep that width.
A native floating window is an egui pass of its own, and can draw several
panel bodies. A Composer drawn there records its descriptor, and the dock
area publishes it once, after the window's last body, so a body drawn after
the editor's cannot clear it and end the composition. DockContent::window_drawn
runs at the same point for apps that publish their own descriptor.
* docking: AppKit moves a native window for its bar drag on macOS
Moving a native window with OuterPosition every frame jitters on macOS:
the window's reported place and the pointer events disagree about where
the window is. On macOS the bar press (or the start of a drag of a
window's only tab or group) now sends ViewportCommand::StartDrag, which
winit turns into performWindowDragWithEvent, and the dock area sends no
OuterPosition for that drag.
egui keeps running frames during the move, but the window's reported
place lags it, so each frame takes the window's place as AppKit's
cursor (NSEvent::mouseLocation) less the pressed point. Drop targets,
the drag fade, cross-window routing and the drop use that point. The
drag ends on the first frame where NSEvent::pressedMouseButtons or egui
reports the release, and is resolved once; a desktop drop records
cursor less grab. Ctrl/Cmd is read from AppKit's modifier flags, since
AppKit sends no key events during the move, and Escape does not cancel
the move. A press released within the click distance docks nothing.
Windows, X11 and Wayland keep their paths.
The window system seam (WindowSystem, formerly DesktopCursor) tells the
cursor, the button, the modifiers and whether it moves windows.
NativeHost models AppKit's move (moves_windows, held): the window
follows the cursor at the grab and reports its place late. The
app-driven cursor path from #325 and its stale-pointer model are
removed, since macOS no longer takes that path.
* docs: a cancel during an AppKit bar drag leaves the window moving
A group dragged to the window edge where an iconic column sits showed the
edge line and an outline around the column. The edge line is drawn just
inside the window, so it lay in the column's body, and paint_drop_line
outlines the iconic column a line lies in. That outline is for drops into
the column; a window-edge drop docks beside it, so it now shows the line
alone.
* docking: menu key equivalents reach the focused text field of a native window
On macOS the menu bar takes key equivalents such as Cmd+C and Cmd+V before
the key window sees them, and an app's menu glue reports them in the main
window's input, where they ran on the document even while a text field in a
floating panel's own window had focus. Each native window notes its text
focus as it draws. While the window with the keyboard has a focused field,
the main window's input hands that window the keys a text field acts on
(Cmd+C/X/V/A, Cmd+Z and Shift+Cmd+Z, Cmd with the arrows, Cmd+Backspace and
Cmd+Delete, and Copy, Cut and Paste events); Cmd+C and Cmd+X arrive as Copy
and Cut, and Cmd+V asks the window for the clipboard text. Other command
keys stay with the main window, and nothing moves while input is blocked.
typing_window and send_keys expose the same routing to menus that run
commands themselves.
* docking: typing_window answers between frames with the last frame's focus
* docking: a dragged native window fades only while a drop target is highlighted
The dragged window stays opaque over empty space and goes to 75% only
while the bar, only-tab or only-tab-row drag shows a drop preview.
paint_group_drag reports whether it highlighted a target; end_cross keeps
that for the next frame, since the dragged window sets its opacity before
the preview is drawn.
* docking: a dragged in-window floating window fades only while a drop target is highlighted
The rule for native windows covers in-window floating windows too. A
title bar drag draws its window at DRAG_OPACITY (75%) while the drag
highlights a drop target, and opaque over empty space and after a drop,
Escape or focus loss. finish_group_drag keeps paint_group_drag's result
for the next frame, since the window draws before the preview.
FloatingFrame takes an opacity for the whole frame, contents included.
* docking: a title-bar drag also fades over a preview the host draws
* docking: keep native palettes shown while the app is inactive
Palettes no longer hide when none of the application's windows has focus.
They drop to WindowLevel::Normal while the application is inactive, so
they do not cover other applications, and go back to AlwaysOnTop when it
is active again. Files dragged from another application reach them, OS
sheets attached to them stay open, and they stay shown, dimmed, while an
app modal blocks input.
* docking: on Windows an inactive app's palettes go behind other windows
* docking: the viewer level test expects the inactive palette level
AppKit reports a native window's new place as soon as a move is
commanded, but measures the pointer events it sends against where the
window server had the window, which can be a move behind. Placing the
window from those events made it overshoot and step back while the
cursor moved smoothly.
On macOS the window now goes to NSEvent::mouseLocation, flipped against
the primary screen's height and divided by egui's zoom factor, less the
pressed point; drop targets are hit at the same point. Other platforms
keep placing the window from the frame's pointer move.
The cursor source is a DesktopCursor the test harness fixes. NativeHost
can tell the cursor (tells_cursor) and measure a window's pointer events
against its place some frames back (stale), through window_pointer.
A group bar drag to a dock band named by one of the moving panels, such as the window edge of the column the group heads, anchors on another panel of that column, as a tab drag does; with none, the drop is a no-op. Before, the model rejected the move and the drop did nothing.
Drops on the bands along the layout's outer edge (a new dock, a new outermost column, the outer edge band) preview the line along that edge instead of the rect the panels take; drops beside groups keep the rect. The window-edge column line sits inside the window, like the new-dock line.
With new_dock_zones (and without side_edge_zones), the body of a frame or
floating group that takes no tabs is no drop target, whatever its
accepts_splits. A floating window released there stays floating and a
docked panel floats as over empty space; the outer edge band, dock columns,
new docks and drops beside other groups still dock. Without new_dock_zones
the whole canvas body still goes to the nearest of drop_edges.
* docking: a minimized native window shrinks to its bar
A floating window shown in its own OS window kept its full size when
minimized, with an empty body under the tab strip. Minimizing now sizes
the OS window to its bar and the tab strip of its only group, at the
same width and top-left corner, and fixes its height with the window's
min and max inner size; expanding restores the saved size. The layout's
native and in-window rects keep the expanded height: the collapsed
height the window reports is not recorded, its position and width are.
* docking: a minimized native window's limits change before its size, and follow its bar height
* docking: fade a dragged native window only when the drag can dock
* docking: narrow the outer edge band to the canvas column and add DockStyle::drop_edges
* docking: drop_edges defaults to all sides; the docking profile's outer band takes only its top and bottom
* panes: preview the slot a dragged pane docks in, also while floating
* docking: a drop that changes only sizes is a no-op; a lone floating group's header drag looks through its window
* docking: a drop beside a frame too narrow to halve takes the room from beyond its divider
* panes: the dock preview counts a pane its drop reveals, and a side pane stays inside the host
With SidePolicy::OneSlot a drop can reveal a pane the frame hides, so the landing slot is
worked out from every open pane. A side pane is no wider than the room the panes outside it
leave, as the preview assumes; egui placed a wider one partly beyond the host's edge.
* docking: anchor an outer edge drop on the area it shows
The edge band and window.panel.dock to an outer edge anchor on the canvas only where the edge area narrows to the canvas column, else on a panel that is not protected, so tree order no longer decides the frame. The renderer tries the drop and offers the band only when it wraps the panels the band shows. A top (bottom) edge also narrows a split of rows to its first (last) row when only that row holds the canvas. to_actions takes the permissions, and FloatSpace records side_edge_zones.
* docking: a sized split gives the new frame its minimum or saved width
* docking: keep a native window opaque during a float-only drag
* docking: DockCommand::to_actions keeps its signature; to_actions_with takes the permissions
FilmCraft calls to_actions. Without permissions no panel is protected, so an outer edge dock
wraps the part between the docks, as before.
* docking: keep a tab's focus outline after Space or Enter
A focused tab activated from the keyboard reported a click, which marked its
focus as pointer focus and hid the outline. Only a primary pointer click marks
it now. The group header and DockArea::monitors docs say how a header widget
starts a drag and where an eframe app gets its monitor list.
* docking: name the area id in the group header's begin_drag note
* ui: panes::Rail, an icon strip that opens one task pane at a time
* ui: panes: a docked pane can go without its title bar
* ui: panes::Rail review fixes
* ui: panes: a docked pane's resize edge works on both sides of the line
The edge band and window.panel.dock to an outer edge anchor on the canvas only where the edge area narrows to the canvas column, else on a panel that is not protected, so tree order no longer decides the frame. The renderer tries the drop and offers the band only when it wraps the panels the band shows. A top (bottom) edge also narrows a split of rows to its first (last) row when only that row holds the canvas. to_actions takes the permissions, and FloatSpace records side_edge_zones.
With SidePolicy::OneSlot a drop can reveal a pane the frame hides, so the landing slot is
worked out from every open pane. A side pane is no wider than the room the panes outside it
leave, as the preview assumes; egui placed a wider one partly beyond the host's edge.