diff --git a/add_camera_rigs/__init__.py b/add_camera_rigs/__init__.py
index 6b5771993f8351bdc7a21fc7ff60fe0bea5202d1..6f9f9eeb43cf828e1936cb310c11c07ad370c1e5 100644
--- a/add_camera_rigs/__init__.py
+++ b/add_camera_rigs/__init__.py
@@ -18,8 +18,8 @@
 
 bl_info = {
     "name": "Add Camera Rigs",
-    "author": "Wayne Dixon, Brian Raschko, Kris Wittig, Damien Picard",
-    "version": (1, 4, 2),
+    "author": "Wayne Dixon, Brian Raschko, Kris Wittig, Damien Picard, Flavio Perez",
+    "version": (1, 4, 3),
     "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 1a37bc6e530a0956212727d69fe601db2c6415e0..57cadc0e3aded4e25b8bafc3090149f9f7f6f892 100644
--- a/add_camera_rigs/build_rigs.py
+++ b/add_camera_rigs/build_rigs.py
@@ -17,18 +17,33 @@
 # ##### END GPL LICENSE BLOCK #####
 
 import bpy
-from bpy_extras import object_utils
 from bpy.types import Operator
-from math import radians, pi
+from bpy_extras import object_utils
+from mathutils import Vector
 from rna_prop_ui import rna_idprop_ui_prop_get
+from math import pi
+
 from .create_widgets import (create_root_widget,
-                             create_widget,
-                             create_camera_widget,
-                             create_aim_widget,
-                             )
+                             create_camera_widget, create_aim_widget,
+                             create_circle_widget, create_corner_widget)
+
+
+def create_prop_driver(rig, cam, prop_from, prop_to):
+    """Create driver to a property on the rig"""
+    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'
 
-def create_dolly_bones(rig, bone_layers):
+
+def create_dolly_bones(rig):
+    """Create bones for the dolly camera rig"""
     bones = rig.data.edit_bones
 
     # Add new bones
@@ -39,7 +54,7 @@ def create_dolly_bones(rig, bone_layers):
     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
+    ctrl_aim_child.layers = tuple(i == 1 for i in range(32))
 
     ctrl_aim = bones.new("Aim")
     ctrl_aim.head = (0.0, 10.0, 1.7)
@@ -57,7 +72,8 @@ def create_dolly_bones(rig, bone_layers):
     ctrl_aim_child.parent = ctrl_aim
 
 
-def create_crane_bones(rig, bone_layers):
+def create_crane_bones(rig):
+    """Create bones for the crane camera rig"""
     bones = rig.data.edit_bones
 
     # Add new bones
@@ -68,7 +84,7 @@ def create_crane_bones(rig, bone_layers):
     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
+    ctrl_aim_child.layers = tuple(i == 1 for i in range(32))
 
     ctrl_aim = bones.new("Aim")
     ctrl_aim.head = (0.0, 10.0, 1.7)
@@ -112,34 +128,13 @@ def create_crane_bones(rig, bone_layers):
     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
-
-    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)
-
+def setup_3d_rig(rig, cam):
+    """Finish setting up Dolly and Crane rigs"""
     # 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
+    for bone in pose_bones:
+        bone.rotation_mode = 'XYZ'
 
     # Lens property
     pb = pose_bones['Camera']
@@ -150,22 +145,6 @@ def build_camera_rig(context, mode):
     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")
@@ -176,7 +155,7 @@ def build_camera_rig(context, mode):
     pose_bones["Aim"].custom_shape = aim_widget
     pose_bones["Camera"].custom_shape = camera_widget
 
-    # Set the "At" field to the child
+    # Set the "At" field to the shape mecanism
     pose_bones["Aim"].custom_shape_transform = pose_bones["Aim_shape_rotation-MCH"]
 
     # Add constraints to bones
@@ -189,55 +168,359 @@ def build_camera_rig(context, mode):
     con.subtarget = "Aim"
     con.use_target_z = True
 
-    # 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'
+    cam.data.display_size = 1.0
+    cam.rotation_euler[0] = pi / 2.0  # Rotate the camera 90 degrees in x
+
+    create_prop_driver(rig, cam, "lens", "lens")
+
+
+def create_2d_bones(context, rig, cam):
+    """Create bones for the 2D camera rig"""
+    scene = context.scene
+    bones = rig.data.edit_bones
+
+    # Add new bones
+    bones = rig.data.edit_bones
+    root = bones.new("Root")
+    root.tail = Vector((0.0, 0.0, 1.0))
+    root.show_wire = True
+
+    ctrl = bones.new('Camera')
+    ctrl.tail = Vector((0.0, 0.0, 1.0))
+    ctrl.show_wire = True
+
+    left_corner = bones.new("Left_corner")
+    left_corner.head = (-3, 10, -2)
+    left_corner.tail = left_corner.head + Vector((0.0, 0.0, 1.0))
+    left_corner.show_wire = True
+
+    right_corner = bones.new("Right_corner")
+    right_corner.head = (3, 10, -2)
+    right_corner.tail = right_corner.head + Vector((0.0, 0.0, 1.0))
+    right_corner.show_wire = True
 
+    corner_distance_x = (left_corner.head - right_corner.head).length
+    corner_distance_y = -left_corner.head.z
+    corner_distance_z = left_corner.head.y
+
+    center = bones.new("Center-MCH")
+    center.head = ((right_corner.head + left_corner.head) / 2.0)
+    center.tail = center.head + Vector((0.0, 0.0, 1.0))
+    center.layers = tuple(i == 1 for i in range(32))
+    center.show_wire = True
+
+    # Setup hierarchy
+    ctrl.parent = root
+    left_corner.parent = root
+    right_corner.parent = root
+    center.parent = root
+
+    # Jump into object mode and change bones to euler
+    bpy.ops.object.mode_set(mode='OBJECT')
+    pose_bones = rig.pose.bones
+    for bone in pose_bones:
+        bone.rotation_mode = 'XYZ'
+
+    # Bone drivers
+    center_drivers = pose_bones["Center-MCH"].driver_add("location")
+
+    # Center X driver
+    driver = center_drivers[0].driver
+    driver.type = 'AVERAGE'
+
+    for corner in ('left', 'right'):
+        var = driver.variables.new()
+        var.name = corner
+        var.type = 'TRANSFORMS'
+        var.targets[0].id = rig
+        var.targets[0].bone_target = corner.capitalize() + '_corner'
+        var.targets[0].transform_type = 'LOC_X'
+        var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+    # Center Y driver
+    driver = center_drivers[1].driver
+    driver.type = 'SCRIPTED'
+
+    driver.expression = '({distance_x} - (left_x-right_x))*(res_y/res_x)/2 + (left_y + right_y)/2'.format(distance_x=corner_distance_x)
+
+    for direction in ('x', 'y'):
+        for corner in ('left', 'right'):
+            var = driver.variables.new()
+            var.name = '%s_%s' % (corner, direction)
+            var.type = 'TRANSFORMS'
+            var.targets[0].id = rig
+            var.targets[0].bone_target = corner.capitalize() + '_corner'
+            var.targets[0].transform_type = 'LOC_' + direction.upper()
+            var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+        var = driver.variables.new()
+        var.name = 'res_' + direction
+        var.type = 'SINGLE_PROP'
+        var.targets[0].id_type = 'SCENE'
+        var.targets[0].id = scene
+        var.targets[0].data_path = 'render.resolution_' + direction
+
+    # Center Z driver
+    driver = center_drivers[2].driver
+    driver.type = 'AVERAGE'
+
+    for corner in ('left', 'right'):
+        var = driver.variables.new()
+        var.name = corner
+        var.type = 'TRANSFORMS'
+        var.targets[0].id = rig
+        var.targets[0].bone_target = corner.capitalize() + '_corner'
+        var.targets[0].transform_type = 'LOC_Z'
+        var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+    # Bone constraints
+    con = pose_bones["Camera"].constraints.new('DAMPED_TRACK')
+    con.target = rig
+    con.subtarget = "Center-MCH"
+    con.track_axis = 'TRACK_NEGATIVE_Z'
+
+    # Build the widgets
+    left_widget = create_corner_widget("Left_corner", reverse=True)
+    right_widget = create_corner_widget("Right_corner")
+    parent_widget = create_circle_widget("Root", radius=0.5)
+    camera_widget = create_circle_widget("Camera_2D", radius=0.3)
+
+    # Add the custom bone shapes
+    pose_bones["Left_corner"].custom_shape = left_widget
+    pose_bones["Right_corner"].custom_shape = right_widget
+    pose_bones["Root"].custom_shape = parent_widget
+    pose_bones["Camera"].custom_shape = camera_widget
+
+    # Lock the relevant loc, rot and scale
+    pose_bones["Left_corner"].lock_rotation = (True,) * 3
+    pose_bones["Right_corner"].lock_rotation = (True,) * 3
+    pose_bones["Camera"].lock_rotation = (True,) * 3
+    pose_bones["Camera"].lock_scale = (True,) * 3
+
+    # Camera settings
+
+    cam.data.sensor_fit = "HORIZONTAL"  # Avoids distortion in portrait format
+
+    # Property to switch between rotation and switch mode
+    pose_bones["Camera"]['rotation_shift'] = 0.0
+    prop = rna_idprop_ui_prop_get(pose_bones["Camera"], 'rotation_shift', create=True)
+    prop["min"] = 0.0
+    prop["max"] = 1.0
+    prop["soft_min"] = 0.0
+    prop["soft_max"] = 1.0
+    prop["description"] = 'rotation_shift'
+
+    # Rotation / shift switch driver
+    driver = con.driver_add('influence').driver
+    driver.expression = '1 - rotation_shift'
+
+    var = driver.variables.new()
+    var.name = 'rotation_shift'
+    var.type = 'SINGLE_PROP'
+    var.targets[0].id = rig
+    var.targets[0].data_path = 'pose.bones["Camera"]["rotation_shift"]'
+
+    # Focal length driver
+    driver = cam.data.driver_add('lens').driver
+    driver.expression = 'abs({distance_z} - (left_z + right_z)/2 + cam_z) * 36 / frame_width'.format(distance_z=corner_distance_z)
+
+    var = driver.variables.new()
+    var.name = 'frame_width'
+    var.type = 'LOC_DIFF'
+    var.targets[0].id = rig
+    var.targets[0].bone_target = "Left_corner"
+    var.targets[0].transform_space = 'WORLD_SPACE'
+    var.targets[1].id = rig
+    var.targets[1].bone_target = "Right_corner"
+    var.targets[1].transform_space = 'WORLD_SPACE'
+
+    for corner in ('left', 'right'):
+        var = driver.variables.new()
+        var.name = corner + '_z'
+        var.type = 'TRANSFORMS'
+        var.targets[0].id = rig
+        var.targets[0].bone_target = corner.capitalize() + '_corner'
+        var.targets[0].transform_type = 'LOC_Z'
+        var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+    var = driver.variables.new()
+    var.name = 'cam_z'
+    var.type = 'TRANSFORMS'
+    var.targets[0].id = rig
+    var.targets[0].bone_target = "Camera"
+    var.targets[0].transform_type = 'LOC_Z'
+    var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+    # Orthographic scale driver
+    driver = cam.data.driver_add('ortho_scale').driver
+    driver.expression = 'abs({distance_x} - (left_x - right_x))'.format(distance_x=corner_distance_x)
+
+    for corner in ('left', 'right'):
+        var = driver.variables.new()
+        var.name = corner + '_x'
+        var.type = 'TRANSFORMS'
+        var.targets[0].id = rig
+        var.targets[0].bone_target = corner.capitalize() + '_corner'
+        var.targets[0].transform_type = 'LOC_X'
+        var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+    # Shift driver X
+    driver = cam.data.driver_add('shift_x').driver
+
+    driver.expression = 'rotation_shift * (((left_x + right_x)/2 - cam_x) * lens / abs({distance_z} - (left_z + right_z)/2 + cam_z) / 36)'.format(distance_z=corner_distance_z)
+
+    var = driver.variables.new()
+    var.name = 'rotation_shift'
+    var.type = 'SINGLE_PROP'
+    var.targets[0].id = rig
+    var.targets[0].data_path = 'pose.bones["Camera"]["rotation_shift"]'
+
+    for direction in ('x', 'z'):
+        for corner in ('left', 'right'):
+            var = driver.variables.new()
+            var.name = '%s_%s' % (corner, direction)
+            var.type = 'TRANSFORMS'
+            var.targets[0].id = rig
+            var.targets[0].bone_target = corner.capitalize() + '_corner'
+            var.targets[0].transform_type = 'LOC_' + direction.upper()
+            var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+        var = driver.variables.new()
+        var.name = 'cam_' + direction
+        var.type = 'TRANSFORMS'
+        var.targets[0].id = rig
+        var.targets[0].bone_target = "Camera"
+        var.targets[0].transform_type = 'LOC_' + direction.upper()
+        var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+    var = driver.variables.new()
+    var.name = 'lens'
+    var.type = 'SINGLE_PROP'
+    var.targets[0].id_type = 'CAMERA'
+    var.targets[0].id = cam.data
+    var.targets[0].data_path = 'lens'
+
+    # Shift driver Y
+    driver = cam.data.driver_add('shift_y').driver
+
+    driver.expression = 'rotation_shift * -(({distance_y} - (left_y + right_y)/2 + cam_y) * lens / abs({distance_z} - (left_z + right_z)/2 + cam_z) / 36 - (res_y/res_x)/2)'.format(distance_y=corner_distance_y, distance_z=corner_distance_z)
+
+    var = driver.variables.new()
+    var.name = 'rotation_shift'
+    var.type = 'SINGLE_PROP'
+    var.targets[0].id = rig
+    var.targets[0].data_path = 'pose.bones["Camera"]["rotation_shift"]'
+
+    for direction in ('y', 'z'):
+        for corner in ('left', 'right'):
+            var = driver.variables.new()
+            var.name = '%s_%s' % (corner, direction)
+            var.type = 'TRANSFORMS'
+            var.targets[0].id = rig
+            var.targets[0].bone_target = corner.capitalize() + '_corner'
+            var.targets[0].transform_type = 'LOC_' + direction.upper()
+            var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+        var = driver.variables.new()
+        var.name = 'cam_' + direction
+        var.type = 'TRANSFORMS'
+        var.targets[0].id = rig
+        var.targets[0].bone_target = "Camera"
+        var.targets[0].transform_type = 'LOC_' + direction.upper()
+        var.targets[0].transform_space = 'TRANSFORM_SPACE'
+
+    for direction in ('x', 'y'):
+        var = driver.variables.new()
+        var.name = 'res_' + direction
+        var.type = 'SINGLE_PROP'
+        var.targets[0].id_type = 'SCENE'
+        var.targets[0].id = scene
+        var.targets[0].data_path = 'render.resolution_' + direction
+
+    var = driver.variables.new()
+    var.name = 'lens'
+    var.type = 'SINGLE_PROP'
+    var.targets[0].id_type = 'CAMERA'
+    var.targets[0].id = cam.data
+    var.targets[0].data_path = 'lens'
+
+
+def build_camera_rig(context, mode):
+    """Create stuff common to all camera rigs."""
     # 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
+    # Add the rig object
+    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
+    rig.location = context.scene.cursor.location
+
+    bpy.ops.object.mode_set(mode='EDIT')
 
+    # Add new bones and setup specific rigs
+    if mode == "DOLLY":
+        create_dolly_bones(rig)
+        setup_3d_rig(rig, cam)
+    elif mode == "CRANE":
+        create_crane_bones(rig)
+        setup_3d_rig(rig, cam)
+    elif mode == "2D":
+        create_2d_bones(context, rig, cam)
+
+    # Parent the camera to the rig
     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"
 
+    # Change display to BBone: it just looks nicer
+    rig.data.display_type = 'BBONE'
+    # Change display to wire for object
+    rig.display_type = 'WIRE'
+
     # Lock camera transforms
     cam.lock_location = (True,) * 3
     cam.lock_rotation = (True,) * 3
     cam.lock_scale = (True,) * 3
 
+    # Add custom properties to the armature’s Camera bone,
+    # so that all properties may be animated in a single action
+
+    pose_bones = rig.pose.bones
+
+    # 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
+
     # 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'
+    create_prop_driver(rig, cam, "focus_distance", "dof.focus_distance")
+    create_prop_driver(rig, cam, "aperture_fstop", "dof.aperture_fstop")
 
     # Make the rig the active object
