[Bf-blender-cvs] [1f819df7df3] blender-projects-basics: Add UI for setting up project asset libraries

Julian Eisel noreply at git.blender.org
Thu Oct 13 16:46:30 CEST 2022


Commit: 1f819df7df3727418a65fd3056c8922518ef4811
Author: Julian Eisel
Date:   Thu Oct 13 16:42:58 2022 +0200
Branches: blender-projects-basics
https://developer.blender.org/rB1f819df7df3727418a65fd3056c8922518ef4811

Add UI for setting up project asset libraries

Looks just like the UI for setting up custom asset libraries in the
Preferences. However project asset libraries use paths relative to the
project root directory.

Had to do some changes to project data storage to avoid memory issues.

===================================================================

M	release/scripts/startup/bl_ui/space_project_settings.py
M	source/blender/blenkernel/BKE_blender_project.h
M	source/blender/blenkernel/BKE_blender_project.hh
M	source/blender/blenkernel/intern/blender_project.cc
M	source/blender/editors/CMakeLists.txt
M	source/blender/editors/asset/intern/asset_ops.cc
A	source/blender/editors/include/ED_project.h
A	source/blender/editors/project/CMakeLists.txt
A	source/blender/editors/project/project_ops.cc
M	source/blender/editors/space_api/CMakeLists.txt
M	source/blender/editors/space_api/spacetypes.c
M	source/blender/editors/space_userpref/userpref_ops.c
M	source/blender/editors/util/CMakeLists.txt
M	source/blender/makesrna/intern/rna_blender_project.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_project_settings.py b/release/scripts/startup/bl_ui/space_project_settings.py
index 73f118a16ee..06114b846cc 100644
--- a/release/scripts/startup/bl_ui/space_project_settings.py
+++ b/release/scripts/startup/bl_ui/space_project_settings.py
@@ -152,6 +152,48 @@ class PROJECTSETTINGS_PT_setup(CenterAlignMixIn, Panel):
         layout.prop(project, "root_path", text="Location")
 
 
