Blender Kitsu: Update Kitsu Context UI #187

Merged
6 changed files with 445 additions and 390 deletions

View File

@ -74,6 +74,7 @@ _episode_cache_proj_id: str = ""
_all_shot_tasks_cache_proj_id: str = ""
_all_task_type_cache_proj_id: str = ""
_seq_cache_proj_id: str = ""
_seq_cache_episode_id: str = ""
_shot_cache_seq_id: str = ""
_task_type_cache_shot_id: str = ""
_asset_cache_asset_type_id: str = ''
@ -127,11 +128,15 @@ def episode_active_set_by_id(context: bpy.types.Context, entity_id: str) -> None
logger.debug("Set active episode to %s", _episode_active.name)
def episode_active_reset(context: bpy.types.Context) -> None:
def episode_active_reset_entity():
global _episode_active
_episode_active = Episode()
def episode_active_reset(context: bpy.types.Context) -> None:
episode_active_reset_entity()
context.scene.kitsu.episode_active_id = ""
context.scene.kitsu.episode_active_name = ""
logger.debug("Reset active episode")
@ -147,11 +152,15 @@ def sequence_active_set_by_id(context: bpy.types.Context, entity_id: str) -> Non
logger.debug("Set active sequence to %s", _sequence_active.name)
def sequence_active_reset(context: bpy.types.Context) -> None:
def sequence_active_reset_entity() -> None:
global _sequence_active
_sequence_active = Sequence()
def sequence_active_reset(context: bpy.types.Context) -> None:
sequence_active_reset_entity()
context.scene.kitsu.sequence_active_id = ""
context.scene.kitsu.sequence_active_name = ""
logger.debug("Reset active sequence")
@ -177,11 +186,15 @@ def shot_active_set_by_id(context: bpy.types.Context, entity_id: str) -> None:
logger.debug("Set active shot to %s", _shot_active.name)
def shot_active_reset(context: bpy.types.Context) -> None:
def shot_active_reset_entity() -> None:
global _shot_active
_shot_active = Shot()
def shot_active_reset(context: bpy.types.Context) -> None:
shot_active_reset_entity()
context.scene.kitsu.shot_active_id = ""
context.scene.kitsu.shot_active_name = ""
logger.debug("Reset active shot")
@ -199,11 +212,15 @@ def asset_active_set_by_id(context: bpy.types.Context, entity_id: str) -> None:
logger.debug("Set active asset to %s", _asset_active.name)
def asset_active_reset(context: bpy.types.Context) -> None:
def asset_active_reset_entity() -> None:
global _asset_active
_asset_active = Asset()
def asset_active_reset(context: bpy.types.Context) -> None:
asset_active_reset_entity()
context.scene.kitsu.asset_active_id = ""
context.scene.kitsu.asset_active_name = ""
logger.debug("Reset active asset")
@ -221,11 +238,15 @@ def asset_type_active_set_by_id(context: bpy.types.Context, entity_id: str) -> N
logger.debug("Set active asset type to %s", _asset_type_active.name)
def asset_type_active_reset(context: bpy.types.Context) -> None:
def asset_type_active_reset_entity() -> None:
global _asset_type_active
_asset_type_active = AssetType()
def asset_type_active_reset(context: bpy.types.Context) -> None:
asset_type_active_reset_entity()
context.scene.kitsu.asset_type_active_id = ""
context.scene.kitsu.asset_type_active_name = ""
logger.debug("Reset active asset type")
@ -243,11 +264,15 @@ def task_type_active_set_by_id(context: bpy.types.Context, entity_id: str) -> No
logger.debug("Set active task type to %s", _task_type_active.name)
def task_type_active_reset(context: bpy.types.Context) -> None:
def task_type_active_reset_entity() -> None:
global _task_type_active
_task_type_active = TaskType()
def task_type_active_reset(context: bpy.types.Context) -> None:
task_type_active_reset_entity()
context.scene.kitsu.task_type_active_id = ""
context.scene.kitsu.task_type_active_name = ""
logger.debug("Reset active task type")
@ -297,6 +322,7 @@ def get_sequences_enum_list(
) -> List[Tuple[str, str, str]]:
global _sequence_enum_list
global _seq_cache_proj_id
global _seq_cache_episode_id
project_active = project_active_get()
episode_active = episode_active_get()
@ -304,7 +330,7 @@ def get_sequences_enum_list(
return []
# Return Cached list if project hasn't changed
if _seq_cache_proj_id == project_active.id:
if _seq_cache_proj_id == project_active.id and _seq_cache_episode_id == episode_active.id:
return _sequence_enum_list
# Update Cache Sequence ID

View File

@ -1,4 +1,5 @@
import bpy
from .. import cache
# Category values are defined in enum props.py KITSU_property_group_scene under category
@ -16,3 +17,50 @@ def is_asset_context():
def is_shot_context():
return bpy.context.scene.kitsu.category == "SHOT"
def active_project_row(layout: bpy.types.UILayout) -> bpy.types.UILayout:
project_active = cache.project_active_get()
row = layout.row(align=True)
if not project_active:
row.enabled = False
return row
def active_episode_row(layout: bpy.types.UILayout) -> None:
episode_active = cache.episode_active_get()
project_active = cache.project_active_get()
row = active_project_row(layout)
if project_active.nb_episodes > 0 and not episode_active:
row.enabled = False
return row
def draw_episode_selector(context: bpy.types.Context, layout: bpy.types.UILayout) -> None:
row = active_project_row(layout)
row.prop(context.scene.kitsu, "episode_active_name")
def draw_sequence_selector(context: bpy.types.Context, layout: bpy.types.UILayout) -> None:
row = active_episode_row(layout)
row.prop(context.scene.kitsu, "sequence_active_name")
def draw_asset_type_selector(context: bpy.types.Context, layout: bpy.types.UILayout) -> None:
row = active_project_row(layout)
row.prop(context.scene.kitsu, "asset_type_active_name")
def draw_shot_selector(context: bpy.types.Context, layout: bpy.types.UILayout) -> None:
row = active_episode_row(layout)
row.prop(context.scene.kitsu, "shot_active_name")
def draw_asset_selector(context: bpy.types.Context, layout: bpy.types.UILayout) -> None:
row = active_project_row(layout)
row.prop(context.scene.kitsu, "asset_active_name")
def draw_task_type_selector(context: bpy.types.Context, layout: bpy.types.UILayout):
layout.prop(context.scene.kitsu, "task_type_active_name")

View File

@ -18,7 +18,7 @@
#
# (c) 2021, Blender Foundation - Paul Golter
from typing import Dict, Optional, Set, Any
from typing import Dict, Optional, Set
from pathlib import Path
import bpy
@ -26,7 +26,6 @@ import bpy
from .. import bkglobals, cache, util, prefs
from ..logger import LoggerFactory
from ..types import TaskType, AssetType
from ..context import core as context_core
logger = LoggerFactory.getLogger()
@ -70,223 +69,6 @@ class KITSU_OT_con_productions_load(bpy.types.Operator):
return {"FINISHED"}
class KITSU_OT_con_episodes_load(bpy.types.Operator):
"""
Gets all episodes that are available in server and let's user select. Invokes a search Popup (enum_prop) on click.
"""
bl_idname = "kitsu.con_episodes_load"
bl_label = "Episodes Load"
bl_property = "enum_prop"
bl_description = "Set active episode for this Production"
enum_prop: bpy.props.EnumProperty(items=cache.get_episodes_enum_list) # type: ignore
@classmethod
def poll(cls, context: bpy.types.Context) -> bool:
return bool(prefs.session_auth(context) and cache.project_active_get())
def execute(self, context: bpy.types.Context) -> Set[str]:
# Store vars to check if project / seq / shot changed.
zep_prev_id = cache.episode_active_get().id
# Update kitsu metadata.
cache.episode_active_set_by_id(context, self.enum_prop)
# Clear active shot when sequence changes.
if self.enum_prop != zep_prev_id:
cache.sequence_active_reset(context)
cache.asset_type_active_reset(context)
cache.shot_active_reset(context)
cache.asset_active_reset(context)
util.ui_redraw()
return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.invoke_search_popup(self)
return {"FINISHED"}
class KITSU_OT_con_sequences_load(bpy.types.Operator):
"""
Gets all sequences that are available in server for active production and let's user select. Invokes a search Popup (enum_prop) on click.
"""
bl_idname = "kitsu.con_sequences_load"
bl_label = "Sequences Load"
bl_property = "enum_prop"
bl_description = "Sets active sequence for this scene"
enum_prop: bpy.props.EnumProperty(items=cache.get_sequences_enum_list) # type: ignore
@classmethod
def poll(cls, context: bpy.types.Context) -> bool:
return bool(prefs.session_auth(context) and cache.project_active_get())
def execute(self, context: bpy.types.Context) -> Set[str]:
# Store vars to check if project / seq / shot changed.
zseq_prev_id = cache.sequence_active_get().id
# Update kitsu metadata.
cache.sequence_active_set_by_id(context, self.enum_prop)
# Clear active shot when sequence changes.
if self.enum_prop != zseq_prev_id:
cache.shot_active_reset(context)
util.ui_redraw()
return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.invoke_search_popup(self)
return {"FINISHED"}
class KITSU_OT_con_shots_load(bpy.types.Operator):
"""
Gets all shots that are available in server for active production and let's user select. Invokes a search Popup (enum_prop) on click.
"""
bl_idname = "kitsu.con_shots_load"
bl_label = "Shots Load"
bl_property = "enum_prop"
bl_description = "Sets active shot for this scene"
enum_prop: bpy.props.EnumProperty(items=cache.get_shots_enum_for_active_seq) # type: ignore
@classmethod
def poll(cls, context: bpy.types.Context) -> bool:
# Only if session is auth active_project and active sequence selected.
return bool(
prefs.session_auth(context)
and cache.sequence_active_get()
and cache.project_active_get()
)
def execute(self, context: bpy.types.Context) -> Set[str]:
# Update kitsu metadata.
if self.enum_prop:
cache.shot_active_set_by_id(context, self.enum_prop)
util.ui_redraw()
return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.invoke_search_popup(self)
return {"FINISHED"}
class KITSU_OT_con_asset_types_load(bpy.types.Operator):
"""
Gets all asset_types that are available in server and let's user select. Invokes a search Popup (enum_prop) on click.
"""
bl_idname = "kitsu.con_asset_types_load"
bl_label = "Asset Types Load"
bl_property = "enum_prop"
bl_description = "Sets active asset type for this scene"
enum_prop: bpy.props.EnumProperty(items=cache.get_assetypes_enum_list) # type: ignore
@classmethod
def poll(cls, context: bpy.types.Context) -> bool:
return bool(prefs.session_auth(context) and cache.project_active_get())
def execute(self, context: bpy.types.Context) -> Set[str]:
# Store vars to check if project / seq / shot changed.
asset_type_prev_id = cache.asset_type_active_get().id
# Update kitsu metadata.
cache.asset_type_active_set_by_id(context, self.enum_prop)
# Clear active shot when sequence changes.
if self.enum_prop != asset_type_prev_id:
cache.asset_active_reset(context)
util.ui_redraw()
return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.invoke_search_popup(self)
return {"FINISHED"}
class KITSU_OT_con_assets_load(bpy.types.Operator):
"""
Gets all assets that are available on server for active production and let's user select. Invokes a search Popup (enum_prop) on click.
"""
bl_idname = "kitsu.con_assets_load"
bl_label = "Assets Load"
bl_property = "enum_prop"
bl_description = "Sets active asset for this scene"
enum_prop: bpy.props.EnumProperty(items=cache.get_assets_enum_for_active_asset_type) # type: ignore
@classmethod
def poll(cls, context: bpy.types.Context) -> bool:
return bool(
prefs.session_auth(context)
and cache.project_active_get()
and cache.asset_type_active_get()
)
def execute(self, context: bpy.types.Context) -> Set[str]:
if not self.enum_prop:
return {"CANCELLED"}
# Update kitsu metadata.
cache.asset_active_set_by_id(context, self.enum_prop)
util.ui_redraw()
return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.invoke_search_popup(self)
return {"FINISHED"}
class KITSU_OT_con_task_types_load(bpy.types.Operator):
"""
Gets all task types that are available on server for active asset/shot and let's user select. Invokes a search Popup (enum_prop) on click.
"""
bl_idname = "kitsu.con_task_types_load"
bl_label = "Task Types Load"
bl_property = "enum_prop"
bl_description = "Sets active task type for this scene"
enum_prop: bpy.props.EnumProperty(items=cache.get_task_types_enum_for_current_context) # type: ignore
@classmethod
def poll(cls, context: bpy.types.Context) -> bool:
addon_prefs = prefs.addon_prefs_get(context)
precon = bool(prefs.session_auth(context) and cache.project_active_get())
if context_core.is_shot_context():
return bool(precon and cache.sequence_active_get() and cache.shot_active_get())
if context_core.is_asset_context():
return bool(precon and cache.asset_type_active_get() and cache.asset_active_get())
if context_core.is_sequence_context():
return bool(precon and cache.sequence_active_get())
return False
def execute(self, context: bpy.types.Context) -> Set[str]:
# Store vars to check if project / seq / shot changed.
asset_task_type_id = cache.task_type_active_get().id
# Update kitsu metadata.
cache.task_type_active_set_by_id(context, self.enum_prop)
util.ui_redraw()
return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.invoke_search_popup(self)
return {"FINISHED"}
class KITSU_OT_con_detect_context(bpy.types.Operator):
bl_idname = "kitsu.con_detect_context"
bl_label = "Detect Context"
@ -303,6 +85,8 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
filepath = Path(bpy.data.filepath)
active_project = cache.project_active_get()
kitsu_props = context.scene.kitsu
# TODO REFACTOR THIS WHOLE THING, BAD HACK
# Path is different for tvshow
if (
@ -322,7 +106,7 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
# TODO: check if frame range update gets triggered.
# Set category.
context.scene.kitsu.category = "SHOT"
kitsu_props.category = "SHOT"
# Detect ad load sequence.
sequence = active_project.get_sequence_by_name(item_group)
@ -330,7 +114,7 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
self.report({"ERROR"}, f"Failed to find sequence: '{item_group}' on server")
return {"CANCELLED"}
bpy.ops.kitsu.con_sequences_load(enum_prop=sequence.id)
kitsu_props.sequence_active_name = sequence.name
# Detect and load shot.
shot = active_project.get_shot_by_name(sequence, item)
@ -338,7 +122,7 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
self.report({"ERROR"}, f"Failed to find shot: '{item}' on server")
return {"CANCELLED"}
bpy.ops.kitsu.con_shots_load(enum_prop=shot.id)
kitsu_props.shot_active_name = shot.name
# Detect and load shot task type.
kitsu_task_type_name = self._find_in_mapping(
@ -355,11 +139,11 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
)
return {"CANCELLED"}
bpy.ops.kitsu.con_task_types_load(enum_prop=task_type.id)
kitsu_props.task_type_active_name = task_type.name
if category == bkglobals.SEQ_DIR_NAME:
# Set category.
context.scene.kitsu.category = "SEQ"
kitsu_props.category = "SEQ"
# Detect and load seqeunce.
sequence = active_project.get_sequence_by_name(item_group)
@ -367,7 +151,7 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
self.report({"ERROR"}, f"Failed to find sequence: '{item_group}' on server")
return {"CANCELLED"}
bpy.ops.kitsu.con_sequences_load(enum_prop=sequence.id)
kitsu_props.sequence_active_name = sequence.name
# Detect and load shot task type.
kitsu_task_type_name = self._find_in_mapping(
@ -384,11 +168,11 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
)
return {"CANCELLED"}
bpy.ops.kitsu.con_task_types_load(enum_prop=task_type.id)
kitsu_props.task_type_active_name = task_type.name
elif category == bkglobals.ASSET_DIR_NAME:
# Set category.
context.scene.kitsu.category = "ASSET"
kitsu_props.category = "ASSET"
# Detect and load asset type.
kitsu_asset_type_name = self._find_in_mapping(
@ -405,15 +189,13 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
)
return {"CANCELLED"}
bpy.ops.kitsu.con_asset_types_load(enum_prop=asset_type.id)
kitsu_props.asset_type_active_name = asset_type.name
# Detect and load asset.
asset = active_project.get_asset_by_name(item)
if not asset:
self.report({"ERROR"}, f"Failed to find asset: '{item}' on server")
return {"CANCELLED"}
bpy.ops.kitsu.con_assets_load(enum_prop=asset.id)
kitsu_props.asset_active_name = asset.name
# Detect and load asset task_type.
kitsu_task_type_name = self._find_in_mapping(
@ -430,7 +212,7 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
)
return {"CANCELLED"}
bpy.ops.kitsu.con_task_types_load(enum_prop=task_type.id)
kitsu_props.task_type_active_name = task_type.name
else:
self.report(
@ -462,12 +244,6 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
classes = [
KITSU_OT_con_productions_load,
KITSU_OT_con_episodes_load,
KITSU_OT_con_sequences_load,
KITSU_OT_con_shots_load,
KITSU_OT_con_asset_types_load,
KITSU_OT_con_assets_load,
KITSU_OT_con_task_types_load,
KITSU_OT_con_detect_context,
]

View File

@ -23,13 +23,7 @@ import bpy
from ..context import core as context_core
from .. import cache, prefs, ui
from ..context.ops import (
KITSU_OT_con_sequences_load,
KITSU_OT_con_shots_load,
KITSU_OT_con_asset_types_load,
KITSU_OT_con_assets_load,
KITSU_OT_con_task_types_load,
KITSU_OT_con_detect_context,
KITSU_OT_con_episodes_load,
)
@ -56,86 +50,10 @@ class KITSU_PT_vi3d_context(bpy.types.Panel):
project_active = cache.project_active_get()
return bool(not project_active)
def draw_episode_selector(self, layout, project_active, episode_active):
row = layout.row(align=True)
if not project_active:
row.enabled = False
label_text = "Select Episode" if not episode_active else episode_active.name
if project_active.nb_episodes > 0:
row.operator(
KITSU_OT_con_episodes_load.bl_idname,
text=label_text,
icon="DOWNARROW_HLT",
)
def draw_sequence_selector(self, layout, project_active, episode_active):
row = layout.row(align=True)
if not project_active:
row.enabled = False
elif project_active.nb_episodes > 0 and not episode_active:
row.enabled = False
sequence = cache.sequence_active_get()
label_text = "Select Sequence" if not sequence else sequence.name
row.operator(
KITSU_OT_con_sequences_load.bl_idname,
text=label_text,
icon="DOWNARROW_HLT",
)
def draw_asset_type_selector(self, layout, project_active):
row = layout.row(align=True)
if not project_active:
row.enabled = False
asset_type = cache.asset_type_active_get()
label_text = "Select Asset Type" if not asset_type else asset_type.name
row.operator(
KITSU_OT_con_asset_types_load.bl_idname,
text=label_text,
icon="DOWNARROW_HLT",
)
def draw_shot_selector(self, layout, project_active):
row = layout.row(align=True)
if not project_active:
row.enabled = False
shot = cache.shot_active_get()
label_text = "Select Shot" if not shot else shot.name
row.operator(
KITSU_OT_con_shots_load.bl_idname,
text=label_text,
icon="DOWNARROW_HLT",
)
def draw_asset_selector(self, layout, project_active):
row = layout.row(align=True)
if not project_active:
row.enabled = False
asset = cache.asset_active_get()
label_text = "Select Asset" if not asset else asset.name
row.operator(
KITSU_OT_con_assets_load.bl_idname,
text=label_text,
icon="DOWNARROW_HLT",
)
def draw(self, context: bpy.types.Context) -> None:
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
project_active = cache.project_active_get()
episode_active = cache.episode_active_get()
@ -160,38 +78,36 @@ class KITSU_PT_vi3d_context(bpy.types.Panel):
emboss=False,
)
flow = layout.grid_flow(
row_major=True, columns=0, even_columns=True, even_rows=False, align=False
)
col = flow.column()
# Entity context
row = layout.row(align=True)
row.prop(context.scene.kitsu, "category")
col.prop(context.scene.kitsu, "category")
if not prefs.session_auth(context) or not project_active:
row.enabled = False
# Episode selector
if project_active.nb_episodes > 0:
self.draw_episode_selector(layout, project_active, episode_active)
context_core.draw_episode_selector(context, col)
# Sequence selector (if context is Sequence)
if context_core.is_sequence_context():
self.draw_sequence_selector(layout, project_active, episode_active)
context_core.draw_sequence_selector(context, col)
# Shot selector
if context_core.is_shot_context():
self.draw_sequence_selector(layout, project_active, episode_active)
self.draw_shot_selector(layout, project_active)
context_core.draw_sequence_selector(context, col)
context_core.draw_shot_selector(context, col)
# AssetType selector (if context is Asset)
if context_core.is_asset_context():
self.draw_asset_type_selector(layout, project_active)
self.draw_asset_selector(layout, project_active)
context_core.draw_asset_type_selector(context, col)
context_core.draw_asset_selector(context, col)
# Task Type selector
t_text = "Select Task Type"
task_type_active = cache.task_type_active_get()
if task_type_active:
t_text = task_type_active.name
row = layout.row(align=True)
row.operator(KITSU_OT_con_task_types_load.bl_idname, text=t_text, icon="DOWNARROW_HLT")
context_core.draw_task_type_selector(context, col)
class KITSU_PT_comp_context(KITSU_PT_vi3d_context):

View File

@ -19,13 +19,14 @@
# (c) 2021, Blender Foundation - Paul Golter
from typing import Any, Union, List, Dict, Optional
from typing import Any, Union, List, Dict, Optional, Tuple
import bpy
from bpy.app.handlers import persistent
from . import propsdata, bkglobals
from .logger import LoggerFactory
from . import cache
logger = LoggerFactory.getLogger()
@ -123,9 +124,327 @@ class KITSU_property_group_sequence(bpy.types.PropertyGroup):
self.linked = False
def set_kitsu_entity_id_via_enum_name(
self,
items: List[Tuple[str, str, str]],
input_name: str,
name_prop: str,
id_prop: str,
) -> str:
"""Set the ID and Name of a Kitsu entity by finding the matching ID for a given name
and updating both values in their corrisponding String Properties (Kitsu Context Properties)
Args:
items (List[Tuple[str, str, str]]): Enum items in the format List[Tuple[id, name, description]]
input_name (str): Name, used to find matching ID in a tuple
name_prop (str): Name of String Property where Kitsu Enitity's Name is stored
id_prop (str): Name of String Property where Kitsu Enitity's ID is stored
Returns:
str: ID of Kitsu entity
"""
if input_name == "":
self[id_prop] = ""
self[name_prop] = input_name
return
for key, value, _ in items:
if value == input_name:
self[id_prop] = key
self[name_prop] = input_name
return key
def get_enum_item_names(enum_items: List[Tuple[str, str, str]]) -> List[str]:
"""Return a list of names from a list of enum items used by (Kitsu Context Properties)
Args:
enum_items (List[Tuple[str, str, str]]): Enum items in the format List[Tuple[id, name, description]]
Returns:
List[str]: List of avaliable names
"""
return [item[1] for item in enum_items]
def get_safely_string_prop(self, name: str) -> str:
"""Return Value of String Property, and return "" if value isn't set"""
try:
return self[name]
except KeyError:
return ""
class KITSU_property_group_scene(bpy.types.PropertyGroup):
""""""
################################
# Kitsu Context Properties
################################
"""
Kitsu Context Properties
These are properties used to store/manage the current "Context"
for a Kitsu Entity. Kitsu Entities represents things like Asset,
Shot and Sequence for a given production.
Each Enitity has an 'ID' Property which is used internally by the add-on
and a 'Name' Property which is used as part of the user interface. When a user selects
the 'Name' of a Kitsu Entity a custom Set function on the property will also update
the Entity's ID.
NOTE: It would be nice to have searchable enums instead of doing all this work manually.
"""
###########
# Sequence
###########
sequence_active_id: bpy.props.StringProperty( # type: ignore
name="Active Sequence ID",
description="ID that refers to the active sequence on server",
default="",
)
def get_sequences_via_name(self):
return get_safely_string_prop(self, "sequence_active_name")
def set_sequences_via_name(self, input):
key = set_kitsu_entity_id_via_enum_name(
self=self,
input_name=input,
items=cache.get_sequences_enum_list(self, bpy.context),
name_prop='sequence_active_name',
id_prop='sequence_active_id',
)
if key:
cache.sequence_active_set_by_id(bpy.context, key)
else:
cache.sequence_active_reset_entity()
return
def get_sequence_search_list(self, context, edit_text):
return get_enum_item_names(cache.get_sequences_enum_list(self, bpy.context))
sequence_active_name: bpy.props.StringProperty(
name="Sequence",
description="Sequence",
default="", # type: ignore
get=get_sequences_via_name,
set=set_sequences_via_name,
options=set(),
search=get_sequence_search_list,
search_options={'SORT'},
)
###########
# Episode
###########
episode_active_id: bpy.props.StringProperty( # type: ignore
name="Active Episode ID",
description="ID that refers to the active episode on server",
default="",
)
def get_episode_via_name(self):
return get_safely_string_prop(self, "episode_active_name")
def set_episode_via_name(self, input):
key = set_kitsu_entity_id_via_enum_name(
self=self,
input_name=input,
items=cache.get_episodes_enum_list(self, bpy.context),
name_prop='episode_active_name',
id_prop='episode_active_id',
)
# Clear active shot when sequence changes.
if cache.episode_active_get().id != key:
cache.sequence_active_reset(bpy.context)
cache.asset_type_active_reset(bpy.context)
cache.shot_active_reset(bpy.context)
cache.asset_active_reset(bpy.context)
if key:
cache.episode_active_set_by_id(bpy.context, key)
return
def get_episode_search_list(self, context, edit_text):
return get_enum_item_names(cache.get_episodes_enum_list(self, bpy.context))
episode_active_name: bpy.props.StringProperty(
name="Episode",
description="Selet Active Episode",
default="", # type: ignore
get=get_episode_via_name,
set=set_episode_via_name,
options=set(),
search=get_episode_search_list,
search_options={'SORT'},
)
###########
# Shot
###########
shot_active_id: bpy.props.StringProperty( # type: ignore
name="Active Shot ID",
description="IDthat refers to the active shot on server",
default="",
# update=propsdata.on_shot_change,
)
def get_shot_via_name(self):
return get_safely_string_prop(self, "shot_active_name")
def set_shot_via_name(self, input):
key = set_kitsu_entity_id_via_enum_name(
self=self,
input_name=input,
items=cache.get_shots_enum_for_active_seq(self, bpy.context),
name_prop='shot_active_name',
id_prop='shot_active_id',
)
if key:
cache.shot_active_set_by_id(bpy.context, key)
else:
cache.shot_active_reset_entity()
return
def get_shot_search_list(self, context, edit_text):
return get_enum_item_names(cache.get_shots_enum_for_active_seq(self, bpy.context))
shot_active_name: bpy.props.StringProperty(
name="Shot",
description="Shot",
default="", # type: ignore
get=get_shot_via_name,
set=set_shot_via_name,
options=set(),
search=get_shot_search_list,
search_options={'SORT'},
)
###########
# Asset
###########
asset_active_id: bpy.props.StringProperty( # type: ignore
name="Active Asset ID",
description="ID that refers to the active asset on server",
default="",
)
def get_asset_via_name(self):
return get_safely_string_prop(self, "asset_active_name")
def set_asset_via_name(self, input):
key = set_kitsu_entity_id_via_enum_name(
self=self,
input_name=input,
items=cache.get_assets_enum_for_active_asset_type(self, bpy.context),
name_prop='asset_active_name',
id_prop='asset_active_id',
)
if key:
cache.asset_active_set_by_id(bpy.context, key) # TODO
else:
cache.asset_active_reset_entity()
return
def get_asset_type_search_list(self, context, edit_text):
return get_enum_item_names(cache.get_assets_enum_for_active_asset_type(self, bpy.context))
asset_active_name: bpy.props.StringProperty(
name="Asset",
description="Active Asset",
default="", # type: ignore
get=get_asset_via_name,
set=set_asset_via_name,
options=set(),
search=get_asset_type_search_list,
search_options={'SORT'},
)
############
# Asset Type
############
asset_type_active_id: bpy.props.StringProperty( # type: ignore
name="Active Asset Type ID",
description="ID that refers to the active asset type on server",
default="",
)
def get_asset_type_via_name(self):
return get_safely_string_prop(self, "asset_type_active_name")
def set_asset_type_via_name(self, input):
key = set_kitsu_entity_id_via_enum_name(
self=self,
input_name=input,
items=cache.get_assetypes_enum_list(self, bpy.context),
name_prop='asset_type_active_name',
id_prop='asset_type_active_id',
)
if key:
cache.asset_type_active_set_by_id(bpy.context, key)
else:
cache.asset_type_active_reset_entity()
return
def get_asset_type_search_list(self, context, edit_text):
return get_enum_item_names(cache.get_assetypes_enum_list(self, bpy.context))
asset_type_active_name: bpy.props.StringProperty(
name="Asset Type",
description="Active Asset Type Name",
default="", # type: ignore
get=get_asset_type_via_name,
set=set_asset_type_via_name,
options=set(),
search=get_asset_type_search_list,
search_options={'SORT'},
)
############
# Task Type
############
task_type_active_id: bpy.props.StringProperty( # type: ignore
name="Active Task Type ID",
description="ID that refers to the active task type on server",
default="",
)
def get_task_type_via_name(self):
return get_safely_string_prop(self, "task_type_active_name")
def set_task_type_via_name(self, input):
key = set_kitsu_entity_id_via_enum_name(
self=self,
input_name=input,
items=cache.get_task_types_enum_for_current_context(self, bpy.context),
name_prop='task_type_active_name',
id_prop='task_type_active_id',
)
if key:
cache.task_type_active_set_by_id(bpy.context, key)
else:
cache.task_type_active_reset_entity()
return
def get_task_type_search_list(self, context, edit_text):
return get_enum_item_names(cache.get_task_types_enum_for_current_context(self, bpy.context))
task_type_active_name: bpy.props.StringProperty(
name="Task Type",
description="Active Task Type Name",
default="", # type: ignore
get=get_task_type_via_name,
set=set_task_type_via_name,
options=set(),
search=get_task_type_search_list,
search_options={'SORT'},
)
category: bpy.props.EnumProperty( # type: ignore
name="Type",
description="Kitsu entity type",
@ -136,46 +455,7 @@ class KITSU_property_group_scene(bpy.types.PropertyGroup):
("EDIT", "Edit", "Edit related tasks", 3),
),
default="SHOT",
update=propsdata.reset_task_type,
)
# Context props.
sequence_active_id: bpy.props.StringProperty( # type: ignore
name="Active Sequence ID",
description="ID that refers to the active sequence on server",
default="",
)
episode_active_id: bpy.props.StringProperty( # type: ignore
name="Active Episode ID",
description="ID that refers to the active episode on server",
default="",
)
shot_active_id: bpy.props.StringProperty( # type: ignore
name="Active Shot ID",
description="IDthat refers to the active shot on server",
default="",
update=propsdata.on_shot_change,
)
asset_active_id: bpy.props.StringProperty( # type: ignore
name="Active Asset ID",
description="ID that refers to the active asset on server",
default="",
)
asset_type_active_id: bpy.props.StringProperty( # type: ignore
name="Active Asset Type ID",
description="ID that refers to the active asset type on server",
default="",
)
task_type_active_id: bpy.props.StringProperty( # type: ignore
name="Active Task Type ID",
description="ID that refers to the active task type on server",
default="",
update=propsdata.reset_all_kitsu_props,
)
# Thumbnail props.

View File

@ -195,3 +195,12 @@ def on_shot_change(self: Any, context: bpy.types.Context) -> None:
# Check frame range.
ops_playblast.load_post_handler_check_frame_range(context)
def reset_all_kitsu_props(self: Any, context: bpy.types.Context) -> None:
cache.sequence_active_reset(context)
cache.asset_type_active_reset(context)
cache.shot_active_reset(context)
cache.asset_active_reset(context)
cache.episode_active_reset(context)
cache.task_type_active_reset(context)