UI: Generalize drop target API, support them for UI views #105963

Closed
Julian Eisel wants to merge 8 commits from JulianEisel:temp-ui-view-drop-controller into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
9 changed files with 138 additions and 145 deletions
Showing only changes of commit 232a9a9f10 - Show all commits

View File

@ -12,7 +12,7 @@
* - Custom context menus
* - Notifier listening
* - Drag controllers (dragging view items)
* - Drop controllers (dropping onto/into view items)
* - Drop targets (dropping onto/into view items)
*/
#pragma once
@ -40,12 +40,12 @@ struct wmNotifier;
namespace blender::ui {
class AbstractViewItem;
class AbstractViewItemDropController;
class AbstractViewItemDropTarget;
class AbstractViewItemDragController;
/** The view drop controller can share logic with the view item drop controller for now, so just an
* alias. */
using AbstractViewDropController = AbstractViewItemDropController;
/** The view drop target can share logic with the view item drop target for now, so just an alias.
*/
using AbstractViewDropTarget = AbstractViewItemDropTarget;
class AbstractView {
friend class AbstractViewItem;
@ -68,13 +68,13 @@ class AbstractView {
virtual ~AbstractView() = default;
/**
* If a view wants to support dropping data into it, it has to return a drop controller here.
* That is an object implementing #AbstractViewDropController.
* If a view wants to support dropping data into it, it has to return a drop target here.
* That is an object implementing #AbstractViewDropTarget.
*
* \note This drop controller may be requested for each event. The view doesn't keep a drop
* controller around currently. So it can not contain persistent state.
* \note This drop target may be requested for each event. The view doesn't keep the drop target
* around currently. So it cannot contain persistent state.
*/
virtual std::unique_ptr<AbstractViewDropController> create_drop_controller() const;
virtual std::unique_ptr<AbstractViewDropTarget> create_drop_target() const;
/** Listen to a notifier, returning true if a redraw is needed. */
virtual bool listen(const wmNotifier &) const;
@ -160,13 +160,13 @@ class AbstractViewItem {
*/
virtual std::unique_ptr<AbstractViewItemDragController> create_drag_controller() const;
/**
* If an item wants to support dropping data into it, it has to return a drop controller here.
* That is an object implementing #AbstractViewItemDropController.
* If an item wants to support dropping data into it, it has to return a drop target here.
* That is an object implementing #AbstractViewItemDropTarget.
*
* \note This drop controller may be requested for each event. The view doesn't keep a drop
* controller around currently. So it can not contain persistent state.
* \note This drop target may be requested for each event. The view doesn't keep a drop target
* around currently. So it can not contain persistent state.
*/
virtual std::unique_ptr<AbstractViewItemDropController> create_drop_controller() const;
virtual std::unique_ptr<AbstractViewItemDropTarget> create_drop_target() const;
/** Get the view this item is registered for using #AbstractView::register_item(). */
AbstractView &get_view() const;
@ -227,7 +227,7 @@ template<typename ToType> ToType *AbstractViewItem::from_item_handle(uiViewItemH
* \{ */
/**
* Class to enable dragging a view item. An item can return a drop controller for itself by
* Class to enable dragging a view item. An item can return a drag controller for itself by
* implementing #AbstractViewItem::create_drag_controller().
*/
class AbstractViewItemDragController {
@ -249,15 +249,15 @@ class AbstractViewItemDragController {
/**
* Class to define the behavior when dropping something onto/into a view item, plus the behavior
* when dragging over this item. An item can return a drop controller for itself via a custom
* implementation of #AbstractViewItem::create_drop_controller().
* when dragging over this item. An item can return a drop target for itself via a custom
* implementation of #AbstractViewItem::create_drop_target().
*/
class AbstractViewItemDropController : public DropControllerInterface {
class AbstractViewItemDropTarget : public DropTargetInterface {
protected:
AbstractView &view_;
public:
AbstractViewItemDropController(AbstractView &view);
AbstractViewItemDropTarget(AbstractView &view);
/** Request the view the item is registered for as type #ViewType. Throws a `std::bad_cast`
* exception if the view is not of the requested type. */
@ -271,7 +271,7 @@ template<class ViewType> ViewType &AbstractViewItemDragController::get_view() co
return dynamic_cast<ViewType &>(view_);
}
template<class ViewType> ViewType &AbstractViewItemDropController::get_view() const
template<class ViewType> ViewType &AbstractViewItemDropTarget::get_view() const
{
static_assert(std::is_base_of<AbstractView, ViewType>::value,
"Type must derive from and implement the ui::AbstractView interface");

View File

@ -61,17 +61,16 @@ void attribute_search_add_items(StringRefNull str,
bool is_first);
/**
* Interface class to implement dropping for various kinds of UI elements. This isn't used widely,
* only UI views and view items use it. Would probably be nice to have more general support for
* dropping this way.
* Interface class to implement dropping for various kinds of UI elements. This isn't used widely
* yet, only UI views and view items use it.
JulianEisel marked this conversation as resolved Outdated

This sort of "would probably be nice to use this more in the future" comment shouldn't be added to main I think. That makes sense in code documentation or design tasks, but the code should stand for itself generally, and this comment will just become out of date otherwise.

This sort of "would probably be nice to use this more in the future" comment shouldn't be added to main I think. That makes sense in code documentation or design tasks, but the code should stand for itself generally, and this comment will just become out of date otherwise.
*/
class DropControllerInterface {
class DropTargetInterface {
public:
DropControllerInterface() = default;
virtual ~DropControllerInterface() = default;
DropTargetInterface() = default;
virtual ~DropTargetInterface() = default;
/**
* Check if the data dragged with \a drag can be dropped on the element this controller is for.
* Check if the data dragged with \a drag can be dropped on the element this drop target is for.
* \param r_disabled_hint: Return a static string to display to the user, explaining why dropping
* isn't possible on this UI element. Shouldn't be done too aggressively,
* e.g. don't set this if the drag-type can't be dropped here; only if it
@ -80,15 +79,15 @@ class DropControllerInterface {
*/
virtual bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const = 0;
/**
* Custom text to display when dragging over the element using this drop controller. Should
* Custom text to display when dragging over the element using this drop target. Should
* explain what happens when dropping the data onto this UI element. Will only be used if
* #DropControllerInterface::can_drop() returns true, so the implementing override doesn't have
* #DropTargetInterface::can_drop() returns true, so the implementing override doesn't have
* to check that again. The returned value must be a translated string.
*/
virtual std::string drop_tooltip(const wmDrag &drag) const = 0;
/**
* Execute the logic to apply a drop of the data dragged with \a drag onto/into the UI element
* this controller is for.
* this drop target is for.
*/
virtual bool on_drop(bContext *C, const wmDrag &drag) const = 0;
};
@ -149,31 +148,31 @@ void UI_list_filter_and_sort_items(uiList *ui_list,
const char *propname,
uiListItemGetNameFn get_name_fn = nullptr);
std::unique_ptr<blender::ui::DropControllerInterface> UI_view_drop_controller(
std::unique_ptr<blender::ui::DropTargetInterface> UI_view_drop_target(
const uiViewHandle *view_handle);
std::unique_ptr<blender::ui::DropControllerInterface> UI_view_item_drop_controller(
std::unique_ptr<blender::ui::DropTargetInterface> UI_view_item_drop_target(
const uiViewItemHandle *item_handle);
/**
* Let a drop controller handle a drop event.
* Let a drop target handle a drop event.
* \return True if the dropping was successful.
*/
bool UI_drop_controller_apply_drop(bContext &C,
const blender::ui::DropControllerInterface &drop_controller,
const ListBase &drags);
bool UI_drop_target_apply_drop(bContext &C,
const blender::ui::DropTargetInterface &drop_target,
const ListBase &drags);
/**
* Call #DropControllerInterface::drop_tooltip() and return the result as newly allocated C string
* 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_controller_drop_tooltip(const blender::ui::DropControllerInterface &drop_controller,
const wmDrag &drag);
char *UI_drop_target_tooltip(const blender::ui::DropTargetInterface &drop_target,
const wmDrag &drag);

Ideally new functions added to this UI C++ header should be in the proper blender::ed::ui (looks like it's blender::ui right now, oops!) namespace, without the UI_ prefix. Might as well start that now IMO.

Ideally new functions added to this UI C++ header should be in the proper `blender::ed::ui` (looks like it's `blender::ui` right now, oops!) namespace, without the `UI_` prefix. Might as well start that now IMO.

Hmmm, I just can't myself to like non-member API functions that don't start with a prefix like UI_. It just looks like local functions to me, not API functions.
Not sure if this is a reasonable concern, or just me having this too deeply embedded in my brain cells :)

Hmmm, I just can't myself to like non-member API functions that don't start with a prefix like `UI_`. It just looks like local functions to me, not API functions. Not sure if this is a reasonable concern, or just me having this too deeply embedded in my brain cells :)

TBH I'd guess it's just something you're used to. With namespaces, it will usually be something like ui::public_function_thing(...) anyway, so the information is there it just looks different. That way it elegantly replaces the need for the ui_ prefix too.

I think consistency is worth it here.

TBH I'd guess it's just something you're used to. With namespaces, it will usually be something like `ui::public_function_thing(...)` anyway, so the information is there it just looks different. That way it elegantly replaces the need for the `ui_` prefix too. I think consistency is worth it here.

Still causes some itches to me, but that won't change unless I try hard enough ;/

Still causes some itches to me, but that won't change unless I try hard enough ;/
/**
* Try to find a view item with a drop controller under the mouse cursor, or if not found, a view
* with a drop controller.
* \param xy: Coordinate to find a drop controller at, in window space.
* 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::DropControllerInterface> UI_region_views_find_drop_controller_at(
std::unique_ptr<blender::ui::DropTargetInterface> UI_region_views_find_drop_target_at(
const ARegion *region, const int xy[2]);
/**

View File

@ -8,24 +8,23 @@
using namespace blender::ui;
bool UI_drop_controller_apply_drop(bContext &C,
const DropControllerInterface &drop_controller,
const ListBase &drags)
bool UI_drop_target_apply_drop(bContext &C,
const DropTargetInterface &drop_target,
const ListBase &drags)
{
const char *disabled_hint_dummy = nullptr;
LISTBASE_FOREACH (const wmDrag *, drag, &drags) {
if (drop_controller.can_drop(*drag, &disabled_hint_dummy)) {
return drop_controller.on_drop(&C, *drag);
if (drop_target.can_drop(*drag, &disabled_hint_dummy)) {
return drop_target.on_drop(&C, *drag);
}
}
return false;
}
char *UI_drop_controller_drop_tooltip(const DropControllerInterface &drop_controller,
const wmDrag &drag)
char *UI_drop_target_tooltip(const DropTargetInterface &drop_target, const wmDrag &drag)
{
const std::string tooltip = drop_controller.drop_tooltip(drag);
const std::string tooltip = drop_target.drop_tooltip(drag);
return tooltip.empty() ? nullptr : BLI_strdup(tooltip.c_str());
}

View File

@ -32,9 +32,9 @@ static bool ui_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
const ARegion *region = CTX_wm_region(C);
std::unique_ptr<DropControllerInterface> drop_controller =
UI_region_views_find_drop_controller_at(region, event->xy);
if (!drop_controller) {
std::unique_ptr<DropTargetInterface> drop_target = UI_region_views_find_drop_target_at(
region, event->xy);
if (!drop_target) {
return false;
}
@ -43,16 +43,16 @@ static bool ui_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
}
drag->drop_state.free_disabled_info = false;
return drop_controller->can_drop(*drag, &drag->drop_state.disabled_info);
return drop_target->can_drop(*drag, &drag->drop_state.disabled_info);
}
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<DropControllerInterface> drop_controller =
UI_region_views_find_drop_controller_at(region, xy);
std::unique_ptr<DropTargetInterface> drop_target = UI_region_views_find_drop_target_at(region,
xy);
return UI_drop_controller_drop_tooltip(*drop_controller, *drag);
return UI_drop_target_tooltip(*drop_target, *drag);
}
/** \} */

View File

@ -2364,7 +2364,7 @@ static bool ui_view_drop_poll(bContext *C)
if (region == nullptr) {
return false;
}
return UI_region_views_find_drop_controller_at(region, win->eventstate->xy) != nullptr;
return UI_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,11 +2374,11 @@ static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *
}
const ARegion *region = CTX_wm_region(C);
std::unique_ptr<DropControllerInterface> drop_controller =
UI_region_views_find_drop_controller_at(region, event->xy);
std::unique_ptr<DropTargetInterface> drop_target = UI_region_views_find_drop_target_at(
region, event->xy);
if (!UI_drop_controller_apply_drop(
*C, *drop_controller, *static_cast<const ListBase *>(event->customdata))) {
if (!UI_drop_target_apply_drop(
*C, *drop_target, *static_cast<const ListBase *>(event->customdata))) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}

View File

@ -62,9 +62,9 @@ void AbstractView::update_from_old(uiBlock &new_block)
/** \name Default implementations of virtual functions
* \{ */
std::unique_ptr<AbstractViewDropController> AbstractView::create_drop_controller() const
std::unique_ptr<AbstractViewDropTarget> AbstractView::create_drop_target() const
{
/* There's no drop controller (and hence no drop support) by default. */
/* There's no drop target (and hence no drop support) by default. */
return nullptr;
}
@ -125,10 +125,10 @@ std::optional<rcti> AbstractView::get_bounds() const
using namespace blender::ui;
std::unique_ptr<DropControllerInterface> UI_view_drop_controller(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);
return view.create_drop_controller();
return view.create_drop_target();
}
/** \} */

View File

@ -174,9 +174,9 @@ std::unique_ptr<AbstractViewItemDragController> AbstractViewItem::create_drag_co
return nullptr;
}
std::unique_ptr<AbstractViewItemDropController> AbstractViewItem::create_drop_controller() const
std::unique_ptr<AbstractViewItemDropTarget> AbstractViewItem::create_drop_target() const
{
/* There's no drop controller (and hence no drop support) by default. */
/* There's no drop target (and hence no drop support) by default. */
return nullptr;
}
@ -189,7 +189,7 @@ void AbstractViewItemDragController::on_drag_start()
/* Do nothing by default. */
}
AbstractViewItemDropController::AbstractViewItemDropController(AbstractView &view) : view_(view)
AbstractViewItemDropTarget::AbstractViewItemDropTarget(AbstractView &view) : view_(view)
{
}
@ -309,11 +309,10 @@ bool UI_view_item_drag_start(bContext *C, const uiViewItemHandle *item_)
return ViewItemAPIWrapper::drag_start(*C, item);
}
std::unique_ptr<DropControllerInterface> UI_view_item_drop_controller(
const uiViewItemHandle *item_handle)
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_controller();
return item.create_drop_target();
}
/** \} */

View File

@ -189,15 +189,14 @@ uiViewItemHandle *UI_region_views_find_active_item(const ARegion *region)
return item_but->view_item;
}
std::unique_ptr<DropControllerInterface> UI_region_views_find_drop_controller_at(
const ARegion *region, const int xy[2])
std::unique_ptr<DropTargetInterface> UI_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<DropControllerInterface> drop_controller = UI_view_item_drop_controller(
hovered_view_item);
if (drop_controller) {
return drop_controller;
std::unique_ptr<DropTargetInterface> drop_target = UI_view_item_drop_target(hovered_view_item);
if (drop_target) {
return drop_target;
}
}
@ -205,10 +204,9 @@ std::unique_ptr<DropControllerInterface> UI_region_views_find_drop_controller_at
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<DropControllerInterface> drop_controller = UI_view_drop_controller(
hovered_view);
if (drop_controller) {
return drop_controller;
std::unique_ptr<DropTargetInterface> drop_target = UI_view_drop_target(hovered_view);
if (drop_target) {
return drop_target;
}
}

View File

@ -49,7 +49,7 @@ class AssetCatalogTreeView : public ui::AbstractTreeView {
SpaceFile &space_file_;
friend class AssetCatalogTreeViewItem;
friend class AssetCatalogDropController;
friend class AssetCatalogDropTarget;
friend class AssetCatalogTreeViewAllItem;
public:
@ -90,7 +90,7 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
/** Add drag support for catalog items. */
std::unique_ptr<ui::AbstractViewItemDragController> create_drag_controller() const override;
/** Add dropping support for catalog items. */
std::unique_ptr<ui::AbstractViewItemDropController> create_drop_controller() const override;
std::unique_ptr<ui::AbstractViewItemDropTarget> create_drop_target() const override;
};
class AssetCatalogDragController : public ui::AbstractViewItemDragController {
@ -105,11 +105,11 @@ class AssetCatalogDragController : public ui::AbstractViewItemDragController {
void on_drag_start() override;
};
class AssetCatalogDropController : public ui::AbstractViewItemDropController {
class AssetCatalogDropTarget : public ui::AbstractViewItemDropTarget {
AssetCatalogTreeItem &catalog_item_;
public:
AssetCatalogDropController(AssetCatalogTreeView &tree_view, AssetCatalogTreeItem &catalog_item);
AssetCatalogDropTarget(AssetCatalogTreeView &tree_view, AssetCatalogTreeItem &catalog_item);
bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override;
std::string drop_tooltip(const wmDrag &drag) const override;
@ -146,29 +146,29 @@ class AssetCatalogTreeViewAllItem : public ui::BasicTreeViewItem {
void build_row(uiLayout &row) override;
struct DropController : public ui::AbstractViewItemDropController {
DropController(AssetCatalogTreeView &tree_view);
struct DropTarget : public ui::AbstractViewItemDropTarget {
DropTarget(AssetCatalogTreeView &tree_view);
bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override;
std::string drop_tooltip(const wmDrag &drag) const override;
bool on_drop(struct bContext *C, const wmDrag &drag) const override;
};
std::unique_ptr<ui::AbstractViewItemDropController> create_drop_controller() const override;
std::unique_ptr<ui::AbstractViewItemDropTarget> create_drop_target() const override;
};
class AssetCatalogTreeViewUnassignedItem : public ui::BasicTreeViewItem {
using BasicTreeViewItem::BasicTreeViewItem;
struct DropController : public ui::AbstractViewItemDropController {
DropController(AssetCatalogTreeView &tree_view);
struct DropTarget : public ui::AbstractViewItemDropTarget {
DropTarget(AssetCatalogTreeView &tree_view);
bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override;
std::string drop_tooltip(const wmDrag &drag) const override;
bool on_drop(struct bContext *C, const wmDrag &drag) const override;
};
std::unique_ptr<ui::AbstractViewItemDropController> create_drop_controller() const override;
std::unique_ptr<ui::AbstractViewItemDropTarget> create_drop_target() const override;
};
/* ---------------------------------------------------------------------- */
@ -339,10 +339,10 @@ bool AssetCatalogTreeViewItem::rename(StringRefNull new_name)
return true;
}
std::unique_ptr<ui::AbstractViewItemDropController> AssetCatalogTreeViewItem::
create_drop_controller() const
std::unique_ptr<ui::AbstractViewItemDropTarget> AssetCatalogTreeViewItem::create_drop_target()
const
{
return std::make_unique<AssetCatalogDropController>(
return std::make_unique<AssetCatalogDropTarget>(
static_cast<AssetCatalogTreeView &>(get_tree_view()), catalog_item_);
}
@ -355,13 +355,13 @@ std::unique_ptr<ui::AbstractViewItemDragController> AssetCatalogTreeViewItem::
/* ---------------------------------------------------------------------- */
AssetCatalogDropController::AssetCatalogDropController(AssetCatalogTreeView &tree_view,
AssetCatalogTreeItem &catalog_item)
: ui::AbstractViewItemDropController(tree_view), catalog_item_(catalog_item)
AssetCatalogDropTarget::AssetCatalogDropTarget(AssetCatalogTreeView &tree_view,
AssetCatalogTreeItem &catalog_item)
: ui::AbstractViewItemDropTarget(tree_view), catalog_item_(catalog_item)
{
}
bool AssetCatalogDropController::can_drop(const wmDrag &drag, const char **r_disabled_hint) const
bool AssetCatalogDropTarget::can_drop(const wmDrag &drag, const char **r_disabled_hint) const
{
if (drag.type == WM_DRAG_ASSET_CATALOG) {
const ::AssetLibrary &library = get_asset_library();
@ -389,7 +389,7 @@ bool AssetCatalogDropController::can_drop(const wmDrag &drag, const char **r_dis
return false;
}
std::string AssetCatalogDropController::drop_tooltip(const wmDrag &drag) const
std::string AssetCatalogDropTarget::drop_tooltip(const wmDrag &drag) const
{
if (drag.type == WM_DRAG_ASSET_CATALOG) {
return drop_tooltip_asset_catalog(drag);
@ -397,7 +397,7 @@ std::string AssetCatalogDropController::drop_tooltip(const wmDrag &drag) const
return drop_tooltip_asset_list(drag);
}
std::string AssetCatalogDropController::drop_tooltip_asset_catalog(const wmDrag &drag) const
std::string AssetCatalogDropTarget::drop_tooltip_asset_catalog(const wmDrag &drag) const
{
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
const AssetCatalog *src_catalog = get_drag_catalog(drag, get_asset_library());
@ -406,7 +406,7 @@ std::string AssetCatalogDropController::drop_tooltip_asset_catalog(const wmDrag
TIP_("into") + " '" + catalog_item_.get_name() + "'";
}
std::string AssetCatalogDropController::drop_tooltip_asset_list(const wmDrag &drag) const
std::string AssetCatalogDropTarget::drop_tooltip_asset_list(const wmDrag &drag) const
{
BLI_assert(drag.type == WM_DRAG_ASSET_LIST);
@ -429,7 +429,7 @@ std::string AssetCatalogDropController::drop_tooltip_asset_list(const wmDrag &dr
return basic_tip;
}
bool AssetCatalogDropController::on_drop(struct bContext *C, const wmDrag &drag) const
bool AssetCatalogDropTarget::on_drop(struct bContext *C, const wmDrag &drag) const
{
if (drag.type == WM_DRAG_ASSET_CATALOG) {
return drop_asset_catalog_into_catalog(
@ -442,7 +442,7 @@ bool AssetCatalogDropController::on_drop(struct bContext *C, const wmDrag &drag)
catalog_item_.get_simple_name());
}
bool AssetCatalogDropController::drop_asset_catalog_into_catalog(
bool AssetCatalogDropTarget::drop_asset_catalog_into_catalog(
const wmDrag &drag,
AssetCatalogTreeView &tree_view,
const std::optional<CatalogID> drop_catalog_id)
@ -456,11 +456,11 @@ bool AssetCatalogDropController::drop_asset_catalog_into_catalog(
return true;
}
bool AssetCatalogDropController::drop_assets_into_catalog(struct bContext *C,
const AssetCatalogTreeView &tree_view,
const wmDrag &drag,
CatalogID catalog_id,
StringRefNull simple_name)
bool AssetCatalogDropTarget::drop_assets_into_catalog(struct bContext *C,
const AssetCatalogTreeView &tree_view,
const wmDrag &drag,
CatalogID catalog_id,
StringRefNull simple_name)
{
BLI_assert(drag.type == WM_DRAG_ASSET_LIST);
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
@ -491,8 +491,8 @@ bool AssetCatalogDropController::drop_assets_into_catalog(struct bContext *C,
return true;
}
AssetCatalog *AssetCatalogDropController::get_drag_catalog(const wmDrag &drag,
const ::AssetLibrary &asset_library)
AssetCatalog *AssetCatalogDropTarget::get_drag_catalog(const wmDrag &drag,
const ::AssetLibrary &asset_library)
{
if (drag.type != WM_DRAG_ASSET_CATALOG) {
return nullptr;
@ -504,8 +504,7 @@ AssetCatalog *AssetCatalogDropController::get_drag_catalog(const wmDrag &drag,
return catalog_service->find_catalog(catalog_drag->drag_catalog_id);
}
bool AssetCatalogDropController::has_droppable_asset(const wmDrag &drag,
const char **r_disabled_hint)
bool AssetCatalogDropTarget::has_droppable_asset(const wmDrag &drag, const char **r_disabled_hint)
{
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
@ -521,8 +520,8 @@ bool AssetCatalogDropController::has_droppable_asset(const wmDrag &drag,
return false;
}
bool AssetCatalogDropController::can_modify_catalogs(const ::AssetLibrary &library,
const char **r_disabled_hint)
bool AssetCatalogDropTarget::can_modify_catalogs(const ::AssetLibrary &library,
const char **r_disabled_hint)
{
if (ED_asset_catalogs_read_only(library)) {
*r_disabled_hint = "Catalogs cannot be edited in this asset library";
@ -531,7 +530,7 @@ bool AssetCatalogDropController::can_modify_catalogs(const ::AssetLibrary &libra
return true;
}
::AssetLibrary &AssetCatalogDropController::get_asset_library() const
::AssetLibrary &AssetCatalogDropTarget::get_asset_library() const
{
return *get_view<AssetCatalogTreeView>().asset_library_;
}
@ -580,30 +579,30 @@ void AssetCatalogTreeViewAllItem::build_row(uiLayout &row)
RNA_string_set(props, "parent_path", nullptr);
}
std::unique_ptr<ui::AbstractViewItemDropController> AssetCatalogTreeViewAllItem::
create_drop_controller() const
std::unique_ptr<ui::AbstractViewItemDropTarget> AssetCatalogTreeViewAllItem::create_drop_target()
const
{
return std::make_unique<AssetCatalogTreeViewAllItem::DropController>(
return std::make_unique<AssetCatalogTreeViewAllItem::DropTarget>(
static_cast<AssetCatalogTreeView &>(get_tree_view()));
}
AssetCatalogTreeViewAllItem::DropController::DropController(AssetCatalogTreeView &tree_view)
: ui::AbstractViewItemDropController(tree_view)
AssetCatalogTreeViewAllItem::DropTarget::DropTarget(AssetCatalogTreeView &tree_view)
: ui::AbstractViewItemDropTarget(tree_view)
{
}
bool AssetCatalogTreeViewAllItem::DropController::can_drop(const wmDrag &drag,
const char **r_disabled_hint) const
bool AssetCatalogTreeViewAllItem::DropTarget::can_drop(const wmDrag &drag,
const char **r_disabled_hint) const
{
if (drag.type != WM_DRAG_ASSET_CATALOG) {
return false;
}
::AssetLibrary &library = *get_view<AssetCatalogTreeView>().asset_library_;
if (!AssetCatalogDropController::can_modify_catalogs(library, r_disabled_hint)) {
if (!AssetCatalogDropTarget::can_modify_catalogs(library, r_disabled_hint)) {
return false;
}
const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog(drag, library);
const AssetCatalog *drag_catalog = AssetCatalogDropTarget::get_drag_catalog(drag, library);
if (drag_catalog->path.parent() == "") {
*r_disabled_hint = "Catalog is already placed at the highest level";
return false;
@ -612,21 +611,21 @@ bool AssetCatalogTreeViewAllItem::DropController::can_drop(const wmDrag &drag,
return true;
}
std::string AssetCatalogTreeViewAllItem::DropController::drop_tooltip(const wmDrag &drag) const
std::string AssetCatalogTreeViewAllItem::DropTarget::drop_tooltip(const wmDrag &drag) const
{
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog(
const AssetCatalog *drag_catalog = AssetCatalogDropTarget::get_drag_catalog(
drag, *get_view<AssetCatalogTreeView>().asset_library_);
return std::string(TIP_("Move Catalog")) + " '" + drag_catalog->path.name() + "' " +
TIP_("to the top level of the tree");
}
bool AssetCatalogTreeViewAllItem::DropController::on_drop(struct bContext * /*C*/,
const wmDrag &drag) const
bool AssetCatalogTreeViewAllItem::DropTarget::on_drop(struct bContext * /*C*/,
const wmDrag &drag) const
{
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
return AssetCatalogDropController::drop_asset_catalog_into_catalog(
return AssetCatalogDropTarget::drop_asset_catalog_into_catalog(
drag,
get_view<AssetCatalogTreeView>(),
/* No value to drop into the root level. */
@ -635,29 +634,28 @@ bool AssetCatalogTreeViewAllItem::DropController::on_drop(struct bContext * /*C*
/* ---------------------------------------------------------------------- */
std::unique_ptr<ui::AbstractViewItemDropController> AssetCatalogTreeViewUnassignedItem::
create_drop_controller() const
std::unique_ptr<ui::AbstractViewItemDropTarget> AssetCatalogTreeViewUnassignedItem::
create_drop_target() const
{
return std::make_unique<AssetCatalogTreeViewUnassignedItem::DropController>(
return std::make_unique<AssetCatalogTreeViewUnassignedItem::DropTarget>(
static_cast<AssetCatalogTreeView &>(get_tree_view()));
}
AssetCatalogTreeViewUnassignedItem::DropController::DropController(AssetCatalogTreeView &tree_view)
: ui::AbstractViewItemDropController(tree_view)
AssetCatalogTreeViewUnassignedItem::DropTarget::DropTarget(AssetCatalogTreeView &tree_view)
: ui::AbstractViewItemDropTarget(tree_view)
{
}
bool AssetCatalogTreeViewUnassignedItem::DropController::can_drop(
const wmDrag &drag, const char **r_disabled_hint) const
bool AssetCatalogTreeViewUnassignedItem::DropTarget::can_drop(const wmDrag &drag,
const char **r_disabled_hint) const
{
if (drag.type != WM_DRAG_ASSET_LIST) {
return false;
}
return AssetCatalogDropController::has_droppable_asset(drag, r_disabled_hint);
return AssetCatalogDropTarget::has_droppable_asset(drag, r_disabled_hint);
}
std::string AssetCatalogTreeViewUnassignedItem::DropController::drop_tooltip(
const wmDrag &drag) const
std::string AssetCatalogTreeViewUnassignedItem::DropTarget::drop_tooltip(const wmDrag &drag) const
{
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
@ -666,11 +664,11 @@ std::string AssetCatalogTreeViewUnassignedItem::DropController::drop_tooltip(
TIP_("Move asset out of any catalog");
}
bool AssetCatalogTreeViewUnassignedItem::DropController::on_drop(struct bContext *C,
const wmDrag &drag) const
bool AssetCatalogTreeViewUnassignedItem::DropTarget::on_drop(struct bContext *C,
const wmDrag &drag) const
{
/* Assign to nil catalog ID. */
return AssetCatalogDropController::drop_assets_into_catalog(
return AssetCatalogDropTarget::drop_assets_into_catalog(
C, get_view<AssetCatalogTreeView>(), drag, CatalogID{});
}