UI: Generalize drop target API, support them for UI views #105963
|
@ -92,6 +92,29 @@ class DropTargetInterface {
|
||||||
virtual bool on_drop(bContext *C, const wmDrag &drag) const = 0;
|
virtual bool on_drop(bContext *C, const wmDrag &drag) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Let a drop target handle a drop event.
|
||||||
|
* \return True if the dropping was successful.
|
||||||
|
*/
|
||||||
|
bool drop_target_apply_drop(bContext &C,
|
||||||
|
const DropTargetInterface &drop_target,
|
||||||
|
const ListBase &drags);
|
||||||
|
/**
|
||||||
|
* Call #DropTargetInterface::drop_tooltip() and return the result as newly allocated C string
|
||||||
|
* (unless the result is empty, returns null then). Needs freeing with MEM_freeN().
|
||||||
|
*/
|
||||||
|
char *drop_target_tooltip(const DropTargetInterface &drop_target, const wmDrag &drag);
|
||||||
|
|
||||||
|
std::unique_ptr<DropTargetInterface> view_drop_target(const uiViewHandle *view_handle);
|
||||||
|
std::unique_ptr<DropTargetInterface> view_item_drop_target(const uiViewItemHandle *item_handle);
|
||||||
|
/**
|
||||||
|
* Try to find a view item with a drop target under the mouse cursor, or if not found, a view
|
||||||
|
* with a drop target.
|
||||||
|
* \param xy: Coordinate to find a drop target at, in window space.
|
||||||
|
*/
|
||||||
|
std::unique_ptr<DropTargetInterface> region_views_find_drop_target_at(const ARegion *region,
|
||||||
|
const int xy[2]);
|
||||||
|
|
||||||
} // namespace blender::ui
|
} // namespace blender::ui
|
||||||
|
|
||||||
enum eUIListFilterResult {
|
enum eUIListFilterResult {
|
||||||
|
@ -148,33 +171,6 @@ void UI_list_filter_and_sort_items(uiList *ui_list,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
uiListItemGetNameFn get_name_fn = nullptr);
|
uiListItemGetNameFn get_name_fn = nullptr);
|
||||||
|
|
||||||
std::unique_ptr<blender::ui::DropTargetInterface> UI_view_drop_target(
|
|
||||||
const uiViewHandle *view_handle);
|
|
||||||
std::unique_ptr<blender::ui::DropTargetInterface> UI_view_item_drop_target(
|
|
||||||
const uiViewItemHandle *item_handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Let a drop target handle a drop event.
|
|
||||||
* \return True if the dropping was successful.
|
|
||||||
*/
|
|
||||||
bool UI_drop_target_apply_drop(bContext &C,
|
|
||||||
const blender::ui::DropTargetInterface &drop_target,
|
|
||||||
const ListBase &drags);
|
|
||||||
/**
|
|
||||||
* Call #DropTargetInterface::drop_tooltip() and return the result as newly allocated C string
|
|
||||||
* (unless the result is empty, returns null then). Needs freeing with MEM_freeN().
|
|
||||||
*/
|
|
||||||
char *UI_drop_target_tooltip(const blender::ui::DropTargetInterface &drop_target,
|
|
||||||
const wmDrag &drag);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to find a view item with a drop target under the mouse cursor, or if not found, a view
|
|
||||||
* with a drop target.
|
|
||||||
* \param xy: Coordinate to find a drop target at, in window space.
|
|
||||||
*/
|
|
||||||
std::unique_ptr<blender::ui::DropTargetInterface> UI_region_views_find_drop_target_at(
|
|
||||||
const ARegion *region, const int xy[2]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this for all available view types.
|
* Override this for all available view types.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
#include "UI_interface.hh"
|
#include "UI_interface.hh"
|
||||||
|
|
||||||
using namespace blender::ui;
|
namespace blender::ui {
|
||||||
|
|
||||||
bool UI_drop_target_apply_drop(bContext &C,
|
bool drop_target_apply_drop(bContext &C,
|
||||||
const DropTargetInterface &drop_target,
|
const DropTargetInterface &drop_target,
|
||||||
const ListBase &drags)
|
const ListBase &drags)
|
||||||
{
|
{
|
||||||
|
|
||||||
const char *disabled_hint_dummy = nullptr;
|
const char *disabled_hint_dummy = nullptr;
|
||||||
|
@ -23,8 +23,10 @@ bool UI_drop_target_apply_drop(bContext &C,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *UI_drop_target_tooltip(const DropTargetInterface &drop_target, const wmDrag &drag)
|
char *drop_target_tooltip(const DropTargetInterface &drop_target, const wmDrag &drag)
|
||||||
{
|
{
|
||||||
const std::string tooltip = drop_target.drop_tooltip(drag);
|
const std::string tooltip = drop_target.drop_tooltip(drag);
|
||||||
return tooltip.empty() ? nullptr : BLI_strdup(tooltip.c_str());
|
return tooltip.empty() ? nullptr : BLI_strdup(tooltip.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace blender::ui
|
||||||
|
|
|
@ -32,7 +32,7 @@ static bool ui_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||||
{
|
{
|
||||||
const ARegion *region = CTX_wm_region(C);
|
const ARegion *region = CTX_wm_region(C);
|
||||||
|
|
||||||
std::unique_ptr<DropTargetInterface> drop_target = UI_region_views_find_drop_target_at(
|
std::unique_ptr<DropTargetInterface> drop_target = region_views_find_drop_target_at(
|
||||||
region, event->xy);
|
region, event->xy);
|
||||||
if (!drop_target) {
|
if (!drop_target) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -49,10 +49,10 @@ static bool ui_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||||
static char *ui_view_drop_tooltip(bContext *C, wmDrag *drag, const int xy[2], wmDropBox * /*drop*/)
|
static char *ui_view_drop_tooltip(bContext *C, wmDrag *drag, const int xy[2], wmDropBox * /*drop*/)
|
||||||
{
|
{
|
||||||
const ARegion *region = CTX_wm_region(C);
|
const ARegion *region = CTX_wm_region(C);
|
||||||
std::unique_ptr<DropTargetInterface> drop_target = UI_region_views_find_drop_target_at(region,
|
std::unique_ptr<DropTargetInterface> drop_target = region_views_find_drop_target_at(region,
|
||||||
xy);
|
xy);
|
||||||
|
|
||||||
return UI_drop_target_tooltip(*drop_target, *drag);
|
return drop_target_tooltip(*drop_target, *drag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
|
@ -2364,7 +2364,7 @@ static bool ui_view_drop_poll(bContext *C)
|
||||||
if (region == nullptr) {
|
if (region == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return UI_region_views_find_drop_target_at(region, win->eventstate->xy) != nullptr;
|
return region_views_find_drop_target_at(region, win->eventstate->xy) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
|
static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
|
||||||
|
@ -2374,10 +2374,10 @@ static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *
|
||||||
}
|
}
|
||||||
|
|
||||||
const ARegion *region = CTX_wm_region(C);
|
const ARegion *region = CTX_wm_region(C);
|
||||||
std::unique_ptr<DropTargetInterface> drop_target = UI_region_views_find_drop_target_at(
|
std::unique_ptr<DropTargetInterface> drop_target = region_views_find_drop_target_at(
|
||||||
region, event->xy);
|
region, event->xy);
|
||||||
|
|
||||||
if (!UI_drop_target_apply_drop(
|
if (!drop_target_apply_drop(
|
||||||
*C, *drop_target, *static_cast<const ListBase *>(event->customdata))) {
|
*C, *drop_target, *static_cast<const ListBase *>(event->customdata))) {
|
||||||
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,18 +117,16 @@ std::optional<rcti> AbstractView::get_bounds() const
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
} // namespace blender::ui
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
/** \name C-API
|
/** \name General API functions
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
using namespace blender::ui;
|
std::unique_ptr<DropTargetInterface> view_drop_target(const uiViewHandle *view_handle)
|
||||||
|
|
||||||
std::unique_ptr<DropTargetInterface> UI_view_drop_target(const uiViewHandle *view_handle)
|
|
||||||
{
|
{
|
||||||
const AbstractView &view = reinterpret_cast<const AbstractView &>(*view_handle);
|
const AbstractView &view = reinterpret_cast<const AbstractView &>(*view_handle);
|
||||||
return view.create_drop_target();
|
return view.create_drop_target();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
} // namespace blender::ui
|
||||||
|
|
|
@ -217,6 +217,18 @@ bool AbstractViewItem::is_active() const
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/** \name General API functions
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
std::unique_ptr<DropTargetInterface> view_item_drop_target(const uiViewItemHandle *item_handle)
|
||||||
|
{
|
||||||
|
const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_handle);
|
||||||
|
return item.create_drop_target();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
} // namespace blender::ui
|
} // namespace blender::ui
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
@ -309,10 +321,4 @@ bool UI_view_item_drag_start(bContext *C, const uiViewItemHandle *item_)
|
||||||
return ViewItemAPIWrapper::drag_start(*C, item);
|
return ViewItemAPIWrapper::drag_start(*C, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DropTargetInterface> UI_view_item_drop_target(const uiViewItemHandle *item_handle)
|
|
||||||
{
|
|
||||||
const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_handle);
|
|
||||||
return item.create_drop_target();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
|
@ -189,12 +189,14 @@ uiViewItemHandle *UI_region_views_find_active_item(const ARegion *region)
|
||||||
return item_but->view_item;
|
return item_but->view_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DropTargetInterface> UI_region_views_find_drop_target_at(const ARegion *region,
|
namespace blender::ui {
|
||||||
const int xy[2])
|
|
||||||
|
std::unique_ptr<DropTargetInterface> region_views_find_drop_target_at(const ARegion *region,
|
||||||
|
const int xy[2])
|
||||||
{
|
{
|
||||||
const uiViewItemHandle *hovered_view_item = UI_region_views_find_item_at(region, xy);
|
const uiViewItemHandle *hovered_view_item = UI_region_views_find_item_at(region, xy);
|
||||||
if (hovered_view_item) {
|
if (hovered_view_item) {
|
||||||
std::unique_ptr<DropTargetInterface> drop_target = UI_view_item_drop_target(hovered_view_item);
|
std::unique_ptr<DropTargetInterface> drop_target = view_item_drop_target(hovered_view_item);
|
||||||
if (drop_target) {
|
if (drop_target) {
|
||||||
return drop_target;
|
return drop_target;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +206,7 @@ std::unique_ptr<DropTargetInterface> UI_region_views_find_drop_target_at(const A
|
||||||
const uiStyle *style = UI_style_get_dpi();
|
const uiStyle *style = UI_style_get_dpi();
|
||||||
const uiViewHandle *hovered_view = UI_region_view_find_at(region, xy, style->buttonspacex);
|
const uiViewHandle *hovered_view = UI_region_view_find_at(region, xy, style->buttonspacex);
|
||||||
if (hovered_view) {
|
if (hovered_view) {
|
||||||
std::unique_ptr<DropTargetInterface> drop_target = UI_view_drop_target(hovered_view);
|
std::unique_ptr<DropTargetInterface> drop_target = view_drop_target(hovered_view);
|
||||||
if (drop_target) {
|
if (drop_target) {
|
||||||
return drop_target;
|
return drop_target;
|
||||||
}
|
}
|
||||||
|
@ -213,6 +215,8 @@ std::unique_ptr<DropTargetInterface> UI_region_views_find_drop_target_at(const A
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace blender::ui
|
||||||
|
|
||||||
static StringRef ui_block_view_find_idname(const uiBlock &block, const AbstractView &view)
|
static StringRef ui_block_view_find_idname(const uiBlock &block, const AbstractView &view)
|
||||||
{
|
{
|
||||||
/* First get the idname the of the view we're looking for. */
|
/* First get the idname the of the view we're looking for. */
|
||||||
|
|
Loading…
Reference in New Issue