+class PROJECTSETTINGS_PT_asset_libraries(Panel):
+    bl_space_type = 'PROJECT_SETTINGS'
+    bl_region_type = 'WINDOW'
+    bl_context = "asset_libraries"
+    bl_label = "Asset Libraries"
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = False
+        layout.use_property_decorate = False
+
+        project = context.project
+
+        box = layout.box()
+        split = box.split(factor=0.35)
+        name_col = split.column()
+        path_col = split.column()
+
+        row = name_col.row(align=True)  # Padding
+        row.separator()
+        row.label(text="Name")
+
+        row = path_col.row(align=True)  # Padding
+        row.separator()
+        row.label(text="Path")
+
+        for i, library in enumerate(project.asset_libraries):
+            row = name_col.row()
+            row.alert = not library.name
+            row.prop(library, "name", text="")
+
+            row = path_col.row()
+            subrow = row.row()
+            subrow.alert = not library.path
+            subrow.prop(library, "path", text="")
+            row.operator("project.custom_asset_library_remove", text="", icon='X', emboss=False).index = i
+
+        row = box.row()
+        row.alignment = 'RIGHT'
+        row.operator("project.custom_asset_library_add", text="", icon='ADD', emboss=False)
+
+
 classes = (
     PROJECTSETTINGS_HT_header,
     PROJECTSETTINGS_MT_editor_menus,
@@ -161,6 +203,7 @@ classes = (
     PROJECTSETTINGS_PT_save_project_settings,
     PROJECTSETTINGS_PT_no_project,
     PROJECTSETTINGS_PT_setup,
+    PROJECTSETTINGS_PT_asset_libraries,
 )
 
 if __name__ == "__main__":  # only for live edit.
diff --git a/source/blender/blenkernel/BKE_blender_project.h b/source/blender/blenkernel/BKE_blender_project.h
index 2127e837d8d..143d48a81f1 100644
--- a/source/blender/blenkernel/BKE_blender_project.h
+++ b/source/blender/blenkernel/BKE_blender_project.h
@@ -58,6 +58,9 @@ const char *BKE_project_root_path_get(const BlenderProject *project) ATTR_WARN_U
 void BKE_project_name_set(const BlenderProject *project_handle, const char *name) ATTR_NONNULL();
 const char *BKE_project_name_get(const BlenderProject *project) ATTR_WARN_UNUSED_RESULT
     ATTR_NONNULL();
+ListBase *BKE_project_custom_asset_libraries_get(const BlenderProject *project)
+    ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void BKE_project_tag_has_unsaved_changes(const BlenderProject *project) ATTR_NONNULL();
 bool BKE_project_has_unsaved_changes(const BlenderProject *project) ATTR_WARN_UNUSED_RESULT
     ATTR_NONNULL();
 
diff --git a/source/blender/blenkernel/BKE_blender_project.hh b/source/blender/blenkernel/BKE_blender_project.hh
index 2417011c122..c4412c8b269 100644
--- a/source/blender/blenkernel/BKE_blender_project.hh
+++ b/source/blender/blenkernel/BKE_blender_project.hh
@@ -10,6 +10,7 @@
 
 #include "BLI_listbase.h"
 #include "BLI_string_ref.hh"
+#include "BLI_utility_mixins.hh"
 
 namespace blender::io::serialize {
 class DictionaryValue;
@@ -21,8 +22,6 @@ class ProjectSettings;
 struct CustomAssetLibraries;
 
 class BlenderProject {
-  inline static std::unique_ptr<BlenderProject> active_;
-
   std::unique_ptr<ProjectSettings> settings_;
 
  public:
@@ -44,13 +43,24 @@ class BlenderProject {
 
  private:
   explicit BlenderProject(std::unique_ptr<ProjectSettings> settings);
+  static std::unique_ptr<BlenderProject> &active_project_ptr();
+};
+
+struct CustomAssetLibraries : NonCopyable {
+  ListBase asset_libraries = {nullptr, nullptr}; /* CustomAssetLibraryDefinition */
+
+  CustomAssetLibraries() = default;
+  CustomAssetLibraries(ListBase asset_libraries);
+  CustomAssetLibraries(CustomAssetLibraries &&);
+  ~CustomAssetLibraries();
+  auto operator=(CustomAssetLibraries &&) -> CustomAssetLibraries &;
 };
 
 class ProjectSettings {
   /* Path to the project root using slashes in the OS native format. */
   std::string project_root_path_;
   std::string project_name_;
-  std::unique_ptr<CustomAssetLibraries> asset_libraries_;
+  CustomAssetLibraries asset_libraries_ = {};
   bool has_unsaved_changes_ = false;
 
  public:
@@ -94,17 +104,23 @@ class ProjectSettings {
   void project_name(StringRef new_name);
   auto project_name [[nodiscard]] () const -> StringRefNull;
   auto asset_library_definitions() const -> const ListBase &;
+  auto asset_library_definitions() -> ListBase &;
+  /**
+   * Forcefully tag the project settings for having unsaved changes. This needs to be done if
+   * project settings data is modified directly by external code, not via a project settings API
+   * function. The API functions set the tag for all changes they manage.
+   */
+  void tag_has_unsaved_changes();
+  /**
+   * Returns true if there were any changes done to the settings that have not been written to
+   * disk yet. Project settings API functions that change data set this, however when external
+   * code modifies project settings data it may have to manually set the tag, see
+   * #tag_has_unsaved_changes().
+   */
   auto has_unsaved_changes [[nodiscard]] () const -> bool;
 
  private:
   auto to_dictionary() const -> std::unique_ptr<io::serialize::DictionaryValue>;
 };
 
-struct CustomAssetLibraries {
-  ListBase asset_libraries = {nullptr, nullptr}; /* CustomAssetLibraryDefinition */
-
-  CustomAssetLibraries(ListBase asset_libraries);
-  ~CustomAssetLibraries();
-};
-
 }  // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/blender_project.cc b/source/blender/blenkernel/intern/blender_project.cc
index d0693c7bab9..1e74d75c368 100644
--- a/source/blender/blenkernel/intern/blender_project.cc
+++ b/source/blender/blenkernel/intern/blender_project.cc
@@ -31,21 +31,30 @@ BlenderProject::BlenderProject(std::unique_ptr<ProjectSettings> settings)
 {
 }
 
+/* Construct on First Use idiom. */
+std::unique_ptr<BlenderProject> &BlenderProject::active_project_ptr()
+{
+  static std::unique_ptr<BlenderProject> active_;
+  return active_;
+}
+
 BlenderProject *BlenderProject::set_active_from_settings(std::unique_ptr<ProjectSettings> settings)
 {
+  std::unique_ptr<BlenderProject> &active = active_project_ptr();
   if (settings) {
-    active_ = std::make_unique<BlenderProject>(BlenderProject(std::move(settings)));
+    active = std::make_unique<BlenderProject>(BlenderProject(std::move(settings)));
   }
   else {
-    active_ = nullptr;
+    active = nullptr;
   }
 
-  return active_.get();
+  return active.get();
 }
 
 BlenderProject *BlenderProject::get_active()
 {
-  return active_.get();
+  std::unique_ptr<BlenderProject> &active = active_project_ptr();
+  return active.get();
 }
 
 StringRef BlenderProject::project_root_path_find_from_path(StringRef path)
@@ -252,8 +261,7 @@ std::unique_ptr<ProjectSettings> ProjectSettings::load_from_disk(StringRef proje
   if (extracted_settings) {
     loaded_settings->project_name_ = extracted_settings->project_name;
     /* Moves ownership. */
-    loaded_settings->asset_libraries_ = std::make_unique<CustomAssetLibraries>(
-        extracted_settings->asset_libraries);
+    loaded_settings->asset_libraries_ = CustomAssetLibraries(extracted_settings->asset_libraries);
   }
 
   return loaded_settings;
@@ -273,11 +281,11 @@ std::unique_ptr<serialize::DictionaryValue> ProjectSettings::to_dictionary() con
     root_attributes.append_as("project", std::move(project_dict));
   }
   /* "asset_libraries": */ {
-    if (asset_libraries_ && !BLI_listbase_is_empty(&asset_libraries_->asset_libraries)) {
+    if (!BLI_listbase_is_empty(&asset_libraries_.asset_libraries)) {
       std::unique_ptr<ArrayValue> asset_libs_array = std::make_unique<ArrayValue>();
       ArrayValue::Items &asset_libs_elements = asset_libs_array->elements();
       LISTBASE_FOREACH (
-          const CustomAssetLibraryDefinition *, library, &asset_libraries_->asset_libraries) {
+          const CustomAssetLibraryDefinition *, library, &asset_libraries_.asset_libraries) {
         std::unique_ptr<DictionaryValue> library_dict = std::make_unique<DictionaryValue>();
         DictionaryValue::Items &library_attributes = library_dict->elements();
 
@@ -356,7 +364,17 @@ StringRefNull ProjectSettings::project_name() const
 
 const ListBase &ProjectSettings::asset_library_definitions() const
 {
-  return asset_libraries_->asset_libraries;
+  return asset_libraries_.asset_libraries;
+}
+
+ListBase &ProjectSettings::asset_library_definitions()
+{
+  return asset_libraries_.asset_libraries;
+}
+
+void ProjectSettings::tag_has_unsaved_changes()
+{
+  has_unsaved_changes_ = true;
 }
 
 bool ProjectSettings::has_unsaved_changes() const
@@ -371,6 +389,18 @@ CustomAssetLibraries::CustomAssetLibraries(ListBase asset_libraries)
 {
 }
 
+CustomAssetLibraries::CustomAssetLibraries(CustomAssetLibraries &&other)
+{
+  *this = std::move(other);
+}
+
+CustomAssetLibraries &CustomAssetLibraries::operator=(CustomAssetLibraries &&other)
+{
+  asset_libraries = other.asset_libraries;
+  BLI_listbase_clear(&other.asset_libraries);
+  return *this;
+}
+
 CustomAssetLibraries::~CustomAssetLibraries()
 {
   LISTBASE_FOREACH_MUTABLE (CustomAssetLibraryDefinition *, library, &asset_libraries) {
@@ -468,6 +498,22 @@ const char *BKE_project_name_get(const BlenderProject *project_handle)
   return project->get_settings().project_name().c_str();
 }
 
+ListBase *BKE_project_custom_asset_libraries_get(const BlenderProject *project_handle)
+{
+  const bke::BlenderProject *project = reinterpret_cast<const bke::BlenderProject *>(
+      project_handle);
+  bke::ProjectSettings &settings = project->get_settings();
+  return &settings.asset_library_definitions();
+}
+
+void BKE_project_tag_has_unsaved_changes(const BlenderProject *project_handle)
+{
+  const bke::BlenderProject *project = reinterpret_cast<const bke::BlenderProject *>(
+    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list