Properties updates and handlers

Added a scene pointer property (x_camera for want of a better
name) which points to a blender object type. The poll method lets it
be narrowed down to those of type 'CAMERA'
Scene.x_camera
has an update method for when this object is changed
and changes scene camera to match.
Added the property to the UI in the scene panel. The benefit of this
approach is the user can choose a camera, and run code based on this
choice.
Next added a simple getter boolean property, cam_change
that is
false when our pointer property camera is not the scene camera
To handle other ways the active camera is set, eg keystrokes, or
markers, a handler is used. The scene update pre handler ticks over a
lot. Another boolean could be utilized to turn the handler on or off.
Test code below. Added a couple of convenience methods to uncomment and remove handlers and panel draw_methods.
import bpy
from bpy.props import PointerProperty, BoolProperty
def cam_changed(self):
return self.x_camera is not self.camera
def cam_update(self, context):
if self.cam_changed:
self.camera = self.x_camera
print("UI UPDATE")
else:
print("HANDER UPDATE")
def cam_update_handler(scene):
if scene.cam_changed:
scene.x_camera = scene.camera
def cam_poll(self, object):
return object.type == 'CAMERA'
bpy.types.Scene.x_camera = PointerProperty(
type=bpy.types.Object,
update=cam_update,
poll=cam_poll,
)
bpy.types.Scene.cam_changed = BoolProperty(
get=cam_changed
)
def cam_draw(self, context):
layout = self.layout
scene = context.scene
row = layout.row()
row.alert = scene.cam_changed
row.prop(scene, "x_camera")
bpy.types.SCENE_PT_scene.prepend(cam_draw)
# handler
bpy.app.handlers.scene_update_pre.append(cam_update_handler)
def remove_handlers(prefix, handler):
handlers = getattr(bpy.app.handlers, handler, [])
remove = (h for h in handers
if h.__name__.startswith(prefix))
for h in remove:
handlers.remove(h)
#emove_handlers("cam_", "scene_update_pre")
def remove_draw_funcs(prefix, panel):
funcs = getattr(panel.draw, "_draw_funcs", [])
remove = (f for f in funcs
if f.__name__.startswith(prefix))
for f in remove:
panel.remove(f)
#remove_draw_funcs("cam_", bpy.types.SCENE_PT_scene)