UI: Generalize drop target API, support them for UI views #105963
|
@ -12,34 +12,44 @@
|
|||
* - 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
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_vec_types.h"
|
||||
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
|
||||
struct bContext;
|
||||
struct uiBlock;
|
||||
struct uiLayout;
|
||||
struct uiViewItemHandle;
|
||||
struct ViewLink;
|
||||
struct wmDrag;
|
||||
struct wmNotifier;
|
||||
|
||||
namespace blender::ui {
|
||||
|
||||
class AbstractViewItem;
|
||||
class AbstractViewItemDropController;
|
||||
class AbstractViewItemDropTarget;
|
||||
class AbstractViewItemDragController;
|
||||
|
||||
/** 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;
|
||||
friend struct ::ViewLink;
|
||||
|
||||
bool is_reconstructed_ = false;
|
||||
/**
|
||||
|
@ -51,9 +61,21 @@ class AbstractView {
|
|||
*/
|
||||
std::unique_ptr<std::array<char, MAX_NAME>> rename_buffer_;
|
||||
|
||||
/* See #get_bounds(). */
|
||||
std::optional<rcti> bounds_;
|
||||
|
||||
public:
|
||||
virtual ~AbstractView() = default;
|
||||
|
||||
/**
|
||||
* 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 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<AbstractViewDropTarget> create_drop_target() const;
|
||||
|
||||
/** Listen to a notifier, returning true if a redraw is needed. */
|
||||
virtual bool listen(const wmNotifier &) const;
|
||||
|
||||
|
@ -70,6 +92,11 @@ class AbstractView {
|
|||
void end_renaming();
|
||||
Span<char> get_rename_buffer() const;
|
||||
MutableSpan<char> get_rename_buffer();
|
||||
/**
|
||||
* Get the rectangle containing all the view items that are in the layout, in button space.
|
||||
* Updated as part of #UI_block_end(), before that it's unset.
|
||||
*/
|
||||
std::optional<rcti> get_bounds() const;
|
||||
|
||||
protected:
|
||||
AbstractView() = default;
|
||||
|
@ -133,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;
|
||||
|
@ -200,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 {
|
||||
|
@ -222,38 +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 {
|
||||
class AbstractViewItemDropTarget : public DropTargetInterface {
|
||||
protected:
|
||||
AbstractView &view_;
|
||||
|
||||
public:
|
||||
AbstractViewItemDropController(AbstractView &view);
|
||||
virtual ~AbstractViewItemDropController() = default;
|
||||
|
||||
/**
|
||||
* Check if the data dragged with \a drag can be dropped on the item this controller is for.
|
||||
* \param r_disabled_hint: Return a static string to display to the user, explaining why dropping
|
||||
* isn't possible on this item. Shouldn't be done too aggressively, e.g.
|
||||
* don't set this if the drag-type can't be dropped here; only if it can
|
||||
* but there's another reason it can't be dropped.
|
||||
* Can assume this is a non-null pointer.
|
||||
*/
|
||||
virtual bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const = 0;
|
||||
/**
|
||||
* Custom text to display when dragging over a view item. Should explain what happens when
|
||||
* dropping the data onto this item. Will only be used if #AbstractViewItem::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 item this
|
||||
* controller is for.
|
||||
*/
|
||||
virtual bool on_drop(struct bContext *C, const wmDrag &drag) = 0;
|
||||
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. */
|
||||
|
@ -267,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");
|
||||
|
|
|
@ -3274,18 +3274,12 @@ void UI_view_item_context_menu_build(struct bContext *C,
|
|||
* \return True if dragging started successfully, otherwise false.
|
||||
*/
|
||||
bool UI_view_item_drag_start(struct bContext *C, const uiViewItemHandle *item_);
|
||||
bool UI_view_item_can_drop(const uiViewItemHandle *item_,
|
||||
const struct wmDrag *drag,
|
||||
const char **r_disabled_hint);
|
||||
char *UI_view_item_drop_tooltip(const uiViewItemHandle *item, const struct wmDrag *drag);
|
||||
/**
|
||||
* Let a view item handle a drop event.
|
||||
* \return True if the drop was handled by the view item.
|
||||
*/
|
||||
bool UI_view_item_drop_handle(struct bContext *C,
|
||||
const uiViewItemHandle *item_,
|
||||
const struct ListBase *drags);
|
||||
|
||||
/**
|
||||
* \param xy: Coordinate to find a view item at, in window space.
|
||||
* \param pad: Extra padding added to the bounding box of the view.
|
||||
*/
|
||||
uiViewHandle *UI_region_view_find_at(const struct ARegion *region, const int xy[2], int pad);
|
||||
/**
|
||||
* \param xy: Coordinate to find a view item at, in window space.
|
||||
*/
|
||||
|
|
|
@ -18,11 +18,17 @@ namespace blender::nodes::geo_eval_log {
|
|||
struct GeometryAttributeInfo;
|
||||
}
|
||||
|
||||
struct ARegion;
|
||||
struct bContext;
|
||||
struct PointerRNA;
|
||||
struct StructRNA;
|
||||
struct uiBlock;
|
||||
struct uiLayout;
|
||||
struct uiList;
|
||||
struct uiSearchItems;
|
||||
struct uiViewHandle;
|
||||
struct uiViewItemHandle;
|
||||
struct wmDrag;
|
||||
|
||||
namespace blender::ui {
|
||||
|
||||
|
@ -54,6 +60,67 @@ void attribute_search_add_items(StringRefNull str,
|
|||
uiSearchItems *items,
|
||||
bool is_first);
|
||||
|
||||
/**
|
||||
* This provides a common interface for UI elements that want to support dragging & dropping
|
||||
* entities into/onto them. With it, the element can determine if the dragged entity can be dropped
|
||||
JulianEisel marked this conversation as resolved
Outdated
|
||||
* onto itself, provide feedback while dragging and run custom code for the dropping.
|
||||
*
|
||||
* Note that this is just an interface. A #wmDropBox is needed to request instances of it from a UI
|
||||
* element and call its functions. For example the drop box using "UI_OT_view_drop" implements
|
||||
* dropping for views and view items via this interface. To support other kinds of UI elements,
|
||||
* similar drop boxes would be necessary.
|
||||
*/
|
||||
class DropTargetInterface {
|
||||
public:
|
||||
DropTargetInterface() = default;
|
||||
virtual ~DropTargetInterface() = default;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* can but there's another reason it can't be dropped. Can assume this is
|
||||
* a non-null pointer.
|
||||
*/
|
||||
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 target. Should
|
||||
* explain what happens when dropping the data onto this UI element. Will only be used if
|
||||
* #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 drop target is for.
|
||||
*/
|
||||
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 {
|
||||
|
|
|
@ -46,6 +46,7 @@ set(SRC
|
|||
interface_context_path.cc
|
||||
interface_drag.cc
|
||||
interface_draw.cc
|
||||
interface_drop.cc
|
||||
interface_dropboxes.cc
|
||||
interface_handlers.cc
|
||||
interface_icons.cc
|
||||
|
|
|
@ -2014,6 +2014,8 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
|
|||
break;
|
||||
}
|
||||
|
||||
ui_block_views_bounds_calc(block);
|
||||
|
||||
if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
|
||||
UI_block_bounds_set_normal(block, 0);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edinterface
|
||||
*/
|
||||
|
||||
#include "UI_interface.hh"
|
||||
|
||||
namespace blender::ui {
|
||||
|
||||
bool 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_target.can_drop(*drag, &disabled_hint_dummy)) {
|
||||
return drop_target.on_drop(&C, *drag);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
|
@ -20,6 +20,9 @@
|
|||
#include "WM_api.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_interface.hh"
|
||||
|
||||
using namespace blender::ui;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name View Drag/Drop Callbacks
|
||||
|
@ -28,28 +31,28 @@
|
|||
static bool ui_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
{
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
const uiViewItemHandle *hovered_item = UI_region_views_find_item_at(region, event->xy);
|
||||
if (!hovered_item) {
|
||||
|
||||
std::unique_ptr<DropTargetInterface> drop_target = region_views_find_drop_target_at(
|
||||
region, event->xy);
|
||||
if (!drop_target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (drag->drop_state.free_disabled_info) {
|
||||
MEM_SAFE_FREE(drag->drop_state.disabled_info);
|
||||
}
|
||||
|
||||
drag->drop_state.free_disabled_info = false;
|
||||
return UI_view_item_can_drop(hovered_item, 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);
|
||||
const uiViewItemHandle *hovered_item = UI_region_views_find_item_at(region, xy);
|
||||
if (!hovered_item) {
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<DropTargetInterface> drop_target = region_views_find_drop_target_at(region,
|
||||
xy);
|
||||
|
||||
return UI_view_item_drop_tooltip(hovered_item, drag);
|
||||
return drop_target_tooltip(*drop_target, *drag);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -1452,6 +1452,7 @@ void ui_interface_tag_script_reload_queries();
|
|||
/* interface_view.cc */
|
||||
|
||||
void ui_block_free_views(uiBlock *block);
|
||||
void ui_block_views_bounds_calc(const uiBlock *block);
|
||||
void ui_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params);
|
||||
uiViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block,
|
||||
const uiViewHandle *new_view);
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "RNA_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_interface.hh"
|
||||
|
||||
#include "interface_intern.hh"
|
||||
|
||||
|
@ -65,6 +66,8 @@
|
|||
#include "ED_screen.h"
|
||||
#include "ED_text.h"
|
||||
|
||||
using namespace blender::ui;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Immediate redraw helper
|
||||
*
|
||||
|
@ -2351,7 +2354,7 @@ static void UI_OT_list_start_filter(wmOperatorType *ot)
|
|||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name UI Tree-View Drop Operator
|
||||
/** \name UI View Drop Operator
|
||||
* \{ */
|
||||
|
||||
static bool ui_view_drop_poll(bContext *C)
|
||||
|
@ -2361,9 +2364,7 @@ static bool ui_view_drop_poll(bContext *C)
|
|||
if (region == nullptr) {
|
||||
return false;
|
||||
}
|
||||
const uiViewItemHandle *hovered_item = UI_region_views_find_item_at(region, win->eventstate->xy);
|
||||
|
||||
return hovered_item != 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)
|
||||
|
@ -2373,10 +2374,11 @@ static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *
|
|||
}
|
||||
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
uiViewItemHandle *hovered_item = UI_region_views_find_item_at(region, event->xy);
|
||||
std::unique_ptr<DropTargetInterface> drop_target = region_views_find_drop_target_at(
|
||||
region, event->xy);
|
||||
|
||||
if (!UI_view_item_drop_handle(
|
||||
C, hovered_item, static_cast<const ListBase *>(event->customdata))) {
|
||||
if (!drop_target_apply_drop(
|
||||
*C, *drop_target, *static_cast<const ListBase *>(event->customdata))) {
|
||||
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
|
@ -2385,9 +2387,9 @@ static int ui_view_drop_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *
|
|||
|
||||
static void UI_OT_view_drop(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "View drop";
|
||||
ot->name = "View Drop";
|
||||
ot->idname = "UI_OT_view_drop";
|
||||
ot->description = "Drag and drop items onto a data-set item";
|
||||
ot->description = "Drag and drop onto a data-set or item within the data-set";
|
||||
|
||||
ot->invoke = ui_view_drop_invoke;
|
||||
ot->poll = ui_view_drop_poll;
|
||||
|
|
|
@ -62,6 +62,12 @@ void AbstractView::update_from_old(uiBlock &new_block)
|
|||
/** \name Default implementations of virtual functions
|
||||
* \{ */
|
||||
|
||||
std::unique_ptr<AbstractViewDropTarget> AbstractView::create_drop_target() const
|
||||
{
|
||||
/* There's no drop target (and hence no drop support) by default. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AbstractView::listen(const wmNotifier & /*notifier*/) const
|
||||
{
|
||||
/* Nothing by default. */
|
||||
|
@ -104,6 +110,23 @@ MutableSpan<char> AbstractView::get_rename_buffer()
|
|||
return *rename_buffer_;
|
||||
}
|
||||
|
||||
std::optional<rcti> AbstractView::get_bounds() const
|
||||
{
|
||||
return bounds_;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name General API functions
|
||||
* \{ */
|
||||
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -264,45 +276,6 @@ class ViewItemAPIWrapper {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool can_drop(const AbstractViewItem &item,
|
||||
const wmDrag &drag,
|
||||
const char **r_disabled_hint)
|
||||
{
|
||||
const std::unique_ptr<AbstractViewItemDropController> drop_controller =
|
||||
item.create_drop_controller();
|
||||
if (!drop_controller) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return drop_controller->can_drop(drag, r_disabled_hint);
|
||||
}
|
||||
|
||||
static std::string drop_tooltip(const AbstractViewItem &item, const wmDrag &drag)
|
||||
{
|
||||
const std::unique_ptr<AbstractViewItemDropController> drop_controller =
|
||||
item.create_drop_controller();
|
||||
if (!drop_controller) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return drop_controller->drop_tooltip(drag);
|
||||
}
|
||||
|
||||
static bool drop_handle(bContext &C, const AbstractViewItem &item, const ListBase &drags)
|
||||
{
|
||||
std::unique_ptr<AbstractViewItemDropController> drop_controller =
|
||||
item.create_drop_controller();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::ui
|
||||
|
@ -348,26 +321,4 @@ bool UI_view_item_drag_start(bContext *C, const uiViewItemHandle *item_)
|
|||
return ViewItemAPIWrapper::drag_start(*C, item);
|
||||
}
|
||||
|
||||
bool UI_view_item_can_drop(const uiViewItemHandle *item_,
|
||||
const wmDrag *drag,
|
||||
const char **r_disabled_hint)
|
||||
{
|
||||
const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_);
|
||||
return ViewItemAPIWrapper::can_drop(item, *drag, r_disabled_hint);
|
||||
}
|
||||
|
||||
char *UI_view_item_drop_tooltip(const uiViewItemHandle *item_, const wmDrag *drag)
|
||||
{
|
||||
const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_);
|
||||
|
||||
const std::string tooltip = ViewItemAPIWrapper::drop_tooltip(item, *drag);
|
||||
return tooltip.empty() ? nullptr : BLI_strdup(tooltip.c_str());
|
||||
}
|
||||
|
||||
bool UI_view_item_drop_handle(bContext *C, const uiViewItemHandle *item_, const ListBase *drags)
|
||||
{
|
||||
const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_);
|
||||
return ViewItemAPIWrapper::drop_handle(*C, item, *drags);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "BKE_screen.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_map.hh"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
|
@ -44,6 +45,8 @@ using namespace blender::ui;
|
|||
struct ViewLink : public Link {
|
||||
std::string idname;
|
||||
std::unique_ptr<AbstractView> view;
|
||||
|
||||
static void views_bounds_calc(const uiBlock &block);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
@ -81,6 +84,51 @@ void ui_block_free_views(uiBlock *block)
|
|||
}
|
||||
}
|
||||
|
||||
void ViewLink::views_bounds_calc(const uiBlock &block)
|
||||
{
|
||||
Map<AbstractView *, rcti> views_bounds;
|
||||
|
||||
rcti minmax;
|
||||
BLI_rcti_init_minmax(&minmax);
|
||||
LISTBASE_FOREACH (ViewLink *, link, &block.views) {
|
||||
views_bounds.add(link->view.get(), minmax);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (uiBut *, but, &block.buttons) {
|
||||
if (but->type != UI_BTYPE_VIEW_ITEM) {
|
||||
continue;
|
||||
}
|
||||
uiButViewItem *view_item_but = static_cast<uiButViewItem *>(but);
|
||||
if (!view_item_but->view_item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the view from the button. */
|
||||
AbstractViewItem &view_item = reinterpret_cast<AbstractViewItem &>(*view_item_but->view_item);
|
||||
AbstractView &view = view_item.get_view();
|
||||
|
||||
rcti &bounds = views_bounds.lookup(&view);
|
||||
rcti but_rcti{};
|
||||
BLI_rcti_rctf_copy_round(&but_rcti, &view_item_but->rect);
|
||||
BLI_rcti_do_minmax_rcti(&bounds, &but_rcti);
|
||||
}
|
||||
|
||||
for (const auto item : views_bounds.items()) {
|
||||
const rcti &bounds = item.value;
|
||||
if (BLI_rcti_is_empty(&bounds)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AbstractView &view = *item.key;
|
||||
view.bounds_ = bounds;
|
||||
}
|
||||
}
|
||||
|
||||
void ui_block_views_bounds_calc(const uiBlock *block)
|
||||
{
|
||||
ViewLink::views_bounds_calc(*block);
|
||||
}
|
||||
|
||||
void ui_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
|
||||
{
|
||||
ARegion *region = listener_params->region;
|
||||
|
@ -92,6 +140,35 @@ void ui_block_views_listen(const uiBlock *block, const wmRegionListenerParams *l
|
|||
}
|
||||
}
|
||||
|
||||
/* Similar to #ui_but_find_mouse_over_ex(). */
|
||||
uiViewHandle *UI_region_view_find_at(const ARegion *region, const int xy[2], const int pad)
|
||||
{
|
||||
if (!ui_region_contains_point_px(region, xy)) {
|
||||
return nullptr;
|
||||
}
|
||||
LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) {
|
||||
float mx = xy[0], my = xy[1];
|
||||
ui_window_to_block_fl(region, block, &mx, &my);
|
||||
|
||||
LISTBASE_FOREACH (ViewLink *, view_link, &block->views) {
|
||||
std::optional<rcti> bounds = view_link->view->get_bounds();
|
||||
if (!bounds) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rcti padded_bounds = *bounds;
|
||||
if (pad) {
|
||||
BLI_rcti_pad(&padded_bounds, pad, pad);
|
||||
}
|
||||
if (BLI_rcti_isect_pt(&padded_bounds, mx, my)) {
|
||||
return reinterpret_cast<uiViewHandle *>(view_link->view.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uiViewItemHandle *UI_region_views_find_item_at(const ARegion *region, const int xy[2])
|
||||
{
|
||||
uiButViewItem *item_but = (uiButViewItem *)ui_view_item_find_mouse_over(region, xy);
|
||||
|
@ -112,6 +189,34 @@ uiViewItemHandle *UI_region_views_find_active_item(const ARegion *region)
|
|||
return item_but->view_item;
|
||||
}
|
||||
|
||||
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 = view_item_drop_target(hovered_view_item);
|
||||
if (drop_target) {
|
||||
return drop_target;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get style for some sensible padding around the view items. */
|
||||
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 = view_drop_target(hovered_view);
|
||||
if (drop_target) {
|
||||
return drop_target;
|
||||
}
|
||||
}
|
||||
|
||||
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. */
|
||||
|
|
|
@ -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,15 +105,15 @@ 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;
|
||||
bool on_drop(struct bContext *C, const wmDrag &drag) override;
|
||||
bool on_drop(struct bContext *C, const wmDrag &drag) const override;
|
||||
|
||||
::AssetLibrary &get_asset_library() const;
|
||||
|
||||
|
@ -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) 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) 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)
|
||||
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)
|
||||
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)
|
||||
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{});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
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.