Skip to content

Instantly share code, notes, and snippets.

@AnomalousUnderdog
Last active January 18, 2022 04:42
Show Gist options
  • Save AnomalousUnderdog/7e836f25275900f0677881abf143edd0 to your computer and use it in GitHub Desktop.
Save AnomalousUnderdog/7e836f25275900f0677881abf143edd0 to your computer and use it in GitHub Desktop.
Blender Add-on for showing number of frames of selected keyframes in Dopesheet
bl_info = {
"name": "Show Length of Selected Keyframes",
"description": "Show number of frames of selected keyframes.",
"author": "Ferdinand Joseph Fernandez",
"version": (1, 1),
"location": "Dopesheet > Key > Get Selected Keyframes Length (default hotkey: Q while in Dopesheet)",
"support": "TESTING",
"category": "Animation",
}
#
# I am putting the MIT license notice right inside this file because this add-on
# is just one file at the moment. --Ferdinand
#
# ----------------------
#
# Copyright (c) 2017 Ferdinand Joseph Fernandez
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
import bpy, bgl, blf, math
from bpy.props import *
class GetSelectedKeyframesLength(bpy.types.Operator):
"""Get Selected Keyframes Length"""
bl_idname = "animation.get_selected_keyframes_length"
bl_label = "Get Selected Keyframes Length"
def __init__(self):
self.text_display = ""
def calculate_selected_keyframes_length(self, context):
if (context.active_object is None):
# no object
return
if (context.active_object.animation_data is None):
# no animation viewed in the dopesheet
return
min = 9999
max = -9999
fcurves = context.active_object.animation_data.action.fcurves
for curve in fcurves:
keyframePoints = curve.keyframe_points
if len(keyframePoints) > 0:
for keyframe in keyframePoints:
if keyframe.select_control_point == False:
continue
if (keyframe.co[0] > max):
max = keyframe.co[0]
if (keyframe.co[0] < min):
min = keyframe.co[0]
# the delta between the two is the number of frames
framelen = (max - min) + 1
if (framelen < 0):
framelen = 0
self.text_display = ""
if (framelen <= 0):
self.text_display = "No keyframes selected"
elif (framelen == 1):
self.text_display = "Length: 1 (frame {0:.0f})".format(min)
else:
self.text_display = "Length: {0:.0f} (frames {1:.0f} to {2:.0f})".format(framelen, min, max)
def execute(self, context):
self.calculate_selected_keyframes_length(context)
label_size = blf.dimensions(0, self.text_display)
wm = context.window_manager
return wm.invoke_popup(self, width=label_size[0]+18, height=20)
def draw(self, context):
self.layout.label(self.text_display)
def menu_separator(self, context):
self.layout.separator()
def get_selected_keyframes_length_menu(self, context):
self.layout.operator(GetSelectedKeyframesLength.bl_idname)
# keymaps are stored here so they can be accessed after registration
addon_keymaps = []
def register():
bpy.utils.register_module(__name__)
# menu registration
bpy.types.DOPESHEET_MT_key.append(menu_separator)
bpy.types.DOPESHEET_MT_key.append(get_selected_keyframes_length_menu)
# hotkey registration
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
keymap = kc.keymaps.new(name='Dopesheet', space_type='DOPESHEET_EDITOR')
keymap_item = keymap.keymap_items.new(GetSelectedKeyframesLength.bl_idname, 'Q', 'PRESS')
# add to list so we can unregister afterwards
addon_keymaps.append((keymap, keymap_item))
def unregister():
# unregister hotkey
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
bpy.utils.unregister_module(__name__)
# unregister menu
bpy.types.DOPESHEET_MT_key.remove(get_selected_keyframes_length_menu)
bpy.types.DOPESHEET_MT_key.remove(menu_separator)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment