Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4075 addon bforartists power user tools #4089

Merged
merged 3 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
108 changes: 108 additions & 0 deletions scripts/addons/bfa_power_user_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# 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 3 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
# MERCHANTIBILITY 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, see <http://www.gnu.org/licenses/>.

bl_info = {
"name": "BFA - Power User Tools",
"description": "Additional set of user experience tools and operators to assist with every day use.",
"author": "Andres Stephens (Draise)",
"version": (0, 2),
"blender": (4, 00, 0),
"location": "Varios locations, customize as you need",
"warning": "This is a Bforartists exclusive addon for the time being", # used for warning icon and text in add-ons panel
"wiki_url": "",
"tracker_url": "https://github.com/Draise14/bfa_power_user_tools",
"support": "COMMUNITY",
"category": "UI"
}

import bpy
from . import operators
from . import ui
from . import properties
from . import preferences


op_list = [
operators.BFA_OT_insertframe_right,
operators.BFA_OT_insertframe_left,
# Add more operators as needed
]


def register():
# Register operators before adding them to the menus
for operator in op_list:
bpy.utils.register_class(operator)

# Register custom menus, do this before filling in operators
bpy.utils.register_class(ui.BFA_MT_timeline_key)
bpy.types.TIME_MT_editor_menus.append(ui.BFA_MT_timeline_key.menu_func)

## 3D View Editor
bpy.types.VIEW3D_MT_object_animation.append(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.VIEW3D_MT_object_animation.append(operators.BFA_OT_insertframe_right.menu_func)

## Dopesheet Editor
bpy.types.DOPESHEET_MT_key.append(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.DOPESHEET_MT_key.append(operators.BFA_OT_insertframe_right.menu_func)

## Graph Editor
bpy.types.GRAPH_MT_key.append(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.GRAPH_MT_key.append(operators.BFA_OT_insertframe_right.menu_func)

## Timeline Editor
bpy.types.BFA_MT_timeline_key.append(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.BFA_MT_timeline_key.append(operators.BFA_OT_insertframe_right.menu_func)


# Register other classes and properties...
bpy.utils.register_class(preferences.BFA_UI_preferences)
bpy.utils.register_class(properties.BFA_UI_toggles)

# Register the toggles
bpy.types.WindowManager.BFA_UI_addon_props = bpy.props.PointerProperty(type=properties.BFA_UI_toggles)

def unregister():
# Unregister operators
for operator in op_list:
bpy.utils.unregister_class(operator)

## 3D View Editor
bpy.types.VIEW3D_MT_object_animation.remove(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.VIEW3D_MT_object_animation.remove(operators.BFA_OT_insertframe_right.menu_func)

## Dopesheet Editor
bpy.types.DOPESHEET_MT_key.remove(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.DOPESHEET_MT_key.remove(operators.BFA_OT_insertframe_right.menu_func)

## Graph Editor
bpy.types.GRAPH_MT_key.remove(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.GRAPH_MT_key.remove(operators.BFA_OT_insertframe_right.menu_func)

## Timeline Editor
bpy.types.BFA_MT_timeline_key.remove(operators.BFA_OT_insertframe_left.menu_func)
bpy.types.BFA_MT_timeline_key.remove(operators.BFA_OT_insertframe_right.menu_func)

# Unregister other classes and properties...
bpy.utils.unregister_class(preferences.BFA_UI_preferences)
bpy.utils.unregister_class(properties.BFA_UI_toggles)

# Unregister custom menus, notice this comes last. First unregister operators, then menus
bpy.utils.unregister_class(ui.BFA_MT_timeline_key)
bpy.types.TIME_MT_editor_menus.remove(ui.BFA_MT_timeline_key.menu_func)

# Unregister the toggles
del bpy.types.WindowManager.BFA_UI_addon_props

if __name__ == "__main__":
register()
115 changes: 115 additions & 0 deletions scripts/addons/bfa_power_user_tools/operators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# 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 3 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
# MERCHANTIBILITY 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, see <http://www.gnu.org/licenses/>.

# my_operator.py
import bpy

op = bpy.types.Operator

################## Animation Operators ##################

class BFA_OT_insertframe_left(op):
bl_idname = "anim.insertframe_left"
bl_label = "Insert Frame Left"
bl_description = "Inserts an empty frame and nudges all keyframes to the left of the time cursor"
bl_icon = 'TRIA_LEFT'

def execute(self, context):
# Get the current frame
current_frame = bpy.context.scene.frame_current

# Get all selected objects
selected_objects = bpy.context.selected_objects

# Iterate over each selected object
for obj in selected_objects:
# Check if the object has animation data
if obj.animation_data and obj.animation_data.action:
# Iterate over each fcurve in the action
for fcurve in obj.animation_data.action.fcurves:
# Iterate over each keyframe point in the fcurve
for keyframe in fcurve.keyframe_points:
# If the keyframe is after the current frame
if keyframe.co.x < current_frame:
# Nudge the key frame one frame backward
keyframe.co.x -= 1

# Check if the object is a grease pencil object
if obj.type == 'GPENCIL':
# Iterate over each layer in the grease pencil object
for layer in obj.data.layers:
# Iterate over each frame in the layer
for frame in layer.frames:
# If the frame is after the current frame
if frame.frame_number < current_frame:
# Nudge the frame one frame backward
frame.frame_number -= 1

# Update the scene
bpy.context.scene.frame_set(current_frame)
return {'FINISHED'}

def menu_func(self, context):
wm = context.window_manager
if wm.BFA_UI_addon_props.BFA_PROP_toggle_insertkeyframes:
self.layout.operator(BFA_OT_insertframe_left.bl_idname, icon=BFA_OT_insertframe_left.bl_icon)


class BFA_OT_insertframe_right(op):
bl_idname = "anim.insertframe_right"
bl_label = "Insert Frame Right"
bl_description = "Inserts an empty frame and nudges all keyframes to the right of the time cursor"
bl_icon = 'TRIA_RIGHT'

def execute(self, context):
# Get the current frame
current_frame = bpy.context.scene.frame_current

# Get all selected objects
selected_objects = bpy.context.selected_objects

# Iterate over each selected object
for obj in selected_objects:
# Check if the object has animation data
if obj.animation_data and obj.animation_data.action:
# Iterate over each fcurve in the action
for fcurve in obj.animation_data.action.fcurves:
# Iterate over each keyframe point in the fcurve
for keyframe in fcurve.keyframe_points:
# If the keyframe is after the current frame
if keyframe.co.x > current_frame:
# Nudge the key frame one frame backward
keyframe.co.x += 1

# Check if the object is a grease pencil object
if obj.type == 'GPENCIL':
# Iterate over each layer in the grease pencil object
for layer in obj.data.layers:
# Iterate over each frame in the layer
for frame in layer.frames:
# If the frame is after the current frame
if frame.frame_number > current_frame:
# Nudge the frame one frame backward
frame.frame_number += 1

# Update the scene
bpy.context.scene.frame_set(current_frame)
return {'FINISHED'}

def menu_func(self, context):
wm = context.window_manager
if wm.BFA_UI_addon_props.BFA_PROP_toggle_insertkeyframes:
self.layout.operator(BFA_OT_insertframe_right.bl_idname, icon=BFA_OT_insertframe_right.bl_icon)



31 changes: 31 additions & 0 deletions scripts/addons/bfa_power_user_tools/preferences.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 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 3 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
# MERCHANTIBILITY 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, see <http://www.gnu.org/licenses/>.


import bpy

class BFA_UI_preferences(bpy.types.AddonPreferences):
bl_idname = __package__

def draw(self, context):
layout = self.layout

row = layout.row()
row.scale_y = 1.5

wm = context.window_manager

row = layout.row()
col = row.column(align=True)
col.label(text="Animation:", icon="TIME")
layout.prop(wm.BFA_UI_addon_props, "BFA_PROP_toggle_insertkeyframes")
18 changes: 18 additions & 0 deletions scripts/addons/bfa_power_user_tools/properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 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 3 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
# MERCHANTIBILITY 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, see <http://www.gnu.org/licenses/>.

import bpy

class BFA_UI_toggles(bpy.types.PropertyGroup):
BFA_PROP_toggle_insertkeyframes: bpy.props.BoolProperty(name='Insert Keyframes', description='Adds operators to insert a blank keyframe to the left or right of the timeline.\nLocated in the 3D View, Timeline, Dopesheet, and Graph editors', default=True)

35 changes: 35 additions & 0 deletions scripts/addons/bfa_power_user_tools/ui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 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 3 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
# MERCHANTIBILITY 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, see <http://www.gnu.org/licenses/>.


import bpy

class BFA_MT_timeline_key(bpy.types.Menu):
bl_idname = "BFA_MT_timeline_key"
bl_label = "Key"

def draw(self, context):
layout = self.layout
layout.separator()
'''
wm = context.window_manager
if wm.BFA_UI_addon_props.BFA_PROP_toggle_insertkeyframes:
layout.operator(operators.BFA_OT_insertframe_left).menu_func
layout.operator(operators.BFA_OT_insertframe_right).menu_func
'''

def menu_func(self, context):
wm = context.window_manager
if wm.BFA_UI_addon_props.BFA_PROP_toggle_insertkeyframes:
self.layout.menu(BFA_MT_timeline_key.bl_idname)