Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-12-12 01:16:29 +0300
committerJulian Eisel <julian@blender.org>2020-12-15 19:03:00 +0300
commitc25e0310497f5228bd04992d6bcd84481d0b0c5b (patch)
tree46ba57daa8c534854742500e15fd2f84f6efa455 /source/blender/editors/asset
parentb71eb3a105b8f7fb216a48082386215a6ea81cc4 (diff)
Asset System: "Mark Asset" & "Clear Asset" operators and UI integration
This makes it possible to turn data-blocks into assets and back into normal data-blocks. A core design decision made for the asset system is that not every data-block should be an asset, because not every data-block is made for reuse. Users have to explicitly mark data-blocks as assets. Exposes "Mark Asset" and "Clear Asset" in Outliner context menus (currently ID Data submenu) and button context menus. We are still not too happy with the names, they may change. This uses the new context members to pass data-blocks to operators, added in af008f553293 and 0c1d4769235c. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9717 Reviewed by: Brecht Van Lommel
Diffstat (limited to 'source/blender/editors/asset')
-rw-r--r--source/blender/editors/asset/CMakeLists.txt39
-rw-r--r--source/blender/editors/asset/asset_edit.c69
-rw-r--r--source/blender/editors/asset/asset_ops.c238
3 files changed, 346 insertions, 0 deletions
diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt
new file mode 100644
index 00000000000..63a1761b264
--- /dev/null
+++ b/source/blender/editors/asset/CMakeLists.txt
@@ -0,0 +1,39 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ ../include
+ ../../blenlib
+ ../../blenkernel
+ ../../makesdna
+ ../../makesrna
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+)
+
+set(INC_SYS
+)
+
+set(SRC
+ asset_edit.c
+ asset_ops.c
+)
+
+set(LIB
+)
+
+blender_add_lib(bf_editor_asset "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/asset/asset_edit.c b/source/blender/editors/asset/asset_edit.c
new file mode 100644
index 00000000000..5333c08c66a
--- /dev/null
+++ b/source/blender/editors/asset/asset_edit.c
@@ -0,0 +1,69 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edasset
+ */
+
+#include "BKE_asset.h"
+#include "BKE_context.h"
+#include "BKE_idtype.h"
+#include "BKE_lib_id.h"
+
+#include "DNA_ID.h"
+#include "DNA_asset_types.h"
+
+#include "UI_interface_icons.h"
+
+#include "RNA_access.h"
+
+#include "ED_asset.h"
+
+bool ED_asset_mark_id(const bContext *C, ID *id)
+{
+ if (id->asset_data) {
+ return false;
+ }
+ if (!BKE_id_can_be_asset(id)) {
+ return false;
+ }
+
+ id_fake_user_set(id);
+
+ id->asset_data = BKE_asset_metadata_create();
+
+ UI_icon_render_id(C, NULL, id, true, true);
+
+ return true;
+}
+
+bool ED_asset_clear_id(ID *id)
+{
+ if (!id->asset_data) {
+ return false;
+ }
+ BKE_asset_metadata_free(&id->asset_data);
+ /* Don't clear fake user here, there's no guarantee that it was actually set by
+ * #ED_asset_mark_id(), it might have been something/someone else. */
+
+ return true;
+}
+
+bool ED_asset_can_make_single_from_context(const bContext *C)
+{
+ /* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */
+ return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != NULL;
+}
diff --git a/source/blender/editors/asset/asset_ops.c b/source/blender/editors/asset/asset_ops.c
new file mode 100644
index 00000000000..929d49e19fa
--- /dev/null
+++ b/source/blender/editors/asset/asset_ops.c
@@ -0,0 +1,238 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edasset
+ */
+
+#include <string.h>
+
+#include "BKE_asset.h"
+#include "BKE_context.h"
+#include "BKE_report.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string_utils.h"
+
+#include "DNA_asset_types.h"
+
+#include "ED_asset.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* -------------------------------------------------------------------- */
+
+struct AssetMarkResultStats {
+ int tot_created;
+ int tot_already_asset;
+ ID *last_id;
+};
+
+/**
+ * Return the IDs to operate on as list of #CollectionPointerLink links. Needs freeing.
+ */
+static ListBase /* CollectionPointerLink */ asset_operation_get_ids_from_context(const bContext *C)
+{
+ ListBase list = {0};
+
+ PointerRNA idptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
+
+ if (idptr.data) {
+ CollectionPointerLink *ctx_link = MEM_callocN(sizeof(*ctx_link), __func__);
+ ctx_link->ptr = idptr;
+ BLI_addtail(&list, ctx_link);
+ }
+ else {
+ CTX_data_selected_ids(C, &list);
+ }
+
+ return list;
+}
+
+static void asset_mark_for_idptr_list(const bContext *C,
+ const ListBase /* CollectionPointerLink */ *ids,
+ struct AssetMarkResultStats *r_stats)
+{
+ memset(r_stats, 0, sizeof(*r_stats));
+
+ LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) {
+ BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type));
+
+ ID *id = ctx_id->ptr.data;
+ if (id->asset_data) {
+ r_stats->tot_already_asset++;
+ continue;
+ }
+
+ if (ED_asset_mark_id(C, id)) {
+ r_stats->last_id = id;
+ r_stats->tot_created++;
+ }
+ }
+}
+
+static bool asset_mark_results_report(const struct AssetMarkResultStats *stats,
+ ReportList *reports)
+{
+ /* User feedback on failure. */
+ if ((stats->tot_created < 1) && (stats->tot_already_asset > 0)) {
+ BKE_report(reports,
+ RPT_ERROR,
+ "Selected data-blocks are already assets (or do not support use as assets)");
+ return false;
+ }
+ if (stats->tot_created < 1) {
+ BKE_report(reports,
+ RPT_ERROR,
+ "No data-blocks to create assets for found (or do not support use as assets)");
+ return false;
+ }
+
+ /* User feedback on success. */
+ if (stats->tot_created == 1) {
+ /* If only one data-block: Give more useful message by printing asset name. */
+ BKE_reportf(reports, RPT_INFO, "Data-block '%s' is now an asset", stats->last_id->name + 2);
+ }
+ else {
+ BKE_reportf(reports, RPT_INFO, "%i data-blocks are now assets", stats->tot_created);
+ }
+
+ return true;
+}
+
+static int asset_mark_exec(bContext *C, wmOperator *op)
+{
+ ListBase ids = asset_operation_get_ids_from_context(C);
+
+ struct AssetMarkResultStats stats;
+ asset_mark_for_idptr_list(C, &ids, &stats);
+ BLI_freelistN(&ids);
+
+ if (!asset_mark_results_report(&stats, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_ASSET | NA_ADDED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void ASSET_OT_mark(wmOperatorType *ot)
+{
+ ot->name = "Mark Asset";
+ ot->description =
+ "Enable easier reuse of selected data-blocks through the Asset Browser, with the help of "
+ "customizable metadata (like previews, descriptions and tags)";
+ ot->idname = "ASSET_OT_mark";
+
+ ot->exec = asset_mark_exec;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* -------------------------------------------------------------------- */
+
+struct AssetClearResultStats {
+ int tot_removed;
+ ID *last_id;
+};
+
+static void asset_clear_from_idptr_list(const ListBase /* CollectionPointerLink */ *ids,
+ struct AssetClearResultStats *r_stats)
+{
+ memset(r_stats, 0, sizeof(*r_stats));
+
+ LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) {
+ BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type));
+
+ ID *id = ctx_id->ptr.data;
+ if (!id->asset_data) {
+ continue;
+ }
+
+ if (ED_asset_clear_id(id)) {
+ r_stats->tot_removed++;
+ r_stats->last_id = id;
+ }
+ }
+}
+
+static bool asset_clear_result_report(const struct AssetClearResultStats *stats,
+ ReportList *reports)
+
+{
+ if (stats->tot_removed < 1) {
+ BKE_report(reports, RPT_ERROR, "No asset data-blocks selected/focused");
+ return false;
+ }
+
+ if (stats->tot_removed == 1) {
+ /* If only one data-block: Give more useful message by printing asset name. */
+ BKE_reportf(
+ reports, RPT_INFO, "Data-block '%s' is no asset anymore", stats->last_id->name + 2);
+ }
+ else {
+ BKE_reportf(reports, RPT_INFO, "%i data-blocks are no assets anymore", stats->tot_removed);
+ }
+
+ return true;
+}
+
+static int asset_clear_exec(bContext *C, wmOperator *op)
+{
+ ListBase ids = asset_operation_get_ids_from_context(C);
+
+ struct AssetClearResultStats stats;
+ asset_clear_from_idptr_list(&ids, &stats);
+ BLI_freelistN(&ids);
+
+ if (!asset_clear_result_report(&stats, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_ASSET | NA_REMOVED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void ASSET_OT_clear(wmOperatorType *ot)
+{
+ ot->name = "Clear Asset";
+ ot->description =
+ "Delete all asset metadata and turn the selected asset data-blocks back into normal "
+ "data-blocks";
+ ot->idname = "ASSET_OT_clear";
+
+ ot->exec = asset_clear_exec;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* -------------------------------------------------------------------- */
+
+void ED_operatortypes_asset(void)
+{
+ WM_operatortype_append(ASSET_OT_mark);
+ WM_operatortype_append(ASSET_OT_clear);
+}