Browse Source

Added simple popups for error/info/warning dialogs
When performing a geometry export of an incorrectly selected node an error dialog will now open instead of the traceback window
Added the dialogs module
Addon version now prints to the log for debugging

repsac 10 years ago
parent
commit
889f42c824

+ 2 - 1
utils/exporters/blender/addons/io_three/__init__.py

@@ -41,7 +41,7 @@ SETTINGS_FILE_EXPORT = 'three_settings_export.js'
 bl_info = {
 bl_info = {
     'name': "Three.js Format",
     'name': "Three.js Format",
     'author': "repsac, mrdoob, yomotsu, mpk, jpweeks",
     'author': "repsac, mrdoob, yomotsu, mpk, jpweeks",
-    'version': (1, 2, 2),
+    'version': (1, 2, 3),
     'blender': (2, 7, 3),
     'blender': (2, 7, 3),
     'location': "File > Export",
     'location': "File > Export",
     'description': "Export Three.js formatted JSON files.",
     'description': "Export Three.js formatted JSON files.",
@@ -693,6 +693,7 @@ class ExportThree(bpy.types.Operator, ExportHelper):
             raise Exception("filename not set")
             raise Exception("filename not set")
 
 
         settings = save_settings_export(self.properties)
         settings = save_settings_export(self.properties)
+        settings['addon_version'] = bl_info['version']
 
 
         filepath = self.filepath
         filepath = self.filepath
         if settings[constants.COMPRESSION] == constants.MSGPACK:
         if settings[constants.COMPRESSION] == constants.MSGPACK:

+ 112 - 0
utils/exporters/blender/addons/io_three/dialogs.py

@@ -0,0 +1,112 @@
+from bpy import context
+
+CONTEXT = {
+    0: {
+        'title': "Error Message",
+        'icon': 'CANCEL'
+    },
+    1: {
+        'title': "Warning Message",
+        'icon': 'ERROR' # I prefer this icon for warnings
+    },
+    2: {
+        'title': "Message",
+        'icon': 'NONE'
+    },
+    3: {
+        'title': "Question",
+        'icon': 'QUESTION'
+    }
+}
+
+
+def error(message, title="", wrap=40):
+    """Creates an error dialog.
+
+    :param message: text of the message body
+    :param title: text to append to the title
+                  (Default value = "")
+    :param wrap: line width (Default value = 40)
+
+    """
+    _draw(message, title, wrap, 0)
+
+
+def warning(message, title="", wrap=40):
+    """Creates an error dialog.
+
+    :param message: text of the message body
+    :param title: text to append to the title
+                  (Default value = "")
+    :param wrap: line width (Default value = 40)
+
+    """
+    _draw(message, title, wrap, 1)
+
+
+
+def info(message, title="", wrap=40):
+    """Creates an error dialog.
+
+    :param message: text of the message body
+    :param title: text to append to the title
+                  (Default value = "")
+    :param wrap: line width (Default value = 40)
+
+    """
+    _draw(message, title, wrap, 2)
+
+
+
+def question(message, title="", wrap=40):
+    """Creates an error dialog.
+
+    :param message: text of the message body
+    :param title: text to append to the title
+                  (Default value = "")
+    :param wrap: line width (Default value = 40)
+
+    """
+    _draw(message, title, wrap, 3)
+
+
+
+# Great idea borrowed from
+# http://community.cgcookie.com/t/code-snippet-easy-error-messages/203
+def _draw(message, title, wrap, key):
+    """
+
+    :type message: str
+    :type title: str
+    :type wrap: int
+    :type key: int
+
+    """
+    lines = []
+    if wrap > 0:
+        while len(message) > wrap:
+            i = message.rfind(' ', 0, wrap)
+            if i == -1:
+                lines += [message[:wrap]]
+                message = message[wrap:]
+            else:
+                lines += [message[:i]]
+                message = message[i+1:]
+    if message:
+        lines += [message]
+
+    def draw(self, *args):
+        """
+
+        :param self:
+        :param *args:
+
+        """
+        for line in lines:
+            self.layout.label(line)
+
+    title = "%s: %s" % (title, CONTEXT[key]['title'])
+    icon = CONTEXT[key]['icon']
+
+    context.window_manager.popup_menu(
+        draw, title=title.strip(), icon=icon)

+ 18 - 5
utils/exporters/blender/addons/io_three/exporter/__init__.py

@@ -1,7 +1,7 @@
 import os
 import os
 import sys
 import sys
 import traceback
 import traceback
-from .. import constants, logger, exceptions
+from .. import constants, logger, exceptions, dialogs
 from . import scene, geometry, api, base_classes
 from . import scene, geometry, api, base_classes
 
 
 
 
@@ -9,7 +9,10 @@ def _error_handler(func):
     
     
     def inner(filepath, options, *args, **kwargs):
     def inner(filepath, options, *args, **kwargs):
         level = options.get(constants.LOGGING, constants.DEBUG)
         level = options.get(constants.LOGGING, constants.DEBUG)
+        version = options.get('addon_version')
         logger.init('io_three.export.log', level=level)
         logger.init('io_three.export.log', level=level)
+        if version is not None:
+            logger.debug("Addon Version %s", version)
         api.init()
         api.init()
         
         
         try:
         try:
@@ -55,16 +58,26 @@ def export_scene(filepath, options):
 
 
 @_error_handler
 @_error_handler
 def export_geometry(filepath, options, node=None):
 def export_geometry(filepath, options, node=None):
+    msg = ""
+    exception = None
     if node is None:
     if node is None:
         node = api.active_object()
         node = api.active_object()
         if node is None:
         if node is None:
-            msg = 'Nothing selected'
+            msg = "Nothing selected"
             logger.error(msg)
             logger.error(msg)
-            raise exceptions.SelectionError(msg)
+            exception = exceptions.SelectionError
         if node.type != 'MESH':
         if node.type != 'MESH':
-            msg = 'Not a valid mesh object'
-            raise exceptions.GeometryError(msg)
+            msg = "%s is not a valid mesh object" % node.name
+            logger.error(msg)
+            exception = exceptions.GeometryError
     
     
+    if exception is not None:
+        if api.batch_mode():
+            raise exception(msg)
+        else:
+            dialogs.error(msg)
+            return
+
     mesh = api.object.mesh(node, options)
     mesh = api.object.mesh(node, options)
     parent = base_classes.BaseScene(filepath, options)
     parent = base_classes.BaseScene(filepath, options)
     geo = geometry.Geometry(mesh, parent)
     geo = geometry.Geometry(mesh, parent)

+ 10 - 0
utils/exporters/blender/addons/io_three/exporter/api/__init__.py

@@ -13,6 +13,16 @@ def active_object():
     return bpy.context.scene.objects.active
     return bpy.context.scene.objects.active
 
 
 
 
+def batch_mode():
+    """
+
+    :return: Whether or not the session is interactive
+    :rtype: bool
+
+    """
+    return bpy.context.area is None
+
+
 def init():
 def init():
     """Initializing the api module. Required first step before
     """Initializing the api module. Required first step before
     initializing the actual export process.
     initializing the actual export process.