Przeglądaj źródła

UI: Widget Socket handle missing socket

in case of missing widgets, the Widget Socket keeps the data around
additionally: the path is now only saved relative to the root
the widget now considers sub-folders in the name
Finally: this commit introduces an idiot check for the widget folder
to prevent the user from freezing Blender with an absurdly large
file system (e.g. the user's home or documents folder).
Joseph Brandenburg 2 miesięcy temu
rodzic
commit
250782343e
3 zmienionych plików z 68 dodań i 9 usunięć
  1. 5 0
      misc_nodes.py
  2. 31 0
      preferences.py
  3. 32 9
      socket_definitions.py

+ 5 - 0
misc_nodes.py

@@ -1275,6 +1275,11 @@ class InputWidget(MantisNode):
         axes_flipped = self.evaluate_input('Flip Axes')
         do_mirror = True
         from os import path as os_path
+        from .preferences import get_bl_addon_object
+        bl_mantis_addon = get_bl_addon_object()
+        widgets_path = bl_mantis_addon.preferences.WidgetsLibraryFolder
+        path = widgets_path+path # this guards the widgets root so the end-user
+        #  can easily change the widgets directory without breaking things
         file_name = os_path.split(path)[-1]
         obj_name = os_path.splitext(file_name)[0]
         obj_name_full = obj_name

+ 31 - 0
preferences.py

@@ -19,6 +19,34 @@ def get_bl_addon_object(raise_error = False):
                     " Please report it on gitlab.")
     return bl_mantis_addon
 
+# Just look and see if it is a ridiculous choice and show an error popup if the user needs
+#    to select a different directory
+def filepath_idiot_test(path):
+    def do_error_popup():
+            def error_popup_draw(self, context):
+                self.layout.label(text="A maximum of 1000 widget files is allowed in the Widget Library.")
+                self.layout.label(text="Make sure the WIdget Library does not scan a huge number of files/folders.")
+            from bpy import context
+            context.window_manager.popup_menu(error_popup_draw, title="Error", icon='ERROR')
+    try:
+        if tot_files := sum([len(files) for r, d, files in os.walk(path)]) > 1000:
+            do_error_popup()
+            return ''
+        else:
+            return path
+    except FileNotFoundError:
+        return ''
+    except RecursionError:
+        do_error_popup()
+        return ''
+    
+
+
+def widget_library_get(self):
+    return self.widget_library_path
+def widget_library_idiot_test(self, value):
+    self.widget_library_path = filepath_idiot_test(value)
+
 class MantisPreferences(bpy.types.AddonPreferences):
     bl_idname = __package__
 
@@ -34,8 +62,11 @@ class MantisPreferences(bpy.types.AddonPreferences):
     #     name = "Seperator file",
     #     subtype = 'FILE_PATH',
     #     default = dir_path + '/preferences/seperator.json',)
+    widget_library_path : bpy.props.StringProperty()
     WidgetsLibraryFolder:bpy.props.StringProperty(
         name = "Widget Library Folder",
+        get=widget_library_get,
+        set=widget_library_idiot_test,
         subtype = 'FILE_PATH',
         default = os.path.join(dir_path, 'widgets'),)
     

+ 32 - 9
socket_definitions.py

@@ -353,6 +353,19 @@ def update_metarig_posebone(self, context,):
     self.node.pose_bone = self.default_value
     default_update(self,context)
 
+def update_socket_external_load(self, context):
+    # this is a socket update for sockets that load data from a pack
+    # e.g. widget, metarig, curve, or component selector sockets
+    # currently no plans to add any but widgets, but whatever
+    default_update(self, context)
+    self.previous_value = self.default_value # this is all I need to do lol
+    items = get_widget_library_items(self, context) # feels silly to do this here
+    for item in items:
+        if item[0] == self.default_value:
+            self.previous_index = item[-1]
+            break
+    
+
 
 
 ########################################################################
@@ -1360,23 +1373,31 @@ class EnumMetaBoneSocket(MantisSocket):
 def get_widget_library_items(self, context):
     from .preferences import get_bl_addon_object
     bl_mantis_addon = get_bl_addon_object()
-    return_value = [('NONE', 'None', 'None', 'ERROR', 0)]
+    from os import path as os_path
+    prev_name = os_path.split(self.previous_value)[-1]
+    default_missing_value = ('MISSING', f'MISSING: {prev_name}', self.previous_value, 'ERROR', self.previous_index)
+    return_value = [default_missing_value]
     widget_names={}
     if bl_mantis_addon:
         widgets_path = bl_mantis_addon.preferences.WidgetsLibraryFolder
-        import os
-        for path_root, dirs, files, in os.walk(widgets_path):
+        from os import walk as os_walk
+        for path_root, dirs, files, in os_walk(widgets_path):
             # TODO handle .blend files
-            # for file in files: # check .blend files first, objs should take precedence
-            #     if file.endswith('.blend'):
-            #         widget_names[file[:-6]] = os.path.join(path_root, file)
             for file in files:
+                relative_file_name = os_path.join(os_path.sep.join(dirs), file)
                 if file.endswith('.obj'):
-                    widget_names[file[:-4]] = os.path.join(path_root, file)
+                    widget_names[relative_file_name[:-4]] = relative_file_name
     if widget_names.keys():
         return_value=[]
+        # first we select the previous value if it exists
+        add_missing_key=False
+        add_one=0
+        if self.previous_value not in widget_names.values():
+            add_missing_key=True # we need to add the missing key at the previous index
         for i, (name, path) in enumerate(widget_names.items()):
-            return_value.append( (path, name, path, 'GIZMO', i) )
+            if add_missing_key and i == self.previous_index:
+                add_one+=1; return_value.append(default_missing_value)
+            return_value.append( (path, name, path, 'GIZMO', i+add_one) )
     return return_value
 
 # THIS is a special socket type that finds the widgets in your widgets library (set in preferences)
@@ -1390,9 +1411,11 @@ class EnumWidgetLibrarySocket(MantisSocket):
         name="Widget",
         description="Which widget to use",
         default = 0,
-        update = update_socket,)
+        update = update_socket_external_load,)
     color_simple = cString
     color : bpy.props.FloatVectorProperty(default=cString, size=4)
+    previous_value : bpy.props.StringProperty(default="")
+    previous_index : bpy.props.IntProperty(default=0)
     def draw(self, context, layout, node, text):
         ChooseDraw(self, context, layout, node, text, use_enum=False)
     def draw_color(self, context, node):