-    for ob in view_layer.objects:
-        ob.select_set(False)
+    view_layer = context.view_layer
+    for obj in view_layer.objects:
+        obj.select_set(False)
     rig.select_set(True)
     view_layer.objects.active = rig
 
-    return rig
-
 
 class OBJECT_OT_build_camera_rig(Operator):
     bl_idname = "object.build_camera_rig"
@@ -245,11 +528,12 @@ class OBJECT_OT_build_camera_rig(Operator):
     bl_description = "Build a Camera Rig"
     bl_options = {'REGISTER', 'UNDO'}
 
-    mode: bpy.props.EnumProperty(items=
-                                 (('DOLLY',) * 3,
-                                  ('CRANE',) * 3,),
+    mode: bpy.props.EnumProperty(items=(('DOLLY', 'Dolly', 'Dolly rig'),
+                                        ('CRANE', 'Crane', 'Crane rig',),
+                                        ('2D', '2D', '2D rig')),
                                  name="mode",
-                                 description="", default="DOLLY")
+                                 description="Type of camera to create",
+                                 default="DOLLY")
 
     def execute(self, context):
         # Build the rig
@@ -260,18 +544,23 @@ class OBJECT_OT_build_camera_rig(Operator):
 def add_dolly_crane_buttons(self, context):
     """Dolly and crane entries in the Add Object > Camera Menu"""
     if context.mode == 'OBJECT':
-        op = self.layout.operator(
+        self.layout.operator(
             OBJECT_OT_build_camera_rig.bl_idname,
             text="Dolly Camera Rig",
-            icon='CAMERA_DATA'
-        )
-        op.mode = "DOLLY"
-        op = self.layout.operator(
+            icon='VIEW_CAMERA'
+        ).mode = "DOLLY"
+
+        self.layout.operator(
             OBJECT_OT_build_camera_rig.bl_idname,
             text="Crane Camera Rig",
-            icon='CAMERA_DATA'
-        )
-        op.mode = "CRANE"
+            icon='VIEW_CAMERA'
+        ).mode = "CRANE"
+
+        self.layout.operator(
+            OBJECT_OT_build_camera_rig.bl_idname,
+            text="2D Camera Rig",
+            icon='PIVOT_BOUNDBOX'
+        ).mode = "2D"
 
 
 classes = (
diff --git a/add_camera_rigs/composition_guides_menu.py b/add_camera_rigs/composition_guides_menu.py
index c3ff43e5a12cfdfac3a0facb8ef7e1411fd09814..165375257ba7fc6db4d01af45981bfd28f76d4c4 100644
--- a/add_camera_rigs/composition_guides_menu.py
+++ b/add_camera_rigs/composition_guides_menu.py
@@ -19,7 +19,7 @@
 import bpy
 from bpy.types import Panel
 
-from .operators import get_arm_and_cam
+from .operators import get_rig_and_cam
 
 class ADD_CAMERA_RIGS_PT_composition_guides(Panel):
     bl_label = "Composition Guides"
@@ -29,7 +29,7 @@ class ADD_CAMERA_RIGS_PT_composition_guides(Panel):
     def draw(self, context):
         layout = self.layout
 
-        arm, cam = get_arm_and_cam(context.active_object)
+        rig, cam = get_rig_and_cam(context.active_object)
         cam = cam.data
 
         layout.prop(cam, "show_safe_areas")
diff --git a/add_camera_rigs/create_widgets.py b/add_camera_rigs/create_widgets.py
index f19fc206e9b0e744a37163e1ba55563b8bd5f4b2..72a8c70d071041aecba28629870b8deebd42051e 100644
--- a/add_camera_rigs/create_widgets.py
+++ b/add_camera_rigs/create_widgets.py
@@ -1,4 +1,24 @@
+# ##### 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 mathutils import Vector
+from math import cos, sin, pi
 
 
 def create_widget(name):
@@ -29,6 +49,44 @@ def create_widget(name):
     return obj
 
 
+def create_corner_widget(name, reverse=False):
+    """Create a wedge-shaped widget"""
+    obj = create_widget(name)
+    if not obj.data.vertices:
+        reverse = -1 if reverse else 1
+        verts = (Vector((reverse *  0.0, 0.0, 0.0)),
+                 Vector((reverse *  0.0, 1.0, 0.0)),
+                 Vector((reverse * -0.1, 1.0, 0.0)),
+                 Vector((reverse * -0.1, 0.1, 0.0)),
+                 Vector((reverse * -1.0, 0.1, 0.0)),
+                 Vector((reverse * -1.0, 0.0, 0.0)),
+                 )
+        edges = [(n, (n+1) % len(verts)) for n in range(len(verts))]
+
+        mesh = obj.data
+        mesh.from_pydata(verts, edges, ())
+        mesh.update()
+    return obj
+
+
+def create_circle_widget(name, radius=1.0):
+    """Create a circle-shaped widget"""
+    obj = create_widget(name)
+    if not obj.data.vertices:
+        vert_n = 16
+        verts = []
+        for n in range(vert_n):
+            angle = n / vert_n * 2*pi
+            verts.append(Vector((cos(angle) * radius,
+                                 sin(angle) * radius, 0.0)))
+        edges = [(n, (n+1) % len(verts)) for n in range(len(verts))]
+
+        mesh = obj.data
+        mesh.from_pydata(verts, edges, ())
+        mesh.update()
+    return obj
+
+
 def create_root_widget(name):
     """Create a compass-shaped widget"""
     obj = create_widget(name)
diff --git a/add_camera_rigs/operators.py b/add_camera_rigs/operators.py
index 7468007e5de6db641d70fca0a161763fb351ca80..058ed14667e4c20d8e32191aa5081da1ed002cfc 100644
--- a/add_camera_rigs/operators.py
+++ b/add_camera_rigs/operators.py
@@ -20,7 +20,7 @@ import bpy
 from bpy.types import Operator
 
 
-def get_arm_and_cam(obj):
+def get_rig_and_cam(obj):
     if obj.type == 'ARMATURE':
         cam = None
         for child in obj.children:
@@ -32,7 +32,8 @@ def get_arm_and_cam(obj):
     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"}):
+          and obj.parent["rig_id"].lower() in {"dolly_rig",
+                                               "crane_rig", "2d_rig"}):
         return obj.parent, obj
     return None, None
 
