Asset Browser: Support dragging catalogs into top level
This was an oversight when I added catalog drag & drop support. I forgot to add this for dragging catalogs into the top level by dragging into to the "All" item as well. This made the drag & drop support rather broken because it wouldn't work for a basic case.
This commit is contained in:
parent
a07089dcb1
commit
01ab36ebc1
Notes:
blender-bot
2023-02-14 10:14:07 +01:00
Referenced by issue #92853, Allow dragging asset catalogs to the highest level
|
@ -20,6 +20,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "BKE_asset_catalog.hh"
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
|
@ -37,6 +39,18 @@ 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);
|
||||
/**
|
||||
* Reinsert catalog identified by \a src_catalog_id as child to catalog identified by \a
|
||||
* dst_parent_catalog_id. If \a dst_parent_catalog_id is not set, the catalog is moved to the root
|
||||
* level of the tree.
|
||||
* The name of the reinserted catalog is made unique within the parent. Note that moving a catalog
|
||||
* to the same level it was before will also change its name, since the name uniqueness check isn't
|
||||
* smart enough to ignore the item to be reinserted. So the caller is expected to handle this case
|
||||
* to avoid unwanted renames.
|
||||
*
|
||||
* Nothing is done (debug builds run into an assert) if the given catalog IDs can't be identified.
|
||||
*/
|
||||
void ED_asset_catalog_move(
|
||||
AssetLibrary *library,
|
||||
blender::bke::CatalogID src_catalog_id,
|
||||
std::optional<blender::bke::CatalogID> dst_parent_catalog_id = std::nullopt);
|
||||
|
|
|
@ -123,7 +123,7 @@ void ED_asset_catalog_rename(::AssetLibrary *library,
|
|||
|
||||
void ED_asset_catalog_move(::AssetLibrary *library,
|
||||
const CatalogID src_catalog_id,
|
||||
const CatalogID dst_parent_catalog_id)
|
||||
const std::optional<CatalogID> dst_parent_catalog_id)
|
||||
{
|
||||
bke::AssetCatalogService *catalog_service = BKE_asset_library_get_catalog_service(library);
|
||||
if (!catalog_service) {
|
||||
|
@ -132,9 +132,24 @@ void ED_asset_catalog_move(::AssetLibrary *library,
|
|||
}
|
||||
|
||||
AssetCatalog *src_catalog = catalog_service->find_catalog(src_catalog_id);
|
||||
AssetCatalog *dst_catalog = catalog_service->find_catalog(dst_parent_catalog_id);
|
||||
if (!src_catalog) {
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
AssetCatalog *dst_catalog = dst_parent_catalog_id ?
|
||||
catalog_service->find_catalog(*dst_parent_catalog_id) :
|
||||
nullptr;
|
||||
if (!dst_catalog && dst_parent_catalog_id) {
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
|
||||
const AssetCatalogPath new_path = dst_catalog->path / StringRef(src_catalog->path.name());
|
||||
std::string unique_name = catalog_name_ensure_unique(
|
||||
*catalog_service, src_catalog->path.name(), dst_catalog ? dst_catalog->path.c_str() : "");
|
||||
/* If a destination catalog was given, construct the path using that. Otherwise, the path is just
|
||||
* the name of the catalog to be moved, which means it ends up at the root level. */
|
||||
const AssetCatalogPath new_path = dst_catalog ? (dst_catalog->path / unique_name) :
|
||||
AssetCatalogPath{unique_name};
|
||||
const AssetCatalogPath clean_new_path = new_path.cleanup();
|
||||
|
||||
if (new_path == src_catalog->path || clean_new_path == src_catalog->path) {
|
||||
|
|
|
@ -52,6 +52,8 @@ using namespace blender::bke;
|
|||
|
||||
namespace blender::ed::asset_browser {
|
||||
|
||||
class AssetCatalogTreeViewAllItem;
|
||||
|
||||
class AssetCatalogTreeView : public ui::AbstractTreeView {
|
||||
::AssetLibrary *asset_library_;
|
||||
/** The asset catalog tree this tree-view represents. */
|
||||
|
@ -61,6 +63,7 @@ class AssetCatalogTreeView : public ui::AbstractTreeView {
|
|||
|
||||
friend class AssetCatalogTreeViewItem;
|
||||
friend class AssetCatalogDropController;
|
||||
friend class AssetCatalogTreeViewAllItem;
|
||||
|
||||
public:
|
||||
AssetCatalogTreeView(::AssetLibrary *library,
|
||||
|
@ -69,6 +72,8 @@ class AssetCatalogTreeView : public ui::AbstractTreeView {
|
|||
|
||||
void build_tree() override;
|
||||
|
||||
void activate_catalog_by_id(CatalogID catalog_id);
|
||||
|
||||
private:
|
||||
ui::BasicTreeViewItem &build_catalog_items_recursive(ui::TreeViewItemContainer &view_parent_item,
|
||||
AssetCatalogTreeItem &catalog);
|
||||
|
@ -122,16 +127,22 @@ class AssetCatalogDropController : public ui::AbstractTreeViewItemDropController
|
|||
bool on_drop(const wmDrag &drag) override;
|
||||
|
||||
::AssetLibrary &get_asset_library() const;
|
||||
AssetCatalog *get_drag_catalog(const wmDrag &drag) const;
|
||||
|
||||
static AssetCatalog *get_drag_catalog(const wmDrag &drag, const ::AssetLibrary &asset_library);
|
||||
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 = "");
|
||||
/**
|
||||
* \param drop_catalog_id: Can be unset to drop into the root level of the tree.
|
||||
*/
|
||||
static bool drop_asset_catalog_into_catalog(
|
||||
const wmDrag &drag,
|
||||
AssetCatalogTreeView &tree_view,
|
||||
const std::optional<CatalogID> drop_catalog_id = std::nullopt);
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -142,6 +153,16 @@ class AssetCatalogTreeViewAllItem : public ui::BasicTreeViewItem {
|
|||
using BasicTreeViewItem::BasicTreeViewItem;
|
||||
|
||||
void build_row(uiLayout &row) override;
|
||||
|
||||
struct DropController : public ui::AbstractTreeViewItemDropController {
|
||||
DropController(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(const wmDrag &drag) override;
|
||||
};
|
||||
|
||||
std::unique_ptr<ui::AbstractTreeViewItemDropController> create_drop_controller() const override;
|
||||
};
|
||||
|
||||
class AssetCatalogTreeViewUnassignedItem : public ui::BasicTreeViewItem {
|
||||
|
@ -228,6 +249,13 @@ void AssetCatalogTreeView::add_unassigned_item()
|
|||
[params]() { return params->asset_catalog_visibility == FILE_SHOW_ASSETS_WITHOUT_CATALOG; });
|
||||
}
|
||||
|
||||
void AssetCatalogTreeView::activate_catalog_by_id(CatalogID catalog_id)
|
||||
{
|
||||
params_->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
|
||||
params_->catalog_id = catalog_id;
|
||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||
}
|
||||
|
||||
bool AssetCatalogTreeView::is_active_catalog(CatalogID catalog_id) const
|
||||
{
|
||||
return (params_->asset_catalog_visibility == FILE_SHOW_ASSETS_FROM_CATALOG) &&
|
||||
|
@ -243,11 +271,8 @@ AssetCatalogTreeViewItem::AssetCatalogTreeViewItem(AssetCatalogTreeItem *catalog
|
|||
|
||||
void AssetCatalogTreeViewItem::on_activate()
|
||||
{
|
||||
const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
|
||||
get_tree_view());
|
||||
tree_view.params_->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
|
||||
tree_view.params_->catalog_id = catalog_item_.get_catalog_id();
|
||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||
AssetCatalogTreeView &tree_view = static_cast<AssetCatalogTreeView &>(get_tree_view());
|
||||
tree_view.activate_catalog_by_id(catalog_item_.get_catalog_id());
|
||||
}
|
||||
|
||||
void AssetCatalogTreeViewItem::build_row(uiLayout &row)
|
||||
|
@ -344,7 +369,7 @@ AssetCatalogDropController::AssetCatalogDropController(AssetCatalogTreeView &tre
|
|||
bool AssetCatalogDropController::can_drop(const wmDrag &drag, const char **r_disabled_hint) const
|
||||
{
|
||||
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||
const AssetCatalog *drag_catalog = get_drag_catalog(drag);
|
||||
const AssetCatalog *drag_catalog = get_drag_catalog(drag, get_asset_library());
|
||||
/* Note: Technically it's not an issue to allow this (the catalog will just receive a new
|
||||
* path and the catalog system will generate missing parents from the path). But it does
|
||||
* appear broken to users, so disabling entirely. */
|
||||
|
@ -371,7 +396,7 @@ std::string AssetCatalogDropController::drop_tooltip(const wmDrag &drag) const
|
|||
std::string AssetCatalogDropController::drop_tooltip_asset_catalog(const wmDrag &drag) const
|
||||
{
|
||||
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||
const AssetCatalog *src_catalog = get_drag_catalog(drag);
|
||||
const AssetCatalog *src_catalog = get_drag_catalog(drag, get_asset_library());
|
||||
|
||||
return std::string(TIP_("Move Catalog")) + " '" + src_catalog->path.name() + "' " +
|
||||
TIP_("into") + " '" + catalog_item_.get_name() + "'";
|
||||
|
@ -396,7 +421,8 @@ std::string AssetCatalogDropController::drop_tooltip_asset_list(const wmDrag &dr
|
|||
bool AssetCatalogDropController::on_drop(const wmDrag &drag)
|
||||
{
|
||||
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||
return drop_asset_catalog_into_catalog(drag);
|
||||
return drop_asset_catalog_into_catalog(
|
||||
drag, tree_view<AssetCatalogTreeView>(), catalog_item_.get_catalog_id());
|
||||
}
|
||||
return drop_assets_into_catalog(tree_view<AssetCatalogTreeView>(),
|
||||
drag,
|
||||
|
@ -404,12 +430,15 @@ bool AssetCatalogDropController::on_drop(const wmDrag &drag)
|
|||
catalog_item_.get_simple_name());
|
||||
}
|
||||
|
||||
bool AssetCatalogDropController::drop_asset_catalog_into_catalog(const wmDrag &drag)
|
||||
bool AssetCatalogDropController::drop_asset_catalog_into_catalog(
|
||||
const wmDrag &drag,
|
||||
AssetCatalogTreeView &tree_view,
|
||||
const std::optional<CatalogID> drop_catalog_id)
|
||||
{
|
||||
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());
|
||||
ED_asset_catalog_move(tree_view.asset_library_, catalog_drag->drag_catalog_id, drop_catalog_id);
|
||||
tree_view.activate_catalog_by_id(catalog_drag->drag_catalog_id);
|
||||
|
||||
WM_main_add_notifier(NC_ASSET | ND_ASSET_CATALOGS, nullptr);
|
||||
return true;
|
||||
|
@ -443,13 +472,14 @@ bool AssetCatalogDropController::drop_assets_into_catalog(const AssetCatalogTree
|
|||
return true;
|
||||
}
|
||||
|
||||
AssetCatalog *AssetCatalogDropController::get_drag_catalog(const wmDrag &drag) const
|
||||
AssetCatalog *AssetCatalogDropController::get_drag_catalog(const wmDrag &drag,
|
||||
const ::AssetLibrary &asset_library)
|
||||
{
|
||||
if (drag.type != WM_DRAG_ASSET_CATALOG) {
|
||||
return nullptr;
|
||||
}
|
||||
const bke::AssetCatalogService *catalog_service = BKE_asset_library_get_catalog_service(
|
||||
&get_asset_library());
|
||||
&asset_library);
|
||||
const wmDragAssetCatalog *catalog_drag = WM_drag_get_asset_catalog_data(&drag);
|
||||
|
||||
return catalog_service->find_catalog(catalog_drag->drag_catalog_id);
|
||||
|
@ -514,6 +544,55 @@ void AssetCatalogTreeViewAllItem::build_row(uiLayout &row)
|
|||
RNA_string_set(props, "parent_path", nullptr);
|
||||
}
|
||||
|
||||
std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewAllItem::
|
||||
create_drop_controller() const
|
||||
{
|
||||
return std::make_unique<AssetCatalogTreeViewAllItem::DropController>(
|
||||
static_cast<AssetCatalogTreeView &>(get_tree_view()));
|
||||
}
|
||||
|
||||
AssetCatalogTreeViewAllItem::DropController::DropController(AssetCatalogTreeView &tree_view)
|
||||
: ui::AbstractTreeViewItemDropController(tree_view)
|
||||
{
|
||||
}
|
||||
|
||||
bool AssetCatalogTreeViewAllItem::DropController::can_drop(const wmDrag &drag,
|
||||
const char **r_disabled_hint) const
|
||||
{
|
||||
if (drag.type != WM_DRAG_ASSET_CATALOG) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog(
|
||||
drag, *tree_view<AssetCatalogTreeView>().asset_library_);
|
||||
if (drag_catalog->path.parent() == "") {
|
||||
*r_disabled_hint = "Catalog is already placed at the highest level";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string AssetCatalogTreeViewAllItem::DropController::drop_tooltip(const wmDrag &drag) const
|
||||
{
|
||||
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||
const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog(
|
||||
drag, *tree_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(const wmDrag &drag)
|
||||
{
|
||||
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||
return AssetCatalogDropController::drop_asset_catalog_into_catalog(
|
||||
drag,
|
||||
tree_view<AssetCatalogTreeView>(),
|
||||
/* No value to drop into the root level. */
|
||||
std::nullopt);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewUnassignedItem::
|
||||
|
|
Loading…
Reference in New Issue