Asset Browser: Support dragging catalogs to move them in the hierarchy
Uses the additions to the UI tree-view API from the previous commit to enable drag & drop of asset catalogs. The catalogs will be moved in the tree including children. A remaining issue is that a catalog with children will always be collapsed when dropping. I need to find a way to fix that in the tree-view API. There are a few improvements I can think of for the tree-item drag & drop support, but time for these is too short. These can be done as normal cleanups at some point.
This commit is contained in:
parent
1832e11f39
commit
aae5f15238
|
@ -37,3 +37,6 @@ void ED_asset_catalog_remove(AssetLibrary *library, const blender::bke::CatalogI
|
|||
void ED_asset_catalog_rename(AssetLibrary *library,
|
||||
blender::bke::CatalogID catalog_id,
|
||||
blender::StringRefNull new_name);
|
||||
void ED_asset_catalog_move(AssetLibrary *library,
|
||||
blender::bke::CatalogID src_catalog_id,
|
||||
blender::bke::CatalogID dst_parent_catalog_id);
|
||||
|
|
|
@ -121,6 +121,33 @@ void ED_asset_catalog_rename(::AssetLibrary *library,
|
|||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||
}
|
||||
|
||||
void ED_asset_catalog_move(::AssetLibrary *library,
|
||||
const CatalogID src_catalog_id,
|
||||
const CatalogID dst_parent_catalog_id)
|
||||
{
|
||||
bke::AssetCatalogService *catalog_service = BKE_asset_library_get_catalog_service(library);
|
||||
if (!catalog_service) {
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
|
||||
AssetCatalog *src_catalog = catalog_service->find_catalog(src_catalog_id);
|
||||
AssetCatalog *dst_catalog = catalog_service->find_catalog(dst_parent_catalog_id);
|
||||
|
||||
const AssetCatalogPath new_path = dst_catalog->path / StringRef(src_catalog->path.name());
|
||||
const AssetCatalogPath clean_new_path = new_path.cleanup();
|
||||
|
||||
if (new_path == src_catalog->path || clean_new_path == src_catalog->path) {
|
||||
/* Nothing changed, so don't bother renaming for nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
catalog_service->undo_push();
|
||||
catalog_service->tag_has_unsaved_changes(src_catalog);
|
||||
catalog_service->update_catalog_path(src_catalog_id, clean_new_path);
|
||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||
}
|
||||
|
||||
void ED_asset_catalogs_save_from_main_path(::AssetLibrary *library, const Main *bmain)
|
||||
{
|
||||
bke::AssetCatalogService *catalog_service = BKE_asset_library_get_catalog_service(library);
|
||||
|
|
|
@ -95,26 +95,44 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
|
|||
bool can_rename() const override;
|
||||
bool rename(StringRefNull new_name) override;
|
||||
|
||||
/** Add drag support for catalog items. */
|
||||
std::unique_ptr<ui::AbstractTreeViewItemDragController> create_drag_controller() const override;
|
||||
/** Add dropping support for catalog items. */
|
||||
std::unique_ptr<ui::AbstractTreeViewItemDropController> create_drop_controller() const override;
|
||||
};
|
||||
|
||||
class AssetCatalogDragController : public ui::AbstractTreeViewItemDragController {
|
||||
AssetCatalogTreeItem &catalog_item_;
|
||||
|
||||
public:
|
||||
explicit AssetCatalogDragController(AssetCatalogTreeItem &catalog_item);
|
||||
|
||||
int get_drag_type() const override;
|
||||
void *create_drag_data() const override;
|
||||
};
|
||||
|
||||
class AssetCatalogDropController : public ui::AbstractTreeViewItemDropController {
|
||||
AssetCatalogTreeItem &catalog_item_;
|
||||
|
||||
public:
|
||||
explicit AssetCatalogDropController(AssetCatalogTreeView &tree_view,
|
||||
AssetCatalogTreeItem &catalog_item);
|
||||
AssetCatalogDropController(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(const wmDrag &drag) override;
|
||||
|
||||
static bool has_droppable_item(const wmDrag &drag, const char **r_disabled_hint);
|
||||
static bool drop_into_catalog(const AssetCatalogTreeView &tree_view,
|
||||
const wmDrag &drag,
|
||||
CatalogID catalog_id,
|
||||
StringRefNull simple_name = "");
|
||||
::AssetLibrary &get_asset_library() const;
|
||||
|
||||
static bool has_droppable_asset(const wmDrag &drag, const char **r_disabled_hint);
|
||||
static bool drop_assets_into_catalog(const AssetCatalogTreeView &tree_view,
|
||||
const wmDrag &drag,
|
||||
CatalogID catalog_id,
|
||||
StringRefNull simple_name = "");
|
||||
|
||||
private:
|
||||
bool drop_asset_catalog_into_catalog(const wmDrag &drag);
|
||||
std::string drop_tooltip_asset_list(const wmDrag &drag) const;
|
||||
std::string drop_tooltip_asset_catalog(const wmDrag &drag) const;
|
||||
};
|
||||
|
||||
/** Only reason this isn't just `BasicTreeViewItem` is to add a '+' icon for adding a root level
|
||||
|
@ -308,6 +326,12 @@ std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewItem
|
|||
static_cast<AssetCatalogTreeView &>(get_tree_view()), catalog_item_);
|
||||
}
|
||||
|
||||
std::unique_ptr<ui::AbstractTreeViewItemDragController> AssetCatalogTreeViewItem::
|
||||
create_drag_controller() const
|
||||
{
|
||||
return std::make_unique<AssetCatalogDragController>(catalog_item_);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
AssetCatalogDropController::AssetCatalogDropController(AssetCatalogTreeView &tree_view,
|
||||
|
@ -318,14 +342,41 @@ AssetCatalogDropController::AssetCatalogDropController(AssetCatalogTreeView &tre
|
|||
|
||||
bool AssetCatalogDropController::can_drop(const wmDrag &drag, const char **r_disabled_hint) const
|
||||
{
|
||||
if (drag.type != WM_DRAG_ASSET_LIST) {
|
||||
return false;
|
||||
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||
/* Always supported. */
|
||||
return true;
|
||||
}
|
||||
return has_droppable_item(drag, r_disabled_hint);
|
||||
if (drag.type == WM_DRAG_ASSET_LIST) {
|
||||
return has_droppable_asset(drag, r_disabled_hint);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string AssetCatalogDropController::drop_tooltip(const wmDrag &drag) const
|
||||
{
|
||||
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||
return drop_tooltip_asset_catalog(drag);
|
||||
}
|
||||
return drop_tooltip_asset_list(drag);
|
||||
}
|
||||
|
||||
std::string AssetCatalogDropController::drop_tooltip_asset_catalog(const wmDrag &drag) const
|
||||
{
|
||||
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||
|
||||
const ::AssetLibrary *asset_library = tree_view<AssetCatalogTreeView>().asset_library_;
|
||||
bke::AssetCatalogService *catalog_service = BKE_asset_library_get_catalog_service(asset_library);
|
||||
wmDragAssetCatalog *catalog_drag = WM_drag_get_asset_catalog_data(&drag);
|
||||
AssetCatalog *src_catalog = catalog_service->find_catalog(catalog_drag->drag_catalog_id);
|
||||
|
||||
return std::string(TIP_("Move Catalog")) + " '" + src_catalog->path.name() + "' " +
|
||||
IFACE_("into") + " '" + catalog_item_.get_name() + "'";
|
||||
}
|
||||
|
||||
std::string AssetCatalogDropController::drop_tooltip_asset_list(const wmDrag &drag) const
|
||||
{
|
||||
BLI_assert(drag.type == WM_DRAG_ASSET_LIST);
|
||||
|
||||
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
|
||||
const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
|
||||
|
||||
|
@ -340,17 +391,32 @@ std::string AssetCatalogDropController::drop_tooltip(const wmDrag &drag) const
|
|||
|
||||
bool AssetCatalogDropController::on_drop(const wmDrag &drag)
|
||||
{
|
||||
return drop_into_catalog(tree_view<AssetCatalogTreeView>(),
|
||||
drag,
|
||||
catalog_item_.get_catalog_id(),
|
||||
catalog_item_.get_simple_name());
|
||||
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||
return drop_asset_catalog_into_catalog(drag);
|
||||
}
|
||||
return drop_assets_into_catalog(tree_view<AssetCatalogTreeView>(),
|
||||
drag,
|
||||
catalog_item_.get_catalog_id(),
|
||||
catalog_item_.get_simple_name());
|
||||
}
|
||||
|
||||
bool AssetCatalogDropController::drop_into_catalog(const AssetCatalogTreeView &tree_view,
|
||||
const wmDrag &drag,
|
||||
CatalogID catalog_id,
|
||||
StringRefNull simple_name)
|
||||
bool AssetCatalogDropController::drop_asset_catalog_into_catalog(const wmDrag &drag)
|
||||
{
|
||||
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||
wmDragAssetCatalog *catalog_drag = WM_drag_get_asset_catalog_data(&drag);
|
||||
ED_asset_catalog_move(
|
||||
&get_asset_library(), catalog_drag->drag_catalog_id, catalog_item_.get_catalog_id());
|
||||
|
||||
WM_main_add_notifier(NC_ASSET | ND_ASSET_CATALOGS, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetCatalogDropController::drop_assets_into_catalog(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);
|
||||
if (!asset_drags) {
|
||||
return false;
|
||||
|
@ -373,8 +439,8 @@ bool AssetCatalogDropController::drop_into_catalog(const AssetCatalogTreeView &t
|
|||
return true;
|
||||
}
|
||||
|
||||
bool AssetCatalogDropController::has_droppable_item(const wmDrag &drag,
|
||||
const char **r_disabled_hint)
|
||||
bool AssetCatalogDropController::has_droppable_asset(const wmDrag &drag,
|
||||
const char **r_disabled_hint)
|
||||
{
|
||||
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
|
||||
|
||||
|
@ -390,6 +456,31 @@ bool AssetCatalogDropController::has_droppable_item(const wmDrag &drag,
|
|||
return false;
|
||||
}
|
||||
|
||||
::AssetLibrary &AssetCatalogDropController::get_asset_library() const
|
||||
{
|
||||
return *tree_view<AssetCatalogTreeView>().asset_library_;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
AssetCatalogDragController::AssetCatalogDragController(AssetCatalogTreeItem &catalog_item)
|
||||
: catalog_item_(catalog_item)
|
||||
{
|
||||
}
|
||||
|
||||
int AssetCatalogDragController::get_drag_type() const
|
||||
{
|
||||
return WM_DRAG_ASSET_CATALOG;
|
||||
}
|
||||
|
||||
void *AssetCatalogDragController::create_drag_data() const
|
||||
{
|
||||
wmDragAssetCatalog *drag_catalog = (wmDragAssetCatalog *)MEM_callocN(sizeof(*drag_catalog),
|
||||
__func__);
|
||||
drag_catalog->drag_catalog_id = catalog_item_.get_catalog_id();
|
||||
return drag_catalog;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void AssetCatalogTreeViewAllItem::build_row(uiLayout &row)
|
||||
|
@ -427,7 +518,7 @@ bool AssetCatalogTreeViewUnassignedItem::DropController::can_drop(
|
|||
if (drag.type != WM_DRAG_ASSET_LIST) {
|
||||
return false;
|
||||
}
|
||||
return AssetCatalogDropController::has_droppable_item(drag, r_disabled_hint);
|
||||
return AssetCatalogDropController::has_droppable_asset(drag, r_disabled_hint);
|
||||
}
|
||||
|
||||
std::string AssetCatalogTreeViewUnassignedItem::DropController::drop_tooltip(
|
||||
|
@ -443,7 +534,7 @@ std::string AssetCatalogTreeViewUnassignedItem::DropController::drop_tooltip(
|
|||
bool AssetCatalogTreeViewUnassignedItem::DropController::on_drop(const wmDrag &drag)
|
||||
{
|
||||
/* Assign to nil catalog ID. */
|
||||
return AssetCatalogDropController::drop_into_catalog(
|
||||
return AssetCatalogDropController::drop_assets_into_catalog(
|
||||
tree_view<AssetCatalogTreeView>(), drag, CatalogID{});
|
||||
}
|
||||
|
||||
|
|
|
@ -770,6 +770,8 @@ void WM_drag_free_imported_drag_ID(struct Main *bmain,
|
|||
struct wmDrag *drag,
|
||||
struct wmDropBox *drop);
|
||||
|
||||
struct wmDragAssetCatalog *WM_drag_get_asset_catalog_data(const struct wmDrag *drag);
|
||||
|
||||
void WM_drag_add_asset_list_item(wmDrag *drag,
|
||||
const struct bContext *C,
|
||||
const struct AssetLibraryReference *asset_library_ref,
|
||||
|
|
|
@ -119,6 +119,7 @@ struct wmWindowManager;
|
|||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_uuid_types.h"
|
||||
#include "DNA_vec_types.h"
|
||||
#include "DNA_xr_types.h"
|
||||
#include "RNA_types.h"
|
||||
|
@ -967,6 +968,7 @@ typedef void (*wmPaintCursorDraw)(struct bContext *C, int, int, void *customdata
|
|||
#define WM_DRAG_VALUE 6
|
||||
#define WM_DRAG_COLOR 7
|
||||
#define WM_DRAG_DATASTACK 8
|
||||
#define WM_DRAG_ASSET_CATALOG 9
|
||||
|
||||
typedef enum wmDragFlags {
|
||||
WM_DRAG_NOP = 0,
|
||||
|
@ -1000,6 +1002,10 @@ typedef struct wmDragAsset {
|
|||
struct bContext *evil_C;
|
||||
} wmDragAsset;
|
||||
|
||||
typedef struct wmDragAssetCatalog {
|
||||
bUUID drag_catalog_id;
|
||||
} wmDragAssetCatalog;
|
||||
|
||||
/**
|
||||
* For some specific cases we support dragging multiple assets (#WM_DRAG_ASSET_LIST). There is no
|
||||
* proper support for dragging multiple items in the `wmDrag`/`wmDrop` API yet, so this is really
|
||||
|
|
|
@ -181,6 +181,7 @@ wmDrag *WM_event_start_drag(
|
|||
}
|
||||
break;
|
||||
case WM_DRAG_ASSET:
|
||||
case WM_DRAG_ASSET_CATALOG:
|
||||
/* Move ownership of poin to wmDrag. */
|
||||
drag->poin = poin;
|
||||
drag->flags |= WM_DRAG_FREE_DATA;
|
||||
|
@ -649,6 +650,15 @@ void WM_drag_free_imported_drag_ID(struct Main *bmain, wmDrag *drag, wmDropBox *
|
|||
}
|
||||
}
|
||||
|
||||
wmDragAssetCatalog *WM_drag_get_asset_catalog_data(const wmDrag *drag)
|
||||
{
|
||||
if (drag->type != WM_DRAG_ASSET_CATALOG) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return drag->poin;
|
||||
}
|
||||
|
||||
/**
|
||||
* \note: Does not store \a asset in any way, so it's fine to pass a temporary.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue