From abb61ca6d45ad9cc059a2edd848c21f1229aaed7 Mon Sep 17 00:00:00 2001 From: pullusb Date: Wed, 27 Nov 2024 16:43:41 +0100 Subject: [PATCH] Initial code for better cursor_follow behavior (wip) --- OP_cursor_snap_canvas.py | 49 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/OP_cursor_snap_canvas.py b/OP_cursor_snap_canvas.py index 3135233..dcae665 100644 --- a/OP_cursor_snap_canvas.py +++ b/OP_cursor_snap_canvas.py @@ -2,6 +2,8 @@ import bpy import mathutils from bpy_extras import view3d_utils +from bpy.app.handlers import persistent + from .utils import get_gp_draw_plane, region_to_location, get_view_origin_position ## override all sursor snap shortcut with this in keymap @@ -105,12 +107,12 @@ def swap_keymap_by_id(org_idname, new_idname): k.idname = new_idname -# prev_matrix = mathutils.Matrix() prev_matrix = None # @call_once(bpy.app.handlers.frame_change_post) -def cursor_follow_update(self,context): +## used in properties file to register in boolprop update +def cursor_follow_update(self, context): '''append or remove cursor_follow handler according a boolean''' global prev_matrix # imported in properties to register in boolprop update @@ -155,6 +157,35 @@ def cursor_follow(scene): # store for next use prev_matrix = current_matrix.copy() +prev_active_obj = None + +## Add check for object selection change +def selection_changed(): + """Callback function for selection changes""" + if not bpy.context.scene.gptoolprops.cursor_follow: + return + print('select_changed') + global prev_matrix, prev_active_obj + if prev_active_obj != bpy.context.object: + ## Set stored matrix to active object + prev_matrix = bpy.context.object.matrix_world + prev_active_obj = bpy.context.object + +## Note: Same owner as layer manager (will be removed as well) +def subscribe_object_change(): + subscribe_to = (bpy.types.LayerObjects, 'active') + bpy.msgbus.subscribe_rna( + key=subscribe_to, + # owner of msgbus subcribe (for clearing later) + owner=bpy.types.GreasePencilv3, # <-- attach to ID during it's lifetime. + args=(), + notify=selection_changed, + options={'PERSISTENT'}, + ) + +@persistent +def subscribe_object_change_handler(dummy): + subscribe_object_change() classes = ( GPTB_OT_cusor_snap, @@ -163,14 +194,18 @@ GPTB_OT_cusor_snap, def register(): for cls in classes: bpy.utils.register_class(cls) - # swap_keymap_by_id('view3d.cursor3d','view3d.cursor_snap')#auto swap to custom GP snap wrap + + ## Follow cursor matrix update on object change + # bpy.app.handlers.load_post.append(subscribe_object_change_handler) # select_change + # ## Directly set msgbus to work at first addon activation # select_change + # bpy.app.timers.register(subscribe_object_change, first_interval=1) # select_change - # bpy.app.handlers.frame_change_post.append(cursor_follow) + ## No need to frame_change_post.append(cursor_follow). Added by property update, when activating 'cursor follow' def unregister(): - # bpy.app.handlers.frame_change_post.remove(cursor_follow) + # bpy.app.handlers.load_post.remove(subscribe_object_change_handler) # select_change # swap_keymap_by_id('view3d.cursor_snap','view3d.cursor3d')#Restore normal snap @@ -179,4 +214,6 @@ def unregister(): # force remove handler if it's there at unregister if cursor_follow.__name__ in [hand.__name__ for hand in bpy.app.handlers.frame_change_post]: - bpy.app.handlers.frame_change_post.remove(cursor_follow) \ No newline at end of file + bpy.app.handlers.frame_change_post.remove(cursor_follow) + + bpy.msgbus.clear_by_owner(bpy.types.GreasePencilv3) \ No newline at end of file