diff --git a/add_camera_rigs/__init__.py b/add_camera_rigs/__init__.py
index 9d296e6ceee5dffa71c48b279c9e611181e93fed..9c742e6ab81f37fa46ecfebb0107b58937d58c4e 100644
--- a/add_camera_rigs/__init__.py
+++ b/add_camera_rigs/__init__.py
@@ -16,11 +16,10 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-
 bl_info = {
     "name": "Add Camera Rigs",
-    "author": "Wayne Dixon, Brian Raschko, Kris Wittig",
-    "version": (1, 4, 1),
+    "author": "Wayne Dixon, Brian Raschko, Kris Wittig, Damien Picard",
+    "version": (1, 4, 2),
     "blender": (2, 80, 0),
     "location": "View3D > Add > Camera > Dolly or Crane Rig",
     "description": "Adds a Camera Rig with UI",
diff --git a/add_camera_rigs/build_rigs.py b/add_camera_rigs/build_rigs.py
index c73031983dd8729a182dd51559aee6b3d3dbb1d1..1a37bc6e530a0956212727d69fe601db2c6415e0 100644
--- a/add_camera_rigs/build_rigs.py
+++ b/add_camera_rigs/build_rigs.py
@@ -1,6 +1,25 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
 import bpy
+from bpy_extras import object_utils
 from bpy.types import Operator
-from math import radians
+from math import radians, pi
 from rna_prop_ui import rna_idprop_ui_prop_get
 from .create_widgets import (create_root_widget,
                              create_widget,
@@ -9,518 +28,254 @@ from .create_widgets import (create_root_widget,
                              )
 
 
-def build_dolly_rig(context):
-    """Operator to build the dolly rig"""
-    # Set the bone layers
-    boneLayer = (False, True, False, False, False, False, False, False,
-                 False, False, False, False, False, False, False, False,
-                 False, False, False, False, False, False, False, False,
-                 False, False, False, False, False, False, False, False)
-
-    # Add the new armature object:
-    bpy.ops.object.armature_add()
-    rig = context.active_object
-
-    # it will try to name the rig "Dolly_rig" but if that name exists it will
-    # add 000 to the name
-    if "Dolly_rig" not in context.scene.objects:
-        rig.name = "Dolly_rig"
-    else:
-        rig.name = "Dolly_rig.000"
-    rig["rig_id"] = "Dolly_rig"
-
-    bpy.ops.object.mode_set(mode='EDIT')
-
-    # Remove default bone:
+def create_dolly_bones(rig, bone_layers):
     bones = rig.data.edit_bones
-    bones.remove(bones[0])
 
-    # Add new bones:
+    # Add new bones
     root = bones.new("Root")
-    root.tail = (0.0, 3.0, 0.0)
+    root.tail = (0.0, 1.0, 0.0)
+    root.show_wire = True
 
-    bpy.ops.object.mode_set(mode='EDIT')
-    ctrlAimChild = bones.new("aim_MCH")
-    ctrlAimChild.head = (0.0, 5.0, 3.0)
-    ctrlAimChild.tail = (0.0, 7.0, 3.0)
-    ctrlAimChild.layers = boneLayer
+    ctrl_aim_child = bones.new("Aim_shape_rotation-MCH")
+    ctrl_aim_child.head = (0.0, 10.0, 1.7)
+    ctrl_aim_child.tail = (0.0, 11.0, 1.7)
+    ctrl_aim_child.layers = bone_layers
 
-    ctrlAim = bones.new("Aim")
-    ctrlAim.head = (0.0, 5.0, 3.0)
-    ctrlAim.tail = (0.0, 7.0, 3.0)
+    ctrl_aim = bones.new("Aim")
+    ctrl_aim.head = (0.0, 10.0, 1.7)
+    ctrl_aim.tail = (0.0, 11.0, 1.7)
+    ctrl_aim.show_wire = True
 
     ctrl = bones.new("Camera")
-    ctrl.head = (0.0, 0.0, 3.0)
-    ctrl.tail = (0.0, 2.0, 3.0)
+    ctrl.head = (0.0, 0.0, 1.7)
+    ctrl.tail = (0.0, 1.0, 1.7)
+    ctrl.show_wire = True
 
-    # Setup hierarchy:
+    # Setup hierarchy
     ctrl.parent = root
-    ctrlAim.parent = root
-    ctrlAimChild.parent = ctrlAim
-
-    # jump into pose mode and change bones to euler
-    bpy.ops.object.mode_set(mode='POSE')
-    for x in bpy.context.object.pose.bones:
-        x.rotation_mode = 'XYZ'
-
-    # jump into pose mode and add the custom bone shapes
-    bpy.ops.object.mode_set(mode='POSE')
-    bpy.context.object.pose.bones["Root"].custom_shape = bpy.data.objects[
-        "WDGT_Camera_root"]  # add the widget as custom shape
-    # set the wireframe checkbox to true
-    bpy.context.object.data.bones["Root"].show_wire = True
-    bpy.context.object.pose.bones[
-        "Aim"].custom_shape = bpy.data.objects["WDGT_Aim"]
-    bpy.context.object.data.bones["Aim"].show_wire = True
-    bpy.context.object.pose.bones["Aim"].custom_shape_transform = bpy.data.objects[
-        rig.name].pose.bones["aim_MCH"]  # sets the "At" field to the child
-    bpy.context.object.pose.bones[
-        "Camera"].custom_shape = bpy.data.objects["WDGT_Camera"]
-    bpy.context.object.data.bones["Camera"].show_wire = True
-
-    # jump into object mode
-    bpy.ops.object.mode_set(mode='OBJECT')
-
-    # Add constraints to bones:
-    con = rig.pose.bones['aim_MCH'].constraints.new('COPY_ROTATION')
-    con.target = rig
-    con.subtarget = "Camera"
-
-    con = rig.pose.bones['Camera'].constraints.new('TRACK_TO')
-    con.target = rig
-    con.subtarget = "Aim"
-    con.use_target_z = True
-
-    # Add custom Bone property to Camera bone
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "lock", create=True)
-    ob["lock"] = 1.0
-    prop["soft_min"] = prop["min"] = 0.0
-    prop["soft_max"] = prop["max"] = 1.0
-
-    # Add Driver to Lock/Unlock Camera from Aim Target
-    rig = bpy.context.view_layer.objects.active
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-
-    constraint = pose_bone.constraints["Track To"]
-    inf_driver = constraint.driver_add('influence')
-    inf_driver.driver.type = 'SCRIPTED'
-    var = inf_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["lock"]'
-    inf_driver.driver.expression = 'var'
-
-    # Add custom property for the lens / add the driver after the camera is created
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "focal_length", create=True)
-    ob["focal_length"] = 50.0
-    prop["soft_min"] = prop["min"] = 1.0
-    prop["default"] = 50.0
-    prop["soft_max"] = prop["max"] = 5000.0
-
-    # Add custom property for the focus distance / add the driver after the camera is created
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "focus_distance", create=True)
-    ob["focus_distance"] = 10.00
-    prop["soft_min"] = prop["min"] = 0.0
-    prop["soft_max"] = prop["max"] = 1000.0
-
-    # Add custom property for the f-stop / add the driver after the camera is created
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "f-stop", create=True)
-    ob["f-stop"] = 2.8
-    prop["soft_min"] = prop["min"] = 0.1
-    prop["soft_max"] = prop["max"] = 128.00
-
-    # Add the camera object:
-    bpy.ops.object.mode_set(mode='OBJECT')
-
-    bpy.ops.object.camera_add()
-    cam = bpy.context.active_object
-
-    # Name the Camera Object
-    if 'Dolly_camera' not in context.scene.objects:
-        cam.name = "Dolly_camera"
-    else:
-        cam.name = "Dolly_camera.000"
-
-    # this will name the camera data
-    cam.data.name = cam.name
-
-    cam_data_name = bpy.context.object.data.name
-    bpy.data.cameras[cam_data_name].display_size = 1.0
-    cam.rotation_euler = [radians(90), 0, 0]  # rotate the camera 90 degrees in x
-
-    cam.location = (0.0, -2.0, 0.0)  # move the camera to the correct postion
-    cam.parent = rig
-    cam.parent_type = "BONE"
-    cam.parent_bone = "Camera"
-
-    # Add Driver to link the camera lens to the custom property on the armature
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-    lens_driver = cam.data.driver_add("lens")
-    lens_driver.driver.type = 'SCRIPTED'
-    var = lens_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["focal_length"]'
-    lens_driver.driver.expression = 'var'
-
-    # Add Driver to link the camera focus distance to the custom property on the armature
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-    lens_driver = cam.data.driver_add("dof.focus_distance")
-    lens_driver.driver.type = 'SCRIPTED'
-    var = lens_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["focus_distance"]'
-    lens_driver.driver.expression = 'var'
-
-    # Add Driver to link the camera f-stop to the custom property on the armature
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-    lens_driver = cam.data.driver_add("dof.aperture_fstop")
-    lens_driver.driver.type = 'SCRIPTED'
-    var = lens_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["f-stop"]'
-    lens_driver.driver.expression = 'var'
-
-    # lock the location/rotation/scale of the camera
-    cam.lock_location = [True, True, True]
-    cam.lock_rotation = [True, True, True]
-    cam.lock_scale = [True, True, True]
-
-    # Set new camera as active camera
-    bpy.context.scene.camera = cam
-
-    # make sure the camera is selectable by default (this can be locked in the UI)
-    bpy.context.object.hide_select = False
-
-    # make the rig the active object before finishing
-    bpy.context.view_layer.objects.active = rig
-    bpy.data.objects[cam.name].select_set(False)
-    bpy.data.objects[rig.name].select_set(True)
-
-    return rig
-
+    ctrl_aim.parent = root
+    ctrl_aim_child.parent = ctrl_aim
 
-class ADD_CAMERA_RIGS_OT_build_dolly_rig(Operator):
-    bl_idname = "add_camera_rigs.build_dolly_rig"
-    bl_label = "Build Dolly Camera Rig"
-    bl_description = "Build a Camera Dolly Rig"
-    bl_options = {'REGISTER', 'UNDO'}
 
-    def execute(self, context):
-        # build the Widgets
-        if not "WDGT_Camera_root" in bpy.context.scene.objects:
-            create_root_widget(self, "Camera_root")
-        if not "WDGT_Camera" in bpy.context.scene.objects:
-            create_camera_widget(self, "Camera")
-        if not "WDGT_Aim" in bpy.context.scene.objects:
-            create_aim_widget(self, "Aim")
-
-        # call the function to build the rig
-        build_dolly_rig(context)
-
-        return {'FINISHED'}
-
-
-def build_crane_rig(context):
-    # Define some useful variables:
-    boneLayer = (False, True, False, False, False, False, False, False,
-                 False, False, False, False, False, False, False, False,
-                 False, False, False, False, False, False, False, False,
-                 False, False, False, False, False, False, False, False)
-
-    # Add the new armature object:
-    bpy.ops.object.armature_add()
-    rig = context.active_object
-
-    # it will try to name the rig "Crane_rig" but if that name exists it will
-    # add .000 to the name
-    if "Crane_rig" not in context.scene.objects:
-        rig.name = "Crane_rig"
-    else:
-        rig.name = "Crane_rig.000"
-    rig["rig_id"] = "Crane_rig"
-
-    bpy.ops.object.mode_set(mode='EDIT')
-
-    # Remove default bone:
+def create_crane_bones(rig, bone_layers):
     bones = rig.data.edit_bones
-    bones.remove(bones[0])
 
-    # Add new bones:
+    # Add new bones
     root = bones.new("Root")
-    root.tail = (0.0, 3.0, 0.0)
+    root.tail = (0.0, 1.0, 0.0)
+    root.show_wire = True
 
-    ctrlAimChild = bones.new("aim_MCH")
-    ctrlAimChild.head = (0.0, 10.0, 1.0)
-    ctrlAimChild.tail = (0.0, 12.0, 1.0)
-    ctrlAimChild.layers = boneLayer
+    ctrl_aim_child = bones.new("Aim_shape_rotation-MCH")
+    ctrl_aim_child.head = (0.0, 10.0, 1.7)
+    ctrl_aim_child.tail = (0.0, 11.0, 1.7)
+    ctrl_aim_child.layers = bone_layers
 
-    ctrlAim = bones.new("Aim")
-    ctrlAim.head = (0.0, 10.0, 1.0)
-    ctrlAim.tail = (0.0, 12.0, 1.0)
+    ctrl_aim = bones.new("Aim")
+    ctrl_aim.head = (0.0, 10.0, 1.7)
+    ctrl_aim.tail = (0.0, 11.0, 1.7)
+    ctrl_aim.show_wire = True
 
     ctrl = bones.new("Camera")
-    ctrl.head = (0.0, 1.0, 1.0)
-    ctrl.tail = (0.0, 3.0, 1.0)
+    ctrl.head = (0.0, 1.0, 1.7)
+    ctrl.tail = (0.0, 2.0, 1.7)
 
     arm = bones.new("Crane_arm")
-    arm.head = (0.0, 0.0, 1.0)
-    arm.tail = (0.0, 1.0, 1.0)
+    arm.head = (0.0, 0.0, 1.7)
+    arm.tail = (0.0, 1.0, 1.7)
 
     height = bones.new("Crane_height")
     height.head = (0.0, 0.0, 0.0)
-    height.tail = (0.0, 0.0, 1.0)
+    height.tail = (0.0, 0.0, 1.7)
 
-    # Setup hierarchy:
+    # Setup hierarchy
     ctrl.parent = arm
     ctrl.use_inherit_rotation = False
     ctrl.use_inherit_scale = False
+    ctrl.show_wire = True
 
     arm.parent = height
     arm.use_inherit_scale = False
 
     height.parent = root
-    ctrlAim.parent = root
-    ctrlAimChild.parent = ctrlAim
-
-    # change display to BBone: it just looks nicer
-    bpy.context.object.data.display_type = 'BBONE'
-    # change display to wire for object
-    bpy.context.object.display_type = 'WIRE'
+    ctrl_aim.parent = root
+    ctrl_aim_child.parent = ctrl_aim
 
-    # jump into pose mode and change bones to euler
-    bpy.ops.object.mode_set(mode='POSE')
-    for x in bpy.context.object.pose.bones:
-        x.rotation_mode = 'XYZ'
-
-    # lock the relevant loc, rot and scale
-    bpy.context.object.pose.bones[
-        "Crane_arm"].lock_rotation = [False, True, False]
-    bpy.context.object.pose.bones["Crane_arm"].lock_scale = [True, False, True]
-    bpy.context.object.pose.bones["Crane_height"].lock_location = [True, True, True]
-    bpy.context.object.pose.bones["Crane_height"].lock_rotation = [True, True, True]
-    bpy.context.object.pose.bones["Crane_height"].lock_scale = [True, False, True]
-
-    # add the custom bone shapes
-    bpy.context.object.pose.bones["Root"].custom_shape = bpy.data.objects[
-        "WDGT_Camera_root"]  # add the widget as custom shape
-    # set the wireframe checkbox to true
-    bpy.context.object.data.bones["Root"].show_wire = True
-    bpy.context.object.pose.bones[
-        "Aim"].custom_shape = bpy.data.objects["WDGT_Aim"]
-    bpy.context.object.data.bones["Aim"].show_wire = True
-    bpy.context.object.pose.bones["Aim"].custom_shape_transform = bpy.data.objects[
-        rig.name].pose.bones["aim_MCH"]  # sets the "At" field to the child
-    bpy.context.object.pose.bones[
-        "Camera"].custom_shape = bpy.data.objects["WDGT_Camera"]
-    bpy.context.object.data.bones["Camera"].show_wire = True
-
-    # jump into object mode
+    # Jump into object mode
     bpy.ops.object.mode_set(mode='OBJECT')
+    pose_bones = rig.pose.bones
+
+    # Lock the relevant loc, rot and scale
+    pose_bones["Crane_arm"].lock_rotation = (False, True, False)
+    pose_bones["Crane_arm"].lock_scale = (True, False, True)
+    pose_bones["Crane_height"].lock_location = (True, True, True)
+    pose_bones["Crane_height"].lock_rotation = (True, True, True)
+    pose_bones["Crane_height"].lock_scale = (True, False, True)
+
+
+def build_camera_rig(context, mode):
+    bone_layers = tuple(i == 1 for i in range(32))
+    view_layer = bpy.context.view_layer
 
-    # Add constraints to bones:
-    con = rig.pose.bones['aim_MCH'].constraints.new('COPY_ROTATION')
+    rig_name = mode.capitalize() + "_Rig"
+    rig_data = bpy.data.armatures.new(rig_name)
+    rig = object_utils.object_data_add(context, rig_data, name=rig_name)
+    rig["rig_id"] = "%s" % rig_name
+    view_layer.objects.active = rig
+    rig.location = context.scene.cursor.location
+
+    bpy.ops.object.mode_set(mode='EDIT')
+
+    # Add new bones
+    if mode == "DOLLY":
+        create_dolly_bones(rig, bone_layers)
+    elif mode == "CRANE":
+        create_crane_bones(rig, bone_layers)
+
+    # Jump into object mode and change bones to euler
+    bpy.ops.object.mode_set(mode='OBJECT')
+    pose_bones = rig.pose.bones
+    for b in pose_bones:
+        b.rotation_mode = 'XYZ'
+
+    # Add custom properties to the armature’s Camera bone,
+    # so that all properties may be animated in a single action
+    # Add driver after the camera is created
+
+    # Lens property
+    pb = pose_bones['Camera']
+    pb["lens"] = 50.0
+    prop = rna_idprop_ui_prop_get(pb, "lens", create=True)
+    prop["default"] = 50.0
+    prop["min"] = 1.0
+    prop["max"] = 1000000.0
+    prop["soft_max"] = 5000.0
+
+    # DOF Focus Distance property
+    pb = pose_bones['Camera']
+    pb["focus_distance"] = 10.0
+    prop = rna_idprop_ui_prop_get(pb, "focus_distance", create=True)
+    prop["default"] = 10.0
+    prop["min"] = 0.0
+
+    # DOF F-Stop property
+    pb = pose_bones['Camera']
+    pb["aperture_fstop"] = 2.8
+    prop = rna_idprop_ui_prop_get(pb, "aperture_fstop", create=True)
+    prop["default"] = 2.8
+    prop["min"] = 0.0
+    prop["soft_min"] = 0.1
+    prop["soft_max"] = 128.0
+
+    # Build the widgets
+    root_widget = create_root_widget("Camera_Root")
+    camera_widget = create_camera_widget("Camera")
+    aim_widget = create_aim_widget("Aim")
+
+    # Add the custom bone shapes
+    pose_bones["Root"].custom_shape = root_widget
+    pose_bones["Aim"].custom_shape = aim_widget
+    pose_bones["Camera"].custom_shape = camera_widget
+
+    # Set the "At" field to the child
+    pose_bones["Aim"].custom_shape_transform = pose_bones["Aim_shape_rotation-MCH"]
+
+    # Add constraints to bones
+    con = pose_bones['Aim_shape_rotation-MCH'].constraints.new('COPY_ROTATION')
     con.target = rig
     con.subtarget = "Camera"
 
-    con = rig.pose.bones['Camera'].constraints.new('TRACK_TO')
+    con = pose_bones['Camera'].constraints.new('TRACK_TO')
     con.target = rig
     con.subtarget = "Aim"
     con.use_target_z = True
 
-    # Add custom Bone property to Camera bone
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "lock", create=True)
-    ob["lock"] = 1.0
-    prop["soft_min"] = prop["min"] = 0.0
-    prop["soft_max"] = prop["max"] = 1.0
-
-    # Add Driver to Lock/Unlock Camera from Aim Target
-    rig = bpy.context.view_layer.objects.active
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-
-    constraint = pose_bone.constraints["Track To"]
-    inf_driver = constraint.driver_add('influence')
-    inf_driver.driver.type = 'SCRIPTED'
-    var = inf_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["lock"]'
-    inf_driver.driver.expression = 'var'
-
-    # Add custom property for the lens / add the driver after the camera is created
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "focal_length", create=True)
-    ob["focal_length"] = 50.0
-    prop["soft_min"] = prop["min"] = 1.0
-    prop["default"] = 50.0
-    prop["soft_max"] = prop["max"] = 5000.0
-
-    # Add custom property for the focus distance / add the driver after the camera is created
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "focus_distance", create=True)
-    ob["focus_distance"] = 10.00
-    prop["soft_min"] = prop["min"] = 0.0
-    prop["soft_max"] = prop["max"] = 1000.0
-
-    # Add custom property for the focus distance / add the driver after the camera is created
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "focus_distance", create=True)
-    ob["focus_distance"] = 10.00
-    prop["soft_min"] = prop["min"] = 0.0
-    prop["soft_max"] = prop["max"] = 1000.0
-
-    # Add custom property for the f-stop / add the driver after the camera is created
-    ob = bpy.context.object.pose.bones['Camera']
-    prop = rna_idprop_ui_prop_get(ob, "f-stop", create=True)
-    ob["f-stop"] = 2.8
-    prop["soft_min"] = prop["min"] = 0.1
-    prop["soft_max"] = prop["max"] = 128.00
-
-    # Add the camera object:
-    bpy.ops.object.mode_set(mode='OBJECT')
+    # Change display to BBone: it just looks nicer
+    bpy.context.object.data.display_type = 'BBONE'
+    # Change display to wire for object
+    bpy.context.object.display_type = 'WIRE'
+
+    # Add the camera object
+    cam_name = "%s_Camera" % mode.capitalize()
+    cam_data = bpy.data.cameras.new(cam_name)
+    cam = object_utils.object_data_add(context, cam_data, name=cam_name)
+    view_layer.objects.active = cam
+    context.scene.camera = cam
+
+    cam.data.display_size = 1.0
+    cam.rotation_euler[0] = pi / 2.0  # Rotate the camera 90 degrees in x
 
-    bpy.ops.object.camera_add()
-    cam = bpy.context.active_object
-
-    # this will name the Camera Object
-    if 'Crane_camera' not in context.scene.objects:
-        cam.name = "Crane_camera"
-    else:
-        cam.name = "Crane_camera.000"
-
-    # this will name the camera Data Object
-    if "Crane_camera" not in bpy.context.scene.objects.data.camera:
-        cam.data.name = "Crane_camera"
-    else:
-        cam.data.name = "Crane_camera.000"
-
-    cam_data_name = bpy.context.object.data.name
-    bpy.data.cameras[cam_data_name].display_size = 1.0
-    cam.rotation_euler = [radians(90), 0, 0]  # rotate the camera 90 degrees in x
-    cam.location = (0.0, -2.0, 0.0)  # move the camera to the correct postion
+    cam.location = (0.0, -1.0, 0.0)  # Move the camera to the correct position
     cam.parent = rig
     cam.parent_type = "BONE"
     cam.parent_bone = "Camera"
 
-    # Add Driver to link the camera lens to the custom property on the armature
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-    lens_driver = cam.data.driver_add("lens")
-    lens_driver.driver.type = 'SCRIPTED'
-    var = lens_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["focal_length"]'
-    lens_driver.driver.expression = 'var'
-
-    # Add Driver to link the camera focus distance to the custom property on the armature
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-    lens_driver = cam.data.driver_add("dof.focus_distance")
-    lens_driver.driver.type = 'SCRIPTED'
-    var = lens_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["focus_distance"]'
-    lens_driver.driver.expression = 'var'
-
-    # Add Driver to link the camera f-stop to the custom property on the armature
-    pose_bone = bpy.data.objects[rig.name].pose.bones['Camera']
-    lens_driver = cam.data.driver_add("dof.aperture_fstop")
-    lens_driver.driver.type = 'SCRIPTED'
-    var = lens_driver.driver.variables.new()
-    var.name = 'var'
-    var.type = 'SINGLE_PROP'
-
-    # Target the Custom bone property
-    var.targets[0].id = bpy.data.objects[rig.name]
-    var.targets[0].data_path = 'pose.bones["Camera"]["f-stop"]'
-    lens_driver.driver.expression = 'var'
-
-    #  the location/rotation/scale of the camera
-    cam.lock_location = [True, True, True]
-    cam.lock_rotation = [True, True, True]
-    cam.lock_scale = [True, True, True]
-
-    # Set new camera as active camera
-    bpy.context.scene.camera = cam
-
-    # make sure the camera is selectable by default (this can be locked in the UI)
-    bpy.context.object.hide_select = False
-
-    # make the rig the active object before finishing
-    bpy.context.view_layer.objects.active = rig
-    bpy.data.objects[cam.name].select_set(False)
-    bpy.data.objects[rig.name].select_set(True)
+    # Lock camera transforms
+    cam.lock_location = (True,) * 3
+    cam.lock_rotation = (True,) * 3
+    cam.lock_scale = (True,) * 3
+
+    # Add drivers to link the camera properties to the custom props
+    # on the armature
+    for prop_from, prop_to in (("lens", "lens"),
+                               ("focus_distance", "dof.focus_distance"),
+                               ("aperture_fstop", "dof.aperture_fstop")):
+        driver = cam.data.driver_add(prop_to)
+        driver.driver.type = 'SCRIPTED'
+        var = driver.driver.variables.new()
+        var.name = 'var'
+        var.type = 'SINGLE_PROP'
+
+        # Target the custom bone property
+        var.targets[0].id = rig
+        var.targets[0].data_path = 'pose.bones["Camera"]["%s"]' % prop_from
+        driver.driver.expression = 'var'
+
+    # Make the rig the active object
+    for ob in view_layer.objects:
+        ob.select_set(False)
+    rig.select_set(True)
+    view_layer.objects.active = rig
 
     return rig
 
 
-class ADD_CAMERA_RIGS_OT_build_crane_rig(Operator):
-    bl_idname = "add_camera_rigs.build_crane_rig"
-    bl_label = "Build Crane Camera Rig"
-    bl_description = "Build a Camera Crane Rig"
+class OBJECT_OT_build_camera_rig(Operator):
+    bl_idname = "object.build_camera_rig"
+    bl_label = "Build Camera Rig"
+    bl_description = "Build a Camera Rig"
     bl_options = {'REGISTER', 'UNDO'}
 
-    def execute(self, context):
-        # build the Widgets
-        if not "WDGT_Camera_root" in bpy.context.scene.objects:
-            create_root_widget(self, "Camera_root")
-        if not "WDGT_Camera" in bpy.context.scene.objects:
-            create_camera_widget(self, "Camera")
-        if not "WDGT_Aim" in bpy.context.scene.objects:
-            create_aim_widget(self, "Aim")
-
-        # call the function to build the rig
-        build_crane_rig(context)
+    mode: bpy.props.EnumProperty(items=
+                                 (('DOLLY',) * 3,
+                                  ('CRANE',) * 3,),
+                                 name="mode",
+                                 description="", default="DOLLY")
 
+    def execute(self, context):
+        # Build the rig
+        build_camera_rig(context, self.mode)
         return {'FINISHED'}
 
 
-# dolly and crane entries in the Add Object > Camera Menu
 def add_dolly_crane_buttons(self, context):
+    """Dolly and crane entries in the Add Object > Camera Menu"""
     if context.mode == 'OBJECT':
-        self.layout.operator(
-            ADD_CAMERA_RIGS_OT_build_dolly_rig.bl_idname,
+        op = self.layout.operator(
+            OBJECT_OT_build_camera_rig.bl_idname,
             text="Dolly Camera Rig",
             icon='CAMERA_DATA'
         )
-        self.layout.operator(
-            ADD_CAMERA_RIGS_OT_build_crane_rig.bl_idname,
+        op.mode = "DOLLY"
+        op = self.layout.operator(
+            OBJECT_OT_build_camera_rig.bl_idname,
             text="Crane Camera Rig",
             icon='CAMERA_DATA'
         )
+        op.mode = "CRANE"
 
 
 classes = (
-    ADD_CAMERA_RIGS_OT_build_dolly_rig,
-    ADD_CAMERA_RIGS_OT_build_crane_rig,
+    OBJECT_OT_build_camera_rig,
 )
 
 
diff --git a/add_camera_rigs/composition_guides_menu.py b/add_camera_rigs/composition_guides_menu.py
index 7ce8dc272c5411f42bdc279378fbb4917b4e00a3..c3ff43e5a12cfdfac3a0facb8ef7e1411fd09814 100644
--- a/add_camera_rigs/composition_guides_menu.py
+++ b/add_camera_rigs/composition_guides_menu.py
@@ -1,16 +1,36 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
 import bpy
-from bpy.types import Menu
+from bpy.types import Panel
 
+from .operators import get_arm_and_cam
 
-class ADD_CAMERA_RIGS_MT_composition_guides_menu(Menu):
+class ADD_CAMERA_RIGS_PT_composition_guides(Panel):
     bl_label = "Composition Guides"
-    bl_idname = "ADD_CAMERA_RIGS_MT_composition_guides_menu"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'HEADER'
 
     def draw(self, context):
         layout = self.layout
 
-        activeCameraName = bpy.context.active_object.children[0].name
-        cam = bpy.data.cameras[bpy.data.objects[activeCameraName].data.name]
+        arm, cam = get_arm_and_cam(context.active_object)
+        cam = cam.data
 
         layout.prop(cam, "show_safe_areas")
         layout.row().separator()
@@ -24,17 +44,12 @@ class ADD_CAMERA_RIGS_MT_composition_guides_menu(Menu):
         layout.prop(cam, "show_composition_thirds")
 
 
-def draw_item(self, context):
-    layout = self.layout
-    layout.menu(CustomMenu.bl_idname)
-
-
 def register():
-    bpy.utils.register_class(ADD_CAMERA_RIGS_MT_composition_guides_menu)
+    bpy.utils.register_class(ADD_CAMERA_RIGS_PT_composition_guides)
 
 
 def unregister():
-    bpy.utils.unregister_class(ADD_CAMERA_RIGS_MT_composition_guides_menu)
+    bpy.utils.unregister_class(ADD_CAMERA_RIGS_PT_composition_guides)
 
 
 if __name__ == "__main__":
diff --git a/add_camera_rigs/create_widgets.py b/add_camera_rigs/create_widgets.py
index 788a868d007a1d65ca83c0e10923b2ff034f11be..f19fc206e9b0e744a37163e1ba55563b8bd5f4b2 100644
--- a/add_camera_rigs/create_widgets.py
+++ b/add_camera_rigs/create_widgets.py
@@ -1,241 +1,258 @@
 import bpy
 
 
-def create_widget(self, name):
-    """ Creates an empty widget object and returns the object."""
-    widget_prefix = bpy.context.preferences.addons["add_camera_rigs"].preferences.widget_prefix
+def create_widget(name):
+    """Create an empty widget object and return the object"""
+    prefs = bpy.context.preferences.addons["add_camera_rigs"].preferences
+    widget_prefix = prefs.widget_prefix
     obj_name = widget_prefix + name
     scene = bpy.context.scene
 
-    mesh = bpy.data.meshes.new(obj_name)
-    obj = bpy.data.objects.new(obj_name, mesh)
+    obj = bpy.data.objects.get(obj_name)
 
-    # create a new collection for the wigets
-    collection_name = bpy.context.preferences.addons["add_camera_rigs"].preferences.camera_widget_collection_name
-    c = bpy.data.collections.get(collection_name)
-    if c is not None:
-        c.objects.link(obj)
-    else:
-        c = bpy.data.collections.new(collection_name)
-        c.hide_viewport = True
-        c.hide_render = True
+    if obj is None:
+        mesh = bpy.data.meshes.new(obj_name)
+        obj = bpy.data.objects.new(obj_name, mesh)
 
-        # link the collection
-        scene.collection.children.link(c)
-        c.objects.link(obj)
+        # Create a new collection for the widgets
+        collection_name = prefs.camera_widget_collection_name
+        coll = bpy.data.collections.get(collection_name)
+        if coll is None:
+            coll = bpy.data.collections.new(collection_name)
+            scene.collection.children.link(coll)
+            coll.hide_viewport = True
+            coll.hide_render = True
+
+        # Link the collection
+        coll.objects.link(obj)
 
     return obj
 
 
-def create_root_widget(self, name):
-    # Creates a compass-shaped widget
-    obj = create_widget(self, name)
-    if obj is not None:
-        verts = [(0.210255, 0.209045, 0), (0.113789, 0.273501, -2.98023e-08),
-                 (-3.07015e-08, 0.296135, 0), (-0.113789, 0.273501, 0),
-                 (-0.210255, 0.209045, 0), (-0.274712, 0.112579, 7.45058e-09),
-                 (-0.297346, -0.00121052, 1.48165e-08), (0.297346, -0.00121046, -1.49858e-08),
-                 (0.274711, 0.112579, 7.45058e-09), (0.071529, 0.505864, 0),
-                 (-0.0715289, 0.505864, 0), (-0.071529, 0.379091, 2.98023e-08),
-                 (0.071529, 0.379091, 0), (-0.132587, 0.505864, 0),
-                 (0.132587, 0.505864, 0), (-3.07015e-08, 0.667601, 1.19209e-07),
-                 (-0.274712, -0.115, 2.23517e-08), (0.274712, -0.115, -7.45058e-09),
-                 (0.210255, -0.211466, 0), (0.113789, -0.275922, 0),
-                 (-9.03062e-08, -0.298556, 0), (-0.113789, -0.275922, 2.98023e-08),
-                 (-0.210255, -0.211466, 0), (-0.668811, -0.00121029, 4.46188e-08),
-                 (-0.507075, 0.131377, 4.47035e-08), (-0.507075, -0.133798, -1.49012e-08),
-                 (-0.380301, 0.0703187, 1.49012e-08), (-0.380301, -0.0727393, 1.49012e-08),
-                 (-0.507075, -0.0727393, -1.49012e-08), (-0.507075, 0.0703187, 4.47035e-08),
-                 (0.507075, -0.0727393, -1.49012e-08), (0.507075, 0.0703187, -1.49012e-08),
-                 (0.380301, 0.0703187, 1.49012e-08), (0.380301, -0.0727393, -1.49012e-08),
-                 (0.507075, 0.131377, -1.49012e-08), (0.507075, -0.133798, -1.49012e-08),
-                 (0.668811, -0.0012103, -1.49858e-08), (1.48112e-07, -0.670021, 0),
-                 (-0.132587, -0.508285, 0), (0.132587, -0.508285, 0),
-                 (-0.0715289, -0.381512, 2.98023e-08), (0.0715291, -0.381512, -2.98023e-08),
-                 (0.0715291, -0.508285, 0), (-0.0715289, -0.508285, 0),
-                 ]
-
-        edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8), (10, 11), (9, 12),
-                 (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16,
-                                                                   22), (17, 18), (18, 19), (19, 20), (20, 21),
-                 (21, 22), (7, 17), (6, 16), (23, 24), (23, 25), (24,
-                                                                  29), (25, 28), (26, 27), (26, 29), (27, 28),
-                 (31, 32), (30, 33), (32, 33), (31, 34), (30, 35), (34,
-                                                                    36), (35, 36), (37, 38), (37, 39), (38, 43),
-                 (39, 42), (40, 41), (40, 43), (41, 42), ]
-
-        faces = []
+def create_root_widget(name):
+    """Create a compass-shaped widget"""
+    obj = create_widget(name)
+    if not obj.data.vertices:
+        verts = [(0.6307649612426758, 0.6271349787712097, 0.0),
+                 (0.3413670063018799, 0.8205029964447021, 0.0),
+                 (0.0, 0.8884050250053406, 0.0),
+                 (-0.3413670063018799, 0.8205029964447021, 0.0),
+                 (-0.6307649612426758, 0.6271349787712097, 0.0),
+                 (-0.8241360187530518, 0.3377370238304138, 0.0),
+                 (-0.8920379877090454, -0.003631560131907463, 0.0),
+                 (0.8920379877090454, -0.003631379920989275, 0.0),
+                 (0.824133038520813, 0.3377370238304138, 0.0),
+                 (0.21458700299263, 1.5175920724868774, 0.0),
+                 (-0.21458669006824493, 1.5175920724868774, 0.0),
+                 (-0.21458700299263, 1.1372729539871216, 0.0),
+                 (0.21458700299263, 1.1372729539871216, 0.0),
+                 (-0.3977609872817993, 1.5175920724868774, 0.0),
+                 (0.3977609872817993, 1.5175920724868774, 0.0),
+                 (0.0, 2.002802848815918, 0.0),
+                 (-0.8241360187530518, -0.3449999988079071, 0.0),
+                 (0.8241360187530518, -0.3449999988079071, 0.0),
+                 (0.6307649612426758, -0.6343979835510254, 0.0),
+                 (0.3413670063018799, -0.8277660012245178, 0.0),
+                 (0.0, -0.8956680297851562, 0.0),
+                 (-0.3413670063018799, -0.8277660012245178, 0.0),
+                 (-0.6307649612426758, -0.6343979835510254, 0.0),
+                 (-2.0064330101013184, -0.003630870021879673, 0.0),
+                 (-1.5212249755859375, 0.39413100481033325, 0.0),
+                 (-1.5212249755859375, -0.4013940095901489, 0.0),
+                 (-1.1409029960632324, 0.21095609664916992, 0.0),
+                 (-1.1409029960632324, -0.2182179093360901, 0.0),
+                 (-1.5212249755859375, -0.2182179093360901, 0.0),
+                 (-1.5212249755859375, 0.21095609664916992, 0.0),
+                 (1.5212249755859375, -0.2182179093360901, 0.0),
+                 (1.5212249755859375, 0.21095609664916992, 0.0),
+                 (1.1409029960632324, 0.21095609664916992, 0.0),
+                 (1.1409029960632324, -0.2182179093360901, 0.0),
+                 (1.5212249755859375, 0.39413100481033325, 0.0),
+                 (1.5212249755859375, -0.4013940095901489, 0.0),
+                 (2.0064330101013184, -0.0036309000570327044, 0.0),
+                 (0.0, -2.0100629329681396, 0.0),
+                 (-0.3977609872817993, -1.5248548984527588, 0.0),
+                 (0.3977609872817993, -1.5248548984527588, 0.0),
+                 (-0.21458669006824493, -1.144536018371582, 0.0),
+                 (0.21458730101585388, -1.144536018371582, 0.0),
+                 (0.21458730101585388, -1.5248548984527588, 0.0),
+                 (-0.21458669006824493, -1.5248548984527588, 0.0)]
+
+        edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8),
+                 (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15),
+                 (16, 22), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17),
+                 (6, 16), (23, 24), (23, 25), (24, 29), (25, 28), (26, 27), (26, 29),
+                 (27, 28), (31, 32), (30, 33), (32, 33), (31, 34), (30, 35), (34, 36),
+                 (35, 36), (37, 38), (37, 39), (38, 43), (39, 42), (40, 41), (40, 43),
+                 (41, 42)]
 
         mesh = obj.data
         mesh.from_pydata(verts, edges, [])
         mesh.update()
