keyframe jump autobind
0.9.3: - feat: keyframe jump keys are now auto-binded - UI: added keyframe jump customisation in addon pref - code: split keyframe jump in a separate file with his new key updatergpv2
parent
3bb7cd5690
commit
6774484226
|
@ -32,82 +32,6 @@ class GPTB_OT_flipx_view(bpy.types.Operator):
|
||||||
context.scene.camera.scale.x *= -1
|
context.scene.camera.scale.x *= -1
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class GPTB_OT_jump_gp_keyframe(bpy.types.Operator):
|
|
||||||
bl_idname = "screen.gp_keyframe_jump"
|
|
||||||
bl_label = "Jump to GPencil keyframe"
|
|
||||||
bl_description = "Jump to prev/next keyframe on active and selected layers of active grease pencil object"
|
|
||||||
bl_options = {"REGISTER"}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
return context.object and context.object.type == 'GPENCIL'
|
|
||||||
|
|
||||||
next : bpy.props.BoolProperty(
|
|
||||||
name="Next GP keyframe", description="Go to next active GP keyframe", default=True)
|
|
||||||
|
|
||||||
target : bpy.props.EnumProperty(
|
|
||||||
name="Target layer", description="Choose wich layer to evaluate for keyframe change", default='ACTIVE',# options={'ANIMATABLE'}, update=None, get=None, set=None,
|
|
||||||
items=(
|
|
||||||
('ACTIVE', 'Active and selected', 'jump in keyframes of active and other selected layers ', 0),
|
|
||||||
('VISIBLE', 'Visibles layers', 'jump in keyframes of visibles layers', 1),
|
|
||||||
('ACCESSIBLE', 'Visible and unlocked layers', 'jump in keyframe of all layers', 2),
|
|
||||||
))
|
|
||||||
#(key, label, descr, id[, icon])
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
if not context.object.data.layers.active:
|
|
||||||
self.report({'ERROR'}, 'No active layer on current GPencil object')
|
|
||||||
return {"CANCELLED"}
|
|
||||||
|
|
||||||
layer = []
|
|
||||||
if self.target == 'ACTIVE':
|
|
||||||
gpl = [l for l in context.object.data.layers if l.select and not l.hide]
|
|
||||||
if not context.object.data.layers.active in gpl:
|
|
||||||
gpl.append(context.object.data.layers.active)
|
|
||||||
|
|
||||||
elif self.target == 'VISIBLE':
|
|
||||||
gpl = [l for l in context.object.data.layers if not l.hide]
|
|
||||||
|
|
||||||
elif self.target == 'ACCESSIBLE':
|
|
||||||
gpl = [l for l in context.object.data.layers if not l.hide and not l.lock]
|
|
||||||
|
|
||||||
|
|
||||||
current = context.scene.frame_current
|
|
||||||
p = n = None
|
|
||||||
|
|
||||||
mins = []
|
|
||||||
maxs = []
|
|
||||||
for l in gpl:
|
|
||||||
for f in l.frames:
|
|
||||||
if f.frame_number < current:
|
|
||||||
p = f.frame_number
|
|
||||||
if f.frame_number > current:
|
|
||||||
n = f.frame_number
|
|
||||||
break
|
|
||||||
mins.append(p)
|
|
||||||
maxs.append(n)
|
|
||||||
p = n = None
|
|
||||||
|
|
||||||
mins = [i for i in mins if i is not None]
|
|
||||||
maxs = [i for i in maxs if i is not None]
|
|
||||||
|
|
||||||
if mins:
|
|
||||||
p = max(mins)
|
|
||||||
if maxs:
|
|
||||||
n = min(maxs)
|
|
||||||
|
|
||||||
if self.next and n is not None:
|
|
||||||
context.scene.frame_set(n)
|
|
||||||
elif not self.next and p is not None:
|
|
||||||
context.scene.frame_set(p)
|
|
||||||
else:
|
|
||||||
self.report({'INFO'}, 'No keyframe in this direction')
|
|
||||||
return {"CANCELLED"}
|
|
||||||
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class GPTB_OT_rename_data_from_obj(bpy.types.Operator):
|
class GPTB_OT_rename_data_from_obj(bpy.types.Operator):
|
||||||
bl_idname = "gp.rename_data_from_obj"
|
bl_idname = "gp.rename_data_from_obj"
|
||||||
bl_label = "Rename GP from object"
|
bl_label = "Rename GP from object"
|
||||||
|
@ -528,7 +452,6 @@ class GPTB_OT_overlay_presets(bpy.types.Operator):
|
||||||
classes = (
|
classes = (
|
||||||
GPTB_OT_copy_text,
|
GPTB_OT_copy_text,
|
||||||
GPTB_OT_flipx_view,
|
GPTB_OT_flipx_view,
|
||||||
GPTB_OT_jump_gp_keyframe,
|
|
||||||
GPTB_OT_rename_data_from_obj,
|
GPTB_OT_rename_data_from_obj,
|
||||||
GPTB_OT_draw_cam,
|
GPTB_OT_draw_cam,
|
||||||
GPTB_OT_set_view_as_cam,
|
GPTB_OT_set_view_as_cam,
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
import bpy
|
||||||
|
from .utils import get_addon_prefs
|
||||||
|
|
||||||
|
class GPTB_OT_jump_gp_keyframe(bpy.types.Operator):
|
||||||
|
bl_idname = "screen.gp_keyframe_jump"
|
||||||
|
bl_label = "Jump to GPencil keyframe"
|
||||||
|
bl_description = "Jump to prev/next keyframe on active and selected layers of active grease pencil object"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.object and context.object.type == 'GPENCIL'
|
||||||
|
|
||||||
|
next : bpy.props.BoolProperty(
|
||||||
|
name="Next GP keyframe", description="Go to next active GP keyframe", default=True)
|
||||||
|
|
||||||
|
target : bpy.props.EnumProperty(
|
||||||
|
name="Target layer", description="Choose wich layer to evaluate for keyframe change", default='ACTIVE',# options={'ANIMATABLE'}, update=None, get=None, set=None,
|
||||||
|
items=(
|
||||||
|
('ACTIVE', 'Active and selected', 'jump in keyframes of active and other selected layers ', 0),
|
||||||
|
('VISIBLE', 'Visibles layers', 'jump in keyframes of visibles layers', 1),
|
||||||
|
('ACCESSIBLE', 'Visible and unlocked layers', 'jump in keyframe of all layers', 2),
|
||||||
|
))
|
||||||
|
#(key, label, descr, id[, icon])
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
if not context.object.data.layers.active:
|
||||||
|
self.report({'ERROR'}, 'No active layer on current GPencil object')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
if self.target == 'ACTIVE':
|
||||||
|
gpl = [l for l in context.object.data.layers if l.select and not l.hide]
|
||||||
|
if not context.object.data.layers.active in gpl:
|
||||||
|
gpl.append(context.object.data.layers.active)
|
||||||
|
|
||||||
|
elif self.target == 'VISIBLE':
|
||||||
|
gpl = [l for l in context.object.data.layers if not l.hide]
|
||||||
|
|
||||||
|
elif self.target == 'ACCESSIBLE':
|
||||||
|
gpl = [l for l in context.object.data.layers if not l.hide and not l.lock]
|
||||||
|
|
||||||
|
|
||||||
|
current = context.scene.frame_current
|
||||||
|
p = n = None
|
||||||
|
|
||||||
|
mins = []
|
||||||
|
maxs = []
|
||||||
|
for l in gpl:
|
||||||
|
for f in l.frames:
|
||||||
|
if f.frame_number < current:
|
||||||
|
p = f.frame_number
|
||||||
|
if f.frame_number > current:
|
||||||
|
n = f.frame_number
|
||||||
|
break
|
||||||
|
mins.append(p)
|
||||||
|
maxs.append(n)
|
||||||
|
p = n = None
|
||||||
|
|
||||||
|
mins = [i for i in mins if i is not None]
|
||||||
|
maxs = [i for i in maxs if i is not None]
|
||||||
|
|
||||||
|
if mins:
|
||||||
|
p = max(mins)
|
||||||
|
if maxs:
|
||||||
|
n = min(maxs)
|
||||||
|
|
||||||
|
if self.next and n is not None:
|
||||||
|
context.scene.frame_set(n)
|
||||||
|
elif not self.next and p is not None:
|
||||||
|
context.scene.frame_set(p)
|
||||||
|
else:
|
||||||
|
self.report({'INFO'}, 'No keyframe in this direction')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class KFJ_OT_rebinder(bpy.types.Operator):
|
||||||
|
bl_idname = "prefs.shortcut_rebinder"
|
||||||
|
bl_label = "rebind keyframe jump shortcut"
|
||||||
|
bl_options = {'REGISTER', 'INTERNAL'}
|
||||||
|
|
||||||
|
s_keycode: bpy.props.StringProperty()
|
||||||
|
s_ctrl: bpy.props.StringProperty()
|
||||||
|
s_shift: bpy.props.StringProperty()
|
||||||
|
s_alt: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
self.prefs = get_addon_prefs()
|
||||||
|
|
||||||
|
self.init_value = getattr(self.prefs, self.s_keycode)
|
||||||
|
setattr(self.prefs, self.s_keycode, '')
|
||||||
|
context.window_manager.modal_handler_add(self)
|
||||||
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
def modal(self, context, event):
|
||||||
|
exclude_keys = {'MOUSEMOVE', 'INBETWEEN_MOUSEMOVE',
|
||||||
|
'TIMER_REPORT', 'ESC', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}
|
||||||
|
exclude_in = ('SHIFT', 'CTRL', 'ALT')
|
||||||
|
|
||||||
|
if event.type == 'ESC':
|
||||||
|
setattr(self.prefs, self.s_keycode, self.init_value)
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
if event.type not in exclude_keys and not any(x in event.type for x in exclude_in):
|
||||||
|
print('key:', event.type, 'value:', event.value)
|
||||||
|
if event.value == 'PRESS':
|
||||||
|
self.report({'INFO'}, event.type)
|
||||||
|
|
||||||
|
setattr(self.prefs, self.s_shift, event.shift)
|
||||||
|
setattr(self.prefs, self.s_alt, event.alt)
|
||||||
|
setattr(self.prefs, self.s_ctrl, event.ctrl)
|
||||||
|
setattr(self.prefs, self.s_keycode, event.type)
|
||||||
|
|
||||||
|
# -# maybe add an autorebind trigger at keycode propertie level
|
||||||
|
# -# now dependent of register function within the scope of the file...
|
||||||
|
|
||||||
|
# auto_rebind()
|
||||||
|
unregister_keymaps()
|
||||||
|
register_keymaps()
|
||||||
|
|
||||||
|
context.area.tag_redraw()# seems to do nothing, have to move the mouse to update
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
|
||||||
|
""" class KFJ_OT_rebind(bpy.types.Operator):
|
||||||
|
bl_idname = "prefs.rebind_kfj_shortcut"
|
||||||
|
bl_label = "rebind keyframe jump shortcut"
|
||||||
|
bl_options = {'REGISTER', 'INTERNAL'}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
unregister_keymaps()
|
||||||
|
register_keymaps()
|
||||||
|
return{'FINISHED'} """
|
||||||
|
|
||||||
|
addon_keymaps = []
|
||||||
|
def register_keymaps():
|
||||||
|
pref = get_addon_prefs()
|
||||||
|
if not pref.kfj_use_shortcut:
|
||||||
|
return
|
||||||
|
addon = bpy.context.window_manager.keyconfigs.addon
|
||||||
|
km = addon.keymaps.new(name = "Screen", space_type = "EMPTY")
|
||||||
|
|
||||||
|
kmi = km.keymap_items.new('screen.gp_keyframe_jump', type=pref.kfj_next_keycode, value="PRESS", alt=pref.kfj_next_alt, ctrl=pref.kfj_next_ctrl, shift=pref.kfj_next_shift, any=False)
|
||||||
|
kmi.properties.next = True
|
||||||
|
addon_keymaps.append((km, kmi))
|
||||||
|
kmi = km.keymap_items.new('screen.gp_keyframe_jump', type=pref.kfj_prev_keycode, value="PRESS", alt=pref.kfj_prev_alt, ctrl=pref.kfj_prev_ctrl, shift=pref.kfj_prev_shift, any=False)
|
||||||
|
kmi.properties.next = False
|
||||||
|
addon_keymaps.append((km, kmi))
|
||||||
|
|
||||||
|
def unregister_keymaps():
|
||||||
|
# print('UNBIND CANVAS ROTATE KEYMAPS')#Dbg
|
||||||
|
for km, kmi in addon_keymaps:
|
||||||
|
km.keymap_items.remove(kmi)
|
||||||
|
addon_keymaps.clear()
|
||||||
|
# del addon_keymaps[:]
|
||||||
|
|
||||||
|
|
||||||
|
classes = (
|
||||||
|
KFJ_OT_rebinder,
|
||||||
|
GPTB_OT_jump_gp_keyframe,
|
||||||
|
)
|
||||||
|
|
||||||
|
def register():
|
||||||
|
if not bpy.app.background:
|
||||||
|
for cls in classes:
|
||||||
|
bpy.utils.register_class(cls)
|
||||||
|
register_keymaps()
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
if not bpy.app.background:
|
||||||
|
unregister_keymaps()
|
||||||
|
for cls in reversed(classes):
|
||||||
|
bpy.utils.unregister_class(cls)
|
20
README.md
20
README.md
|
@ -29,6 +29,12 @@ Set path to the palette folder (there is a json palette IO but you an also put a
|
||||||
Note about palette : For now the importer is not working with linked palette as it's not easy for animator (there are properties of the material you cannot access and the link grey-out fade the real color in UIlist preview)
|
Note about palette : For now the importer is not working with linked palette as it's not easy for animator (there are properties of the material you cannot access and the link grey-out fade the real color in UIlist preview)
|
||||||
|
|
||||||
|
|
||||||
|
### Passive action
|
||||||
|
|
||||||
|
Add an "on save" Handler that trigger relative remap of all path.
|
||||||
|
|
||||||
|
### function
|
||||||
|
|
||||||
- Mirror flip : If in cam view flip the camera X scale value (you can see and draw mnirrored to see problems)
|
- Mirror flip : If in cam view flip the camera X scale value (you can see and draw mnirrored to see problems)
|
||||||
|
|
||||||
<!-- - Overlay toggle : (toggle pref and overlay) -->
|
<!-- - Overlay toggle : (toggle pref and overlay) -->
|
||||||
|
@ -43,9 +49,10 @@ Note about palette : For now the importer is not working with linked palette as
|
||||||
|
|
||||||
- can auto launch and/or auto open folder at finished (option in addon preferences)
|
- can auto launch and/or auto open folder at finished (option in addon preferences)
|
||||||
|
|
||||||
- jump to GP keyframe operator
|
- Jump to GP keyframe :
|
||||||
|
|
||||||
- you need to set two keymap shortcut in _windows_ or _screen(global)_ with indentifier `screen.gp_keyframe_jump`
|
- Choose key to Auto bind in addon prefs (since 0.9.3).
|
||||||
|
> Manual setup: Add two keymap shortcut in _windows_ or _screen(global)_ with indentifier `screen.gp_keyframe_jump`, one should have `next` toggled off to jump back
|
||||||
|
|
||||||
- Rotate canvas with a clic + modifier combo (default is `ctrl + alt + MID-mouse`), can be change in addon preferences.
|
- Rotate canvas with a clic + modifier combo (default is `ctrl + alt + MID-mouse`), can be change in addon preferences.
|
||||||
|
|
||||||
|
@ -96,10 +103,17 @@ Panel in sidebar : 3D view > sidebar 'N' > Gpencil
|
||||||
|
|
||||||
## Changelog:
|
## Changelog:
|
||||||
|
|
||||||
|
0.9.3:
|
||||||
|
|
||||||
|
- feat: keyframe jump keys are now auto-binded
|
||||||
|
- UI: added keyframe jump customisation in addon pref
|
||||||
|
- code: split keyframe jump in a separate file with his new key updater
|
||||||
|
|
||||||
0.9.2:
|
0.9.2:
|
||||||
|
|
||||||
- doc: Correct download link (important, bugged the addon install) + update
|
- doc: Correct download link (important, bugged the addon install) + update
|
||||||
- updater: remove updater temp file, reset minimum version
|
- code: added tracker url
|
||||||
|
- updater: remove updater temp file, reset minimum version, turn off verbose mode
|
||||||
|
|
||||||
0.9.1:
|
0.9.1:
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,9 @@ Expose les options suivantes:
|
||||||
|
|
||||||
**Edit line opacity** - Il est pratique de pouvoir cacher l'edit line pour avoir un meilleur aperçu du rendu lors du sculpt par exemple. C'est une option lié au layer. Ce slider appelle une fonction pour affecter tout les layers de tout les objets au lieu de se cantonner au layer courant.
|
**Edit line opacity** - Il est pratique de pouvoir cacher l'edit line pour avoir un meilleur aperçu du rendu lors du sculpt par exemple. C'est une option lié au layer. Ce slider appelle une fonction pour affecter tout les layers de tout les objets au lieu de se cantonner au layer courant.
|
||||||
|
|
||||||
|
### Action passive
|
||||||
|
|
||||||
|
- Ajoute un handler qui déclenche un remmapage des chemins en relatif à chaque sauvegarde.
|
||||||
### Tools principaux d'anim:
|
### Tools principaux d'anim:
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ L'action cam (peut-être renommé en follow_cam ?) fonctionne sur le même princ
|
||||||
|
|
||||||
**Box deform** (`Ctrl+T`) - Déformation 4 coins (Déjà dans _Grease pencil tools_ donc a potentiellement retirer pour éviter de possible confits/redondances, mais d'un autre côté la version intégrée peut être customisée et corriger d'éventuel souci sans attendre les updates de la version native...)
|
**Box deform** (`Ctrl+T`) - Déformation 4 coins (Déjà dans _Grease pencil tools_ donc a potentiellement retirer pour éviter de possible confits/redondances, mais d'un autre côté la version intégrée peut être customisée et corriger d'éventuel souci sans attendre les updates de la version native...)
|
||||||
|
|
||||||
**GP keyframe jump** (raccourci a ajouter manuellement, tant qu'on a pas une keymap anim un minimum standard) - Essentiel ! Permet d'ajouter une ou plusieurs paire de raccourcis pour aller de keyframe en keyframe (filtrage du saut personnalisable). Le raccourci doit appeler l'operateur `screen.gp_keyframe_jump`, (en ajouter un second avec le `next` décoché pour faire un saut arrière)
|
**GP keyframe jump** (auto bind et personnalisable dans les addon prefs depuis 0.9.3) - Essentiel ! Permet d'ajouter une ou plusieurs paire de raccourcis pour aller de keyframe en keyframe (filtrage du saut personnalisable). Lance l'operateur `screen.gp_keyframe_jump`, (si ajout manuel, rajouter une seconde keymap avec la propriété `next` décoché pour faire un saut arrière)
|
||||||
|
|
||||||
**Breakdown en mode objet** (`Shift+E`) - Breakdown en pourcentage entre les deux keyframes (pose une clé si l’auto-key est actif et utilise le keying set si actif). Même comportement et raccourci que le breakdown de bones en pose mode (juste qu'il n'existait bizzarement pas en objet)
|
**Breakdown en mode objet** (`Shift+E`) - Breakdown en pourcentage entre les deux keyframes (pose une clé si l’auto-key est actif et utilise le keying set si actif). Même comportement et raccourci que le breakdown de bones en pose mode (juste qu'il n'existait bizzarement pas en objet)
|
||||||
|
|
||||||
|
|
86
__init__.py
86
__init__.py
|
@ -15,7 +15,7 @@ bl_info = {
|
||||||
"name": "gp toolbox",
|
"name": "gp toolbox",
|
||||||
"description": "Set of tools for Grease Pencil in animation production",
|
"description": "Set of tools for Grease Pencil in animation production",
|
||||||
"author": "Samuel Bernou",
|
"author": "Samuel Bernou",
|
||||||
"version": (0, 9, 2),
|
"version": (0, 9, 3),
|
||||||
"blender": (2, 91, 0),
|
"blender": (2, 91, 0),
|
||||||
"location": "sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
"location": "sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
@ -39,6 +39,7 @@ from . import OP_canvas_rotate
|
||||||
from . import OP_playblast_bg
|
from . import OP_playblast_bg
|
||||||
from . import OP_playblast
|
from . import OP_playblast
|
||||||
from . import OP_helpers
|
from . import OP_helpers
|
||||||
|
from . import OP_keyframe_jump
|
||||||
from . import OP_box_deform
|
from . import OP_box_deform
|
||||||
from . import OP_cursor_snap_canvas
|
from . import OP_cursor_snap_canvas
|
||||||
from . import OP_palettes
|
from . import OP_palettes
|
||||||
|
@ -239,6 +240,52 @@ class GPTB_prefs(bpy.types.AddonPreferences):
|
||||||
max=10000
|
max=10000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
## KF jumper
|
||||||
|
kfj_use_shortcut: BoolProperty(
|
||||||
|
name = "Use Keyframe Jump Shortcut",
|
||||||
|
description = "Auto bind shotcut for keyframe jump (else you can bien manually using 'screen.gp_keyframe_jump' id_name)",
|
||||||
|
default = True)
|
||||||
|
|
||||||
|
kfj_prev_keycode : StringProperty(
|
||||||
|
name="Jump Prev Shortcut",
|
||||||
|
description="Shortcut to trigger previous keyframe jump",
|
||||||
|
default="F5")
|
||||||
|
|
||||||
|
kfj_prev_shift: BoolProperty(
|
||||||
|
name = "Shift",
|
||||||
|
description = "add shift",
|
||||||
|
default = False)
|
||||||
|
|
||||||
|
kfj_prev_alt: BoolProperty(
|
||||||
|
name = "Alt",
|
||||||
|
description = "add alt",
|
||||||
|
default = False)
|
||||||
|
|
||||||
|
kfj_prev_ctrl: BoolProperty(
|
||||||
|
name = "combine with ctrl",
|
||||||
|
description = "add ctrl",
|
||||||
|
default = False)
|
||||||
|
|
||||||
|
kfj_next_keycode : StringProperty(
|
||||||
|
name="Jump Next Shortcut",
|
||||||
|
description="Shortcut to trigger keyframe jump",
|
||||||
|
default="F6")
|
||||||
|
|
||||||
|
kfj_next_shift: BoolProperty(
|
||||||
|
name = "Shift",
|
||||||
|
description = "add shift",
|
||||||
|
default = False)
|
||||||
|
|
||||||
|
kfj_next_alt: BoolProperty(
|
||||||
|
name = "Alt",
|
||||||
|
description = "add alt",
|
||||||
|
default = False)
|
||||||
|
|
||||||
|
kfj_next_ctrl: BoolProperty(
|
||||||
|
name = "combine with ctrl",
|
||||||
|
description = "add ctrl",
|
||||||
|
default = False)
|
||||||
|
|
||||||
## Temp cutter
|
## Temp cutter
|
||||||
# temp_cutter_use_shortcut: BoolProperty(
|
# temp_cutter_use_shortcut: BoolProperty(
|
||||||
# name = "Use temp cutter Shortcut",
|
# name = "Use temp cutter Shortcut",
|
||||||
|
@ -285,6 +332,41 @@ class GPTB_prefs(bpy.types.AddonPreferences):
|
||||||
box.prop(self, 'playblast_auto_play')
|
box.prop(self, 'playblast_auto_play')
|
||||||
box.prop(self, 'playblast_auto_open_folder')
|
box.prop(self, 'playblast_auto_open_folder')
|
||||||
|
|
||||||
|
# box.separator()## Keyframe jumper
|
||||||
|
box = layout.box()
|
||||||
|
box.label(text='Keyframe Jump option:')
|
||||||
|
|
||||||
|
box.prop(self, "kfj_use_shortcut", text='Bind shortcuts')
|
||||||
|
if self.kfj_use_shortcut:
|
||||||
|
prompt = '[TYPE SHORTCUT TO USE (can be with modifiers)]'
|
||||||
|
if self.kfj_prev_keycode:
|
||||||
|
mods = '+'.join([m for m, b in [('Ctrl', self.kfj_prev_ctrl), ('Shift', self.kfj_prev_shift), ('Alt', self.kfj_prev_alt)] if b])
|
||||||
|
text = f'{mods}+{self.kfj_prev_keycode}' if mods else self.kfj_prev_keycode
|
||||||
|
text = f'Jump Keyframe Prev: {text} (Click to change)'
|
||||||
|
else:
|
||||||
|
text = prompt
|
||||||
|
ops = box.operator('prefs.shortcut_rebinder', text=text, icon='FILE_REFRESH')
|
||||||
|
ops.s_keycode = 'kfj_prev_keycode'
|
||||||
|
ops.s_ctrl = 'kfj_prev_ctrl'
|
||||||
|
ops.s_shift = 'kfj_prev_shift'
|
||||||
|
ops.s_alt = 'kfj_prev_alt'
|
||||||
|
|
||||||
|
if self.kfj_next_keycode:
|
||||||
|
mods = '+'.join([m for m, b in [('Ctrl', self.kfj_next_ctrl), ('Shift', self.kfj_next_shift), ('Alt', self.kfj_next_alt)] if b])
|
||||||
|
text = f'{mods}+{self.kfj_next_keycode}' if mods else self.kfj_next_keycode
|
||||||
|
text = f'Jump Keyframe Next: {text} (Click to change)'
|
||||||
|
else:
|
||||||
|
text = prompt
|
||||||
|
ops = box.operator('prefs.shortcut_rebinder', text=text, icon='FILE_REFRESH')
|
||||||
|
ops.s_keycode = 'kfj_next_keycode'
|
||||||
|
ops.s_ctrl = 'kfj_next_ctrl'
|
||||||
|
ops.s_shift = 'kfj_next_shift'
|
||||||
|
ops.s_alt = 'kfj_next_alt'
|
||||||
|
|
||||||
|
else:
|
||||||
|
box.label(text="No Jump hotkey auto set. Following operators needs to be set manually", icon="ERROR")
|
||||||
|
box.label(text="screen.gp_keyframe_jump - preferably in 'screen' category to jump from any editor")
|
||||||
|
|
||||||
# box.separator()## Canvas
|
# box.separator()## Canvas
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
box.label(text='Canvas rotate options:')
|
box.label(text='Canvas rotate options:')
|
||||||
|
@ -386,6 +468,7 @@ def register():
|
||||||
bpy.utils.register_class(cls)
|
bpy.utils.register_class(cls)
|
||||||
OP_box_deform.register()
|
OP_box_deform.register()
|
||||||
OP_helpers.register()
|
OP_helpers.register()
|
||||||
|
OP_keyframe_jump.register()
|
||||||
OP_file_checker.register()
|
OP_file_checker.register()
|
||||||
OP_breakdowner.register()
|
OP_breakdowner.register()
|
||||||
OP_temp_cutter.register()
|
OP_temp_cutter.register()
|
||||||
|
@ -418,6 +501,7 @@ def unregister():
|
||||||
OP_palettes.unregister()
|
OP_palettes.unregister()
|
||||||
OP_file_checker.unregister()
|
OP_file_checker.unregister()
|
||||||
OP_helpers.unregister()
|
OP_helpers.unregister()
|
||||||
|
OP_keyframe_jump.unregister()
|
||||||
OP_breakdowner.unregister()
|
OP_breakdowner.unregister()
|
||||||
OP_temp_cutter.unregister()
|
OP_temp_cutter.unregister()
|
||||||
GP_colorize.unregister()## GP_guided_colorize.
|
GP_colorize.unregister()## GP_guided_colorize.
|
||||||
|
|
Loading…
Reference in New Issue