ui::DragDrop¶
Header: winui/ui/DragDrop.hpp.
The drag in progress, one per process: how a control starts an in-process drag and drop.
A source calls start() from its own pointer handling, usually once a pressed pointer has moved a few DIPs. The Window the event was dispatched in then takes the drag over: - pointer input drives the drag instead of reaching the tree - the recorded visual follows the pointer at 0.8 opacity - drop targets (Element::allow_drop()) get drag_enter(), drag_over(), drag_leave() and drop() - Escape cancels the drag
The source learns the outcome through Element::drag_completed(). Only one drag runs at a time, and start() while one is running is ignored. ListView, TileView and TreeView use this for their item dragging, and an app's own control can too.
Example:
class Chip final : public ui::Element
{
public:
explicit Chip(std::string label) : label_(std::move(label)) {}
void drag_completed(ui::DataPackageOperation result) override
{
dropped_ = result != ui::DataPackageOperation::None;
}
protected:
ui::Size measure_override(ui::Size, const ui::MeasureContext& context) const override
{
return context.measurer.measure(label_, context.theme.text_style);
}
void render_override(ui::Renderer& r, const ui::RenderContext& context) const override
{
r.draw_text(label_, bounds(), context.theme.colors().text, context.theme.text_style);
}
bool pointer_override(const ui::PointerEvent& e) override
{
if (e.action != ui::PointerAction::Down || ui::DragDrop::active())
{
return false;
}
ui::DataPackage package;
package.text = label_;
ui::RenderRecording visual; // what follows the pointer
render(visual);
ui::DragDrop::start(*this, std::move(package), std::move(visual), bounds(), e.position);
return true;
}
private:
std::string label_;
bool dropped_ = false;
};
start¶
static void start(Element& source, DataPackage data, RenderRecording visual, Rect visual_bounds, Point pointer)
Start carrying data from source. visual is drawn under the pointer. It is recorded in the same coordinates as visual_bounds, the dragged thing's rect, and pointer is where the pointer is now, so the visual keeps that offset to the pointer as it moves. Sets data.source to &source. Ignored while another drag is running.
active¶
Whether a drag is in progress (or about to be taken over by its window).
pending¶
Whether a drag has been started but no window has taken it over yet.
cancel¶
End the drag in progress without a drop. The source's drag_completed() gets None. A pending drag is discarded.