+    return obj
 
 
-def create_camera_widget(self, name):
-    # Creates a camera ctrl widget
-
-    obj = create_widget(self, name)
-    if obj != None:
-        verts = [(0.13756819069385529, 1.0706068032106941e-08, -0.13756819069385529),
-                 (0.1797415018081665, 5.353034016053471e-09, -0.07445136457681656),
-                 (0.19455081224441528, -6.381313819948996e-16, 8.504085435845354e-09),
-                 (0.1797415018081665, -5.353034016053471e-09, 0.07445138692855835),
-                 (0.13756819069385529, -1.0706068032106941e-08, 0.13756819069385529),
-                 (0.07445137947797775, -2.1412136064213882e-08, 0.1797415018081665),
-                 (-9.740904971522468e-08, -2.1412136064213882e-08, 0.19455081224441528),
-                 (-5.87527146933553e-08, 2.1412136064213882e-08, -0.19455081224441528),
-                 (0.0744515135884285, 2.1412136064213882e-08, -0.17974145710468292),
-                 (0.3317747414112091, 5.353034016053471e-09, -0.04680081456899643),
-                 (0.3317747414112091, -5.353034016053471e-09, 0.04680081456899643),
-                 (0.24882805347442627, -5.353034016053471e-09, 0.04680081456899643),
-                 (0.24882805347442627, 5.353034016053471e-09, -0.04680084437131882),
-                 (0.3317747414112091, -5.353034016053471e-09, 0.08675074577331543),
-                 (0.3317747414112091, 5.353034016053471e-09, -0.08675074577331543),
-                 (0.43759751319885254, 0.0, 0.0), (-0.07445148378610611, -
-                                                   2.1412136064213882e-08, 0.17974145710468292),
-                 (-0.07445141673088074, 2.1412136064213882e-08, -0.1797415018081665),
-                 (-0.13756820559501648, 1.0706068032106941e-08, -0.1375681608915329),
-                 (-0.1797415018081665, 5.353034016053471e-09, -0.07445136457681656),
-                 (-0.19455081224441528, -1.2762627639897992e-15, 2.0872269246297037e-08),
-                 (-0.1797415018081665, -5.353034016053471e-09, 0.07445140182971954),
-                 (-0.1375681608915329, -1.0706068032106941e-08, 0.13756820559501648),
-                 (5.1712785165136665e-08, -4.2824272128427765e-08, 0.43759751319885254),
-                 (0.08675077557563782, -2.1412136064213882e-08, 0.3317747414112091),
-                 (-0.08675073087215424, -2.1412136064213882e-08, 0.3317747414112091),
-                 (0.046800870448350906, -2.1412136064213882e-08, 0.24882805347442627),
-                 (-0.04680079594254494, -2.1412136064213882e-08, 0.24882805347442627),
-                 (-0.04680079594254494, -2.1412136064213882e-08, 0.3317747414112091),
-                 (0.04680084437131882, -2.1412136064213882e-08, 0.3317747414112091),
-                 (-0.04680076241493225, 2.1412136064213882e-08, -0.3317747414112091),
-                 (0.046800874173641205, 2.1412136064213882e-08, -0.3317747414112091),
-                 (0.04680086299777031, 2.1412136064213882e-08, -0.24882805347442627),
-                 (-0.046800799667835236, 2.1412136064213882e-08, -0.24882805347442627),
-                 (0.0867508053779602, 2.1412136064213882e-08, -0.3317747414112091),
-                 (-0.08675070106983185, 2.1412136064213882e-08, -0.3317747414112091),
-                 (4.711345980012993e-08, 4.2824272128427765e-08, -0.43759751319885254),
-                 (-0.43759751319885254, 1.0210102111918393e-14, -9.882624141255292e-08),
-                 (-0.3317747414112091, -5.353034016053471e-09, 0.08675065636634827),
-                 (-0.3317747414112091, 5.353034016053471e-09, -0.08675083518028259),
-                 (-0.24882805347442627, -5.353034016053471e-09, 0.04680076986551285),
-                 (-0.24882805347442627, 5.353034016053471e-09, -0.0468008853495121),
-                 (-0.3317747414112091, 5.353034016053471e-09, -0.046800896525382996),
-                 (-0.3317747414112091, -5.353034016053471e-09, 0.04680073633790016),
-                 (-0.08263588696718216, -7.0564780685344886e-09, 0.08263592422008514),
-                 (-0.10796899348497391, -3.5282390342672443e-09, 0.04472224414348602),
-                 (-0.11686481535434723, -8.411977372806655e-16, 1.2537773486087644e-08),
-                 (-0.10796899348497391, 3.5282390342672443e-09, -0.04472222551703453),
-                 (-0.08263592422008514, 7.0564780685344886e-09, -0.08263588696718216),
-                 (-0.04472225159406662, 7.0564780685344886e-09, -0.10796899348497391),
-                 (-0.0447222925722599, -7.0564780685344886e-09, 0.10796897858381271),
-                 (0.0447223074734211, 7.0564780685344886e-09, -0.10796897858381271),
-                 (-3.529219583242593e-08, 7.0564780685344886e-09, -0.11686481535434723),
-                 (-5.8512675593647145e-08, -7.0564780685344886e-09, 0.11686481535434723),
-                 (0.04472222924232483, -7.0564780685344886e-09, 0.10796899348497391),
-                 (0.08263590186834335, -7.0564780685344886e-09, 0.08263590186834335),
-                 (0.10796899348497391, -3.5282390342672443e-09, 0.04472223296761513),
-                 (0.11686481535434723, -4.2059886864033273e-16, 5.108323541946902e-09),
-                 (0.10796899348497391, 3.5282390342672443e-09, -0.04472222924232483),
-                 (0.08263590186834335, 7.0564780685344886e-09, -0.08263590186834335),
-                 (3.725290298461914e-08, -2.1412136064213882e-08, 0.24882805347442627)]
+def create_camera_widget(name):
+    """Create a camera control widget"""
+    obj = create_widget(name)
+    if not obj.data.vertices:
+        verts = [(0.27513638138771057, 0.0, -0.27513638138771057),
+                 (0.359483003616333, 0.0, -0.14890272915363312),
+                 (0.38910162448883057, 0.0, 0.0),
+                 (0.359483003616333, 0.0, 0.1489027738571167),
+                 (0.27513638138771057, 0.0, 0.27513638138771057),
+                 (0.1489027589559555, 0.0, 0.359483003616333),
+                 (-1.9481809943044937e-07, 0.0, 0.38910162448883057),
+                 (-1.175054293867106e-07, 0.0, -0.38910162448883057),
+                 (0.148903027176857, 0.0, -0.35948291420936584),
+                 (0.6635494828224182, 0.0, -0.09360162913799286),
+                 (0.6635494828224182, 0.0, 0.09360162913799286),
+                 (0.49765610694885254, 0.0, 0.09360162913799286),
+                 (0.49765610694885254, 0.0, -0.09360168874263763),
+                 (0.6635494828224182, 0.0, 0.17350149154663086),
+                 (0.6635494828224182, 0.0, -0.17350149154663086),
+                 (0.8751950263977051, 0.0, 0.0),
+                 (-0.14890296757221222, 0.0, 0.35948291420936584),
+                 (-0.14890283346176147, 0.0, -0.359483003616333),
+                 (-0.27513641119003296, 0.0, -0.2751363217830658),
+                 (-0.359483003616333, 0.0, -0.14890272915363312),
+                 (-0.38910162448883057, 0.0, 0.0),
+                 (-0.359483003616333, 0.0, 0.1489028036594391),
+                 (-0.2751363217830658, 0.0, 0.27513641119003296),
+                 (1.0342557033027333e-07, 0.0, 0.8751950263977051),
+                 (0.17350155115127563, 0.0, 0.6635494828224182),
+                 (-0.17350146174430847, 0.0, 0.6635494828224182),
+                 (0.09360174089670181, 0.0, 0.49765610694885254),
+                 (-0.09360159188508987, 0.0, 0.49765610694885254),
+                 (-0.09360159188508987, 0.0, 0.6635494828224182),
+                 (0.09360168874263763, 0.0, 0.6635494828224182),
+                 (-0.0936015248298645, 0.0, -0.6635494828224182),
+                 (0.09360174834728241, 0.0, -0.6635494828224182),
+                 (0.09360172599554062, 0.0, -0.49765610694885254),
+                 (-0.09360159933567047, 0.0, -0.49765610694885254),
+                 (0.1735016107559204, 0.0, -0.6635494828224182),
+                 (-0.1735014021396637, 0.0, -0.6635494828224182),
+                 (9.422691960025986e-08, 0.0, -0.8751950263977051),
+                 (-0.8751950263977051, 0.0, 0.0),
+                 (-0.6635494828224182, 0.0, 0.17350131273269653),
+                 (-0.6635494828224182, 0.0, -0.17350167036056519),
+                 (-0.49765610694885254, 0.0, 0.0936015397310257),
+                 (-0.49765610694885254, 0.0, -0.0936017706990242),
+                 (-0.6635494828224182, 0.0, -0.09360179305076599),
+                 (-0.6635494828224182, 0.0, 0.09360147267580032),
+                 (-0.16527177393436432, 0.0, 0.1652718484401703),
+                 (-0.21593798696994781, 0.0, 0.08944448828697205),
+                 (-0.23372963070869446, 0.0, 0.0),
+                 (-0.21593798696994781, 0.0, -0.08944445103406906),
+                 (-0.1652718484401703, 0.0, -0.16527177393436432),
+                 (-0.08944450318813324, 0.0, -0.21593798696994781),
+                 (-0.0894445851445198, 0.0, 0.21593795716762543),
+                 (0.0894446149468422, 0.0, -0.21593795716762543),
+                 (-7.058439166485186e-08, 0.0, -0.23372963070869446),
+                 (-1.1702535118729429e-07, 0.0, 0.23372963070869446),
+                 (0.08944445848464966, 0.0, 0.21593798696994781),
+                 (0.1652718037366867, 0.0, 0.1652718037366867),
+                 (0.21593798696994781, 0.0, 0.08944446593523026),
+                 (0.23372963070869446, 0.0, 0.0),
+                 (0.21593798696994781, 0.0, -0.08944445848464966),
+                 (0.1652718037366867, 0.0, -0.1652718037366867)]
 
         edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8),