@@ -41,25 +42,31 @@ class CameraRigMixin():
     @classmethod
     def poll(cls, context):
         if context.active_object is not None:
-            return get_arm_and_cam(context.active_object) != (None, None)
+            return get_rig_and_cam(context.active_object) != (None, None)
 
         return False
 
 
-class ADD_CAMERA_RIGS_OT_set_scene_camera(Operator, CameraRigMixin):
+class ADD_CAMERA_RIGS_OT_set_scene_camera(Operator):
     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):
+        if context.active_object is not None:
+            rig, cam = get_rig_and_cam(context.active_object)
+            if cam is not None:
+                return cam is not context.scene.camera
+
+        return False
+
     def execute(self, context):
-        arm, cam = get_arm_and_cam(context.active_object)
+        rig, cam = get_rig_and_cam(context.active_object)
         scene_cam = context.scene.camera
 
-        if cam is not None and cam is not scene_cam:
-            context.scene.camera = cam
-            return {'FINISHED'}
-
-        return {'CANCELLED'}
+        context.scene.camera = cam
+        return {'FINISHED'}
 
 
 class ADD_CAMERA_RIGS_OT_add_marker_bind(Operator, CameraRigMixin):
@@ -68,7 +75,7 @@ class ADD_CAMERA_RIGS_OT_add_marker_bind(Operator, CameraRigMixin):
     bl_description = "Add marker to current frame then bind rig camera to it (for camera switching)"
 
     def execute(self, context):
-        arm, cam = get_arm_and_cam(context.active_object)
+        rig, cam = get_rig_and_cam(context.active_object)
 
         marker = context.scene.timeline_markers.new(
             "cam_" + str(context.scene.frame_current),
@@ -85,15 +92,15 @@ class ADD_CAMERA_RIGS_OT_add_dof_object(Operator, CameraRigMixin):
     bl_description = "Create Empty and add as DOF Object"
 
     def execute(self, context):
-        arm, cam = get_arm_and_cam(context.active_object)
-        bone = arm.data.bones['Aim_shape_rotation-MCH']
+        rig, cam = get_rig_and_cam(context.active_object)
+        bone = rig.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 = rig
         empty_obj.parent_type = "BONE"
         empty_obj.parent_bone = "Aim_shape_rotation-MCH"
 
diff --git a/add_camera_rigs/ui_panels.py b/add_camera_rigs/ui_panels.py
index 63fe158a6b0e9e7281a0f81d1d3f235cd87c5dbb..0dc3c69e54fe024c802ad226eb5bb6872a20d25f 100644
--- a/add_camera_rigs/ui_panels.py
+++ b/add_camera_rigs/ui_panels.py
@@ -19,7 +19,7 @@
 import bpy
 from bpy.types import Panel
 
-from .operators import get_arm_and_cam, CameraRigMixin
+from .operators import get_rig_and_cam, CameraRigMixin
 
 
 class ADD_CAMERA_RIGS_PT_camera_rig_ui(Panel, CameraRigMixin):
@@ -30,66 +30,87 @@ class ADD_CAMERA_RIGS_PT_camera_rig_ui(Panel, CameraRigMixin):
 
     def draw(self, context):
         active_object = context.active_object
-        arm, cam = get_arm_and_cam(context.active_object)
-        pose_bones = arm.pose.bones
+        rig, cam = get_rig_and_cam(context.active_object)
+        pose_bones = rig.pose.bones
         cam_data = cam.data
+        layout = self.layout
+
+        # Camera lens
+        if rig["rig_id"].lower() in ("dolly_rig", "crane_rig"):
+            layout.prop(pose_bones["Camera"], '["lens"]',
+                        text="Focal Length (mm)")
+
+        col = layout.column(align=True)
+        col.label(text="Clipping:")
+        col.prop(cam_data, "clip_start", text="Start")
+        col.prop(cam_data, "clip_end", text="End")
 
-        layout = self.layout.box().column()
-        layout.label(text="Clipping:")
-        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")
 
+        # DoF
+        col = layout.column(align=True)
+        col.prop(cam_data.dof, "use_dof")
+        if cam_data.dof.use_dof:
+            if rig["rig_id"].lower() in ("crane_rig", "dolly_rig"):
+                if cam_data.dof.focus_object is None:
+                    col.operator("add_camera_rigs.add_dof_object",
+                                 text="Add DOF Empty", icon="OUTLINER_OB_EMPTY")
+            else:
+                col.prop(cam_data.dof, "focus_object")
+            row = col.row(align=True)
+            row.active = cam_data.dof.focus_object is None
+            row.prop(pose_bones["Camera"],
+                     '["focus_distance"]', text="Focus Distance")
+            col.prop(pose_bones["Camera"],
+                     '["aperture_fstop"]', text="F-Stop")
+
+        # Viewport display
         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")
+        col = layout.column(align=True)
+        col.prop(cam_data, "show_passepartout")
         if cam_data.show_passepartout:
-            layout.prop(cam_data, "passepartout_alpha")
+            col.prop(cam_data, "passepartout_alpha")
 
-        layout.row().separator()
-        # Added the comp guides here
+        # Composition guides
         layout.popover(
             panel="ADD_CAMERA_RIGS_PT_composition_guides",
             text="Composition Guides",)
-        layout.row().separator()
 
-        layout.prop(cam,
+        # Props and operators
+        col = layout.column(align=True)
+        col.prop(cam,
                     "hide_select", text="Make Camera Unselectable")
-
-        layout.operator("add_camera_rigs.add_marker_bind",
-                        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.separator()
-        layout.prop(pose_bones["Camera"], '["lens"]', text="Focal Length (mm)")
-
-        # Track to Constraint
-        layout.label(text="Tracking:")
-        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()
+        col.operator("add_camera_rigs.add_marker_bind",
+                     text="Add Marker and Bind", icon="MARKER_HLT")
+        col.operator("add_camera_rigs.set_scene_camera",
+                     text="Make Camera Active", icon='CAMERA_DATA')
+
+        if rig["rig_id"].lower() in ("dolly_rig", "crane_rig"):
+            # Track to Constraint
+            col = layout.column(align=True)
+            col.label(text="Tracking:")
+            col.prop(pose_bones["Camera"].constraints["Track To"],
+                     'influence', text="Aim Lock", slider=True)
 
             # 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")
+            if rig["rig_id"].lower() == "crane_rig":
+                col = layout.column(align=True)
+                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")
+
+        # 2D rig stuff
+        elif rig["rig_id"].lower() == "2d_rig":
+            col = layout.column(align=True)
+            col.label(text="2D Rig:")
+            col.prop(pose_bones["Camera"], '["rotation_shift"]',
+                     text="Rotation/Shift")
+            if cam.data.sensor_width != 36:
+                col.label(text="Please set Camera Sensor Width to 36", icon="ERROR")
 
 
 def register():