[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27053] trunk/blender: generic modal operator to make adjusting almost any rna property with the mouse possible with a few lines .

Campbell Barton ideasman42 at gmail.com
Sun Feb 21 15:05:03 CET 2010


Revision: 27053
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27053
Author:   campbellbarton
Date:     2010-02-21 15:05:02 +0100 (Sun, 21 Feb 2010)

Log Message:
-----------
generic modal operator to make adjusting almost any rna property with the mouse possible with a few lines.

Example which is similar to interactive lamp adjusting in 2.4x ...
  wm.context_modal_mouse(path_iter="selected_editable_objects", path_item="data.spot_size")

Added lamp Wkey menu back.

Modified Paths:
--------------
    trunk/blender/release/scripts/op/wm.py
    trunk/blender/release/scripts/ui/space_view3d.py
    trunk/blender/source/blender/editors/object/object_ops.c

Modified: trunk/blender/release/scripts/op/wm.py
===================================================================
--- trunk/blender/release/scripts/op/wm.py	2010-02-21 12:15:38 UTC (rev 27052)
+++ trunk/blender/release/scripts/op/wm.py	2010-02-21 14:05:02 UTC (rev 27053)
@@ -297,6 +297,91 @@
         description="", maxlen=1024, default="")
 
 
+
+class WM_OT_context_modal_mouse(bpy.types.Operator):
+    '''Adjust arbitrary values with mouse input'''
+    bl_idname = "wm.context_modal_mouse"
+    bl_label = "Context Modal Mouse"
+    
+    path_iter = StringProperty(description="The path relative to the context, must point to an iterable.")
+    path_item = StringProperty(description="The path from each iterable to the value (int or float)")
+    input_scale = FloatProperty(default=0.01, description="Scale the mouse movement by this value before applying the delta")
+    invert = BoolProperty(default=False, description="Invert the mouse input")
+    initial_x = IntProperty(options={'HIDDEN'})
+
+    _values = {}
+
+    def _values_store(self, context):
+        path_iter = self.properties.path_iter
+        path_item = self.properties.path_item
+
+        self._values.clear()
+        values = self._values
+
+        for item in getattr(context, path_iter):
+            try:
+                value_orig = eval("item." + path_item)
+            except:
+                continue
+            
+            # check this can be set, maybe this is library data.
+            try:
+                exec("item.%s = %s" % (path_item, value_orig))
+            except:
+                continue
+
+            values[item] = value_orig
+
+
+    def _values_delta(self, delta):
+        delta *= self.properties.input_scale
+        if self.properties.invert:
+            delta = -delta
+
+        path_item = self.properties.path_item
+        for item, value_orig in self._values.items():
+            exec("item.%s = %s" % (path_item, value_orig + delta))
+
+    def _values_restore(self):
+        path_item = self.properties.path_item
+        for item, value_orig in self._values.items():
+            exec("item.%s = %s" % (path_item, value_orig))
+
+        self._values.clear()
+        
+    def _values_clear(self):
+        self._values.clear()
+
+    def modal(self, context, event):
+        event_type = event.type
+
+        if event_type == 'MOUSEMOVE':
+            delta = event.mouse_x - self.properties.initial_x
+            self._values_delta(delta)
+
+        elif 'LEFTMOUSE' == event_type:
+            self._values_clear()
+            return {'FINISHED'}
+
+        elif event_type in ('RIGHTMOUSE', 'ESCAPE'):
+            self._values_restore()
+            return {'FINISHED'}
+            
+        return {'RUNNING_MODAL'}
+
+    def invoke(self, context, event):
+        self._values_store(context)
+
+        if not self._values:
+            self.report({'WARNING'}, "Nothing to operate on: %s[ ].%s" % (self.properties.path_iter, self.properties.path_item))
+            return {'CANCELLED'}
+        else:
+            self.properties.initial_x = event.mouse_x
+
+            context.manager.add_modal_handler(self)
+            return {'RUNNING_MODAL'}
+
+
 class WM_OT_doc_view(bpy.types.Operator):
     '''Load online reference docs'''
     bl_idname = "wm.doc_view"
@@ -433,6 +518,7 @@
     WM_OT_context_toggle_enum,
     WM_OT_context_cycle_enum,
     WM_OT_context_cycle_int,
+    WM_OT_context_modal_mouse,
 
     WM_OT_doc_view,
     WM_OT_doc_edit,

Modified: trunk/blender/release/scripts/ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/ui/space_view3d.py	2010-02-21 12:15:38 UTC (rev 27052)
+++ trunk/blender/release/scripts/ui/space_view3d.py	2010-02-21 14:05:02 UTC (rev 27053)
@@ -700,6 +700,42 @@
         layout.operator("object.origin_clear", text="Origin")
 
 
+class VIEW3D_MT_object_specials(bpy.types.Menu):
+    bl_label = "Specials"
+
+    def poll(self, context):
+        # add more special types
+        obj = context.object
+        return bool(obj and obj.type == 'LAMP')
+
+    def draw(self, context):
+        layout = self.layout
+
+        obj = context.object
+        if obj and obj.type == 'LAMP':
+            layout.operator_context = 'INVOKE_REGION_WIN'
+
+            props = layout.operator("wm.context_modal_mouse", text="Spot Size")
+            props.path_iter = "selected_editable_objects"
+            props.path_item = "data.spot_size"
+            props.input_scale = 0.01
+            
+            props = layout.operator("wm.context_modal_mouse", text="Distance")
+            props.path_iter = "selected_editable_objects"
+            props.path_item = "data.distance"
+            props.input_scale = 0.1
+            
+            props = layout.operator("wm.context_modal_mouse", text="Clip Start")
+            props.path_iter = "selected_editable_objects"
+            props.path_item = "data.shadow_buffer_clip_start"
+            props.input_scale = 0.05
+            
+            props = layout.operator("wm.context_modal_mouse", text="Clip End")
+            props.path_iter = "selected_editable_objects"
+            props.path_item = "data.shadow_buffer_clip_end"
+            props.input_scale = 0.05
+
+
 class VIEW3D_MT_object_apply(bpy.types.Menu):
     bl_label = "Apply"
 
@@ -2141,6 +2177,7 @@
     VIEW3D_MT_uv_map, # Edit Menus
 
     VIEW3D_MT_object, # Object Menu
+    VIEW3D_MT_object_specials,
     VIEW3D_MT_object_apply,
     VIEW3D_MT_object_clear,
     VIEW3D_MT_object_parent,

Modified: trunk/blender/source/blender/editors/object/object_ops.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_ops.c	2010-02-21 12:15:38 UTC (rev 27052)
+++ trunk/blender/source/blender/editors/object/object_ops.c	2010-02-21 14:05:02 UTC (rev 27053)
@@ -336,6 +336,8 @@
 	WM_keymap_verify_item(keymap, "GROUP_OT_objects_add_active", GKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
 	WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
 
+	WM_keymap_add_menu(keymap, "VIEW3D_MT_object_specials", WKEY, KM_PRESS, 0, 0);
+
 	for(i=0; i<=5; i++) {
 		kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", ZEROKEY+i, KM_PRESS, KM_CTRL, 0);
 		RNA_int_set(kmi->ptr, "level", i);





More information about the Bf-blender-cvs mailing list