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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
enum eUIListFilterResult {
|
||||
|
@ -148,33 +171,6 @@ void UI_list_filter_and_sort_items(uiList *ui_list,
|
|||
const char *propname,
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
#include "UI_interface.hh"
|
||||
|
||||
using namespace blender::ui;
|
||||
namespace blender::ui {
|
||||
|
||||
bool UI_drop_target_apply_drop(bContext &C,
|
||||
const DropTargetInterface &drop_target,
|
||||
const ListBase &drags)
|
||||
bool drop_target_apply_drop(bContext &C,
|
||||
const DropTargetInterface &drop_target,
|
||||
const ListBase &drags)
|
||||
{
|
||||
|
||||
const char *disabled_hint_dummy = nullptr;
|
||||
|
@ -23,8 +23,10 @@ bool UI_drop_target_apply_drop(bContext &C,
|
|||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
if (!drop_target) {
|
||||
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*/)
|
||||
{
|
||||
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);
|
||||
|
||||
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) {
|
||||
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)
|
||||
|
@ -2374,10 +2374,10 @@ static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!UI_drop_target_apply_drop(
|
||||
if (!drop_target_apply_drop(
|
||||
*C, *drop_target, *static_cast<const ListBase *>(event->customdata))) {
|
||||
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> UI_view_drop_target(const uiViewHandle *view_handle)
|
||||
std::unique_ptr<DropTargetInterface> view_drop_target(const uiViewHandle *view_handle)
|
||||
{
|
||||
const AbstractView &view = reinterpret_cast<const AbstractView &>(*view_handle);
|
||||
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
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -309,10 +321,4 @@ bool UI_view_item_drag_start(bContext *C, const uiViewItemHandle *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;
|
||||
}
|
||||
|
||||
std::unique_ptr<DropTargetInterface> UI_region_views_find_drop_target_at(const ARegion *region,
|
||||
const int xy[2])
|
||||
namespace blender::ui {
|
||||
|
||||
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);
|
||||
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) {
|
||||
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 uiViewHandle *hovered_view = UI_region_view_find_at(region, xy, style->buttonspacex);
|
||||
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) {
|
||||
return drop_target;
|
||||
}
|
||||
|
@ -213,6 +215,8 @@ std::unique_ptr<DropTargetInterface> UI_region_views_find_drop_target_at(const A
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace blender::ui
|
||||
|
||||
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. */
|
||||
|
|
Loading…
Reference in New Issue