[Bf-blender-cvs] [bd1ebcb0e2b] shot-tools-development: Moved WindowManager struct to global instance.
Jeroen Bakker
noreply at git.blender.org
Fri Jan 15 12:09:35 CET 2021
Commit: bd1ebcb0e2bb35f5f4ba97f4a7c779547e948a01
Author: Jeroen Bakker
Date: Wed Jan 13 16:41:09 2021 +0100
Branches: shot-tools-development
https://developer.blender.org/rBbd1ebcb0e2bb35f5f4ba97f4a7c779547e948a01
Moved WindowManager struct to global instance.
===================================================================
M .gitignore
M shot-builder/shot_builder/operators.py
M shot-builder/shot_builder/project.py
M shot-builder/shot_builder/properties.py
A shot-builder/shot_builder/task_type.py
===================================================================
diff --git a/.gitignore b/.gitignore
index bee8a64b79a..3883e04873c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
__pycache__
+.mypy_cache
diff --git a/shot-builder/shot_builder/operators.py b/shot-builder/shot_builder/operators.py
index 9f159679e0e..d3a5e8d6313 100644
--- a/shot-builder/shot_builder/operators.py
+++ b/shot-builder/shot_builder/operators.py
@@ -1,6 +1,10 @@
import bpy
from shot_builder.project import *
+def production_task_types_items(self, context: bpy.types.Context) -> list:
+ production = get_active_production()
+ return production.get_task_types_items()
+
class SHOTBUILDER_OT_NewShotFile(bpy.types.Operator):
"""Build a new shot file"""
bl_idname = "shotbuilder.new_shot_file"
@@ -20,17 +24,26 @@ class SHOTBUILDER_OT_NewShotFile(bpy.types.Operator):
task_type: bpy.props.EnumProperty(
name="Task",
description="Task to create the shot file for",
- items=(
- ("anim", "anim", "anim"),
- )
+ items=production_task_types_items
)
- def invoke(self, context, event):
+ def invoke(self, context: bpy.types.Context, event: bpy.types.Event):
production_root = get_production_root(context)
- if production_root:
- self.production_root = str(production_root)
+ if production_root is None:
+ self.report({'WARNING'}, "Operator is cancelled due to inability to determine the production path. Make sure the a default path in configured in the preferences.")
+ return {'CANCELLED'}
+ ensure_loaded_production(context)
+ production = get_active_production()
+ self.production_root = str(production.path)
+
return context.window_manager.invoke_props_dialog(self, width = 400)
- def execute(self, context):
+ def execute(self, context: bpy.types.Context):
+ production = get_active_production()
return {'CANCELLED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "shot_id")
+ layout.prop(self, "task_type")
\ No newline at end of file
diff --git a/shot-builder/shot_builder/project.py b/shot-builder/shot_builder/project.py
index f53ef24e291..71151a13ebf 100644
--- a/shot-builder/shot_builder/project.py
+++ b/shot-builder/shot_builder/project.py
@@ -19,43 +19,76 @@
# <pep8 compliant>
import pathlib
+import logging
+from typing import *
import bpy
+from shot_builder.task_type import *
-def is_valid_project_path(project_path: pathlib.Path) -> bool:
+
+logger = logging.getLogger(__name__)
+
+
+class Production():
+ """
+ Class containing data and methods for a production.
+ """
+ def __init__(self, production_path: pathlib.Path):
+ self.path = production_path
+ self.task_types = []
+ self.task_types.extend([TaskType('anim'), TaskType('light')])
+
+ def get_task_types_items(self) -> list:
+ """
+ Get the list of task types items to be used in an item function of a
+ `bpy.props.EnumProperty`
+ """
+ return [
+ (task_type.name, task_type.name, task_type.name)
+ for task_type in self.task_types
+ ]
+
+
+_PRODUCTION: Optional[Production] = None
+
+
+def is_valid_production_root(path: pathlib.Path) -> bool:
"""
Test if the given project path is configured correctly.
A valid project path contains a subfolder with the name `shot-builder`
holding configuration files.
"""
- if not project_path.is_absolute():
+ if not path.is_absolute():
return False
- if not project_path.exists():
+ if not path.exists():
return False
- if not project_path.is_dir():
+ if not path.is_dir():
return False
- config_file_path = get_project_config_file_path(project_path)
+ config_file_path = get_production_config_file_path(path)
return config_file_path.exists()
-def get_project_config_dir_path(project_path: pathlib.Path) -> pathlib.Path:
+def get_production_config_dir_path(path: pathlib.Path) -> pathlib.Path:
"""
- Get the project configuration dir path.
+ Get the production configuration dir path.
"""
- return project_path / "shot-builder"
+ return path / "shot-builder"
-def get_project_config_file_path(project_path: pathlib.Path) -> pathlib.Path:
+def get_production_config_file_path(path: pathlib.Path) -> pathlib.Path:
"""
- Get the project configuration file path.
+ Get the production configuration file path.
"""
- return get_project_config_dir_path(project_path) / "config.py"
+ return get_production_config_dir_path(path) / "config.py"
-def _find_production_root(path: pathlib.Path) -> pathlib.Path:
- if is_valid_project_path(path):
+def _find_production_root(path: pathlib.Path) -> Optional[pathlib.Path]:
+ """
+ Given a path try to find the production root
+ """
+ if is_valid_production_root(path):
return path
try:
parent_path = path.parents[0]
@@ -63,8 +96,9 @@ def _find_production_root(path: pathlib.Path) -> pathlib.Path:
except IndexError:
return None
+
# TODO: return type is optional
-def get_production_root(context: bpy.types.Context) -> pathlib.Path:
+def get_production_root(context: bpy.types.Context) -> Optional[pathlib.Path]:
"""
Determine the project root based on the current file.
When current file isn't part of a project the project root
@@ -75,7 +109,38 @@ def get_production_root(context: bpy.types.Context) -> pathlib.Path:
if production_root:
return production_root
production_root = pathlib.Path(
- context.preferences.addons[__package__].preferences.project_path)
- if is_valid_project_path(production_root):
+ context.preferences.addons[__package__].preferences.production_path)
+ if is_valid_production_root(production_root):
return production_root
return None
+
+
+def ensure_loaded_production(context: bpy.types.Context) -> bool:
+ """
+ Ensure that the production of the current context is loaded.
+
+ Returns if the production of for the given context is loaded.
+ """
+ global _PRODUCTION
+ production_root = get_production_root(context)
+ if production_root is None:
+ _PRODUCTION = None
+ return False
+ if _PRODUCTION and (_PRODUCTION.path == production_root):
+ return True
+
+ logger.debug(f"loading new production configuration from '{production_root}'.")
+ return __load_production_configuration(context, production_root)
+
+
+def __load_production_configuration(context: bpy.types.Context,
+ production_path: pathlib.Path) -> bool:
+ global _PRODUCTION
+ _PRODUCTION = Production(production_path)
+ return False
+
+
+def get_active_production() -> Production:
+ global _PRODUCTION
+ assert(_PRODUCTION)
+ return _PRODUCTION
\ No newline at end of file
diff --git a/shot-builder/shot_builder/properties.py b/shot-builder/shot_builder/properties.py
index 79b74e689e3..ffd2444adda 100644
--- a/shot-builder/shot_builder/properties.py
+++ b/shot-builder/shot_builder/properties.py
@@ -21,13 +21,14 @@ import bpy
import pathlib
-from shot_builder.project import is_valid_project_path
+from shot_builder.project import is_valid_production_root
+
class ShotBuilderPreferences(bpy.types.AddonPreferences):
bl_idname = __package__
- project_path: bpy.props.StringProperty(
- name="Project Root",
+ production_path: bpy.props.StringProperty(
+ name="Production Root",
description="The location to load configuration files from when "
"they couldn't be found in any parent folder of the current "
"file. Folder must contain a sub-folder named `shot-builder` "
@@ -38,8 +39,8 @@ class ShotBuilderPreferences(bpy.types.AddonPreferences):
def draw(self, context):
layout = self.layout
- is_valid = is_valid_project_path(pathlib.Path(self.project_path))
- layout.prop(self, "project_path", icon='NONE' if is_valid else 'ERROR')
+ is_valid = is_valid_production_root(pathlib.Path(self.production_path))
+ layout.prop(self, "production_path", icon='NONE' if is_valid else 'ERROR')
if not is_valid:
layout.label(text="Folder must contain a sub-folder named "
"`shot-builder` that holds the configuration "
diff --git a/shot-builder/shot_builder/task_type.py b/shot-builder/shot_builder/task_type.py
new file mode 100644
index 00000000000..28314cb7f10
--- /dev/null
+++ b/shot-builder/shot_builder/task_type.py
@@ -0,0 +1,3 @@
+class TaskType:
+ def __init__(self, task_name: str):
+ self.name = task_name
\ No newline at end of file
More information about the Bf-blender-cvs
mailing list