Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Ebb <matt@mke3.net>2010-04-14 10:27:50 +0400
committerMatt Ebb <matt@mke3.net>2010-04-14 10:27:50 +0400
commit486796ce31cdbec68ec765b011cd09b141e20578 (patch)
treee92dbfc6a717c6701f3786ea4c72294d4611b945 /release
parent85590301a53f97080208d40ee97d88c4789d72d4 (diff)
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of User Preferences to choose a preset interaction style, consisting of key configurations and also other user preferences such as select mouse button, view rotation style, etc. Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more presets contributed (and maintained!) by the community. It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one I changed the view manipulation key/mouse combos and also the transform manipulator keys, not much more than that. To save an interaction preset, open the user preferences Input section, and press the [ + ] button next to the presets menu. It will save out a .py file containing any edited key maps and navigation preferences to the presets/interaction folder in your scripts folder. --- Part of this commit changes the way that key maps are exported/displayed in preferences - now partial key configs are allowed. Previously it would export/import the entire key configuration, regardless of whether individual key maps were edited or not (which would make them more susceptible to conflicts in unexpected areas). (note, in blender terminology, a key map is a category of key items, such as 'Object Mode' or 'View 2d'.) Now, the export and the UI display work in a similar way to how key maps are processed internally - Locally edited key maps (after pressing the 'Edit' button) are processed first, falling back to other key maps in the current key config, and then falling back to the default key config. So it's possible for a key config to only include a few key maps, and the rest just gets pulled from the default key config. The preferences UI display works like this too behind the scenes in deciding what to show users, however using it is just like it was before, the complexity is hidden.
Diffstat (limited to 'release')
-rw-r--r--release/datafiles/splash.pngbin211350 -> 204235 bytes
-rw-r--r--release/scripts/modules/bpy_types.py6
-rw-r--r--release/scripts/op/presets.py48
-rw-r--r--release/scripts/ui/properties_data_lamp.py6
-rw-r--r--release/scripts/ui/properties_material.py6
-rw-r--r--release/scripts/ui/properties_physics_cloth.py6
-rw-r--r--release/scripts/ui/properties_render.py6
-rw-r--r--release/scripts/ui/space_userpref.py750
8 files changed, 96 insertions, 732 deletions
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 1894d2c2bdc..78a44ba9cb5 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 9f066677e5d..19ee886abb7 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -511,12 +511,16 @@ class Menu(StructRNA, _GenericUI):
if f.startswith("."):
continue
- props = layout.operator(operator, text=bpy.utils.display_name(f))
+ preset_name = bpy.utils.display_name(f)
+ props = layout.operator(operator, text=preset_name)
for attr, value in props_default.items():
setattr(props, attr, value)
props.path = path
+ if operator == "script.execute_preset":
+ props.menu_idname = self.bl_idname
+ props.preset_name = preset_name
def draw_preset(self, context):
"""Define these on the subclass
diff --git a/release/scripts/op/presets.py b/release/scripts/op/presets.py
index 1a8e57f7c32..3272bdfb8ad 100644
--- a/release/scripts/op/presets.py
+++ b/release/scripts/op/presets.py
@@ -46,7 +46,13 @@ class AddPresetBase(bpy.types.Operator):
target_path = bpy.utils.preset_paths(self.preset_subdir)[0] # we need some way to tell the user and system preset path
- file_preset = open(os.path.join(target_path, filename), 'w')
+ path = os.path.join(target_path, filename)
+ if getattr(self, "save_keyconfig", True):
+ bpy.ops.wm.keyconfig_export(path=path, kc_name=self.properties.name)
+ file_preset = open(path, 'a')
+ file_preset.write("wm.active_keyconfig = kc\n\n")
+ else:
+ file_preset = open(path, 'w')
for rna_path in self.preset_values:
value = eval(rna_path)
@@ -68,6 +74,24 @@ class AddPresetBase(bpy.types.Operator):
return {'RUNNING_MODAL'}
+class ExecutePreset(bpy.types.Operator):
+ ''' Executes a preset '''
+ bl_idname = "script.execute_preset"
+ bl_label = "Execute a Python Preset"
+
+ path = bpy.props.StringProperty(name="Path", description="Path of the Python file to execute", maxlen=512, default="")
+ preset_name = bpy.props.StringProperty(name="Preset Name", description="Name of the Preset being executed", default="")
+ menu_idname = bpy.props.StringProperty(name="Menu ID Name", description="ID name of the menu this was called from", default="")
+
+ def execute(self, context):
+ # change the menu title to the most recently chosen option
+ exec("bpy.types.%s.bl_label=\'%s\'" % (self.properties.menu_idname, self.properties.preset_name))
+
+ # execute the preset using script.python_file_run
+ bpy.ops.script.python_file_run(path=self.properties.path)
+ return {'FINISHED'}
+
+
class AddPresetRender(AddPresetBase):
'''Add a Render Preset'''
bl_idname = "render.preset_add"
@@ -157,12 +181,32 @@ class AddPresetSunSky(AddPresetBase):
preset_subdir = "sunsky"
+class AddPresetInteraction(AddPresetBase):
+ '''Add an Application Interaction Preset'''
+ bl_idname = "wm.interaction_preset_add"
+ bl_label = "Add Interaction Preset"
+ name = AddPresetBase.name
+ save_keyconfig = True
+
+ preset_values = [
+ "bpy.context.user_preferences.edit.drag_immediately",
+ "bpy.context.user_preferences.edit.insertkey_xyz_to_rgb",
+ "bpy.context.user_preferences.inputs.select_mouse",
+ "bpy.context.user_preferences.inputs.zoom_style",
+ "bpy.context.user_preferences.inputs.zoom_axis",
+ "bpy.context.user_preferences.inputs.view_rotation",
+ "bpy.context.user_preferences.inputs.invert_zoom_direction",
+ ]
+
+ preset_subdir = "interaction"
classes = [
+ ExecutePreset,
AddPresetRender,
AddPresetSSS,
AddPresetCloth,
- AddPresetSunSky]
+ AddPresetSunSky,
+ AddPresetInteraction]
def register():
diff --git a/release/scripts/ui/properties_data_lamp.py b/release/scripts/ui/properties_data_lamp.py
index ceafb121c09..26f4b158c90 100644
--- a/release/scripts/ui/properties_data_lamp.py
+++ b/release/scripts/ui/properties_data_lamp.py
@@ -26,7 +26,7 @@ narrowui = 180
class LAMP_MT_sunsky_presets(bpy.types.Menu):
bl_label = "Render Presets"
preset_subdir = "sunsky"
- preset_operator = "script.python_file_run"
+ preset_operator = "script.execute_preset"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
draw = bpy.types.Menu.draw_preset
@@ -146,8 +146,8 @@ class DATA_PT_sunsky(DataButtonsPanel):
row = layout.row(align=True)
row.prop(lamp, "use_sky")
- row.menu("LAMP_MT_sunsky_presets", text="Presets")
- row.operator("lamp.sunsky_preset_add", text="Add")
+ row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label)
+ row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMIN")
row = layout.row()
row.active = lamp.use_sky or lamp.use_atmosphere
diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py
index 13bfd7a7f5d..7effa5817a2 100644
--- a/release/scripts/ui/properties_material.py
+++ b/release/scripts/ui/properties_material.py
@@ -39,7 +39,7 @@ def active_node_mat(mat):
class MATERIAL_MT_sss_presets(bpy.types.Menu):
bl_label = "SSS Presets"
preset_subdir = "sss"
- preset_operator = "script.python_file_run"
+ preset_operator = "script.execute_preset"
draw = bpy.types.Menu.draw_preset
@@ -505,8 +505,8 @@ class MATERIAL_PT_sss(MaterialButtonsPanel):
row = layout.row().split()
sub = row.row(align=True).split(percentage=0.75)
- sub.menu("MATERIAL_MT_sss_presets", text="Presets")
- sub.operator("material.sss_preset_add", text="Add")
+ sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label)
+ sub.operator("material.sss_preset_add", text="", icon="ZOOMIN")
split = layout.split()
diff --git a/release/scripts/ui/properties_physics_cloth.py b/release/scripts/ui/properties_physics_cloth.py
index 8761e8a38c0..c7c1a0c828f 100644
--- a/release/scripts/ui/properties_physics_cloth.py
+++ b/release/scripts/ui/properties_physics_cloth.py
@@ -36,7 +36,7 @@ class CLOTH_MT_presets(bpy.types.Menu):
'''
bl_label = "Cloth Presets"
preset_subdir = "cloth"
- preset_operator = "script.python_file_run"
+ preset_operator = "script.execute_preset"
draw = bpy.types.Menu.draw_preset
@@ -91,8 +91,8 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
col.label(text="Presets:")
sub = col.row(align=True).split(percentage=0.75)
- sub.menu("CLOTH_MT_presets", text="Presets")
- sub.operator("cloth.preset_add", text="Add")
+ sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label)
+ sub.operator("cloth.preset_add", text="", icon="ZOOMIN")
col.label(text="Quality:")
col.prop(cloth, "quality", text="Steps", slider=True)
diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py
index 57cd23e64ef..c084b1f56a4 100644
--- a/release/scripts/ui/properties_render.py
+++ b/release/scripts/ui/properties_render.py
@@ -25,7 +25,7 @@ narrowui = 180
class RENDER_MT_presets(bpy.types.Menu):
bl_label = "Render Presets"
preset_subdir = "render"
- preset_operator = "script.python_file_run"
+ preset_operator = "script.execute_preset"
draw = bpy.types.Menu.draw_preset
@@ -530,8 +530,8 @@ class RENDER_PT_dimensions(RenderButtonsPanel):
row = layout.row().split()
sub = row.row(align=True).split(percentage=0.75)
- sub.menu("RENDER_MT_presets", text="Presets")
- sub.operator("render.preset_add", text="Add")
+ sub.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label)
+ sub.operator("render.preset_add", text="", icon="ZOOMIN")
split = layout.split()
diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py
index 00bde5eb47d..56a15afee24 100644
--- a/release/scripts/ui/space_userpref.py
+++ b/release/scripts/ui/space_userpref.py
@@ -19,7 +19,6 @@
# <pep8 compliant>
import bpy
import os
-import re
import shutil
@@ -67,92 +66,6 @@ def opengl_lamp_buttons(column, lamp):
col.active = lamp.enabled
col.prop(lamp, "direction", text="")
-KM_HIERARCHY = [
- ('Window', 'EMPTY', 'WINDOW', []), # file save, window change, exit
- ('Screen', 'EMPTY', 'WINDOW', [ # full screen, undo, screenshot
- ('Screen Editing', 'EMPTY', 'WINDOW', []), # resizing, action corners
- ]),
-
- ('View2D', 'EMPTY', 'WINDOW', []), # view 2d navigation (per region)
- ('View2D Buttons List', 'EMPTY', 'WINDOW', []), # view 2d with buttons navigation
- ('Header', 'EMPTY', 'WINDOW', []), # header stuff (per region)
- ('Grease Pencil', 'EMPTY', 'WINDOW', []), # grease pencil stuff (per region)
-
- ('3D View', 'VIEW_3D', 'WINDOW', [ # view 3d navigation and generic stuff (select, transform)
- ('Object Mode', 'EMPTY', 'WINDOW', []),
- ('Mesh', 'EMPTY', 'WINDOW', []),
- ('Curve', 'EMPTY', 'WINDOW', []),
- ('Armature', 'EMPTY', 'WINDOW', []),
- ('Metaball', 'EMPTY', 'WINDOW', []),
- ('Lattice', 'EMPTY', 'WINDOW', []),
- ('Font', 'EMPTY', 'WINDOW', []),
-
- ('Pose', 'EMPTY', 'WINDOW', []),
-
- ('Vertex Paint', 'EMPTY', 'WINDOW', []),
- ('Weight Paint', 'EMPTY', 'WINDOW', []),
- ('Face Mask', 'EMPTY', 'WINDOW', []),
- ('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
- ('Sculpt', 'EMPTY', 'WINDOW', []),
-
- ('Armature Sketch', 'EMPTY', 'WINDOW', []),
- ('Particle', 'EMPTY', 'WINDOW', []),
-
- ('Object Non-modal', 'EMPTY', 'WINDOW', []), # mode change
-
- ('3D View Generic', 'VIEW_3D', 'WINDOW', []) # toolbar and properties
- ]),
-
- ('Frames', 'EMPTY', 'WINDOW', []), # frame navigation (per region)
- ('Markers', 'EMPTY', 'WINDOW', []), # markers (per region)
- ('Animation', 'EMPTY', 'WINDOW', []), # frame change on click, preview range (per region)
- ('Animation Channels', 'EMPTY', 'WINDOW', []),
- ('Graph Editor', 'GRAPH_EDITOR', 'WINDOW', [
- ('Graph Editor Generic', 'GRAPH_EDITOR', 'WINDOW', [])
- ]),
- ('Dopesheet', 'DOPESHEET_EDITOR', 'WINDOW', []),
- ('NLA Editor', 'NLA_EDITOR', 'WINDOW', [
- ('NLA Channels', 'NLA_EDITOR', 'WINDOW', []),
- ('NLA Generic', 'NLA_EDITOR', 'WINDOW', [])
- ]),
-
- ('Image', 'IMAGE_EDITOR', 'WINDOW', [
- ('UV Editor', 'EMPTY', 'WINDOW', []), # image (reverse order, UVEdit before Image
- ('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
- ('Image Generic', 'IMAGE_EDITOR', 'WINDOW', [])
- ]),
-
- ('Timeline', 'TIMELINE', 'WINDOW', []),
- ('Outliner', 'OUTLINER', 'WINDOW', []),
-
- ('Node Editor', 'NODE_EDITOR', 'WINDOW', [
- ('Node Generic', 'NODE_EDITOR', 'WINDOW', [])
- ]),
- ('Sequencer', 'SEQUENCE_EDITOR', 'WINDOW', []),
- ('Logic Editor', 'LOGIC_EDITOR', 'WINDOW', []),
-
- ('File Browser', 'FILE_BROWSER', 'WINDOW', [
- ('File Browser Main', 'FILE_BROWSER', 'WINDOW', []),
- ('File Browser Buttons', 'FILE_BROWSER', 'WINDOW', [])
- ]),
-
- ('Property Editor', 'PROPERTIES', 'WINDOW', []), # align context menu
-
- ('Script', 'SCRIPTS_WINDOW', 'WINDOW', []),
- ('Text', 'TEXT_EDITOR', 'WINDOW', []),
- ('Console', 'CONSOLE', 'WINDOW', []),
-
- ('View3D Gesture Circle', 'EMPTY', 'WINDOW', []),
- ('Gesture Border', 'EMPTY', 'WINDOW', []),
- ('Standard Modal Map', 'EMPTY', 'WINDOW', []),
- ('Transform Modal Map', 'EMPTY', 'WINDOW', []),
- ('View3D Fly Modal', 'EMPTY', 'WINDOW', []),
- ('View3D Rotate Modal', 'EMPTY', 'WINDOW', []),
- ('View3D Move Modal', 'EMPTY', 'WINDOW', []),
- ('View3D Zoom Modal', 'EMPTY', 'WINDOW', []),
- ]
-
-
class USERPREF_HT_header(bpy.types.Header):
bl_space_type = 'USER_PREFERENCES'
@@ -178,7 +91,6 @@ class USERPREF_HT_header(bpy.types.Header):
elif userpref.active_section == 'THEMES':
op = layout.operator("ui.reset_default_theme")
-
class USERPREF_PT_tabs(bpy.types.Panel):
bl_label = ""
bl_space_type = 'USER_PREFERENCES'
@@ -193,6 +105,26 @@ class USERPREF_PT_tabs(bpy.types.Panel):
layout.prop(userpref, "active_section", expand=True)
+class USERPREF_MT_interaction_presets(bpy.types.Menu):
+ bl_label = "Presets"
+ preset_subdir = "interaction"
+ preset_operator = "script.execute_preset"
+ draw = bpy.types.Menu.draw_preset
+
+
+class USERPREF_MT_splash(bpy.types.Menu):
+ bl_label = "Splash"
+
+ def draw(self, context):
+ layout = self.layout
+ split = layout.split()
+ row = split.row()
+ row.label("")
+ row = split.row()
+ row.label("Interaction:")
+ row.menu("USERPREF_MT_interaction_presets", text=bpy.types.USERPREF_MT_interaction_presets.bl_label)
+
+
class USERPREF_PT_interface(bpy.types.Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Interface"
@@ -1074,202 +1006,28 @@ class USERPREF_PT_file(bpy.types.Panel):
sub.enabled = paths.auto_save_temporary_files
sub.prop(paths, "auto_save_time", text="Timer (mins)")
+from space_userpref_keymap import InputKeyMapPanel
-class USERPREF_PT_input(bpy.types.Panel):
+class USERPREF_PT_input(InputKeyMapPanel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Input"
- bl_region_type = 'WINDOW'
- bl_show_header = False
def poll(self, context):
userpref = context.user_preferences
return (userpref.active_section == 'INPUT')
- def draw_entry(self, kc, entry, col, level=0):
- idname, spaceid, regionid, children = entry
-
- km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
-
- if km:
- self.draw_km(kc, km, children, col, level)
-
- def indented_layout(self, layout, level):
- indentpx = 16
- if level == 0:
- level = 0.0001 # Tweak so that a percentage of 0 won't split by half
- indent = level * indentpx / bpy.context.region.width
-
- split = layout.split(percentage=indent)
- col = split.column()
- col = split.column()
- return col
-
- def draw_km(self, kc, km, children, layout, level):
- km = km.active()
-
- layout.set_context_pointer("keymap", km)
-
- col = self.indented_layout(layout, level)
-
- row = col.row()
- row.prop(km, "children_expanded", text="", no_bg=True)
- row.label(text=km.name)
-
- row.label()
- row.label()
-
- if km.modal:
- row.label(text="", icon='LINKED')
- if km.user_defined:
- op = row.operator("wm.keymap_restore", text="Restore")
- else:
- op = row.operator("wm.keymap_edit", text="Edit")
-
- if km.children_expanded:
- if children:
- # Put the Parent key map's entries in a 'global' sub-category
- # equal in hierarchy to the other children categories
- subcol = self.indented_layout(col, level + 1)
- subrow = subcol.row()
- subrow.prop(km, "items_expanded", text="", no_bg=True)
- subrow.label(text="%s (Global)" % km.name)
- else:
- km.items_expanded = True
-
- # Key Map items
- if km.items_expanded:
- for kmi in km.items:
- self.draw_kmi(kc, km, kmi, col, level + 1)
-
- # "Add New" at end of keymap item list
- col = self.indented_layout(col, level + 1)
- subcol = col.split(percentage=0.2).column()
- subcol.enabled = km.user_defined
- op = subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
-
- col.separator()
-
- # Child key maps
- if children:
- subcol = col.column()
- row = subcol.row()
-
- for entry in children:
- self.draw_entry(kc, entry, col, level + 1)
-
- def draw_kmi(self, kc, km, kmi, layout, level):
- map_type = kmi.map_type
-
- col = self.indented_layout(layout, level)
-
- if km.user_defined:
- col = col.column(align=True)
- box = col.box()
- else:
- box = col.column()
-
- split = box.split(percentage=0.05)
-
- # header bar
- row = split.row()
- row.prop(kmi, "expanded", text="", no_bg=True)
-
- row = split.row()
- row.enabled = km.user_defined
- row.prop(kmi, "active", text="", no_bg=True)
-
- if km.modal:
- row.prop(kmi, "propvalue", text="")
- else:
- row.label(text=kmi.name)
-
- row = split.row()
- row.enabled = km.user_defined
- row.prop(kmi, "map_type", text="")
- if map_type == 'KEYBOARD':
- row.prop(kmi, "type", text="", full_event=True)
- elif map_type == 'MOUSE':
- row.prop(kmi, "type", text="", full_event=True)
- elif map_type == 'TWEAK':
- subrow = row.row()
- subrow.prop(kmi, "type", text="")
- subrow.prop(kmi, "value", text="")
- elif map_type == 'TIMER':
- row.prop(kmi, "type", text="")
- else:
- row.label()
-
- if kmi.id:
- op = row.operator("wm.keyitem_restore", text="", icon='BACK')
- op.item_id = kmi.id
- op = row.operator("wm.keyitem_remove", text="", icon='X')
- op.item_id = kmi.id
-
- # Expanded, additional event settings
- if kmi.expanded:
- box = col.box()
-
- box.enabled = km.user_defined
-
- if map_type not in ('TEXTINPUT', 'TIMER'):
- split = box.split(percentage=0.4)
- sub = split.row()
-
- if km.modal:
- sub.prop(kmi, "propvalue", text="")
- else:
- sub.prop(kmi, "idname", text="")
-
- sub = split.column()
- subrow = sub.row(align=True)
-
- if map_type == 'KEYBOARD':
- subrow.prop(kmi, "type", text="", event=True)
- subrow.prop(kmi, "value", text="")
- elif map_type == 'MOUSE':
- subrow.prop(kmi, "type", text="")
- subrow.prop(kmi, "value", text="")
-
- subrow = sub.row()
- subrow.scale_x = 0.75
- subrow.prop(kmi, "any")
- subrow.prop(kmi, "shift")
- subrow.prop(kmi, "ctrl")
- subrow.prop(kmi, "alt")
- subrow.prop(kmi, "oskey", text="Cmd")
- subrow.prop(kmi, "key_modifier", text="", event=True)
-
- def display_properties(properties, title=None):
- box.separator()
- if title:
- box.label(text=title)
- flow = box.column_flow(columns=2)
- for pname in dir(properties):
- if not properties.is_property_hidden(pname):
- value = eval("properties." + pname)
- if isinstance(value, bpy.types.OperatorProperties):
- display_properties(value, title=pname)
- else:
- flow.prop(properties, pname)
-
- # Operator properties
- props = kmi.properties
- if props is not None:
- display_properties(props)
-
- # Modal key maps attached to this operator
- if not km.modal:
- kmm = kc.find_keymap_modal(kmi.idname)
- if kmm:
- self.draw_km(kc, kmm, None, layout, level + 1)
- layout.set_context_pointer("keymap", km)
-
def draw_input_prefs(self, inputs, layout):
# General settings
row = layout.row()
col = row.column()
sub = col.column()
+ sub.label(text="Presets:")
+ subrow = sub.row(align=True)
+ subrow.menu("USERPREF_MT_interaction_presets", text=bpy.types.USERPREF_MT_interaction_presets.bl_label)
+ subrow.operator("wm.interaction_preset_add", text="", icon="ZOOMIN")
+ sub.separator()
+
sub.label(text="Mouse:")
sub1 = sub.column()
sub1.enabled = (inputs.select_mouse == 'RIGHT')
@@ -1316,42 +1074,6 @@ class USERPREF_PT_input(bpy.types.Panel):
row.separator()
- def draw_filtered(self, kc, layout):
- filter = kc.filter.lower()
-
- for km in kc.keymaps:
- km = km.active()
- layout.set_context_pointer("keymap", km)
-
- filtered_items = [kmi for kmi in km.items if filter in kmi.name.lower()]
-
- if len(filtered_items) != 0:
- col = layout.column()
-
- row = col.row()
- row.label(text=km.name, icon="DOT")
-
- row.label()
- row.label()
-
- if km.user_defined:
- op = row.operator("wm.keymap_restore", text="Restore")
- else:
- op = row.operator("wm.keymap_edit", text="Edit")
-
- for kmi in filtered_items:
- self.draw_kmi(kc, km, kmi, col, 1)
-
- # "Add New" at end of keymap item list
- col = self.indented_layout(layout, 1)
- subcol = col.split(percentage=0.2).column()
- subcol.enabled = km.user_defined
- op = subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
-
- def draw_hierarchy(self, defkc, layout):
- for entry in KM_HIERARCHY:
- self.draw_entry(defkc, entry, layout)
-
def draw(self, context):
layout = self.layout
@@ -1370,28 +1092,7 @@ class USERPREF_PT_input(bpy.types.Panel):
self.draw_input_prefs(inputs, split)
# Keymap Settings
- col = split.column()
- # kc = wm.active_keyconfig
- kc = wm.default_keyconfig
-
- sub = col.column()
-
- subsplit = sub.split()
- subcol = subsplit.column()
- row = subcol.row()
- row.prop_object(wm, "active_keyconfig", wm, "keyconfigs", text="Configuration:")
-
- layout.set_context_pointer("keyconfig", wm.active_keyconfig)
- row.operator("wm.keyconfig_remove", text="", icon='X')
-
- row.prop(kc, "filter", icon="VIEWZOOM")
-
- col.separator()
-
- if kc.filter != "":
- self.draw_filtered(kc, col)
- else:
- self.draw_hierarchy(kc, col)
+ self.draw_keymaps(context, split)
#print("runtime", time.time() - start)
@@ -1708,384 +1409,6 @@ class WM_OT_addon_links(bpy.types.Operator):
return {'FINISHED'}
-class WM_OT_keyconfig_test(bpy.types.Operator):
- "Test keyconfig for conflicts"
- bl_idname = "wm.keyconfig_test"
- bl_label = "Test Key Configuration for Conflicts"
-
- def testEntry(self, kc, entry, src=None, parent=None):
- result = False
-
- def kmistr(kmi):
- if km.modal:
- s = ["kmi = km.items.add_modal(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
- else:
- s = ["kmi = km.items.add(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)]
-
- if kmi.any:
- s.append(", any=True")
- else:
- if kmi.shift:
- s.append(", shift=True")
- if kmi.ctrl:
- s.append(", ctrl=True")
- if kmi.alt:
- s.append(", alt=True")
- if kmi.oskey:
- s.append(", oskey=True")
- if kmi.key_modifier and kmi.key_modifier != 'NONE':
- s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
-
- s.append(")\n")
-
- def export_properties(prefix, properties):
- for pname in dir(properties):
- if not properties.is_property_hidden(pname):
- value = eval("properties.%s" % pname)
- if isinstance(value, bpy.types.OperatorProperties):
- export_properties(prefix + "." + pname, value)
- elif properties.is_property_set(pname):
- value = _string_value(value)
- if value != "":
- s.append(prefix + ".%s = %s\n" % (pname, value))
-
- props = kmi.properties
-
- if props is not None:
- export_properties("kmi.properties", props)
-
- return "".join(s).strip()
-
- idname, spaceid, regionid, children = entry
-
- km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
-
- if km:
- km = km.active()
-
- if src:
- for item in km.items:
- if src.compare(item):
- print("===========")
- print(parent.name)
- print(kmistr(src))
- print(km.name)
- print(kmistr(item))
- result = True
-
- for child in children:
- if self.testEntry(kc, child, src, parent):
- result = True
- else:
- for i in range(len(km.items)):
- src = km.items[i]
-
- for child in children:
- if self.testEntry(kc, child, src, km):
- result = True
-
- for j in range(len(km.items) - i - 1):
- item = km.items[j + i + 1]
- if src.compare(item):
- print("===========")
- print(km.name)
- print(kmistr(src))
- print(kmistr(item))
- result = True
-
- for child in children:
- if self.testEntry(kc, child):
- result = True
-
- return result
-
- def testConfig(self, kc):
- result = False
- for entry in KM_HIERARCHY:
- if self.testEntry(kc, entry):
- result = True
- return result
-
- def execute(self, context):
- wm = context.manager
- kc = wm.default_keyconfig
-
- if self.testConfig(kc):
- print("CONFLICT")
-
- return {'FINISHED'}
-
-
-def _string_value(value):
- if isinstance(value, str) or isinstance(value, bool) or isinstance(value, float) or isinstance(value, int):
- result = repr(value)
- elif getattr(value, '__len__', False):
- repr(list(value))
- else:
- print("Export key configuration: can't write ", value)
-
- return result
-
-
-class WM_OT_keyconfig_import(bpy.types.Operator):
- "Import key configuration from a python script"
- bl_idname = "wm.keyconfig_import"
- bl_label = "Import Key Configuration..."
-
- path = StringProperty(name="File Path", description="File path to write file to")
- filename = StringProperty(name="File Name", description="Name of the file")
- directory = StringProperty(name="Directory", description="Directory of the file")
- filter_folder = BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
- filter_text = BoolProperty(name="Filter text", description="", default=True, options={'HIDDEN'})
- filter_python = BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
-
- keep_original = BoolProperty(name="Keep original", description="Keep original file after copying to configuration folder", default=True)
-
- def execute(self, context):
- if not self.properties.path:
- raise Exception("File path not set")
-
- f = open(self.properties.path, "r")
- if not f:
- raise Exception("Could not open file")
-
- name_pattern = re.compile("^kc = wm.add_keyconfig\('(.*)'\)$")
-
- for line in f.readlines():
- match = name_pattern.match(line)
-
- if match:
- config_name = match.groups()[0]
-
- f.close()
-
- path = os.path.split(os.path.split(__file__)[0])[0] # remove ui/space_userpref.py
- path = os.path.join(path, "cfg")
-
- # create config folder if needed
- if not os.path.exists(path):
- os.mkdir(path)
-
- path = os.path.join(path, config_name + ".py")
-
- if self.properties.keep_original:
- shutil.copy(self.properties.path, path)
- else:
- shutil.move(self.properties.path, path)
-
- exec("import " + config_name)
-
- wm = bpy.context.manager
- wm.active_keyconfig = wm.keyconfigs[config_name]
-
- return {'FINISHED'}
-
- def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
- return {'RUNNING_MODAL'}
-
-
-class WM_OT_keyconfig_export(bpy.types.Operator):
- "Export key configuration to a python script"
- bl_idname = "wm.keyconfig_export"
- bl_label = "Export Key Configuration..."
-
- path = StringProperty(name="File Path", description="File path to write file to")
- filename = StringProperty(name="File Name", description="Name of the file")
- directory = StringProperty(name="Directory", description="Directory of the file")
- filter_folder = BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
- filter_text = BoolProperty(name="Filter text", description="", default=True, options={'HIDDEN'})
- filter_python = BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
-
- def execute(self, context):
- if not self.properties.path:
- raise Exception("File path not set")
-
- f = open(self.properties.path, "w")
- if not f:
- raise Exception("Could not open file")
-
- wm = context.manager
- kc = wm.active_keyconfig
-
- if kc.name == 'Blender':
- name = os.path.splitext(os.path.basename(self.properties.path))[0]
- else:
- name = kc.name
-
- f.write("# Configuration %s\n" % name)
-
- f.write("import bpy\n\n")
- f.write("wm = bpy.context.manager\n")
- f.write("kc = wm.add_keyconfig('%s')\n\n" % name)
-
- for km in kc.keymaps:
- km = km.active()
- f.write("# Map %s\n" % km.name)
- f.write("km = kc.add_keymap('%s', space_type='%s', region_type='%s', modal=%s)\n\n" % (km.name, km.space_type, km.region_type, km.modal))
- for kmi in km.items:
- if km.modal:
- f.write("kmi = km.items.add_modal('%s', '%s', '%s'" % (kmi.propvalue, kmi.type, kmi.value))
- else:
- f.write("kmi = km.items.add('%s', '%s', '%s'" % (kmi.idname, kmi.type, kmi.value))
- if kmi.any:
- f.write(", any=True")
- else:
- if kmi.shift:
- f.write(", shift=True")
- if kmi.ctrl:
- f.write(", ctrl=True")
- if kmi.alt:
- f.write(", alt=True")
- if kmi.oskey:
- f.write(", oskey=True")
- if kmi.key_modifier and kmi.key_modifier != 'NONE':
- f.write(", key_modifier='%s'" % kmi.key_modifier)
- f.write(")\n")
-
- def export_properties(prefix, properties):
- for pname in dir(properties):
- if not properties.is_property_hidden(pname):
- value = eval("properties.%s" % pname)
- if isinstance(value, bpy.types.OperatorProperties):
- export_properties(prefix + "." + pname, value)
- elif properties.is_property_set(pname):
- value = _string_value(value)
- if value != "":
- f.write(prefix + ".%s = %s\n" % (pname, value))
-
- props = kmi.properties
-
- if props is not None:
- export_properties("kmi.properties", props)
-
- f.write("\n")
-
- f.close()
-
- return {'FINISHED'}
-
- def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
- return {'RUNNING_MODAL'}
-
-
-class WM_OT_keymap_edit(bpy.types.Operator):
- "Edit key map"
- bl_idname = "wm.keymap_edit"
- bl_label = "Edit Key Map"
-
- def execute(self, context):
- wm = context.manager
- km = context.keymap
- km.copy_to_user()
- return {'FINISHED'}
-
-
-class WM_OT_keymap_restore(bpy.types.Operator):
- "Restore key map(s)"
- bl_idname = "wm.keymap_restore"
- bl_label = "Restore Key Map(s)"
-
- all = BoolProperty(attr="all", name="All Keymaps", description="Restore all keymaps to default")
-
- def execute(self, context):
- wm = context.manager
-
- if self.properties.all:
- for km in wm.default_keyconfig.keymaps:
- km.restore_to_default()
- else:
- km = context.keymap
- km.restore_to_default()
-
- return {'FINISHED'}
-
-
-class WM_OT_keyitem_restore(bpy.types.Operator):
- "Restore key map item"
- bl_idname = "wm.keyitem_restore"
- bl_label = "Restore Key Map Item"
-
- item_id = IntProperty(attr="item_id", name="Item Identifier", description="Identifier of the item to remove")
-
- def execute(self, context):
- wm = context.manager
- km = context.keymap
- kmi = km.item_from_id(self.properties.item_id)
-
- km.restore_item_to_default(kmi)
-
- return {'FINISHED'}
-
-
-class WM_OT_keyitem_add(bpy.types.Operator):
- "Add key map item"
- bl_idname = "wm.keyitem_add"
- bl_label = "Add Key Map Item"
-
- def execute(self, context):
- wm = context.manager
- km = context.keymap
- kc = wm.default_keyconfig
-
- if km.modal:
- km.items.add_modal("", 'A', 'PRESS') # kmi
- else:
- km.items.add("none", 'A', 'PRESS') # kmi
-
- # clear filter and expand keymap so we can see the newly added item
- if kc.filter != '':
- kc.filter = ''
- km.items_expanded = True
- km.children_expanded = True
-
- return {'FINISHED'}
-
-
-class WM_OT_keyitem_remove(bpy.types.Operator):
- "Remove key map item"
- bl_idname = "wm.keyitem_remove"
- bl_label = "Remove Key Map Item"
-
- item_id = IntProperty(attr="item_id", name="Item Identifier", description="Identifier of the item to remove")
-
- def execute(self, context):
- wm = context.manager
- km = context.keymap
- kmi = km.item_from_id(self.properties.item_id)
- km.remove_item(kmi)
- return {'FINISHED'}
-
-
-class WM_OT_keyconfig_remove(bpy.types.Operator):
- "Remove key config"
- bl_idname = "wm.keyconfig_remove"
- bl_label = "Remove Key Config"
-
- def poll(self, context):
- wm = context.manager
- return wm.active_keyconfig.user_defined
-
- def execute(self, context):
- wm = context.manager
-
- keyconfig = wm.active_keyconfig
-
- module = __import__(keyconfig.name)
-
- os.remove(module.__file__)
-
- compiled_path = module.__file__ + "c" # for .pyc
-
- if os.path.exists(compiled_path):
- os.remove(compiled_path)
-
- wm.remove_keyconfig(keyconfig)
- return {'FINISHED'}
-
classes = [
USERPREF_HT_header,
@@ -2098,21 +1421,14 @@ classes = [
USERPREF_PT_input,
USERPREF_PT_addons,
+ USERPREF_MT_interaction_presets,
+ USERPREF_MT_splash,
+
WM_OT_addon_enable,
WM_OT_addon_disable,
WM_OT_addon_install,
WM_OT_addon_expand,
- WM_OT_addon_links,
-
- WM_OT_keyconfig_export,
- WM_OT_keyconfig_import,
- WM_OT_keyconfig_test,
- WM_OT_keyconfig_remove,
- WM_OT_keymap_edit,
- WM_OT_keymap_restore,
- WM_OT_keyitem_add,
- WM_OT_keyitem_remove,
- WM_OT_keyitem_restore]
+ WM_OT_addon_links ]
def register():