DragArea¶
Header: winui/ui/hosting/DragArea.hpp. Spec: winui/ui/hosting/DragArea.hpp.
A wrapper whose content the window can be dragged by. It stands in for the caption of a borderless window, or of content extended into the title bar, where a TitleBar doesn't fit, such as a splash screen's whole face, a sidebar header or a custom toolbar strip.
A press on the area moves the window, a double-click maximizes it and a right-click opens the system menu, except over a focusable control inside it: a label or icon drags, a button still clicks. In a window with an ordinary frame it does nothing. Otherwise it passes everything through to its content as ContentHost does, so wrapping a subtree changes nothing about how it lays out or behaves.
Example:
ui::Control<ui::Text> label;
ui::Control<ui::Button> cancel;
window.set_content(ui::DragArea{
.content = ui::VerticalStack{
.content = {
ui::Text{.text = "Loading...", .control = label},
ui::Button{.text = "Cancel", .on_click = [] { /* ... */ }, .control = cancel},
},
},
});
// window.hit_region_at(label->bounds().center()) == ui::HitRegion::Caption
// window.hit_region_at(cancel->bounds().center()) == ui::HitRegion::Client
ui::DragArea¶
Content the window can be dragged by, the caption stand-in for a borderless window wherever a TitleBar is not the right shape. Builds a ui::DragAreaControl.
Empty parts of the area hit-test as the window caption; interactive descendants (buttons, text boxes) stay ordinary client area, so they still take clicks.
Example:
window.set_content(ui::DragArea{
.content = ui::VerticalStack{.spacing = 12, .content = {
ui::Text{.text = "Loading..."}, // drags the window
ui::Button{.text = "Cancel", .on_click = [&] { window.close(); }}, // still clickable
}},
});
Every field, in the order a designated initializer names them:
ui::DragArea{
.style, .margin, .width, .height, .min_width, .min_height, .max_width, .max_height,
.horizontal_alignment, .vertical_alignment, .visible, .tool_tip, .accessibility,
.on_pointer_entered, .on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down,
.on_wheel, .control, .content
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
on_pointer_entered |
ui::Action |
The pointer moved onto the control. | |
on_pointer_exited |
ui::Action |
The pointer left the control. | |
on_got_focus |
ui::Action |
Keyboard focus arrived on the control, or on anything inside it, from outside it. A control with nothing focusable in it never gets focus, and never raises this. | |
on_lost_focus |
ui::Action |
Keyboard focus left the control and everything inside it. | |
on_key_down |
ui::Callback<ui::Handling(const ui::KeyEvent&)> |
A key pressed while focus is on the control or inside it, before the control's own handling; ui::Handled stops it there (Element::on_key_down()). | |
on_wheel |
ui::Callback<ui::Handling(const ui::PointerEvent&)> |
A wheel turn over the control, before the control scrolls; ui::Handled stops it there (Element::on_wheel()). | |
control |
ui::ControlOut<ui::DragArea> |
Out: the handle that receives the built control. | |
content |
ui::Spec |
What the area shows; may be empty for a bare drag band. |
Plus the common fields style, margin, width, height, min_width, min_height, max_width, max_height, horizontal_alignment, vertical_alignment, visible, tool_tip, accessibility every spec carries (conventions).
build¶
Consumes the spec and returns the built ui::DragAreaControl; the caller owns it.
ui::DragAreaControl¶
Derives from ui::ContentHost.
A wrapper whose content the window can be dragged by. It stands in for the caption of a borderless window, or of content extended into the title bar, where a TitleBar doesn't fit, such as a splash screen's whole face, a sidebar header or a custom toolbar strip.
A press on the area moves the window, a double-click maximizes it and a right-click opens the system menu, except over a focusable control inside it: a label or icon drags, a button still clicks. In a window with an ordinary frame it does nothing. Otherwise it passes everything through to its content as ContentHost does, so wrapping a subtree changes nothing about how it lays out or behaves.
Example:
ui::Control<ui::Text> label;
ui::Control<ui::Button> cancel;
window.set_content(ui::DragArea{
.content = ui::VerticalStack{
.content = {
ui::Text{.text = "Loading...", .control = label},
ui::Button{.text = "Cancel", .on_click = [] { /* ... */ }, .control = cancel},
},
},
});
// window.hit_region_at(label->bounds().center()) == ui::HitRegion::Caption
// window.hit_region_at(cancel->bounds().center()) == ui::HitRegion::Client
hit_test_transparent¶
False: the whole area takes the pointer, empty parts included, since they drag the window.
DragAreaControl¶
An empty area; give it content with ContentHost::set_child().
hit_region¶
Caption everywhere inside the area, except Client along the path under p from the first focusable element down (that element takes the press).
Tests¶
tests/test_window_state.cpp