Files
test2/scripts/startup/bl_ui/temp_anim_layers.py
Campbell Barton 949dfbfaa8 Cleanup: Python script formatting
- Double quotes for strings.
- Trailing commas when wrapped lines.
2024-06-06 11:26:28 +10:00

129 lines
4.2 KiB
Python

# SPDX-FileCopyrightText: 2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""NOTE: this is temporary UI code to show animation layers.
It is not meant for any particular use, just to have *something* in the UI.
"""
import threading
import bpy
from bpy.types import (
Panel,
WindowManager,
)
from bpy.props import PointerProperty
class VIEW3D_PT_animation_layers(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "Animation"
bl_label = "Baklava"
@classmethod
def poll(cls, context):
return context.preferences.experimental.use_animation_baklava and context.object
def draw(self, context) -> None:
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
# FIXME: this should be done in response to a message-bus callback, notifier, whatnot.
adt = context.object.animation_data
with _wm_selected_action_lock:
selected_action = getattr(adt, "action", None)
# Only set if it has to change, to avoid unnecessary notifies (that cause
# a redraw, that cause this code to be called, etc.)
if context.window_manager.selected_action != selected_action:
context.window_manager.selected_action = selected_action
col = layout.column()
# This has to go via an auxiliary property, as assigning an Animation
# data-block should be possible even when `context.object.animation_data`
# is `None`, and thus its `animation` property does not exist.
col.template_ID(context.window_manager, "selected_action")
col = layout.column(align=False)
anim = adt and adt.action
if anim:
binding_sub = col.column(align=True)
# Binding selector.
row = binding_sub.row(align=True)
row.prop(adt, "action_binding", text="Binding")
row.operator("anim.binding_unassign_object", text="", icon='X')
binding = anim.bindings.get(adt.action_binding, None)
if binding:
binding_sub.prop(binding, "name_display", text="Name")
internal_sub = binding_sub.box().column(align=True)
internal_sub.active = False
internal_sub.prop(adt, "action_binding_handle", text="handle")
if binding:
internal_sub.prop(binding, "name", text="Internal Name")
if adt:
col.prop(adt, "action_binding_name", text="ADT Binding Name")
else:
col.label(text="ADT Binding Name: -")
layout.separator()
if not anim:
layout.label(text="No layers")
return
for layer_idx, layer in reversed(list(enumerate(anim.layers))):
layerbox = layout.box()
col = layerbox.column(align=True)
col.prop(layer, "name", text="Layer {:d}:".format(layer_idx + 1))
col.prop(layer, "influence")
col.prop(layer, "mix_mode")
classes = (
VIEW3D_PT_animation_layers,
)
_wm_selected_action_lock = threading.Lock()
def _wm_selected_action_update(wm, context):
# Avoid responding to changes written by the panel above.
lock_ok = _wm_selected_action_lock.acquire(blocking=False)
if not lock_ok:
return
try:
if wm.selected_action is None and context.object.animation_data is None:
return
adt = context.object.animation_data_create()
if adt.action == wm.selected_action:
# Avoid writing to the property when the new value hasn't changed.
return
adt.action = wm.selected_action
finally:
_wm_selected_action_lock.release()
def register_props():
# Due to this hackyness, the WindowManager will increase the user count of
# the pointed-to Animation data-block.
WindowManager.selected_action = PointerProperty(
type=bpy.types.Action,
name="Action",
description="Action assigned to the active Object",
update=_wm_selected_action_update,
)
if __name__ == "__main__": # only for live edit.
register_, _ = bpy.utils.register_classes_factory(classes)
register_()
register_props()