[fix] recursive selections

This commit is contained in:
jrkb 2025-05-31 19:53:37 +02:00
parent d61607c75d
commit 6160b99c93
2 changed files with 46 additions and 108 deletions

View file

@ -269,8 +269,9 @@ class ABC3D_data(bpy.types.PropertyGroup):
)
def active_text_index_update(self, context):
lock_depsgraph_updates()
if self.active_text_index != -1:
text_properties = butils.get_text_properties(
text_properties = butils.get_text_properties_by_index(
self.active_text_index, context.scene
)
if text_properties is not None:
@ -278,16 +279,20 @@ class ABC3D_data(bpy.types.PropertyGroup):
# active_text_index changed. so let's update the selection
# check if it is already selected
# or perhaps one of the glyphs
if (
o is not None
and not o.select_get()
and not len([c for c in o.children if c.select_get()]) > 0
if os is not None and not butils.is_or_has_parent(
context.active_object, o
):
# if (
# o is not None
# and not o.select_get()
# and not len([c for c in o.children if c.select_get()]) > 0
# ):
bpy.ops.object.select_all(action="DESELECT")
o.select_set(True)
context.view_layer.objects.active = o
# else:
# print("already selected")
unlock_depsgraph_updates()
# else:
# print("already selected")
active_text_index: bpy.props.IntProperty(update=active_text_index_update)
@ -487,99 +492,6 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
bl_region_type = "UI"
bl_options = {"DEFAULT_CLOSED"}
# TODO: perhaps this should be done in a periodic timer
@classmethod
def poll(self, context):
scene = context.scene
abc3d_data = scene.abc3d_data
# TODO: update available_texts
def update():
if bpy.context.screen.is_animation_playing:
return
active_text_index = -1
remove_list = []
for i, t in enumerate(abc3d_data.available_texts):
if type(t.text_object) == type(None):
remove_list.append(i)
continue
remove_me = True
for c in t.text_object.children:
if (
len(c.users_collection) > 0
and not isinstance(c.get(f"{utils.prefix()}_text_id"), None)
and c.get(f"{utils.prefix()}_text_id") == t.text_id
):
remove_me = False
# not sure how to solve this reliably atm,
# we need to reassign the glyph, but also get the proper properties from glyph_properties
# these might be there in t.glyphs, but linked to removed objects
# or they might be lost
if type(
next(
(
g
for g in t.glyphs
if type(g.glyph_object) == type(None)
),
None,
)
) == type(None):
g = next(
(
g
for g in t.glyphs
if type(g.glyph_object) == type(None)
),
None,
)
# for g in t.glyphs:
# if type(g) == type(None):
# print("IS NONE")
# if type(g.glyph_object) == type(None):
# print("go IS NONE")
# else:
# if g.glyph_object == c:
# # print(g.glyph_object.name)
# pass
if remove_me:
remove_list.append(i)
for i in remove_list:
if abc3d_data.available_texts[i].text_object is not None:
mom = abc3d_data.available_texts[i].text_object
def delif(o, p):
if p in o:
del o[p]
delif(mom, f"{utils.prefix()}_text_id")
delif(mom, f"{utils.prefix()}_font_name")
delif(mom, f"{utils.prefix()}_face_name")
delif(mom, f"{utils.prefix()}_font_size")
delif(mom, f"{utils.prefix()}_letter_spacing")
delif(mom, f"{utils.prefix()}_orientation")
delif(mom, f"{utils.prefix()}_translation")
delif(mom, f"{utils.prefix()}_offset")
abc3d_data.available_texts.remove(i)
for i, t in enumerate(abc3d_data.available_texts):
if context.active_object == t.text_object:
active_text_index = i
if (
hasattr(context.active_object, "parent")
and context.active_object.parent == t.text_object
):
active_text_index = i
if active_text_index != abc3d_data.active_text_index:
abc3d_data.active_text_index = active_text_index
# butils.run_in_main_thread(update)
return True
def draw(self, context):
layout = self.layout
wm = context.window_manager
@ -1234,7 +1146,7 @@ class ABC3D_OT_RemoveText(bpy.types.Operator):
def execute(self, context):
abc3d_data = context.scene.abc3d_data
lock_depsgraph_updates(auto_unlock_s=-1)
lock_depsgraph_updates()
if abc3d_data.active_text_index < 0:
butils.ShowMessageBox(
title="No text selected",
@ -1354,10 +1266,7 @@ class ABC3D_OT_PlaceText(bpy.types.Operator):
distribution_type = "DEFAULT"
text_id = 0
for i, tt in enumerate(abc3d_data.available_texts):
while text_id == tt.text_id:
text_id = text_id + 1
text_id = butils.find_free_text_id()
t = abc3d_data.available_texts.add()
# If you wish to set a value and not fire an update, set the id property.
# A property defined via bpy.props for example ob.prop is stored as ob["prop"] once set to non default.
@ -1907,13 +1816,33 @@ def compare_text_object_with_object(t, o, strict=False):
def link_text_object_with_new_text_properties(text_object, scene=None):
lock_depsgraph_updates(auto_unlock_s=-1)
lock_depsgraph_updates()
butils.link_text_object_with_new_text_properties(text_object, scene)
unlock_depsgraph_updates()
def determine_active_text_index_from_selection():
if bpy.context.active_object is None:
return -1
for text_index, text_properties in enumerate(
bpy.context.scene.abc3d_data.available_texts
):
if butils.is_text_object_legit(text_properties.text_object):
if butils.is_or_has_parent(
bpy.context.active_object, text_properties.text_object
):
return text_index
return -1
def update_active_text_index():
text_index = determine_active_text_index_from_selection()
if text_index != bpy.context.scene.abc3d_data.active_text_index:
bpy.context.scene.abc3d_data.active_text_index = text_index
def detect_text():
lock_depsgraph_updates(auto_unlock_s=-1)
lock_depsgraph_updates()
scene = bpy.context.scene
abc3d_data = scene.abc3d_data
required_keys = [
@ -2015,7 +1944,7 @@ def unlock_depsgraph_updates():
depsgraph_updates_locked -= 1
def lock_depsgraph_updates(auto_unlock_s=1):
def lock_depsgraph_updates(auto_unlock_s=-1):
global depsgraph_updates_locked
depsgraph_updates_locked += 1
if auto_unlock_s >= 0:
@ -2059,6 +1988,7 @@ def on_depsgraph_update(scene, depsgraph):
# must be a new thing, maybe manually created or so
link_text_object_with_new_text_properties(u.id.original, scene)
butils.clean_text_properties()
update_active_text_index()
unlock_depsgraph_updates()

View file

@ -1184,6 +1184,14 @@ def get_text_properties(text_id, scene=None):
return t
return None
def get_text_properties_by_index(text_index, scene=None):
if scene is None:
scene = bpy.context.scene
abc3d_data = scene.abc3d_data
if text_index >= len(abc3d_data.available_texts):
return None
return abc3d_data.available_texts[text_index]
def duplicate(
obj,