Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Adds a label in the 3D View of the name of the Action currently being edited in the Dopesheet.
bl_info = {
"name": "Show Action Name in 3D View",
"description": "Adds a label in the 3D View of the name of the Action currently being edited in the Dopesheet.",
"author": "Ferdinand Joseph Fernandez",
"version": (1, 0),
"location": "",
"support": "TESTING",
"category": "Animation",
import bpy, bgl, blf
def is_in_visible_layer(ob):
ob_layers = ob.layers
scene_layers = bpy.context.scene.layers
for layer_index in range(len(ob_layers)):
if ob_layers[layer_index] == True and scene_layers[layer_index] == True:
return True
return False
class DrawingClass:
def start(self, context): = bpy.types.SpaceView3D
self.area_id = "VIEW_3D"
self.region_id = "WINDOW"
self.handle =
self.region_id, "POST_PIXEL")
self.area = None
self.dopesheet_area = None
def draw_text_callback(self, context):
text = None
# if selected object has an action, use that
if (bpy.context.active_object is not None and bpy.context.active_object.animation_data is not None and bpy.context.active_object.animation_data.action is not None):
text =
# if dopesheet is open and has an action, use that
if (self.dopesheet_area is None):
# loop through areas
# get the dopesheet
for area in bpy.context.screen.areas:
if area.type == "DOPESHEET_EDITOR":
self.dopesheet_area = area
if (self.dopesheet_area is not None):
action = self.dopesheet_area.spaces[0].action
if (action is not None):
text =
# if scene has an armature that is visisble in the 3d view and is using an action, use that
for scene_ob in bpy.context.scene.objects:
if scene_ob.type != 'ARMATURE' or scene_ob.hide == True or is_in_visible_layer(scene_ob) == False:
if (scene_ob.animation_data is not None and scene_ob.animation_data.action is not None):
text =
if (text is None):
# determine text pos and size
font_id = 0 # 0 is default font
blf.size(font_id, 11, 72)
#label_size = blf.dimensions(font_id, text)
text_x = 68
text_y = 25
#padding = 5
#text_x = 100
#if (self.area is not None):
# # alight to right edge
# text_x = self.area.width - label_size[0] - 15
#text_y = 27 # above scrollbar
# draw the text's bg
# glPushAttrib is done to return everything to normal after drawing
# bgl.glVertex2f(text_x-padding, text_y-padding)
# bgl.glVertex2f(text_x-padding, text_y+label_size[1]+padding)
# bgl.glVertex2f(text_x+label_size[0]+padding, text_y+label_size[1]+padding)
# bgl.glVertex2f(text_x+label_size[0]+padding, text_y-padding)
# bgl.glEnd()
# bgl.glPopAttrib()
# draw the text
blf.position(font_id, text_x, text_y, 0)
blf.enable(font_id, blf.SHADOW)
blf.shadow(font_id, 5, 0, 0, 0, 1)
blf.draw(font_id, text)
blf.disable(font_id, blf.SHADOW)
def remove_handle(self):, self.region_id)
dc = DrawingClass()
def register():
def unregister():
dc.remove_handle() # will remove the handle and stop drawing
if __name__ == "__main__":
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment