Add keymaps, specials menu and auto center view checkbox #3

Merged
dupoxy merged 10 commits from add-keymaps into main 2024-09-21 20:42:48 +02:00
Showing only changes of commit 55198533f4 - Show all commits

View File

@ -2,19 +2,35 @@
import bpy
class C3DB_PG_properties(bpy.types.PropertyGroup):
location: bpy.props.FloatVectorProperty(name="Location")
rotation: bpy.props.FloatVectorProperty(name="Rotation")
class C3DB_MT_menu_restore(bpy.types.Menu):
bl_label = "3D Cursor Specials"
bl_idname = "c3db.menu.restore"
def draw(self, context):
layout = self.layout
layout.operator("c3db.restore_next")
layout.operator("c3db.restore_previous")
class C3DB_UL_list(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
def draw_item(
self, context, layout, data, item, icon, active_data, active_propname, index
):
layout.prop(item, "name", text="", emboss=False)
class C3DB_OT_save(bpy.types.Operator):
"""Save 3D Cursor location and rotation"""
bl_idname = "c3db.save"
bl_label = "Save"
bl_options = {'REGISTER', 'UNDO'}
bl_label = "Save 3D Cursor"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
item = context.scene.C3DB_3Dcursors_collection.add()
@ -22,92 +38,125 @@ class C3DB_OT_save(bpy.types.Operator):
item.location = context.scene.cursor.location
item.rotation = context.scene.cursor.rotation_euler
# Select the 3D cursor currently saving from the list
context.scene.C3DB_3Dcursors_index = len(context.scene.C3DB_3Dcursors_collection) - 1
context.scene.C3DB_3Dcursors_index = (
len(context.scene.C3DB_3Dcursors_collection) - 1
)
context.area.tag_redraw() # Add this line to refresh the UI
return {'FINISHED'}
return {"FINISHED"}
class C3DB_OT_restore(bpy.types.Operator):
"""Restore selected 3D Cursor"""
bl_idname = "c3db.restore"
bl_label = "Load"
bl_options = {'REGISTER', 'UNDO'}
bl_label = "Load 3D Cursor"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return bool(context.scene.C3DB_3Dcursors_collection) and context.scene.C3DB_3Dcursors_index < len(context.scene.C3DB_3Dcursors_collection)
return bool(
context.scene.C3DB_3Dcursors_collection
) and context.scene.C3DB_3Dcursors_index < len(
context.scene.C3DB_3Dcursors_collection
)
def execute(self, context):
if context.scene.C3DB_3Dcursors_collection:
item = context.scene.C3DB_3Dcursors_collection[context.scene.C3DB_3Dcursors_index]
item = context.scene.C3DB_3Dcursors_collection[
context.scene.C3DB_3Dcursors_index
]
context.scene.cursor.location = item.location
context.scene.cursor.rotation_euler = item.rotation
if context.scene.c3db_auto_center_view_checkbox:
bpy.ops.view3d.view_center_cursor()
context.area.tag_redraw() # Add this line to refresh the UI
return {'FINISHED'}
class C3DB_OT_restore_and_next(bpy.types.Operator):
"""Restore selected 3D Cursor and go to next one in the list"""
bl_idname = "c3db.restore_and_next"
bl_label = "Load & next"
bl_options = {'REGISTER', 'UNDO'}
return {"FINISHED"}
class C3DB_OT_restore_next(bpy.types.Operator):
"""Go to next 3D Cursor and Restore it"""
bl_idname = "c3db.restore_next"
bl_label = "Load next 3D Cursor"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return bool(context.scene.C3DB_3Dcursors_collection) and len(context.scene.C3DB_3Dcursors_collection) > 1
return (
bool(context.scene.C3DB_3Dcursors_collection)
and len(context.scene.C3DB_3Dcursors_collection) > 1
)
def execute(self, context):
if context.scene.C3DB_3Dcursors_collection:
item = context.scene.C3DB_3Dcursors_collection[context.scene.C3DB_3Dcursors_index]
context.scene.cursor.location = item.location
context.scene.cursor.rotation_euler = item.rotation
if context.scene.c3db_auto_center_view_checkbox:
bpy.ops.view3d.view_center_cursor()
# Select the next valid 3D cursor in the list
C3DB_3Dcursors_collection = context.scene.C3DB_3Dcursors_collection
C3DB_3Dcursors_index = context.scene.C3DB_3Dcursors_index
if C3DB_3Dcursors_index < len(C3DB_3Dcursors_collection) - 1:
context.scene.C3DB_3Dcursors_index = C3DB_3Dcursors_index + 1
elif C3DB_3Dcursors_index == len(C3DB_3Dcursors_collection) - 1:
context.scene.C3DB_3Dcursors_index = 0
context.area.tag_redraw() # Add this line to refresh the UI
return {'FINISHED'}
class C3DB_OT_restore_and_previous(bpy.types.Operator):
"""Restore selected 3D Cursor and go to previous one in the list"""
bl_idname = "c3db.restore_and_previous"
bl_label = "Load & previous"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
return bool(context.scene.C3DB_3Dcursors_collection) and len(context.scene.C3DB_3Dcursors_collection) > 1
def execute(self, context):
context.scene.C3DB_3Dcursors_index = 0
# Restore selected 3D cursor in the list
if context.scene.C3DB_3Dcursors_collection:
item = context.scene.C3DB_3Dcursors_collection[context.scene.C3DB_3Dcursors_index]
item = context.scene.C3DB_3Dcursors_collection[
context.scene.C3DB_3Dcursors_index
]
context.scene.cursor.location = item.location
context.scene.cursor.rotation_euler = item.rotation
if context.scene.c3db_auto_center_view_checkbox:
bpy.ops.view3d.view_center_cursor()
context.area.tag_redraw() # Add this line to refresh the UI
return {"FINISHED"}
class C3DB_OT_restore_previous(bpy.types.Operator):
"""Go to previous 3D Cursor and Restore it"""
bl_idname = "c3db.restore_previous"
bl_label = "Load previous 3D Cursor"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return (
bool(context.scene.C3DB_3Dcursors_collection)
and len(context.scene.C3DB_3Dcursors_collection) > 1
)
def execute(self, context):
# Select the previous valid 3D cursor in the list
C3DB_3Dcursors_collection = context.scene.C3DB_3Dcursors_collection
C3DB_3Dcursors_index = context.scene.C3DB_3Dcursors_index
if C3DB_3Dcursors_index > 0:
context.scene.C3DB_3Dcursors_index = C3DB_3Dcursors_index - 1
elif C3DB_3Dcursors_index == 0:
context.scene.C3DB_3Dcursors_index = len(C3DB_3Dcursors_collection) - 1
context.scene.C3DB_3Dcursors_index = len(C3DB_3Dcursors_collection) - 1
# Restore selected 3D cursor in the list
if context.scene.C3DB_3Dcursors_collection:
item = context.scene.C3DB_3Dcursors_collection[
context.scene.C3DB_3Dcursors_index
]
context.scene.cursor.location = item.location
context.scene.cursor.rotation_euler = item.rotation
if context.scene.c3db_auto_center_view_checkbox:
bpy.ops.view3d.view_center_cursor()
context.area.tag_redraw() # Add this line to refresh the UI
return {'FINISHED'}
return {"FINISHED"}
class C3DB_OT_remove_from_list(bpy.types.Operator):
"""Delete selected 3D Cursor from the list"""
"""Delete selected 3D Cursor"""
bl_idname = "c3db.remove_from_list"
bl_label = "Delete"
bl_options = {'REGISTER', 'UNDO'}
bl_label = "Delete 3D Cursor"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return bool(context.scene.C3DB_3Dcursors_collection) and context.scene.C3DB_3Dcursors_index < len(context.scene.C3DB_3Dcursors_collection)
return bool(
context.scene.C3DB_3Dcursors_collection
) and context.scene.C3DB_3Dcursors_index < len(
context.scene.C3DB_3Dcursors_collection
)
def execute(self, context):
C3DB_3Dcursors_collection = context.scene.C3DB_3Dcursors_collection
@ -121,10 +170,12 @@ class C3DB_OT_remove_from_list(bpy.types.Operator):
elif C3DB_3Dcursors_collection:
context.scene.C3DB_3Dcursors_index = len(C3DB_3Dcursors_collection) - 1
context.area.tag_redraw() # Add this line to refresh the UI
return {'FINISHED'}
return {"FINISHED"}
class C3DB_OT_move_up_list(bpy.types.Operator):
"""Move the selected 3D Cursor up in the list"""
bl_idname = "c3db.move_up_list"
bl_label = "Move 3D Cursor Up the list"
@ -138,16 +189,21 @@ class C3DB_OT_move_up_list(bpy.types.Operator):
collection.move(index, index - 1)
context.scene.C3DB_3Dcursors_index -= 1
context.area.tag_redraw() # Add this line to refresh the UI
return {'FINISHED'}
return {"FINISHED"}
class C3DB_OT_move_down_list(bpy.types.Operator):
"""Move the selected 3D Cursor down in the list"""
bl_idname = "c3db.move_down_list"
bl_label = "Move 3D Cursor Down the list"
@classmethod
def poll(cls, context):
return context.scene.C3DB_3Dcursors_index < len(context.scene.C3DB_3Dcursors_collection) - 1
return (
context.scene.C3DB_3Dcursors_index
< len(context.scene.C3DB_3Dcursors_collection) - 1
)
def execute(self, context):
index = context.scene.C3DB_3Dcursors_index
@ -155,13 +211,14 @@ class C3DB_OT_move_down_list(bpy.types.Operator):
collection.move(index, index + 1)
context.scene.C3DB_3Dcursors_index += 1
context.area.tag_redraw() # Add this line to refresh the UI
return {'FINISHED'}
return {"FINISHED"}
class C3DB_PT_panel(bpy.types.Panel):
bl_label = "3D Cursors 💼"
bl_idname = "C3DB_PT_panel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "View"
bl_parent_id = "VIEW3D_PT_view3d_cursor"
@ -169,57 +226,95 @@ class C3DB_PT_panel(bpy.types.Panel):
layout = self.layout
row = layout.row()
col = row.column()
col.template_list("C3DB_UL_list", "", context.scene, "C3DB_3Dcursors_collection", context.scene, "C3DB_3Dcursors_index", rows=3)
col.template_list(
"C3DB_UL_list",
"",
context.scene,
"C3DB_3Dcursors_collection",
context.scene,
"C3DB_3Dcursors_index",
rows=3,
)
col = row.column(align=True)
col.operator("c3db.save", icon='ADD', text="")
col.operator("c3db.remove_from_list", icon='REMOVE', text="")
col.operator("c3db.save", icon="ADD", text="")
col.operator("c3db.remove_from_list", icon="REMOVE", text="")
col.separator()
if context.scene.C3DB_3Dcursors_collection and context.scene.C3DB_3Dcursors_index < len(context.scene.C3DB_3Dcursors_collection):
col.operator("c3db.move_up_list", icon='TRIA_UP', text="")
col.operator("c3db.move_down_list", icon='TRIA_DOWN', text="")
col.menu("c3db.menu.restore", icon="DOWNARROW_HLT", text="")
col.separator()
if (
context.scene.C3DB_3Dcursors_collection
and context.scene.C3DB_3Dcursors_index
< len(context.scene.C3DB_3Dcursors_collection)
):
col.operator("c3db.move_up_list", icon="TRIA_UP", text="")
col.operator("c3db.move_down_list", icon="TRIA_DOWN", text="")
row = layout.row()
row.operator("c3db.restore")
row.operator("c3db.restore", text="Load")
row.operator("view3d.view_center_cursor", text="Center View")
row.prop(context.scene, "c3db_auto_center_view_checkbox")
row = layout.row()
row.operator("c3db.restore_and_next")
row = layout.row()
row.operator("c3db.restore_and_previous")
classes = (C3DB_PG_properties, C3DB_UL_list, C3DB_OT_save, C3DB_OT_restore, C3DB_OT_restore_and_next, C3DB_OT_restore_and_previous, C3DB_OT_remove_from_list, C3DB_OT_move_up_list, C3DB_OT_move_down_list, C3DB_PT_panel)
classes = (
C3DB_PG_properties,
C3DB_UL_list,
C3DB_MT_menu_restore,
C3DB_OT_save,
C3DB_OT_restore,
C3DB_OT_restore_next,
C3DB_OT_restore_previous,
C3DB_OT_remove_from_list,
C3DB_OT_move_up_list,
C3DB_OT_move_down_list,
C3DB_PT_panel,
)
c3db_keymaps = []
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.C3DB_3Dcursors_collection = bpy.props.CollectionProperty(type=C3DB_PG_properties)
bpy.types.Scene.C3DB_3Dcursors_collection = bpy.props.CollectionProperty(
type=C3DB_PG_properties
)
bpy.types.Scene.C3DB_3Dcursors_index = bpy.props.IntProperty()
bpy.types.Scene.c3db_auto_center_view_checkbox = bpy.props.BoolProperty(
name="",
description="Auto center view on load",
default=False
name="", description="Auto center view on 3D Cursor", default=False
)
wm = bpy.context.window_manager
km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
km = wm.keyconfigs.addon.keymaps.new(name="3D View", space_type="VIEW_3D")
kmi = km.keymap_items.new(C3DB_OT_save.bl_idname, 'S', 'PRESS', ctrl=True, shift=True)
kmi = km.keymap_items.new(
C3DB_OT_save.bl_idname, "S", "PRESS", ctrl=True, shift=True
)
c3db_keymaps.append((km, kmi))
kmi = km.keymap_items.new(C3DB_OT_remove_from_list.bl_idname, 'D', 'PRESS', ctrl=True, shift=True)
kmi = km.keymap_items.new(
C3DB_OT_remove_from_list.bl_idname, "D", "PRESS", ctrl=True, shift=True
)
c3db_keymaps.append((km, kmi))
kmi = km.keymap_items.new(C3DB_OT_restore.bl_idname, 'R', 'PRESS', ctrl=True)
kmi = km.keymap_items.new(C3DB_OT_restore.bl_idname, "R", "PRESS", ctrl=True)
c3db_keymaps.append((km, kmi))
kmi = km.keymap_items.new(C3DB_OT_restore_and_next.bl_idname, 'R', 'PRESS', ctrl=True, shift=True)
kmi = km.keymap_items.new(
C3DB_OT_restore_next.bl_idname, "R", "PRESS", ctrl=True, shift=True
)
c3db_keymaps.append((km, kmi))
kmi = km.keymap_items.new(C3DB_OT_restore_and_previous.bl_idname, 'R', 'PRESS', ctrl=True, shift=True, alt=True)
kmi = km.keymap_items.new(
C3DB_OT_restore_previous.bl_idname,
"R",
"PRESS",
ctrl=True,
shift=True,
alt=True,
)
c3db_keymaps.append((km, kmi))
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
@ -233,5 +328,6 @@ def unregister():
km.keymap_items.remove(kmi)
c3db_keymaps.clear()
if __name__ == "__main__":
register()