-                 (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16, 22),
-                 (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17), (6, 16), (23, 24),
-                 (23, 25), (24, 29), (25, 28), (26, 29), (27, 28), (31, 32), (30, 33), (32, 33),
-                 (31, 34), (30, 35), (34, 36), (35, 36), (37, 38), (37, 39), (38, 43), (39, 42),
-                 (40, 41), (40, 43), (41, 42), (50, 53), (49, 52), (44, 45), (45, 46), (46, 47),
-                 (47, 48), (48, 49), (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56),
-                 (56, 57), (57, 58), (58, 59), (26, 60), (27, 60), (23, 60)]
-
-        faces = []
+                 (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15),
+                 (16, 22), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17),
+                 (6, 16), (23, 24), (23, 25), (24, 29), (25, 28), (26, 29), (27, 28),
+                 (31, 32), (30, 33), (32, 33), (31, 34), (30, 35), (34, 36), (35, 36),
+                 (37, 38), (37, 39), (38, 43), (39, 42), (40, 41), (40, 43), (41, 42),
+                 (50, 53), (49, 52), (44, 45), (45, 46), (46, 47), (47, 48), (48, 49),
+                 (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56), (56, 57),
+                 (57, 58), (58, 59), (27, 26)]
 
         mesh = obj.data
         mesh.from_pydata(verts, edges, [])
         mesh.update()
+    return obj
 
 
-def create_aim_widget(self, name):
-    # Creates a camera aim widget
-
-    obj = create_widget(self, name)
-    if obj != None:
-        verts = [(0.15504144132137299, 1.4901161193847656e-08, 0.15504144132137299),
-                 (0.20257140696048737, 7.450580596923828e-09, 0.0839078277349472),
-                 (0.21926172077655792, -8.881784197001252e-16, -9.584233851001045e-09),
-                 (0.20257140696048737, -7.450580596923828e-09, -0.0839078426361084),
-                 (0.15504144132137299, -1.4901161193847656e-08, -0.15504144132137299),
-                 (0.0839078351855278, -1.4901161193847656e-08, -0.20257140696048737),
-                 (-1.0978147457763043e-07, -1.4901161193847656e-08, -0.21926172077655792),
-                 (-6.621520043381679e-08, 1.4901161193847656e-08, 0.21926172077655792),
-                 (0.08390798419713974, 1.4901161193847656e-08, 0.2025713473558426),
-                 (0.39969685673713684, 3.725290298461914e-09, 0.05274524539709091),
-                 (0.39969685673713684, -3.725290298461914e-09, -0.05274524167180061),
-                 (0.4931790232658386, -3.725290298461914e-09, -0.05274524167180061),
-                 (0.4931790232658386, 3.725290298461914e-09, 0.052745271474123),
-                 (0.39969685673713684, -7.450580596923828e-09, -0.09776943176984787),
-                 (0.39969685673713684, 7.450580596923828e-09, 0.09776943176984787),
-                 (0.28043296933174133, 6.226862126577502e-17, -6.226862788321993e-17),
-                 (-0.08390796184539795, -1.4901161193847656e-08, -0.2025713473558426),
-                 (-0.08390787988901138, 1.4901161193847656e-08, 0.20257140696048737),
-                 (-0.15504147112369537, 1.4901161193847656e-08, 0.1550414115190506),
-                 (-0.20257140696048737, 7.450580596923828e-09, 0.08390782028436661),
-                 (-0.21926172077655792, -1.7763568394002505e-15, -2.352336458955051e-08),
-                 (-0.20257140696048737, -7.450580596923828e-09, -0.08390786498785019),
-                 (-0.1550414115190506, -1.4901161193847656e-08, -0.15504147112369537),
-                 (2.9140544199890428e-08, 2.9802322387695312e-08, 0.2804329991340637),
-                 (-0.09776944667100906, 2.9802322387695312e-08, 0.3996969163417816),
-                 (0.09776947647333145, 2.9802322387695312e-08, 0.3996969163417816),
-                 (-0.052745264023542404, 2.9802322387695312e-08, 0.4931790828704834),
-                 (0.05274529010057449, 2.9802322387695312e-08, 0.4931790828704834),
-                 (0.052745264023542404, 2.9802322387695312e-08, 0.3996969163417816),
-                 (-0.052745234221220016, 2.9802322387695312e-08, 0.3996969163417816),
-                 (0.05274517461657524, -2.9802322387695312e-08, -0.3996969759464264),
-                 (-0.052745334804058075, -2.9802322387695312e-08, -0.3996969759464264),
-                 (-0.05274537205696106, -2.9802322387695312e-08, -0.49317920207977295),
-                 (0.05274519696831703, -2.9802322387695312e-08, -0.49317920207977295),
-                 (-0.09776955097913742, -2.9802322387695312e-08, -0.3996969163417816),
-                 (0.09776940196752548, -2.9802322387695312e-08, -0.39969703555107117),
-                 (-7.148475589247028e-08, -2.9802322387695312e-08, -0.2804329991340637),
-                 (-0.2804330289363861, 3.552713678800501e-15, 4.234420103443881e-08),
-                 (-0.3996969759464264, -7.450580596923828e-09, -0.09776938706636429),
-                 (-0.39969685673713684, 7.450580596923828e-09, 0.09776950627565384),
-                 (-0.4931790232658386, -3.725290298461914e-09, -0.05274520441889763),
-                 (-0.4931790232658386, 3.725290298461914e-09, 0.05274531990289688),
-                 (-0.3996969163417816, 3.725290298461914e-09, 0.052745312452316284),
-                 (-0.3996969163417816, -3.725290298461914e-09, -0.05274519324302673),
-                 (-0.06401804089546204, -7.450580596923828e-09, -0.06401806324720383),
-                 (-0.0836436077952385, -3.725290298461914e-09, -0.03464633598923683),
-                 (-0.09053517132997513, -8.881784197001252e-16, -9.713016169143884e-09),
-                 (-0.0836436077952385, 3.725290298461914e-09, 0.03464631363749504),
-                 (-0.06401806324720383, 7.450580596923828e-09, 0.06401804089546204),
-                 (-0.03464633598923683, 7.450580596923828e-09, 0.0836436077952385),
-                 (-0.034646373242139816, -7.450580596923828e-09, -0.0836435854434967),
-                 (0.03464638441801071, 7.450580596923828e-09, 0.0836435854434967),
-                 (-2.734086912425937e-08, 7.450580596923828e-09, 0.09053517132997513),
-                 (-4.532979147597871e-08, -7.450580596923828e-09, -0.09053517132997513),
-                 (0.034646324813365936, -7.450580596923828e-09, -0.0836436077952385),
-                 (0.06401804834604263, -7.450580596923828e-09, -0.06401804834604263),
-                 (0.0836436077952385, -3.725290298461914e-09, -0.034646324813365936),
-                 (0.09053517132997513, -4.440892098500626e-16, -3.957419281164221e-09),
-                 (0.0836436077952385, 3.725290298461914e-09, 0.03464632108807564),
-                 (0.06401804834604263, 7.450580596923828e-09, 0.06401804834604263),
-                 (1.1175870895385742e-08, 2.9802322387695312e-08, 0.4931790828704834),
-                 (-3.3337176574832483e-08, 2.4835267176115394e-09, 0.030178390443325043),
-                 (-3.9333485801762436e-08, -2.4835271617007493e-09, -0.030178390443325043),
-                 (-0.030178390443325043, -7.40148665436918e-16, -7.794483281031717e-09),
-                 (0.030178390443325043, -5.921189111737107e-16, -5.875951281097969e-09)]
+def create_aim_widget(name):
+    """Create a camera aim widget"""
+    obj = create_widget(name)
+    if not obj.data.vertices:
+        verts = [(0.31008288264274597, 0.0, 0.31008288264274597),
+                 (0.40514281392097473, 0.0, 0.1678156554698944),
+                 (0.43852344155311584, 0.0, 0.0),
+                 (0.40514281392097473, 0.0, -0.1678156852722168),
+                 (0.31008288264274597, 0.0, -0.31008288264274597),
+                 (0.1678156703710556, 0.0, -0.40514281392097473),
+                 (-2.1956294915526087e-07, 0.0, -0.43852344155311584),
+                 (-1.3243040086763358e-07, 0.0, 0.43852344155311584),
+                 (0.16781596839427948, 0.0, 0.4051426947116852),
+                 (0.7993937134742737, 0.0, 0.10549049079418182),
+                 (0.7993937134742737, 0.0, -0.10549048334360123),
+                 (0.9863580465316772, 0.0, -0.10549048334360123),
+                 (0.9863580465316772, 0.0, 0.105490542948246),
+                 (0.7993937134742737, 0.0, -0.19553886353969574),
+                 (0.7993937134742737, 0.0, 0.19553886353969574),
+                 (0.5608659386634827, 0.0, 0.0),
+                 (-0.1678159236907959, 0.0, -0.4051426947116852),
+                 (-0.16781575977802277, 0.0, 0.40514281392097473),
+                 (-0.31008294224739075, 0.0, 0.3100828230381012),
+                 (-0.40514281392097473, 0.0, 0.16781564056873322),
+                 (-0.43852344155311584, 0.0, 0.0),
+                 (-0.40514281392097473, 0.0, -0.16781572997570038),
+                 (-0.3100828230381012, 0.0, -0.31008294224739075),
+                 (5.8281088399780856e-08, 0.0, 0.5608659982681274),
+                 (-0.19553889334201813, 0.0, 0.7993938326835632),
+                 (0.1955389529466629, 0.0, 0.7993938326835632),
+                 (-0.10549052804708481, 0.0, 0.9863581657409668),
+                 (0.10549058020114899, 0.0, 0.9863581657409668),
+                 (0.10549052804708481, 0.0, 0.7993938326835632),
+                 (-0.10549046844244003, 0.0, 0.7993938326835632),
+                 (0.10549034923315048, 0.0, -0.7993939518928528),
+                 (-0.10549066960811615, 0.0, -0.7993939518928528),
+                 (-0.10549074411392212, 0.0, -0.9863584041595459),
+                 (0.10549039393663406, 0.0, -0.9863584041595459),
+                 (-0.19553910195827484, 0.0, -0.7993938326835632),
+                 (0.19553880393505096, 0.0, -0.7993940711021423),
+                 (-1.4296951178494055e-07, 0.0, -0.5608659982681274),
+                 (-0.5608660578727722, 0.0, 0.0),
+                 (-0.7993939518928528, 0.0, -0.19553877413272858),
+                 (-0.7993937134742737, 0.0, 0.19553901255130768),
+                 (-0.9863580465316772, 0.0, -0.10549040883779526),
+                 (-0.9863580465316772, 0.0, 0.10549063980579376),
+                 (-0.7993938326835632, 0.0, 0.10549062490463257),
+                 (-0.7993938326835632, 0.0, -0.10549038648605347),
+                 (-0.12803608179092407, 0.0, -0.12803612649440765),
+                 (-0.167287215590477, 0.0, -0.06929267197847366),
+                 (-0.18107034265995026, 0.0, 0.0),
+                 (-0.167287215590477, 0.0, 0.06929262727499008),
+                 (-0.12803612649440765, 0.0, 0.12803608179092407),
+                 (-0.06929267197847366, 0.0, 0.167287215590477),
+                 (-0.06929274648427963, 0.0, -0.1672871708869934),
+                 (0.06929276883602142, 0.0, 0.1672871708869934),
+                 (-5.468173824851874e-08, 0.0, 0.18107034265995026),
+                 (-9.065958295195742e-08, 0.0, -0.18107034265995026),
+                 (0.06929264962673187, 0.0, -0.167287215590477),
+                 (0.12803609669208527, 0.0, -0.12803609669208527),
+                 (0.167287215590477, 0.0, -0.06929264962673187),
+                 (0.18107034265995026, 0.0, 0.0),
+                 (0.167287215590477, 0.0, 0.06929264217615128),
+                 (0.12803609669208527, 0.0, 0.12803609669208527),
+                 (-6.667435314966497e-08, 0.0, 0.060356780886650085),
+                 (-7.866697160352487e-08, 0.0, -0.060356780886650085),
+                 (-0.060356780886650085, 0.0, 0.0),
+                 (0.060356780886650085, 0.0, 0.0)]
 
         edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8),
-                 (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16, 22),
-                 (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17), (6, 16), (23, 24),
-                 (23, 25), (24, 29), (25, 28), (26, 29), (27, 28), (31, 32), (30, 33), (32, 33),
-                 (31, 34), (30, 35), (34, 36), (35, 36), (37, 38), (37, 39), (38, 43), (39, 42),
-                 (40, 41), (40, 43), (41, 42), (50, 53), (49, 52), (44, 45), (45, 46), (46, 47),
-                 (47, 48), (48, 49), (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56),
-                 (56, 57), (57, 58), (58, 59), (26, 60), (27, 60), (23, 60), (61, 62), (63, 64)]
-
-        faces = []
+                 (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15),
+                 (16, 22), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17),
+                 (6, 16), (23, 24), (23, 25), (24, 29), (25, 28), (26, 29), (27, 28),
+                 (31, 32), (30, 33), (32, 33), (31, 34), (30, 35), (34, 36), (35, 36),
+                 (37, 38), (37, 39), (38, 43), (39, 42), (40, 41), (40, 43), (41, 42),
+                 (50, 53), (49, 52), (44, 45), (45, 46), (46, 47), (47, 48), (48, 49),
+                 (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56), (56, 57),
+                 (57, 58), (58, 59), (27, 26), (60, 61), (62, 63)]
 
         mesh = obj.data
         mesh.from_pydata(verts, edges, [])
         mesh.update()
+    return obj
diff --git a/add_camera_rigs/operators.py b/add_camera_rigs/operators.py
index fe93041d0871ed19f207dc03f7205a4841f4e87b..7468007e5de6db641d70fca0a161763fb351ca80 100644
--- a/add_camera_rigs/operators.py
+++ b/add_camera_rigs/operators.py
@@ -1,118 +1,108 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
 import bpy
 from bpy.types import Operator
 
 
-def set_scene_camera():
-    '''Makes the camera the active and sets it to the scene camera'''
-    ob = bpy.context.active_object
-    # find the children on the rig (the camera name)
-    active_cam = ob.children[0].name
-    # cam = bpy.data.cameras[bpy.data.objects[active_cam]]
-    scene_cam = bpy.context.scene.camera
+def get_arm_and_cam(obj):
+    if obj.type == 'ARMATURE':
+        cam = None
+        for child in obj.children:
+            if child.type == 'CAMERA':
+                cam = child
+                break
+        if cam is not None:
+            return obj, cam
+    elif (obj.type == 'CAMERA'
+          and obj.parent is not None
+          and "rig_id" in obj.parent
+          and obj.parent["rig_id"].lower() in {"dolly_rig", "crane_rig"}):
+        return obj.parent, obj
+    return None, None
+
+
+class CameraRigMixin():
+    @classmethod
+    def poll(cls, context):
+        if context.active_object is not None:
+            return get_arm_and_cam(context.active_object) != (None, None)
 
-    if active_cam != scene_cam.name:
-        bpy.context.scene.camera = bpy.data.objects[active_cam]
-    else:
-        return None
+        return False
 
 
-class ADD_CAMERA_RIGS_OT_set_scene_camera(Operator):
+class ADD_CAMERA_RIGS_OT_set_scene_camera(Operator, CameraRigMixin):
     bl_idname = "add_camera_rigs.set_scene_camera"
     bl_label = "Make Camera Active"
     bl_description = "Makes the camera parented to this rig the active scene camera"
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
     def execute(self, context):
-        set_scene_camera()
+        arm, cam = get_arm_and_cam(context.active_object)
+        scene_cam = context.scene.camera
 
-        return {'FINISHED'}
+        if cam is not None and cam is not scene_cam:
+            context.scene.camera = cam
+            return {'FINISHED'}
 
+        return {'CANCELLED'}
 
-def markerBind():
-    '''Defines the function to add a marker to timeling and bind camera'''
-    rig = bpy.context.active_object  # rig object
-    active_cam = rig.children[0]  # camera object
-
-    # switch area to DOPESHEET to add marker
-    bpy.context.area.type = 'DOPESHEET_EDITOR'
-    # add marker
-    bpy.ops.marker.add()  # it will automatiically have the name of the camera
-    # select rig camera
-    bpy.context.view_layer.objects.active = active_cam
-    # bind marker to selected camera
-    bpy.ops.marker.camera_bind()
-    # make the rig the active object before finishing
-    bpy.context.view_layer.objects.active = rig
-    bpy.data.objects[active_cam.name].select_set(False)
-    bpy.data.objects[rig.name].select_set(True)
-    # switch back to 3d view
-    bpy.context.area.type = 'VIEW_3D'
-
-
-class ADD_CAMERA_RIGS_OT_add_marker_bind(Operator):
+
+class ADD_CAMERA_RIGS_OT_add_marker_bind(Operator, CameraRigMixin):
     bl_idname = "add_camera_rigs.add_marker_bind"
     bl_label = "Add Marker and Bind Camera"
     bl_description = "Add marker to current frame then bind rig camera to it (for camera switching)"
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
     def execute(self, context):
-        markerBind()
-
-        return {'FINISHED'}
+        arm, cam = get_arm_and_cam(context.active_object)
 
+        marker = context.scene.timeline_markers.new(
+            "cam_" + str(context.scene.frame_current),
+            frame=context.scene.frame_current
+        )
+        marker.camera = cam
 
-def add_DOF_object():
-    """Define the function to add an Empty as DOF object """
-    smode = bpy.context.mode
-    rig = bpy.context.active_object
-    bone = rig.data.bones['aim_MCH']
-    active_cam = rig.children[0].name
-    cam = bpy.data.cameras[bpy.data.objects[active_cam].data.name]
-
-    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-    # Add Empty
-    bpy.ops.object.empty_add()
-    obj = bpy.context.active_object
-
-    obj.name = "Empty_DOF"
-    # parent to aim_MCH
-    obj.parent = rig
-    obj.parent_type = "BONE"
-    obj.parent_bone = "aim_MCH"
-    # clear loc and rot
-    bpy.ops.object.location_clear()
-    bpy.ops.object.rotation_clear()
-    # move to bone head
-    obj.location = bone.head
-
-    # make this new empty the dof_object
-    cam.dof.focus_object = obj
-
-    # make the rig the active object before finishing
-    bpy.context.view_layer.objects.active = rig
-    bpy.data.objects[obj.name].select_set(False)
-    bpy.data.objects[rig.name].select_set(True)
-
-    bpy.ops.object.mode_set(mode=smode, toggle=False)
+        return {'FINISHED'}
 
 
-class ADD_CAMERA_RIGS_OT_add_dof_object(Operator):
+class ADD_CAMERA_RIGS_OT_add_dof_object(Operator, CameraRigMixin):
     bl_idname = "add_camera_rigs.add_dof_object"
     bl_label = "Add DOF Object"
     bl_description = "Create Empty and add as DOF Object"
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
     def execute(self, context):
-        add_DOF_object()
+        arm, cam = get_arm_and_cam(context.active_object)
+        bone = arm.data.bones['Aim_shape_rotation-MCH']
+
+        # Add Empty
+        empty_obj = bpy.data.objects.new("EmptyDOF", None)
+        context.scene.collection.objects.link(empty_obj)
+
+        # Parent to Aim Child bone
+        empty_obj.parent = arm
+        empty_obj.parent_type = "BONE"
+        empty_obj.parent_bone = "Aim_shape_rotation-MCH"
+
+        # Move to bone head
+        empty_obj.location = bone.head
+
+        # Make this new empty the dof_object
+        cam.data.dof.use_dof = True
+        cam.data.dof.focus_object = empty_obj
 
         return {'FINISHED'}
 
diff --git a/add_camera_rigs/prefs.py b/add_camera_rigs/prefs.py
index 18c75bc4e96c17b38b0ea7396222c525d0169127..465c42a669389ea0e309f704448c8c326ba8f92b 100644
--- a/add_camera_rigs/prefs.py
+++ b/add_camera_rigs/prefs.py
@@ -1,23 +1,40 @@
-import bpy
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
 from bpy.types import AddonPreferences
 from bpy.props import StringProperty
 
 
-class Add_Camera_Rigs_Preferences(AddonPreferences):
+class AddCameraRigsPreferences(AddonPreferences):
     bl_idname = 'add_camera_rigs'
 
-    # widget prefix
+    # Widget prefix
     widget_prefix: StringProperty(
         name="Camera Widget prefix",
-        description="Choose a prefix for the widget objects",
-        default="WDGT_",
+        description="Prefix for the widget objects",
+        default="WGT-",
     )
 
-    # collection name
+    # Collection name
     camera_widget_collection_name: StringProperty(
         name="Bone Widget collection name",
-        description="Choose a name for the collection the widgets will appear",
-        default="WDGTS_camera",
+        description="Name for the collection the widgets will appear",
+        default="Widgets",
     )
 
     def draw(self, context):
@@ -30,7 +47,7 @@ class Add_Camera_Rigs_Preferences(AddonPreferences):
 
 
 classes = (
-    Add_Camera_Rigs_Preferences,
+    AddCameraRigsPreferences,
 )
 
 
diff --git a/add_camera_rigs/ui_panels.py b/add_camera_rigs/ui_panels.py
index 3356d3898fcf834819189d21860d9935a4098671..63fe158a6b0e9e7281a0f81d1d3f235cd87c5dbb 100644
--- a/add_camera_rigs/ui_panels.py
+++ b/add_camera_rigs/ui_panels.py
@@ -1,84 +1,95 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
 import bpy
 from bpy.types import Panel
 
+from .operators import get_arm_and_cam, CameraRigMixin
+
 
-class ADD_CAMERA_RIGS_PT_camera_rig_ui(Panel):
-    bl_category = 'Create'
-    bl_label = "Camera Rig UI"
+class ADD_CAMERA_RIGS_PT_camera_rig_ui(Panel, CameraRigMixin):
+    bl_label = "Camera Rig"
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
-
-    _ACTIVE_OBJECT: object = None
-
-    _ACTIVE_RIG_TYPE: str = None
-
-    @classmethod
-    def poll(self, context):
-        self._ACTIVE_OBJECT = bpy.context.active_object
-
-        if self._ACTIVE_OBJECT != None and "rig_id" in self._ACTIVE_OBJECT:
-            rigType = self._ACTIVE_OBJECT["rig_id"]
-
-            if rigType == "Dolly_rig" or rigType == "Crane_rig":
-                self._ACTIVE_RIG_TYPE = rigType
-                return True
-
-        return False
+    bl_category = 'Item'
 
     def draw(self, context):
-        arm = self._ACTIVE_OBJECT.data
-        poseBones = self._ACTIVE_OBJECT.pose.bones
-        activeCameraName = self._ACTIVE_OBJECT.children[0].name
-
-        cam = bpy.data.cameras[bpy.data.objects[activeCameraName].data.name]
+        active_object = context.active_object
+        arm, cam = get_arm_and_cam(context.active_object)
+        pose_bones = arm.pose.bones
+        cam_data = cam.data
 
         layout = self.layout.box().column()
         layout.label(text="Clipping:")
-        layout.prop(cam, "clip_start", text="Start")
-        layout.prop(cam, "clip_end", text="End")
-        layout.prop(cam, "type")
-        layout.prop(cam.dof, "use_dof")
-        if cam.dof.use_dof:
-            if cam.dof.focus_object is None:
-                layout.operator("add_camera_rigs.add_dof_object", text="Add DOF Empty")
-            layout.prop(poseBones["Camera"], '["focus_distance"]', text="Focus Distance")
-            layout.prop(poseBones["Camera"], '["f-stop"]', text="F-Stop")
-
-        layout.prop(self._ACTIVE_OBJECT, 'show_in_front', toggle=False, text='Show in front')
-        layout.prop(cam, "show_limits")
-        layout.prop(cam, "show_passepartout")
-        if cam.show_passepartout:
-            layout.prop(cam, "passepartout_alpha")
+        layout.prop(cam_data, "clip_start", text="Start")
+        layout.prop(cam_data, "clip_end", text="End")
+        layout.prop(cam_data, "type")
+        layout.prop(cam_data.dof, "use_dof")
+        if cam_data.dof.use_dof:
+            if cam_data.dof.focus_object is None:
+                layout.operator("add_camera_rigs.add_dof_object",
+                                text="Add DOF Empty", icon="OUTLINER_OB_EMPTY")
+            layout.prop(pose_bones["Camera"],
+                        '["focus_distance"]', text="Focus Distance")
+            layout.prop(pose_bones["Camera"],
+                        '["aperture_fstop"]', text="F-Stop")
+
+        layout.prop(active_object, 'show_in_front',
+                    toggle=False, text='Show in Front')
+        layout.prop(cam_data, "show_limits")
+        layout.prop(cam_data, "show_passepartout")
+        if cam_data.show_passepartout:
+            layout.prop(cam_data, "passepartout_alpha")
 
         layout.row().separator()
-        # added the comp guides here
-        layout.operator(
-            "wm.call_menu", text="Composition Guides").name = "ADD_CAMERA_RIGS_MT_composition_guides_menu"
+        # Added the comp guides here
+        layout.popover(
+            panel="ADD_CAMERA_RIGS_PT_composition_guides",
+            text="Composition Guides",)
         layout.row().separator()
 
-        layout.prop(bpy.data.objects[activeCameraName],
+        layout.prop(cam,
                     "hide_select", text="Make Camera Unselectable")
 
         layout.operator("add_camera_rigs.add_marker_bind",
-                        text="Add Marker and Bind")
-        if bpy.context.scene.camera.name != activeCameraName:
+                        text="Add Marker and Bind", icon="MARKER_HLT")
+        if context.scene.camera is not cam:
             layout.operator("add_camera_rigs.set_scene_camera",
                             text="Make Camera Active", icon='CAMERA_DATA')
-        # Camera Lens
-        layout.label(text="Focal Length:")
-        layout.prop(poseBones["Camera"], '["focal_length"]', text="Focal Length (mm)")
 
-        if self._ACTIVE_RIG_TYPE == "Crane_rig":
-            layout = layout.box().column()
-
-            # Crane arm stuff
-            layout.label(text="Crane Arm:")
-            layout.prop(poseBones["Crane_height"], 'scale', index=1, text="Arm Height")
-            layout.prop(poseBones["Crane_arm"], 'scale', index=1, text="Arm Length")
+        # Camera lens
+        layout.separator()
+        layout.prop(pose_bones["Camera"], '["lens"]', text="Focal Length (mm)")
 
         # Track to Constraint
         layout.label(text="Tracking:")
-        layout.prop(poseBones["Camera"], '["lock"]', text="Aim Lock", slider=True)
+        layout.prop(pose_bones["Camera"].constraints["Track To"],
+                    'influence', text="Aim Lock", slider=True)
+
+        if arm["rig_id"].lower() == "crane_rig":
+            col = layout.box().column()
+
+            # Crane arm stuff
+            col.label(text="Crane Arm:")
+            col.prop(pose_bones["Crane_height"],
+                     'scale', index=1, text="Arm Height")
+            col.prop(pose_bones["Crane_arm"],
+                     'scale', index=1, text="Arm Length")
 
 
 def register():