Merge from trunk -r 23000:23968.
authorArystanbek Dyussenov <arystan.d@gmail.com>
Sun, 25 Oct 2009 06:53:04 +0000 (06:53 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Sun, 25 Oct 2009 06:53:04 +0000 (06:53 +0000)
Resolved the 'inconsistent newlines' merge error by updating my svn client.
The error was caused by a bug in svn client (http://subversion.tigris.org/issues/show_bug.cgi?id=3262) that was
fixed in 1.5.5.

Fixed conflicts in image.c, object_edit.c, wm_operators.c, source/creator/CMakeLists.txt and CMakeLists.txt.
Merge didn't remove some files that were moved/renamed in trunk, svn reported 'Skipped [filename]' on these files.
I removed them with:

svn --force remove release/io
svn --force remove release/ui
svn --force remove source/blender/editors/preview
svn --force remove source/blender/editors/physics/ed_fluidsim.c
svn --force remove source/blender/editors/physics/editparticle.c
svn --force remove source/blender/editors/physics/ed_pointcache.c
svn --force remove source/blender/editors/mesh/mesh_layers.c

Now, before merging into trunk, need to update collada code so it builds ok and fix the possibility to build without
collada.

32 files changed:
1  2 
CMake/macros.cmake
CMakeLists.txt
config/linux2-config.py
config/win32-vc-config.py
config/win64-vc-config.py
release/ui/buttons_data_armature.py
release/ui/buttons_data_bone.py
release/ui/buttons_data_curve.py
release/ui/buttons_data_empty.py
release/ui/buttons_data_modifier.py
release/ui/buttons_data_text.py
release/ui/buttons_object_constraint.py
release/ui/buttons_particle.py
release/ui/buttons_physics_smoke.py
release/ui/space_console.py
release/ui/space_image.py
release/ui/space_info.py
release/ui/space_sequencer.py
release/ui/space_view3d.py
release/ui/space_view3d_toolbar.py
source/blender/CMakeLists.txt
source/blender/SConscript
source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_keyframing.h
source/blender/editors/include/ED_object.h
source/blender/windowmanager/intern/wm_operators.c
source/creator/CMakeLists.txt
tools/Blender.py
tools/btools.py

Simple merge
diff --cc CMakeLists.txt
@@@ -71,13 -75,19 +75,20 @@@ OPTION(WITH_WEBPLUGIN     "Enable Web P
  OPTION(WITH_FFTW3         "Enable FFTW3 support" OFF)
  OPTION(WITH_JACK          "Enable Jack Support (http://www.jackaudio.org)" OFF)
  OPTION(WITH_SNDFILE       "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
+ OPTION(WITH_LZO           "Enable fast LZO compression, used for pointcache" ON)
+ OPTION(WITH_LZMA          "Enable best LZMA compression, used for pointcache" ON)
  OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF)
OPTION(WITH_BUILDINFO     "Include extra build details" ON)
+ OPTION(WITH_BUILDINFO     "Include extra build details" ON)
  OPTION(WITH_INSTALL       "Install accompanying scripts and language files needed to run blender" ON)
 +OPTION(WITH_OPENCOLLADA               "Enable OpenCollada Support (http://www.opencollada.org/)"      OFF)
  
+ IF (APPLE)
+ OPTION(WITH_COCOA       "Use Cocoa framework instead of deprecated Carbon" ON)
+ OPTION(WITH_LIBS10.5    "Use 10.5 libs (needed for 64bit builds)" OFF)
+ ENDIF (APPLE)
  IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
-   MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
+       MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
  ENDIF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
  
  # For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
@@@ -117,120 -127,107 +128,119 @@@ IF(UNIX AND NOT APPLE
        SET(SNDFILE_INC ${SNDFILE}/include)
        SET(SNDFILE_LIB sndfile)
        SET(SNDFILE_LIBPATH ${SNDFILE}/lib)
-   ENDIF(WITH_SNDFILE)
-   FIND_LIBRARY(INTL_LIBRARY
-     NAMES intl
-     PATHS
-     /sw/lib
-   )
-   FIND_LIBRARY(ICONV_LIBRARY
-     NAMES iconv
-     PATHS
-     /sw/lib
-   )
+       ENDIF(WITH_SNDFILE)
+       FIND_LIBRARY(INTL_LIBRARY
+               NAMES intl
+               PATHS
+               /sw/lib
+       )
+       FIND_LIBRARY(ICONV_LIBRARY
+               NAMES iconv
+               PATHS
+               /sw/lib
+       )
    
-   IF(INTL_LIBRARY AND ICONV_LIBRARY)
-     SET(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY})
-   ENDIF(INTL_LIBRARY AND ICONV_LIBRARY)
-   FIND_PACKAGE(Freetype)
-   # UNSET(FREETYPE_INCLUDE_DIRS CACHE) # cant use
-   # No way to set py31. remove for now.
-   # FIND_PACKAGE(PythonLibs)
-   SET(PYTHON /usr)
-   SET(PYTHON_VERSION 3.1)
-   SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "")
-   # SET(PYTHON_BINARY python) # not used yet
-   SET(PYTHON_LIB python${PYTHON_VERSION} CACHE STRING "")
-   SET(PYTHON_LIBPATH ${PYTHON}/lib CACHE STRING "")
+       IF(INTL_LIBRARY AND ICONV_LIBRARY)
+               SET(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY})
+       ENDIF(INTL_LIBRARY AND ICONV_LIBRARY)
+       FIND_PACKAGE(Freetype)
+       # UNSET(FREETYPE_INCLUDE_DIRS CACHE) # cant use
+       # No way to set py31. remove for now.
+       # FIND_PACKAGE(PythonLibs)
+       SET(PYTHON /usr)
+       SET(PYTHON_VERSION 3.1)
+       SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "")
+       # SET(PYTHON_BINARY python) # not used yet
+       SET(PYTHON_LIB python${PYTHON_VERSION} CACHE STRING "")
+       SET(PYTHON_LIBPATH ${PYTHON}/lib CACHE STRING "")
    
-   # FIND_PACKAGE(PythonInterp) # not used yet
-   # SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
+       # FIND_PACKAGE(PythonInterp) # not used yet
+       # SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
    
-   SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
-   IF(WITH_SDL)
-     FIND_PACKAGE(SDL)
-     # UNSET(SDLMAIN_LIBRARY CACHE)
-     IF(NOT SDL_FOUND)
-       SET(WITH_SDL OFF)
-     ENDIF(NOT SDL_FOUND)
-   ENDIF(WITH_SDL)
-   IF(WITH_OPENCOLLADA)
-     SET(OPENCOLLADA /usr/local/opencollada)
-     SET(OPENCOLLADA_LIBPATH ${OPENCOLLADA})
-     SET(OPENCOLLADA_LIB OpenCollada)
-     SET(PCRE /usr)
-     SET(PCRE_LIBPATH ${PCRE}/lib)
-     SET(PCRE_LIB pcre)
-     SET(EXPAT /usr)
-     SET(EXPAT_LIBPATH ${EXPAT}/lib)
-     SET(EXPAT_LIB expat)
-   ENDIF(WITH_OPENCOLLADA)
-   FIND_PATH(OPENEXR_INC
-     ImfXdr.h
-     PATHS
-     /usr/local/include/OpenEXR
-     /usr/include/OpenEXR
-     /sw/include/OpenEXR
-     /opt/local/include/OpenEXR
-     /opt/csw/include/OpenEXR
-     /opt/include/OpenEXR
-   )
-   SET(OPENEXR_LIB Half IlmImf Iex Imath)
-   SET(FFMPEG /usr)
-   SET(FFMPEG_INC ${FFMPEG}/include)
-   SET(FFMPEG_LIB avformat avcodec avutil avdevice swscale)
-   SET(FFMPEG_LIBPATH ${FFMPEG}/lib)
+       SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
+       IF(WITH_SDL)
+               FIND_PACKAGE(SDL)
+               # UNSET(SDLMAIN_LIBRARY CACHE)
+               IF(NOT SDL_FOUND)
+                       SET(WITH_SDL OFF)
+               ENDIF(NOT SDL_FOUND)
+       ENDIF(WITH_SDL)
++      IF(WITH_OPENCOLLADA)
++              SET(OPENCOLLADA /usr/local/opencollada)
++              SET(OPENCOLLADA_LIBPATH ${OPENCOLLADA})
++              SET(OPENCOLLADA_LIB OpenCollada)
++              SET(PCRE /usr)
++              SET(PCRE_LIBPATH ${PCRE}/lib)
++              SET(PCRE_LIB pcre)
++              SET(EXPAT /usr)
++              SET(EXPAT_LIBPATH ${EXPAT}/lib)
++              SET(EXPAT_LIB expat)
++      ENDIF(WITH_OPENCOLLADA)
++
+       FIND_PATH(OPENEXR_INC
+               ImfXdr.h
+               PATHS
+               /usr/local/include/OpenEXR
+               /usr/include/OpenEXR
+               /sw/include/OpenEXR
+               /opt/local/include/OpenEXR
+               /opt/csw/include/OpenEXR
+               /opt/include/OpenEXR
+       )
+       SET(OPENEXR_LIB Half IlmImf Iex Imath)
+       SET(FFMPEG /usr)
+       SET(FFMPEG_INC ${FFMPEG}/include)
+       SET(FFMPEG_LIB avformat avcodec avutil avdevice swscale)
+       SET(FFMPEG_LIBPATH ${FFMPEG}/lib)
    
-   IF(WITH_FFTW3)
-     SET(FFTW3 /usr)
-     SET(FFTW3_INC ${FFTW3}/include)
-     SET(FFTW3_LIB fftw3)
-     SET(FFTW3_LIBPATH ${FFTW3}/lib)
-   ENDIF(WITH_FFTW3)
+       IF(WITH_FFTW3)
+               SET(FFTW3 /usr)
+               SET(FFTW3_INC ${FFTW3}/include)
+               SET(FFTW3_LIB fftw3)
+               SET(FFTW3_LIBPATH ${FFTW3}/lib)
+       ENDIF(WITH_FFTW3)
  
-   SET(LIBSAMPLERATE /usr)
-   SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include)
-   SET(LIBSAMPLERATE_LIB samplerate)
-   SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib)
+       SET(LIBSAMPLERATE /usr)
+       SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include)
+       SET(LIBSAMPLERATE_LIB samplerate)
+       SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib)
  
-   FIND_PACKAGE(JPEG REQUIRED)
+       FIND_PACKAGE(JPEG REQUIRED)
  
-   FIND_PACKAGE(PNG REQUIRED)
+       FIND_PACKAGE(PNG REQUIRED)
  
-   FIND_PACKAGE(ZLIB REQUIRED)
+       FIND_PACKAGE(ZLIB REQUIRED)
  
-   # Could use ${X11_Xinput_LIB} ${X11_X11_LIB} too
-   SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11")
+       # Could use ${X11_Xinput_LIB} ${X11_X11_LIB} too
+       SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11")
  
-   IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
-     # BSD's dont use libdl.so
-     SET(LLIBS "${LLIBS} -ldl")
-   ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+       IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+               # BSD's dont use libdl.so
+               SET(LLIBS "${LLIBS} -ldl")
+       ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
  
-   IF(WITH_OPENMP)
-     SET(LLIBS "${LLIBS} -lgomp")
-     SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
-     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
-   ENDIF(WITH_OPENMP)
+       IF(WITH_OPENMP)
+               SET(LLIBS "${LLIBS} -lgomp")
+               SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
+               SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
+       ENDIF(WITH_OPENMP)
  
  
-   SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts")
+       SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts")
  
-   SET(PLATFORM_LINKFLAGS "-pthread")
+       SET(PLATFORM_LINKFLAGS "-pthread")
  
-   # Better warnings
-   SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement")
-   SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare")
+       # Better warnings
+       SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement")
+       SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare")
  
-   INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
+       INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
  ENDIF(UNIX AND NOT APPLE)
  
  IF(WIN32)
Simple merge
Simple merge
Simple merge
index ff0cc53,0000000..5924a2e
mode 100644,000000..100644
--- /dev/null
@@@ -1,177 -1,0 +1,177 @@@
-               col.template_layers(arm, "layer")
 +
 +import bpy
 + 
 +class DataButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "data"
 +      
 +      def poll(self, context):
 +              return (context.armature)
 +
 +class DATA_PT_context_arm(DataButtonsPanel):
 +      __show_header__ = False
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              arm = context.armature
 +              space = context.space_data
 +
 +              split = layout.split(percentage=0.65)
 +
 +              if ob:
 +                      split.template_ID(ob, "data")
 +                      split.itemS()
 +              elif arm:
 +                      split.template_ID(space, "pin_id")
 +                      split.itemS()
 +
 +class DATA_PT_skeleton(DataButtonsPanel):
 +      __label__ = "Skeleton"
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              arm = context.armature
 +              space = context.space_data
 +
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemL(text="Layers:")
-               col.template_layers(arm, "layer_protection")
++              col.itemR(arm, "layer", text="")
 +              col.itemL(text="Protected Layers:")
++              col.itemR(arm, "layer_protection", text="")
 +              col.itemL(text="Edit Options:")
 +              col.itemR(arm, "x_axis_mirror")
 +              col.itemR(arm, "auto_ik")
 +              
 +              col = split.column()
 +              col.itemR(arm, "rest_position")
 +              col.itemL(text="Deform:")
 +              col.itemR(arm, "deform_vertexgroups", text="Vertex Groups")
 +              col.itemR(arm, "deform_envelope", text="Envelopes")
 +              col.itemR(arm, "deform_quaternion", text="Quaternion")
 +              col.itemR(arm, "deform_bbone_rest", text="B-Bones Rest")
 +              
 +class DATA_PT_display(DataButtonsPanel):
 +      __label__ = "Display"
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              arm = context.armature
 +
 +              layout.row().itemR(arm, "drawtype", expand=True)
 +
 +              flow = layout.column_flow()
 +              flow.itemR(arm, "draw_names", text="Names")
 +              flow.itemR(arm, "draw_axes", text="Axes")
 +              flow.itemR(arm, "draw_custom_bone_shapes", text="Shapes")
 +              flow.itemR(arm, "draw_group_colors", text="Colors")
 +              flow.itemR(arm, "delay_deform", text="Delay Refresh")
 +
 +class DATA_PT_bone_groups(DataButtonsPanel):
 +      __label__ = "Bone Groups"
 +      
 +      def poll(self, context):
 +              return (context.object and context.object.type=='ARMATURE' and context.object.pose)
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              pose = ob.pose
 +              
 +              row = layout.row()
 +              row.template_list(pose, "bone_groups", pose, "active_bone_group_index")
 +              
 +              col = row.column(align=True)
 +              col.active = (ob.proxy == None)
 +              col.itemO("pose.group_add", icon='ICON_ZOOMIN', text="")
 +              col.itemO("pose.group_remove", icon='ICON_ZOOMOUT', text="")
 +              
 +              group = pose.active_bone_group
 +              if group:
 +                      col = layout.column()
 +                      col.active= (ob.proxy == None)
 +                      col.itemR(group, "name")
 +                      
 +                      split = layout.split(0.5)
 +                      split.active= (ob.proxy == None)
 +                      split.itemR(group, "color_set")
 +                      if group.color_set:
 +                              split.template_triColorSet(group, "colors")
 +              
 +              row = layout.row(align=True)
 +              row.active = (ob.proxy == None)
 +              
 +              row.itemO("pose.group_assign", text="Assign")
 +              row.itemO("pose.group_remove", text="Remove") #row.itemO("pose.bone_group_remove_from", text="Remove")
 +              #row.itemO("object.bone_group_select", text="Select")
 +              #row.itemO("object.bone_group_deselect", text="Deselect")
 +
 +class DATA_PT_paths(DataButtonsPanel):
 +      __label__ = "Paths"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              arm = context.armature
 +
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(arm, "paths_show_around_current_frame", text="Around Frame")
 +              
 +              sub = col.column(align=True)
 +              if (arm.paths_show_around_current_frame):
 +                      sub.itemR(arm, "path_before_current", text="Before")
 +                      sub.itemR(arm, "path_after_current", text="After")
 +              else:
 +                      sub.itemR(arm, "path_start_frame", text="Start")
 +                      sub.itemR(arm, "path_end_frame", text="End")
 +
 +              sub.itemR(arm, "path_size", text="Step")        
 +              col.itemR(arm, "paths_calculate_head_positions", text="Head")
 +              
 +              col = split.column()
 +              col.itemL(text="Show:")
 +              col.itemR(arm, "paths_show_frame_numbers", text="Frame Numbers")
 +              col.itemR(arm, "paths_highlight_keyframes", text="Keyframes")
 +              col.itemR(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers")
 +
 +class DATA_PT_ghost(DataButtonsPanel):
 +      __label__ = "Ghost"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              arm = context.armature
 +
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemR(arm, "ghost_type", text="")
 +
 +              sub = col.column(align=True)
 +              if arm.ghost_type == 'RANGE':
 +                      sub.itemR(arm, "ghost_start_frame", text="Start")
 +                      sub.itemR(arm, "ghost_end_frame", text="End")
 +                      sub.itemR(arm, "ghost_size", text="Step")
 +              elif arm.ghost_type == 'CURRENT_FRAME':
 +                      sub.itemR(arm, "ghost_step", text="Range")
 +                      sub.itemR(arm, "ghost_size", text="Step")
 +
 +              col = split.column()
 +              col.itemR(arm, "ghost_only_selected", text="Selected Only")
 +
 +bpy.types.register(DATA_PT_context_arm)
 +bpy.types.register(DATA_PT_skeleton)
 +bpy.types.register(DATA_PT_display)
 +bpy.types.register(DATA_PT_bone_groups)
 +bpy.types.register(DATA_PT_paths)
 +bpy.types.register(DATA_PT_ghost)
index 276ca06,0000000..a012182
mode 100644,000000..100644
--- /dev/null
@@@ -1,244 -1,0 +1,278 @@@
-               col.template_layers(bone, "layer")
 +
 +import bpy
 + 
 +class BoneButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "bone"
 +      
 +      def poll(self, context):
 +              return (context.bone or context.edit_bone)
 +
 +class BONE_PT_context_bone(BoneButtonsPanel):
 +      __show_header__ = False
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              bone = context.bone
 +              if not bone:
 +                      bone = context.edit_bone
 +              
 +              row = layout.row()
 +              row.itemL(text="", icon='ICON_BONE_DATA')
 +              row.itemR(bone, "name", text="")
 +
 +class BONE_PT_transform(BoneButtonsPanel):
 +      __label__ = "Transform"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              bone = context.bone
 +              if not bone:
 +                      bone = context.edit_bone
 +
 +                      row = layout.row()
 +                      row.column().itemR(bone, "head")
 +                      row.column().itemR(bone, "tail")
 +
 +                      col = row.column()
 +                      sub = col.column(align=True)
 +                      sub.itemL(text="Roll:")
 +                      sub.itemR(bone, "roll", text="")
 +                      sub.itemL()
 +                      sub.itemR(bone, "locked")
 +
 +              else:
 +                      pchan = ob.pose.pose_channels[context.bone.name]
 +
 +                      layout.itemR(pchan, "rotation_mode")
 +
 +                      row = layout.row()
 +                      col = row.column()
 +                      col.itemR(pchan, "location")
 +                      col.active = not (bone.parent and bone.connected)
 +
 +                      col = row.column()
 +                      if pchan.rotation_mode == 'QUATERNION':
 +                              col.itemR(pchan, "rotation", text="Rotation")
++                      elif pchan.rotation_mode == 'AXIS_ANGLE':
++                              col.itemL(text="Rotation")
++                              col.itemR(pchan, "rotation_angle", text="Angle")
++                              col.itemR(pchan, "rotation_axis", text="Axis")
 +                      else:
 +                              col.itemR(pchan, "euler_rotation", text="Rotation")
 +
 +                      row.column().itemR(pchan, "scale")
 +
 +                      if pchan.rotation_mode == 'QUATERNION':
 +                              col = layout.column(align=True)
 +                              col.itemL(text="Euler:")
 +                              col.row().itemR(pchan, "euler_rotation", text="")
++                              
++class BONE_PT_transform_locks(BoneButtonsPanel):
++      __label__ = "Transform Locks"
++      
++      def poll(self, context):
++              return context.bone
++      
++      def draw(self, context):
++              layout = self.layout
++              
++              ob = context.object
++              bone = context.bone
++              pchan = ob.pose.pose_channels[context.bone.name]
++              
++              row = layout.row()
++              col = row.column()
++              col.itemR(pchan, "lock_location")
++              col.active = not (bone.parent and bone.connected)
++              
++              col = row.column()
++              if pchan.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
++                      col.itemR(pchan, "lock_rotations_4d", text="Lock Rotation")
++                      if pchan.lock_rotations_4d:
++                              col.itemR(pchan, "lock_rotation_w", text="W")
++                      col.itemR(pchan, "lock_rotation", text="")
++              else:
++                      col.itemR(pchan, "lock_rotation", text="Rotation")
++              
++              row.column().itemR(pchan, "lock_scale")
 +
 +class BONE_PT_bone(BoneButtonsPanel):
 +      __label__ = "Bone"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              bone = context.bone
 +              arm = context.armature
 +              
 +              if not bone:
 +                      bone = context.edit_bone
 +                      pchan = None
 +              else:
 +                      pchan = ob.pose.pose_channels[context.bone.name]
 +
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemL(text="Parent:")
 +              if context.bone:
 +                      col.itemR(bone, "parent", text="")
 +              else:
 +                      col.item_pointerR(bone, "parent", arm, "edit_bones", text="")
 +              
 +              row = col.row()
 +              row.active = bone.parent != None
 +              row.itemR(bone, "connected")
 +              
 +              col.itemL(text="Layers:")
++              col.itemR(bone, "layer", text="")
 +              
 +              col = split.column()
 +              col.itemL(text="Inherit:")
 +              col.itemR(bone, "hinge", text="Rotation")
 +              col.itemR(bone, "inherit_scale", text="Scale")
 +              col.itemL(text="Display:")
 +              col.itemR(bone, "draw_wire", text="Wireframe")
 +              col.itemR(bone, "hidden", text="Hide")
 +              
 +              if ob and pchan:
 +                      split = layout.split()
 +                      
 +                      col = split.column()
 +                      col.itemL(text="Bone Group:")
 +                      col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
 +                      
 +                      col = split.column()
 +                      col.itemL(text="Custom Shape:")
 +                      col.itemR(pchan, "custom_shape", text="")
 +
 +class BONE_PT_inverse_kinematics(BoneButtonsPanel):
 +      __label__ = "Inverse Kinematics"
 +      __default_closed__ = True
 +      
 +      def poll(self, context):
 +              ob = context.object
 +              bone = context.bone
 +
 +              if ob and context.bone:
 +                      pchan = ob.pose.pose_channels[context.bone.name]
 +                      return pchan.has_ik
 +              
 +              return False
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              bone = context.bone
 +              pchan = ob.pose.pose_channels[context.bone.name]
 +
 +              split = layout.split(percentage=0.25)
 +              split.itemR(pchan, "ik_dof_x", text="X")
 +              row = split.row()
 +              row.itemR(pchan, "ik_stiffness_x", text="Stiffness")
 +              row.active = pchan.ik_dof_x
 +
 +              split = layout.split(percentage=0.25)
 +              row = split.row()
 +              row.itemR(pchan, "ik_limit_x", text="Limit")
 +              row.active = pchan.ik_dof_x
 +              row = split.row(align=True)
 +              row.itemR(pchan, "ik_min_x", text="")
 +              row.itemR(pchan, "ik_max_x", text="")
 +              row.active = pchan.ik_dof_x and pchan.ik_limit_x
 +
 +              split = layout.split(percentage=0.25)
 +              split.itemR(pchan, "ik_dof_y", text="Y")
 +              row = split.row()
 +              row.itemR(pchan, "ik_stiffness_y", text="Stiffness")
 +              row.active = pchan.ik_dof_y
 +
 +              split = layout.split(percentage=0.25)
 +              row = split.row()
 +              row.itemR(pchan, "ik_limit_y", text="Limit")
 +              row.active = pchan.ik_dof_y
 +              row = split.row(align=True)
 +              row.itemR(pchan, "ik_min_y", text="")
 +              row.itemR(pchan, "ik_max_y", text="")
 +              row.active = pchan.ik_dof_y and pchan.ik_limit_y
 +
 +              split = layout.split(percentage=0.25)
 +              split.itemR(pchan, "ik_dof_z", text="Z")
 +              row = split.row()
 +              row.itemR(pchan, "ik_stiffness_z", text="Stiffness")
 +              row.active = pchan.ik_dof_z
 +
 +              split = layout.split(percentage=0.25)
 +              row = split.row()
 +              row.itemR(pchan, "ik_limit_z", text="Limit")
 +              row.active = pchan.ik_dof_z
 +              row = split.row(align=True)
 +              row.itemR(pchan, "ik_min_z", text="")
 +              row.itemR(pchan, "ik_max_z", text="")
 +              row.active = pchan.ik_dof_z and pchan.ik_limit_z
 +
 +              split = layout.split()
 +              split.itemR(pchan, "ik_stretch", text="Stretch")
 +              split.itemL()
 +
 +class BONE_PT_deform(BoneButtonsPanel):
 +      __label__ = "Deform"
 +      __default_closed__ = True
 +
 +      def draw_header(self, context):
 +              bone = context.bone
 +              
 +              if not bone:
 +                      bone = context.edit_bone
 +                      
 +              self.layout.itemR(bone, "deform", text="")
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              bone = context.bone
 +              
 +              if not bone:
 +                      bone = context.edit_bone
 +      
 +              layout.active = bone.deform
 +                      
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemL(text="Envelope:")
 +              
 +              sub = col.column(align=True)
 +              sub.itemR(bone, "envelope_distance", text="Distance")
 +              sub.itemR(bone, "envelope_weight", text="Weight")
 +              col.itemR(bone, "multiply_vertexgroup_with_envelope", text="Multiply")
 +
 +              sub = col.column(align=True)
 +              sub.itemL(text="Radius:")
 +              sub.itemR(bone, "head_radius", text="Head")
 +              sub.itemR(bone, "tail_radius", text="Tail")
 +
 +              col = split.column()
 +              col.itemL(text="Curved Bones:")
 +              
 +              sub = col.column(align=True)
 +              sub.itemR(bone, "bbone_segments", text="Segments")
 +              sub.itemR(bone, "bbone_in", text="Ease In")
 +              sub.itemR(bone, "bbone_out", text="Ease Out")
 +              
 +              col.itemL(text="Offset:")
 +              col.itemR(bone, "cyclic_offset")
 +
 +bpy.types.register(BONE_PT_context_bone)
 +bpy.types.register(BONE_PT_transform)
++bpy.types.register(BONE_PT_transform_locks)
 +bpy.types.register(BONE_PT_bone)
 +bpy.types.register(BONE_PT_deform)
 +bpy.types.register(BONE_PT_inverse_kinematics)
index ced3c65,0000000..010acd1
mode 100644,000000..100644
--- /dev/null
@@@ -1,154 -1,0 +1,225 @@@
-               layout.itemR(curve, "curve_2d")                 
-                                                       
 +
 +import bpy
 +
 +class DataButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "data"
 +      
++      def poll(self, context):
++              return (context.object and context.object.type in ('CURVE', 'SURFACE') and context.curve)
++              
++class DataButtonsPanelCurve(DataButtonsPanel):
++      '''
++      Same as above but for curves only
++      '''
 +      def poll(self, context):
 +              return (context.object and context.object.type == 'CURVE' and context.curve)
 +
++class DataButtonsPanelActive(DataButtonsPanel):
++      '''
++      Same as above but for curves only
++      '''
++      def poll(self, context):
++              curve = context.curve
++              return (curve and curve.active_spline)
++
 +class DATA_PT_context_curve(DataButtonsPanel):
 +      __show_header__ = False
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              curve = context.curve
 +              space = context.space_data
 +
 +              split = layout.split(percentage=0.65)
 +
 +              if ob:
 +                      split.template_ID(ob, "data")
 +                      split.itemS()
 +              elif curve:
 +                      split.template_ID(space, "pin_id")
 +                      split.itemS()
 +
 +class DATA_PT_shape_curve(DataButtonsPanel):
 +      __label__ = "Shape"
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              curve = context.curve
 +              space = context.space_data
++              is_surf = (ob.type == 'SURFACE')
 +
-               sub = col.column()
-               sub.active = curve.curve_2d
-               sub.itemL(text="Caps:")
-               sub.itemR(curve, "front")
-               sub.itemR(curve, "back")
++              if not is_surf:
++                      row = layout.row()
++                      row.itemR(curve, "curve_2d")
++              
 +              split = layout.split()
 +              
 +              col = split.column()
-               sub = col.column(align=True)
-               sub.itemR(curve, "resolution_v", text="Preview V")
-               sub.itemR(curve, "render_resolution_v", text="Render V")
++              
++              if not is_surf:
++                      sub = col.column()
++                      sub.active = curve.curve_2d
++                      sub.itemL(text="Caps:")
++                      row = sub.row()
++                      row.itemR(curve, "front")
++                      row.itemR(curve, "back")
 +                      
 +              col.itemL(text="Textures:")
 +#             col.itemR(curve, "uv_orco")
 +              col.itemR(curve, "auto_texspace")
 +                      
 +              col = split.column()    
 +              col.itemL(text="Resolution:")
 +              sub = col.column(align=True)
 +              sub.itemR(curve, "resolution_u", text="Preview U")
 +              sub.itemR(curve, "render_resolution_u", text="Render U")
- class DATA_PT_geometry_curve(DataButtonsPanel):
++
++              if is_surf:
++                      sub = col.column(align=True)
++                      sub.itemR(curve, "resolution_v", text="Preview V")
++                      sub.itemR(curve, "render_resolution_v", text="Render V")
++              
++              # XXX - put somewhere nicer.
++              row= layout.row()
++              row.itemR(curve, "twist_mode")
++              row.itemR(curve, "twist_smooth") # XXX - may not be kept
++
 +
 +#             col.itemL(text="Display:")
 +#             col.itemL(text="HANDLES")
 +#             col.itemL(text="NORMALS")
 +#             col.itemR(curve, "vertex_normal_flip")
 +
++class DATA_PT_geometry_curve(DataButtonsPanelCurve):
 +      __label__ = "Geometry "
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              curve = context.curve
- class DATA_PT_pathanim(DataButtonsPanel):
++              
 +              split = layout.split()
 +      
 +              col = split.column()
 +              col.itemL(text="Modification:")
 +              col.itemR(curve, "width")
 +              col.itemR(curve, "extrude")
 +              col.itemR(curve, "taper_object", icon='ICON_OUTLINER_OB_CURVE')
 +              
 +              col = split.column()
 +              col.itemL(text="Bevel:")
 +              col.itemR(curve, "bevel_depth", text="Depth")
 +              col.itemR(curve, "bevel_resolution", text="Resolution")
 +              col.itemR(curve, "bevel_object", icon='ICON_OUTLINER_OB_CURVE')
++
 +      
-               self.layout.itemR(curve, "path", text="")
++class DATA_PT_pathanim(DataButtonsPanelCurve):
 +      __label__ = "Path Animation"
 +      
 +      def draw_header(self, context):
 +              curve = context.curve
 +
-               layout.active = curve.path      
++              self.layout.itemR(curve, "use_path", text="")
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              curve = context.curve
 +              
-               col.itemR(curve, "follow")
++              layout.active = curve.use_path  
 +              
 +              split = layout.split()          
 +              
 +              col = split.column()
 +              col.itemR(curve, "path_length", text="Frames")
-               col.itemR(curve, "stretch")
-               col.itemR(curve, "offset_path_distance", text="Offset Children")
++              col.itemR(curve, "use_path_follow")
 +
 +              col = split.column()
- class DATA_PT_current_curve(DataButtonsPanel):
-       __label__ = "Current Curve"
++              col.itemR(curve, "use_stretch")
++              col.itemR(curve, "use_time_offset", text="Offset Children")
 +      
-               currentcurve = context.curve.curves[0] # XXX
++class DATA_PT_active_spline(DataButtonsPanelActive):
++      __label__ = "Active Spline"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
-       
-               col = split.column()
-               col.itemL(text="Cyclic:")
-               col.itemR(currentcurve, "cyclic_u", text="U")
-               col.itemR(currentcurve, "cyclic_v", text="V")
-               col.itemL(text="Order:")
-               col.itemR(currentcurve, "order_u", text="U")
-               col.itemR(currentcurve, "order_v", text="V")
-               col.itemL(text="Endpoints:")
-               col.itemR(currentcurve, "endpoint_u", text="U")
-               col.itemR(currentcurve, "endpoint_v", text="V")
++              ob = context.object
++              curve = context.curve
++              act_spline = curve.active_spline
++              is_surf = (ob.type == 'SURFACE')
++              is_poly = (act_spline.type == 'POLY')
++              
 +              split = layout.split()
-               col = split.column()
-               col.itemL(text="Bezier:")
-               col.itemR(currentcurve, "bezier_u", text="U")
-               col.itemR(currentcurve, "bezier_v", text="V")
-               col.itemL(text="Resolution:")
-               col.itemR(currentcurve, "resolution_u", text="U")
-               col.itemR(currentcurve, "resolution_v", text="V")
-               col.itemL(text="Interpolation:")
-               col.itemR(currentcurve, "tilt_interpolation", text="Tilt")
-               col.itemR(currentcurve, "radius_interpolation", text="Tilt")
-               col.itemR(currentcurve, "smooth")
 +              
- bpy.types.register(DATA_PT_current_curve)
++              if is_poly:
++                      # These settings are below but its easier to have 
++                      # poly's set aside since they use so few settings
++                      col = split.column()
++                      col.itemL(text="Cyclic:")
++                      col.itemR(act_spline, "smooth")
++                      col = split.column()
++                      col.itemR(act_spline, "cyclic_u", text="U")
 +              
++              else:
++                      col = split.column()
++                      col.itemL(text="Cyclic:")
++                      if act_spline.type == 'NURBS':
++                              col.itemL(text="Bezier:")
++                              col.itemL(text="Endpoint:")
++                              col.itemL(text="Order:")
++                      
++                      col.itemL(text="Resolution:")
++                                      
++                      col = split.column()
++                      col.itemR(act_spline, "cyclic_u", text="U")
++                      
++                      if act_spline.type == 'NURBS':
++                              sub = col.column()
++                              # sub.active = (not act_spline.cyclic_u)
++                              sub.itemR(act_spline, "bezier_u", text="U")
++                              sub.itemR(act_spline, "endpoint_u", text="U")
++                              
++                              sub = col.column()
++                              sub.itemR(act_spline, "order_u", text="U")
++                      col.itemR(act_spline, "resolution_u", text="U")
++                      
++                      if is_surf:
++                              col = split.column()
++                              col.itemR(act_spline, "cyclic_v", text="V")
++                              
++                              # its a surface, assume its a nurb.
++                              sub = col.column()
++                              sub.active = (not act_spline.cyclic_v)
++                              sub.itemR(act_spline, "bezier_v", text="V")
++                              sub.itemR(act_spline, "endpoint_v", text="V")
++                              sub = col.column()
++                              sub.itemR(act_spline, "order_v", text="V")
++                              sub.itemR(act_spline, "resolution_v", text="V")
++
++                      
++                      if not is_surf:
++                              split = layout.split()
++                              col = split.column()
++                              col.active = (not curve.curve_2d)
++                              
++                              col.itemL(text="Interpolation:")
++                              col.itemR(act_spline, "tilt_interpolation", text="Tilt")
++                              col.itemR(act_spline, "radius_interpolation", text="Radius")
++                      
++                      split = layout.split()
++                      col = split.column()
++                      col.itemR(act_spline, "smooth")
++
++
 +bpy.types.register(DATA_PT_context_curve)
 +bpy.types.register(DATA_PT_shape_curve)
 +bpy.types.register(DATA_PT_geometry_curve)
 +bpy.types.register(DATA_PT_pathanim)
++bpy.types.register(DATA_PT_active_spline)
index 98c9b88,0000000..c07f313
mode 100644,000000..100644
--- /dev/null
@@@ -1,23 -1,0 +1,23 @@@
-               layout.itemR(ob, "empty_draw_type")
-               layout.itemR(ob, "empty_draw_size")
 +
 +import bpy
 +
 +class DataButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "data"
 +      
 +      def poll(self, context):
 +              return (context.object and context.object.type == 'EMPTY')
 +      
 +class DATA_PT_empty(DataButtonsPanel):
 +      __label__ = "Empty"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +
++              layout.itemR(ob, "empty_draw_type", text="Draw Type")
++              layout.itemR(ob, "empty_draw_size", text="Draw Size")
 +              
 +bpy.types.register(DATA_PT_empty)
index 2835f55,0000000..754e8ce
mode 100644,000000..100644
--- /dev/null
@@@ -1,446 -1,0 +1,449 @@@
-               layout.itemO("object.meshdeform_bind", text="Bind")
-               row = layout.row()
-               row.itemR(md, "precision")
-               row.itemR(md, "dynamic")
 +
 +import bpy
 +
 +class DataButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "modifier"
 +      
 +class DATA_PT_modifiers(DataButtonsPanel):
 +      __label__ = "Modifiers"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +
 +              row = layout.row()
 +              row.item_menu_enumO("object.modifier_add", "type")
 +              row.itemL()
 +
 +              for md in ob.modifiers:
 +                      box = layout.template_modifier(md)
 +                      if box:
 +                              # match enum type to our functions, avoids a lookup table.
 +                              getattr(self, md.type)(box, ob, md)
 +      
 +      # the mt.type enum is (ab)used for a lookup on function names
 +      # ...to avoid lengthy if statements
 +      # so each type must have a function here.
 +
 +      def ARMATURE(self, layout, ob, md):
 +              layout.itemR(md, "object")
 +              
 +              split = layout.split(percentage=0.5)
 +              split.itemL(text="Vertex Group:")
 +              sub = split.split(percentage=0.7)
 +              sub.item_pointerR(md, "vertex_group", ob, "vertex_groups", text="")
 +              subsub = sub.row()
 +              subsub.active = md.vertex_group
 +              subsub.itemR(md, "invert")
 +              
 +              layout.itemS()
 +              
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemL(text="Bind To:")
 +              col.itemR(md, "use_vertex_groups", text="Vertex Groups")
 +              col.itemR(md, "use_bone_envelopes", text="Bone Envelopes")
 +              
 +              col = split.column()
 +              col.itemL(text="Deformation:")
 +              col.itemR(md, "quaternion")
 +              col.itemR(md, "multi_modifier")
 +              
 +      def ARRAY(self, layout, ob, md):
 +              layout.itemR(md, "fit_type")
 +              if md.fit_type == 'FIXED_COUNT':
 +                      layout.itemR(md, "count")
 +              elif md.fit_type == 'FIT_LENGTH':
 +                      layout.itemR(md, "length")
 +              elif md.fit_type == 'FIT_CURVE':
 +                      layout.itemR(md, "curve")
 +
 +              layout.itemS()
 +              
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(md, "constant_offset")
 +              sub = col.column()
 +              sub.active = md.constant_offset
 +              sub.itemR(md, "constant_offset_displacement", text="")
 +
 +              col.itemS()
 +
 +              col.itemR(md, "merge_adjacent_vertices", text="Merge")
 +              sub = col.column()
 +              sub.active = md.merge_adjacent_vertices
 +              sub.itemR(md, "merge_end_vertices", text="First Last")
 +              sub.itemR(md, "merge_distance", text="Distance")
 +              
 +              col = split.column()
 +              col.itemR(md, "relative_offset")
 +              sub = col.column()
 +              sub.active = md.relative_offset
 +              sub.itemR(md, "relative_offset_displacement", text="")
 +
 +              col.itemS()
 +
 +              col.itemR(md, "add_offset_object")
 +              sub = col.column()
 +              sub.active = md.add_offset_object
 +              sub.itemR(md, "offset_object", text="")
 +
 +              layout.itemS()
 +              
 +              col = layout.column()
 +              col.itemR(md, "start_cap")
 +              col.itemR(md, "end_cap")
 +      
 +      def BEVEL(self, layout, ob, md):
 +              row = layout.row()
 +              row.itemR(md, "width")
 +              row.itemR(md, "only_vertices")
 +              
 +              layout.itemL(text="Limit Method:")
 +              layout.row().itemR(md, "limit_method", expand=True)
 +              if md.limit_method == 'ANGLE':
 +                      layout.itemR(md, "angle")
 +              elif md.limit_method == 'WEIGHT':
 +                      layout.row().itemR(md, "edge_weight_method", expand=True)
 +                      
 +      def BOOLEAN(self, layout, ob, md):
 +              layout.itemR(md, "operation")
 +              layout.itemR(md, "object")
 +              
 +      def BUILD(self, layout, ob, md):
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(md, "start")
 +              col.itemR(md, "length")
 +
 +              col = split.column()
 +              col.itemR(md, "randomize")
 +              sub = col.column()
 +              sub.active = md.randomize
 +              sub.itemR(md, "seed")
 +
 +      def CAST(self, layout, ob, md):
 +              layout.itemR(md, "cast_type")
 +              layout.itemR(md, "object")
 +              if md.object:
 +                      layout.itemR(md, "use_transform")
 +              
 +              flow = layout.column_flow()
 +              flow.itemR(md, "x")
 +              flow.itemR(md, "y")
 +              flow.itemR(md, "z")
 +              flow.itemR(md, "factor")
 +              flow.itemR(md, "radius")
 +              flow.itemR(md, "size")
 +
 +              layout.itemR(md, "from_radius")
 +              
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              
 +      def CLOTH(self, layout, ob, md):
 +              layout.itemL(text="See Cloth panel.")
 +              
 +      def COLLISION(self, layout, ob, md):
 +              layout.itemL(text="See Collision panel.")
 +              
 +      def CURVE(self, layout, ob, md):
 +              layout.itemR(md, "object")
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "deform_axis")
 +              
 +      def DECIMATE(self, layout, ob, md):
 +              layout.itemR(md, "ratio")
 +              layout.itemR(md, "face_count")
 +              
 +      def DISPLACE(self, layout, ob, md):
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "texture")
 +              layout.itemR(md, "midlevel")
 +              layout.itemR(md, "strength")
 +              layout.itemR(md, "direction")
 +              layout.itemR(md, "texture_coordinates")
 +              if md.texture_coordinates == 'OBJECT':
 +                      layout.itemR(md, "texture_coordinate_object", text="Object")
 +              elif md.texture_coordinates == 'UV' and ob.type == 'MESH':
 +                      layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
 +      
 +      def EDGE_SPLIT(self, layout, ob, md):
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(md, "use_edge_angle", text="Edge Angle")
 +              sub = col.column()
 +              sub.active = md.use_edge_angle
 +              sub.itemR(md, "split_angle")
 +              
 +              col = split.column()
 +              col.itemR(md, "use_sharp", text="Sharp Edges")
 +              
 +      def EXPLODE(self, layout, ob, md):
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "protect")
 +
 +              flow = layout.column_flow(2)
 +              flow.itemR(md, "split_edges")
 +              flow.itemR(md, "unborn")
 +              flow.itemR(md, "alive")
 +              flow.itemR(md, "dead")
 +
 +              layout.itemO("object.explode_refresh", text="Refresh");
 +              
 +      def FLUID_SIMULATION(self, layout, ob, md):
 +              layout.itemL(text="See Fluid panel.")
 +              
 +      def HOOK(self, layout, ob, md):
 +              col = layout.column()
 +              col.itemR(md, "object")
 +              if md.object and md.object.type == 'ARMATURE':
 +                      layout.item_pointerR(md, "subtarget", md.object.data, "bones", text="Bone")
 +              
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +
 +              split = layout.split()
 +              split.itemR(md, "falloff")
 +              split.itemR(md, "force", slider=True)
 +
 +              layout.itemS()
 +
 +              row = layout.row()
 +              row.itemO("object.hook_reset", text="Reset")
 +              row.itemO("object.hook_recenter", text="Recenter")
 +
 +              if ob.mode == 'EDIT':
 +                      row = layout.row()
 +                      row.itemO("object.hook_select", text="Select")
 +                      row.itemO("object.hook_assign", text="Assign")
 +              
 +      def LATTICE(self, layout, ob, md):
 +              layout.itemR(md, "object")
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              
 +      def MASK(self, layout, ob, md):
 +              layout.itemR(md, "mode")
 +              if md.mode == 'ARMATURE':
 +                      layout.itemR(md, "armature")
 +              elif md.mode == 'VERTEX_GROUP':
 +                      layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "inverse")
 +              
 +      def MESH_DEFORM(self, layout, ob, md):
 +              layout.itemR(md, "object")
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "invert")
 +
 +              layout.itemS()
 +              
++              if md.is_bound:
++                      layout.itemO("object.meshdeform_bind", text="Unbind")
++              else:
++                      layout.itemO("object.meshdeform_bind", text="Bind")
++                      row = layout.row()
++                      row.itemR(md, "precision")
++                      row.itemR(md, "dynamic")
 +              
 +      def MIRROR(self, layout, ob, md):
 +              layout.itemR(md, "merge_limit")
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(md, "x")
 +              col.itemR(md, "y")
 +              col.itemR(md, "z")
 +              
 +              col = split.column()
 +              col.itemL(text="Textures:")
 +              col.itemR(md, "mirror_u")
 +              col.itemR(md, "mirror_v")
 +              
 +              col = split.column()
 +              col.itemR(md, "clip", text="Do Clipping")
 +              col.itemR(md, "mirror_vertex_groups", text="Vertex Group")
 +              
 +              layout.itemR(md, "mirror_object")
 +              
 +      def MULTIRES(self, layout, ob, md):
 +              layout.itemR(md, "subdivision_type")
 +              
 +              row = layout.row()
 +              row.itemO("object.multires_subdivide", text="Subdivide")
 +              row.itemO("object.multires_higher_levels_delete", text="Delete Higher")
 +
 +              layout.itemR(md, "level")
 +      
 +      def PARTICLE_INSTANCE(self, layout, ob, md):
 +              layout.itemR(md, "object")
 +              layout.itemR(md, "particle_system_number")
 +              
 +              flow = layout.column_flow()
 +              flow.itemR(md, "normal")
 +              flow.itemR(md, "children")
 +              flow.itemR(md, "size")
 +              flow.itemR(md, "path")
 +              if md.path:
 +                      flow.itemR(md, "keep_shape")
 +              flow.itemR(md, "unborn")
 +              flow.itemR(md, "alive")
 +              flow.itemR(md, "dead")
 +              flow.itemL(md, "")
 +              if md.path:
 +                      flow.itemR(md, "axis", text="")
 +              
 +              if md.path:
 +                      row = layout.row()
 +                      row.itemR(md, "position", slider=True)
 +                      row.itemR(md, "random_position", text = "Random", slider=True)
 +              
 +      def PARTICLE_SYSTEM(self, layout, ob, md):
 +              layout.itemL(text="See Particle panel.")
 +              
 +      def SHRINKWRAP(self, layout, ob, md):
 +              layout.itemR(md, "target")
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "offset")
 +              layout.itemR(md, "subsurf_levels")
 +              layout.itemR(md, "mode")
 +              if md.mode == 'PROJECT':
 +                      layout.itemR(md, "subsurf_levels")
 +                      layout.itemR(md, "auxiliary_target")
 +              
 +                      row = layout.row()
 +                      row.itemR(md, "x")
 +                      row.itemR(md, "y")
 +                      row.itemR(md, "z")
 +              
 +                      flow = layout.column_flow()
 +                      flow.itemR(md, "negative")
 +                      flow.itemR(md, "positive")
 +                      flow.itemR(md, "cull_front_faces")
 +                      flow.itemR(md, "cull_back_faces")
 +              elif md.mode == 'NEAREST_SURFACEPOINT':
 +                      layout.itemR(md, "keep_above_surface")
 +              
 +      def SIMPLE_DEFORM(self, layout, ob, md):
 +              layout.itemR(md, "mode")
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "origin")
 +              layout.itemR(md, "relative")
 +              layout.itemR(md, "factor")
 +              layout.itemR(md, "limits")
 +              if md.mode in ('TAPER', 'STRETCH'):
 +                      layout.itemR(md, "lock_x_axis")
 +                      layout.itemR(md, "lock_y_axis")
 +                      
 +      def SMOKE(self, layout, ob, md):
 +              layout.itemL(text="See Smoke panel.")
 +      
 +      def SMOOTH(self, layout, ob, md):
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(md, "x")
 +              col.itemR(md, "y")
 +              col.itemR(md, "z")
 +              
 +              col = split.column()
 +              col.itemR(md, "factor")
 +              col.itemR(md, "repeat")
 +              
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              
 +      def SOFT_BODY(self, layout, ob, md):
 +              layout.itemL(text="See Soft Body panel.")
 +      
 +      def SUBSURF(self, layout, ob, md):
 +              layout.row().itemR(md, "subdivision_type", expand=True)
 +              
 +              flow = layout.column_flow()
 +              flow.itemR(md, "levels", text="Preview")
 +              flow.itemR(md, "render_levels", text="Render")
 +              flow.itemR(md, "optimal_draw", text="Optimal Display")
 +              flow.itemR(md, "subsurf_uv")
 +
 +      def SURFACE(self, layout, ob, md):
 +              layout.itemL(text="See Fields panel.")
 +      
 +      def UV_PROJECT(self, layout, ob, md):
 +              if ob.type == 'MESH':
 +                      layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
 +                      layout.itemR(md, "image")
 +                      layout.itemR(md, "override_image")
 +
 +                      split = layout.split()
 +
 +                      col = split.column()
 +                      col.itemL(text="Aspect Ratio:")
 +
 +                      sub = col.column(align=True)
 +                      sub.itemR(md, "horizontal_aspect_ratio", text="Horizontal")
 +                      sub.itemR(md, "vertical_aspect_ratio", text="Vertical")
 +
 +                      col = split.column()
 +                      col.itemL(text="Projectors:")
 +
 +                      sub = col.column(align=True)
 +                      sub.itemR(md, "num_projectors", text="Number")
 +                      for proj in md.projectors:
 +                              sub.itemR(proj, "object", text="")
 +              
 +      def WAVE(self, layout, ob, md):
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemL(text="Motion:")
 +              col.itemR(md, "x")
 +              col.itemR(md, "y")
 +              col.itemR(md, "cyclic")
 +              
 +              col = split.column()
 +              col.itemR(md, "normals")
 +              sub = col.column()
 +              sub.active = md.normals
 +              sub.itemR(md, "x_normal", text="X")
 +              sub.itemR(md, "y_normal", text="Y")
 +              sub.itemR(md, "z_normal", text="Z")
 +              
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemL(text="Time:")
 +              sub = col.column(align=True)
 +              sub.itemR(md, "time_offset", text="Offset")
 +              sub.itemR(md, "lifetime", text="Life")
 +              col.itemR(md, "damping_time", text="Damping")
 +              
 +              col = split.column()
 +              col.itemL(text="Position:")
 +              sub = col.column(align=True)
 +              sub.itemR(md, "start_position_x", text="X")
 +              sub.itemR(md, "start_position_y", text="Y")
 +              col.itemR(md, "falloff_radius", text="Falloff")
 +              
 +              layout.itemS()
 +              
 +              layout.itemR(md, "start_position_object")
 +              layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 +              layout.itemR(md, "texture")
 +              layout.itemR(md, "texture_coordinates")
 +              if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
 +                      layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
 +              elif md.texture_coordinates == 'OBJECT':
 +                      layout.itemR(md, "texture_coordinates_object")
 +              
 +              layout.itemS()
 +              
 +              flow = layout.column_flow()
 +              flow.itemR(md, "speed", slider=True)
 +              flow.itemR(md, "height", slider=True)
 +              flow.itemR(md, "width", slider=True)
 +              flow.itemR(md, "narrowness", slider=True)
 +
 +bpy.types.register(DATA_PT_modifiers)
index aabf218,0000000..d0e7ea0
mode 100644,000000..100644
--- /dev/null
@@@ -1,156 -1,0 +1,183 @@@
 +
 +import bpy
 +
 +class DataButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "data"
 +      
 +      def poll(self, context):
 +              return (context.object and context.object.type == 'TEXT' and context.curve)
 +
 +class DATA_PT_context_text(DataButtonsPanel):
 +      __show_header__ = False
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              curve = context.curve
 +              space = context.space_data
 +
 +              split = layout.split(percentage=0.65)
 +
 +              if ob:
 +                      split.template_ID(ob, "data")
 +                      split.itemS()
 +              elif curve:
 +                      split.template_ID(space, "pin_id")
 +                      split.itemS()
 +
 +class DATA_PT_shape_text(DataButtonsPanel):
 +      __label__ = "Shape Text"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              curve = context.curve
 +              space = context.space_data
 +
-               col.itemR(curve, "front")
-               col.itemR(curve, "back")
 +              layout.itemR(curve, "curve_2d")                 
 +                                                      
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemL(text="Caps:")
-               sub.itemR(curve, "resolution_v", text="Preview V")
-               sub.itemR(curve, "render_resolution_v", text="Render V")
++              row = col.row()
++              row .itemR(curve, "front")
++              row .itemR(curve, "back")
++              # col = split.column()
 +              col.itemL(text="Textures:")
 +              col.itemR(curve, "uv_orco")
 +              col.itemR(curve, "auto_texspace")
 +                      
 +              col = split.column()    
 +              col.itemL(text="Resolution:")
 +              sub = col.column(align=True)
 +              sub.itemR(curve, "resolution_u", text="Preview U")
 +              sub.itemR(curve, "render_resolution_u", text="Render U")
++              
++              # resolution_v is not used for text
++              
 +              sub = col.column(align=True)
-               col.itemR(curve, "fast")
 +              col.itemL(text="Display:")
-               col.itemR(curve, "taper_object")
++              col.itemR(curve, "fast", text="Fast Editing")
 +
 +class DATA_PT_geometry_text(DataButtonsPanel):
 +      __label__ = "Geometry"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              curve = context.curve
 +
 +              split = layout.split()
 +      
 +              col = split.column()
 +              col.itemL(text="Modification:")
 +              col.itemR(curve, "width")
 +              col.itemR(curve, "extrude")
-               col.itemR(curve, "bevel_object")
++              col.itemL(text="Taper Object:")
++              col.itemR(curve, "taper_object", text="")
 +              
 +              col = split.column()
 +              col.itemL(text="Bevel:")
 +              col.itemR(curve, "bevel_depth", text="Depth")
 +              col.itemR(curve, "bevel_resolution", text="Resolution")
-       #       col.itemR(text, "style")
-       #       col.itemR(text, "bold")
-       #       col.itemR(text, "italic")
-       #       col.itemR(text, "underline")
-       #       ToDo: These settings are in a sub struct (Edit Format). 
-               col.itemR(text, "text_size")            
-               col.itemR(text, "shear")
++              col.itemL(text="Bevel Object:")
++              col.itemR(curve, "bevel_object", text="")
 +
 +class DATA_PT_font(DataButtonsPanel):
 +      __label__ = "Font"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              text = context.curve
++              char = context.curve.edit_format
 +
 +              layout.itemR(text, "font")
 +              
++              row = layout.row()
++              row.itemR(text, "text_size", text="Size")       
++              row.itemR(text, "shear")
++              
 +              split = layout.split()
 +              
 +              col = split.column()    
-               col.itemR(text, "text_on_curve")
-               col.itemR(text, "family")
++              col.itemL(text="Object Font:")
++              col.itemR(text, "family", text="")
 +
 +              col = split.column()
-               col.itemR(text, "ul_height", text="Height")
-       #       col.itemR(text, "edit_format")
++              col.itemL(text="Text on Curve:")
++              col.itemR(text, "text_on_curve", text="")
++              
++              split = layout.split()
++              
++              col = split.column()
++              col.itemL(text="Character:")
++              col.itemR(char, "bold")
++              col.itemR(char, "italic")
++              col.itemR(char, "underline")
++#             col.itemR(char, "style")
++#             col.itemR(char, "wrap")
++
++              col = split.column(align=True)
 +              col.itemL(text="Underline:")
 +              col.itemR(text, "ul_position", text="Position")
-               #col.itemR(text, "wrap")
++              col.itemR(text, "ul_height", text="Thickness")
++              
 +
 +class DATA_PT_paragraph(DataButtonsPanel):
 +      __label__ = "Paragraph"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              text = context.curve
 +
 +              layout.itemL(text="Align:")
 +              layout.itemR(text, "spacemode", expand=True)
 +
 +              split = layout.split()
 +              
 +              col = split.column(align=True)  
 +              col.itemL(text="Spacing:")
 +              col.itemR(text, "spacing", text="Character")
 +              col.itemR(text, "word_spacing", text="Word")
 +              col.itemR(text, "line_dist", text="Line")
 +
 +              col = split.column(align=True)
 +              col.itemL(text="Offset:")
 +              col.itemR(text, "offset_x", text="X")
 +              col.itemR(text, "offset_y", text="Y")
- """           
 +
-               __label__ = "Text Boxes"
++
 +class DATA_PT_textboxes(DataButtonsPanel):
-               def draw(self, context):
-                       layout = self.layout
++      __label__ = "Text Boxes"
 +
-                       text = context.curve
- """
++      def draw(self, context):
++              layout = self.layout
 +                      
- #bpy.types.register(DATA_PT_textboxes)
++              text = context.curve
++              
++              for box in text.textboxes:
++                      split = layout.box().split()
++                      
++                      col = split.column(align=True)
++                      col.itemL(text="Dimensions:")
++                      col.itemR(box, "width", text="Width")
++                      col.itemR(box, "height", text="Height")
++              
++                      col = split.column(align=True)  
++                      col.itemL(text="Offset:")
++                      col.itemR(box, "x", text="X")
++                      col.itemR(box, "y", text="Y")
 +
 +bpy.types.register(DATA_PT_context_text)      
 +bpy.types.register(DATA_PT_shape_text)        
 +bpy.types.register(DATA_PT_geometry_text)
 +bpy.types.register(DATA_PT_font)
 +bpy.types.register(DATA_PT_paragraph)
++bpy.types.register(DATA_PT_textboxes)
index cdc18e3,0000000..ff3231a
mode 100644,000000..100644
--- /dev/null
@@@ -1,527 -1,0 +1,535 @@@
-               row = layout.row()
-               row.itemR(con, "curve_follow")
-               row.itemR(con, "offset")
 +
 +import bpy
 +
 +class ConstraintButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "constraint"
 +
 +      def draw_constraint(self, con):
 +              layout = self.layout
 +              
 +              box = layout.template_constraint(con)
 +
 +              if box:
 +                      # match enum type to our functions, avoids a lookup table.
 +                      getattr(self, con.type)(box, con)
 +      
 +                      # show/key buttons here are most likely obsolete now, with
 +                      # keyframing functionality being part of every button
 +                      if con.type not in ('RIGID_BODY_JOINT', 'NULL'):
 +                              box.itemR(con, "influence")
 +      
 +      def space_template(self, layout, con, target=True, owner=True):
 +              if target or owner:
 +                      row = layout.row()
 +
 +                      row.itemL(text="Convert:")
 +
 +                      if target:
 +                              row.itemR(con, "target_space", text="")
 +
 +                      if target and owner:
 +                              row.itemL(icon='ICON_ARROW_LEFTRIGHT')
 +
 +                      if owner:
 +                              row.itemR(con, "owner_space", text="")
 +                      
 +      def target_template(self, layout, con, subtargets=True):
 +              layout.itemR(con, "target") # XXX limiting settings for only 'curves' or some type of object
 +              
 +              if con.target and subtargets:
 +                      if con.target.type == 'ARMATURE':
 +                              layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
 +                              
 +                              if con.type == 'COPY_LOCATION':
 +                                      row = layout.row()
 +                                      row.itemL(text="Head/Tail:")
 +                                      row.itemR(con, "head_tail", text="")
 +                      elif con.target.type in ('MESH', 'LATTICE'):
 +                              layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
 +      
 +      def CHILD_OF(self, layout, con):
 +              self.target_template(layout, con)
 +
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemL(text="Location:")
 +              col.itemR(con, "locationx", text="X")
 +              col.itemR(con, "locationy", text="Y")
 +              col.itemR(con, "locationz", text="Z")
 +              
 +              col = split.column()
 +              col.itemL(text="Rotation:")
 +              col.itemR(con, "rotationx", text="X")
 +              col.itemR(con, "rotationy", text="Y")
 +              col.itemR(con, "rotationz", text="Z")
 +              
 +              col = split.column()
 +              col.itemL(text="Scale:")
 +              col.itemR(con, "sizex", text="X")
 +              col.itemR(con, "sizey", text="Y")
 +              col.itemR(con, "sizez", text="Z")
 +              
 +              row = layout.row()
 +              row.itemO("constraint.childof_set_inverse")
 +              row.itemO("constraint.childof_clear_inverse")
 +              
 +      def TRACK_TO(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              row = layout.row()
 +              row.itemL(text="To:")
 +              row.itemR(con, "track", expand=True)
 +              
 +              row = layout.row()
 +              #row.itemR(con, "up", text="Up", expand=True) # XXX: up and expand don't play nice together
 +              row.itemR(con, "up", text="Up")
 +              row.itemR(con, "target_z")
 +              
 +              self.space_template(layout, con)
 +              
 +      def IK(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              layout.itemR(con, "pole_target")
 +      
 +              if con.pole_target and con.pole_target.type == 'ARMATURE':
 +                      layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
 +              
 +              split = layout.split()
 +      
 +              col = split.column()
 +              col.itemR(con, "iterations")
 +              col.itemR(con, "chain_length")
 +              sub = col.column()
 +              sub.active = con.pole_target
 +              sub.itemR(con, "pole_angle")
 +              col.itemL(text="Weight:")
 +              col.itemR(con, "weight", text="Position", slider=True)
 +              sub = col.column()
 +              sub.active = con.rotation
 +              sub.itemR(con, "orient_weight", text="Rotation", slider=True)
 +              
 +              col = split.column()
 +              col.itemR(con, "tail")
 +              col.itemR(con, "rotation")
 +              col.itemR(con, "targetless")
 +              col.itemR(con, "stretch")
 +              
 +      def FOLLOW_PATH(self, layout, con):
 +              self.target_template(layout, con)
 +              
++              split = layout.split()
++              
++              col = split.column()
++              col.itemR(con, "curve_follow")
++              
++              col = split.column()
++              col.itemR(con, "fixed_position")
++              if con.fixed_position:
++                      col.itemR(con, "offset_percentage", text="Offset")
++              else:
++                      col.itemR(con, "offset")
 +              
 +              row = layout.row()
 +              row.itemL(text="Forward:")
 +              row.itemR(con, "forward", expand=True)
 +              
 +              row = layout.row()
 +              row.itemR(con, "up", text="Up")
 +              row.itemL()
 +              
 +      def LIMIT_ROTATION(self, layout, con):
 +              
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(con, "use_limit_x")
 +              sub = col.column()
 +              sub.active = con.use_limit_x
 +              sub.itemR(con, "minimum_x", text="Min")
 +              sub.itemR(con, "maximum_x", text="Max")
 +              
 +              col = split.column()
 +              col.itemR(con, "use_limit_y")
 +              sub = col.column()
 +              sub.active = con.use_limit_y
 +              sub.itemR(con, "minimum_y", text="Min")
 +              sub.itemR(con, "maximum_y", text="Max")
 +              
 +              col = split.column()
 +              col.itemR(con, "use_limit_z")
 +              sub = col.column()
 +              sub.active = con.use_limit_z
 +              sub.itemR(con, "minimum_z", text="Min")
 +              sub.itemR(con, "maximum_z", text="Max")
 +              
 +              row = layout.row()
 +              row.itemR(con, "limit_transform")
 +              row.itemL()
 +              
 +              row = layout.row()
 +              row.itemL(text="Convert:")
 +              row.itemR(con, "owner_space", text="")
 +              
 +      def LIMIT_LOCATION(self, layout, con):
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(con, "use_minimum_x")
 +              sub = col.column()
 +              sub.active = con.use_minimum_x
 +              sub.itemR(con, "minimum_x", text="")
 +              col.itemR(con, "use_maximum_x")
 +              sub = col.column()
 +              sub.active = con.use_maximum_x
 +              sub.itemR(con, "maximum_x", text="")
 +              
 +              col = split.column()
 +              col.itemR(con, "use_minimum_y")
 +              sub = col.column()
 +              sub.active = con.use_minimum_y
 +              sub.itemR(con, "minimum_y", text="")
 +              col.itemR(con, "use_maximum_y")
 +              sub = col.column()
 +              sub.active = con.use_maximum_y
 +              sub.itemR(con, "maximum_y", text="")
 +              
 +              col = split.column()
 +              col.itemR(con, "use_minimum_z")
 +              sub = col.column()
 +              sub.active = con.use_minimum_z
 +              sub.itemR(con, "minimum_z", text="")
 +              col.itemR(con, "use_maximum_z")
 +              sub = col.column()
 +              sub.active = con.use_maximum_z
 +              sub.itemR(con, "maximum_z", text="")
 +      
 +              row = layout.row()
 +              row.itemR(con, "limit_transform")
 +              row.itemL()
 +              
 +              row = layout.row()
 +              row.itemL(text="Convert:")
 +              row.itemR(con, "owner_space", text="")
 +              
 +      def LIMIT_SCALE(self, layout, con):
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemR(con, "use_minimum_x")
 +              sub = col.column()
 +              sub.active = con.use_minimum_x
 +              sub.itemR(con, "minimum_x", text="")
 +              col.itemR(con, "use_maximum_x")
 +              sub = col.column()
 +              sub.active = con.use_maximum_x
 +              sub.itemR(con, "maximum_x", text="")
 +              
 +              col = split.column()
 +              col.itemR(con, "use_minimum_y")
 +              sub = col.column()
 +              sub.active = con.use_minimum_y
 +              sub.itemR(con, "minimum_y", text="")
 +              col.itemR(con, "use_maximum_y")
 +              sub = col.column()
 +              sub.active = con.use_maximum_y
 +              sub.itemR(con, "maximum_y", text="")
 +              
 +              col = split.column()
 +              col.itemR(con, "use_minimum_z")
 +              sub = col.column()
 +              sub.active = con.use_minimum_z
 +              sub.itemR(con, "minimum_z", text="")
 +              col.itemR(con, "use_maximum_z")
 +              sub = col.column()
 +              sub.active = con.use_maximum_z
 +              sub.itemR(con, "maximum_z", text="")
 +              
 +              row = layout.row()
 +              row.itemR(con, "limit_transform")
 +              row.itemL()
 +              
 +              row = layout.row()
 +              row.itemL(text="Convert:")
 +              row.itemR(con, "owner_space", text="")
 +      
 +      def COPY_ROTATION(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(con, "rotate_like_x", text="X")
 +              sub = col.column()
 +              sub.active = con.rotate_like_x
 +              sub.itemR(con, "invert_x", text="Invert")
 +              
 +              col = split.column()
 +              col.itemR(con, "rotate_like_y", text="Y")
 +              sub = col.column()
 +              sub.active = con.rotate_like_y
 +              sub.itemR(con, "invert_y", text="Invert")
 +              
 +              col = split.column()
 +              col.itemR(con, "rotate_like_z", text="Z")
 +              sub = col.column()
 +              sub.active = con.rotate_like_z
 +              sub.itemR(con, "invert_z", text="Invert")
 +
 +              layout.itemR(con, "offset")
 +              
 +              self.space_template(layout, con)
 +              
 +      def COPY_LOCATION(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemR(con, "locate_like_x", text="X")
 +              sub = col.column()
 +              sub.active = con.locate_like_x
 +              sub.itemR(con, "invert_x", text="Invert")
 +              
 +              col = split.column()
 +              col.itemR(con, "locate_like_y", text="Y")
 +              sub = col.column()
 +              sub.active = con.locate_like_y
 +              sub.itemR(con, "invert_y", text="Invert")
 +              
 +              col = split.column()
 +              col.itemR(con, "locate_like_z", text="Z")
 +              sub = col.column()
 +              sub.active = con.locate_like_z
 +              sub.itemR(con, "invert_z", text="Invert")
 +
 +              layout.itemR(con, "offset")
 +                      
 +              self.space_template(layout, con)
 +              
 +      def COPY_SCALE(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              row = layout.row(align=True)
 +              row.itemR(con, "size_like_x", text="X")
 +              row.itemR(con, "size_like_y", text="Y")
 +              row.itemR(con, "size_like_z", text="Z")
 +
 +              layout.itemR(con, "offset")
 +              
 +              self.space_template(layout, con)
 +              
 +      #def SCRIPT(self, layout, con):
 +      
 +      def ACTION(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              layout.itemR(con, "action")
 +              layout.itemR(con, "transform_channel")
 +
 +              split = layout.split()
 +      
 +              col = split.column(align=True)
 +              col.itemR(con, "start_frame", text="Start")
 +              col.itemR(con, "end_frame", text="End")
 +              
 +              col = split.column(align=True)
 +              col.itemR(con, "minimum", text="Min")
 +              col.itemR(con, "maximum", text="Max")
 +              
 +              row = layout.row()
 +              row.itemL(text="Convert:")
 +              row.itemR(con, "owner_space", text="")
 +      
 +      def LOCKED_TRACK(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              row = layout.row()
 +              row.itemL(text="To:")
 +              row.itemR(con, "track", expand=True)
 +              
 +              row = layout.row()
 +              row.itemL(text="Lock:")
 +              row.itemR(con, "locked", expand=True)
 +              
 +      def LIMIT_DISTANCE(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              col = layout.column(align=True);
 +              col.itemR(con, "distance")
 +              col.itemO("constraint.limitdistance_reset")
 +              
 +              row = layout.row()
 +              row.itemL(text="Clamp Region:")
 +              row.itemR(con, "limit_mode", text="")
 +              
 +      def STRETCH_TO(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              row = layout.row()
 +              row.itemR(con, "original_length", text="Rest Length")
 +              row.itemO("constraint.stretchto_reset", text="Reset")
 +              
 +              col = layout.column()
 +              col.itemR(con, "bulge", text="Volume Variation")
 +              
 +              row = layout.row()
 +              row.itemL(text="Volume:")
 +              row.itemR(con, "volume", expand=True)
 +              row.itemL(text="Plane:")
 +              row.itemR(con, "keep_axis", expand=True)
 +              
 +      def FLOOR(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              row = layout.row()
 +              row.itemR(con, "sticky")
 +              row.itemR(con, "use_rotation")
 +              
 +              layout.itemR(con, "offset")
 +              
 +              row = layout.row()
 +              row.itemL(text="Min/Max:")
 +              row.itemR(con, "floor_location", expand=True)
 +              
 +      def RIGID_BODY_JOINT(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              layout.itemR(con, "pivot_type")
 +              layout.itemR(con, "child")
 +              
 +              row = layout.row()
 +              row.itemR(con, "disable_linked_collision", text="No Collision")
 +              row.itemR(con, "draw_pivot", text="Display Pivot")
 +              
 +              split = layout.split()
 +              
 +              col = split.column(align=True)
 +              col.itemL(text="Pivot:")
 +              col.itemR(con, "pivot_x", text="X")
 +              col.itemR(con, "pivot_y", text="Y")
 +              col.itemR(con, "pivot_z", text="Z")
 +              
 +              col = split.column(align=True)
 +              col.itemL(text="Axis:")
 +              col.itemR(con, "axis_x", text="X")
 +              col.itemR(con, "axis_y", text="Y")
 +              col.itemR(con, "axis_z", text="Z")
 +              
 +              #Missing: Limit arrays (not wrapped in RNA yet) 
 +      
 +      def CLAMP_TO(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              row = layout.row()
 +              row.itemL(text="Main Axis:")
 +              row.itemR(con, "main_axis", expand=True)
 +              
 +              row = layout.row()
 +              row.itemR(con, "cyclic")
 +              
 +      def TRANSFORM(self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              layout.itemR(con, "extrapolate_motion", text="Extrapolate")
 +              
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemL(text="Source:")
 +              col.row().itemR(con, "map_from", expand=True)
 +              
 +              sub = col.row(align=True)
 +              sub.itemL(text="X:")
 +              sub.itemR(con, "from_min_x", text="")
 +              sub.itemR(con, "from_max_x", text="")
 +              
 +              sub = col.row(align=True)
 +              sub.itemL(text="Y:")
 +              sub.itemR(con, "from_min_y", text="")
 +              sub.itemR(con, "from_max_y", text="")
 +              
 +              sub = col.row(align=True)
 +              sub.itemL(text="Z:")
 +              sub.itemR(con, "from_min_z", text="")
 +              sub.itemR(con, "from_max_z", text="")
 +              
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemL(text="Destination:")
 +              col.row().itemR(con, "map_to", expand=True)
 +
 +              sub = col.row(align=True)
 +              sub.itemR(con, "map_to_x_from", text="")
 +              sub.itemR(con, "to_min_x", text="")
 +              sub.itemR(con, "to_max_x", text="")
 +              
 +              sub = col.row(align=True)
 +              sub.itemR(con, "map_to_y_from", text="")
 +              sub.itemR(con, "to_min_y", text="")
 +              sub.itemR(con, "to_max_y", text="")
 +              
 +              sub = col.row(align=True)
 +              sub.itemR(con, "map_to_z_from", text="")
 +              sub.itemR(con, "to_min_z", text="")
 +              sub.itemR(con, "to_max_z", text="")
 +              
 +              self.space_template(layout, con)
 +              
 +      def SHRINKWRAP (self, layout, con):
 +              self.target_template(layout, con)
 +              
 +              layout.itemR(con, "distance")
 +              layout.itemR(con, "shrinkwrap_type")
 +              
 +              if con.shrinkwrap_type == 'PROJECT':
 +                      row = layout.row(align=True)
 +                      row.itemR(con, "axis_x")
 +                      row.itemR(con, "axis_y")
 +                      row.itemR(con, "axis_z")
 +              
 +class OBJECT_PT_constraints(ConstraintButtonsPanel):
 +      __label__ = "Constraints"
 +      __context__ = "constraint"
 +
 +      def poll(self, context):
 +              return (context.object)
 +              
 +      def draw(self, context):
 +              layout = self.layout
 +              ob = context.object
 +
 +              row = layout.row()
 +              row.item_menu_enumO("object.constraint_add", "type")
 +              row.itemL();
 +
 +              for con in ob.constraints:
 +                      self.draw_constraint(con)
 +
 +class BONE_PT_constraints(ConstraintButtonsPanel):
 +      __label__ = "Constraints"
 +      __context__ = "bone"
 +
 +      def poll(self, context):
 +              ob = context.object
 +              return (ob and ob.type == 'ARMATURE' and context.bone)
 +              
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              ob = context.object
 +              pchan = ob.pose.pose_channels[context.bone.name]
 +
 +              row = layout.row()
 +              row.item_menu_enumO("pose.constraint_add", "type")
 +              row.itemL();
 +
 +              for con in pchan.constraints:
 +                      self.draw_constraint(con)
 +
 +bpy.types.register(OBJECT_PT_constraints)
 +bpy.types.register(BONE_PT_constraints)
index 0b18b7c,0000000..1d496e1
mode 100644,000000..100644
--- /dev/null
@@@ -1,905 -1,0 +1,959 @@@
-               return psys.settings.type in ('EMITTER', 'REACTOR')
 +
 +import bpy
 +
 +def particle_panel_enabled(psys):
 +      return psys.point_cache.baked==False and psys.edited==False
 +      
 +def particle_panel_poll(context):
 +      psys = context.particle_system
 +      if psys==None:  return False
 +      if psys.settings==None:  return False
 +      return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
 +      
 +def point_cache_ui(self, cache, enabled, particles, smoke):
 +      layout = self.layout
 +      layout.set_context_pointer("PointCache", cache)
 +      
 +      row = layout.row()
 +      row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
 +      col = row.column(align=True)
 +      col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
 +      col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
 +      
 +      row = layout.row()
 +      row.itemL(text="File Name:")
 +      if particles:
 +              row.itemR(cache, "external")
 +      
 +      if cache.external:
 +              split = layout.split(percentage=0.80)
 +              split.itemR(cache, "name", text="")
 +              split.itemR(cache, "index", text="")
 +              
 +              layout.itemL(text="File Path:")
 +              layout.itemR(cache, "filepath", text="")
 +              
 +              layout.itemL(text=cache.info)
 +      else:
 +              layout.itemR(cache, "name", text="")
 +              
 +              if not particles:
 +                      row = layout.row()
 +                      row.enabled = enabled
 +                      row.itemR(cache, "start_frame")
 +                      row.itemR(cache, "end_frame")
 +              
 +              row = layout.row()
 +      
 +              if cache.baked == True:
 +                      row.itemO("ptcache.free_bake", text="Free Bake")
 +              else:
 +                      row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
 +      
 +              sub = row.row()
 +              sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
 +              sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
 +              
 +              row = layout.row()
 +              row.enabled = enabled
 +              row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
 +              row.itemR(cache, "step");
 +      
 +              if not smoke:
 +                      row = layout.row()
 +                      sub = row.row()
 +                      sub.enabled = enabled
 +                      sub.itemR(cache, "quick_cache")
 +                      row.itemR(cache, "disk_cache")
 +      
 +              layout.itemL(text=cache.info)
 +              
 +              layout.itemS()
 +              
 +              row = layout.row()
 +              row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
 +              row.itemO("ptcache.free_bake_all", text="Free All Bakes")
 +              layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
 +      
 +
 +class ParticleButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "particle"
 +
 +      def poll(self, context):
 +              return particle_panel_poll(context)
 +
 +class PARTICLE_PT_particles(ParticleButtonsPanel):
 +      __show_header__ = False
 +
 +      def poll(self, context):
 +              return (context.particle_system or context.object)
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              ob = context.object
 +              psys = context.particle_system
 +
 +              if ob:
 +                      row = layout.row()
 +
 +                      row.template_list(ob, "particle_systems", ob, "active_particle_system_index", rows=2)
 +
 +                      col = row.column(align=True)
 +                      col.itemO("object.particle_system_add", icon='ICON_ZOOMIN', text="")
 +                      col.itemO("object.particle_system_remove", icon='ICON_ZOOMOUT', text="")
 +
 +              if psys and not psys.settings:
 +                      split = layout.split(percentage=0.32)
 +                      col = split.column()
 +                      col.itemL(text="Name:")
 +                      col.itemL(text="Settings:")
 +                      
 +                      col = split.column()
 +                      col.itemR(psys, "name", text="")
 +                      col.template_ID(psys, "settings", new="particle.new")
 +              elif psys:
 +                      part = psys.settings
 +                      
 +                      split = layout.split(percentage=0.32)
 +                      col = split.column()
 +                      col.itemL(text="Name:")
 +                      if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
 +                              col.itemL(text="Settings:")
 +                              col.itemL(text="Type:")
 +                      
 +                      col = split.column()
 +                      col.itemR(psys, "name", text="")
 +                      if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
 +                              col.template_ID(psys, "settings", new="particle.new")
 +                      
 +                      #row = layout.row()
 +                      #row.itemL(text="Viewport")
 +                      #row.itemL(text="Render")
 +                      
 +                      if part:
 +                              if part.type not in ('EMITTER', 'REACTOR', 'HAIR'):
 +                                      layout.itemL(text="No settings for fluid particles")
 +                                      return
 +                              
 +                              row=col.row()
 +                              row.enabled = particle_panel_enabled(psys)
 +                              row.itemR(part, "type", text="")
 +                              row.itemR(psys, "seed")
 +                              
 +                              split = layout.split(percentage=0.65)
 +                              if part.type=='HAIR':
 +                                      if psys.edited==True:
 +                                              split.itemO("particle.edited_clear", text="Free Edit")
 +                                      else:
 +                                              split.itemL(text="")
 +                                      row = split.row()
 +                                      row.enabled = particle_panel_enabled(psys)
 +                                      row.itemR(part, "hair_step")
++                                      if psys.edited==True:
++                                              if psys.global_hair:
++                                                      layout.itemO("particle.connect_hair")
++                                                      layout.itemL(text="Hair is disconnected.")
++                                              else:
++                                                      layout.itemO("particle.disconnect_hair")
++                                                      layout.itemL(text="")
 +                              elif part.type=='REACTOR':
 +                                      split.enabled = particle_panel_enabled(psys)
 +                                      split.itemR(psys, "reactor_target_object")
 +                                      split.itemR(psys, "reactor_target_particle_system", text="Particle System")
 +              
 +class PARTICLE_PT_emission(ParticleButtonsPanel):
 +      __label__ = "Emission"
 +      
 +      def poll(self, context):
 +              if particle_panel_poll(context):
 +                      return not context.particle_system.point_cache.external
 +              else:
 +                      return False
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +              
 +              layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches
 +              
 +              row = layout.row()
 +              row.itemR(part, "amount")
 +              
 +              split = layout.split()
 +              
 +              col = split.column(align=True)
 +              col.itemR(part, "start")
 +              col.itemR(part, "end")
 +
 +              col = split.column(align=True)
 +              col.itemR(part, "lifetime")
 +              col.itemR(part, "random_lifetime", slider=True)
 +              
 +              layout.row().itemL(text="Emit From:")
 +              
 +              row = layout.row()
 +              row.itemR(part, "emit_from", expand=True)
 +              row = layout.row()
 +              row.itemR(part, "trand")
 +              if part.distribution!='GRID':
 +                      row.itemR(part, "even_distribution")
 +              
 +              if part.emit_from=='FACE' or part.emit_from=='VOLUME':
 +                      row = layout.row()
 +                      row.itemR(part, "distribution", expand=True)
 +                      
 +                      row = layout.row()
 +
 +                      if part.distribution=='JIT':
 +                              row.itemR(part, "userjit", text="Particles/Face")
 +                              row.itemR(part, "jitter_factor", text="Jittering Amount", slider=True)
 +                      elif part.distribution=='GRID':
 +                              row.itemR(part, "grid_resolution")
 +
++class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
++      __label__ = "Hair dynamics"
++      __default_closed__ = True
++      
++      def poll(self, context):
++              psys = context.particle_system
++              if psys==None:  return False
++              if psys.settings==None:  return False
++              return psys.settings.type == 'HAIR'
++              
++      def draw_header(self, context):
++              #cloth = context.cloth.collision_settings
++              
++              #self.layout.active = cloth_panel_enabled(context.cloth)
++              #self.layout.itemR(cloth, "enable_collision", text="")
++              psys = context.particle_system
++              self.layout.itemR(psys, "hair_dynamics", text="")
++              
++      def draw(self, context):
++              layout = self.layout
++
++              psys = context.particle_system
++              part = psys.settings
++              cloth = psys.cloth.settings
++              
++              layout.enabled = psys.hair_dynamics
++              
++              split = layout.split()
++                      
++              col = split.column()
++              col.itemL(text="Quality:")
++              col.itemR(cloth, "quality", text="Steps",slider=True)
++              col.itemL(text="Gravity:")
++              col.itemR(cloth, "gravity", text="")
++              
++              col = split.column()
++              col.itemL(text="Material:")
++              sub = col.column(align=True)
++              sub.itemR(cloth, "pin_stiffness", text="Stiffness")
++              sub.itemR(cloth, "mass")
++              col.itemL(text="Damping:")
++              sub = col.column(align=True)
++              sub.itemR(cloth, "spring_damping", text="Spring")
++              sub.itemR(cloth, "air_damping", text="Air")
++              
++              layout.itemR(cloth, "internal_friction", slider="True")
++                              
 +class PARTICLE_PT_cache(ParticleButtonsPanel):
 +      __label__ = "Cache"
 +      __default_closed__ = True
 +      
 +      def poll(self, context):
 +              psys = context.particle_system
 +              if psys==None:  return False
 +              if psys.settings==None:  return False
 +              phystype = psys.settings.physics_type
 +              if phystype == 'NO' or phystype == 'KEYED':
 +                      return False
-               point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), 1, 0)
++              return psys.settings.type in ('EMITTER', 'REACTOR') or (psys.settings.type == 'HAIR' and psys.hair_dynamics)
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              
-                       sub.itemR(part, "sticky")
++              point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0)
 +
 +class PARTICLE_PT_initial(ParticleButtonsPanel):
 +      __label__ = "Velocity"
 +      
 +      def poll(self, context):
 +              if particle_panel_poll(context):
 +                      psys = context.particle_system
 +                      return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
 +              else:
 +                      return False
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +              
 +              layout.enabled = particle_panel_enabled(psys)
 +                              
 +              layout.row().itemL(text="Direction:")
 +      
 +              split = layout.split()
 +                      
 +              sub = split.column()
 +              sub.itemR(part, "normal_factor")
 +              if part.emit_from=='PARTICLE':
 +                      sub.itemR(part, "particle_factor")
 +              else:
 +                      sub.itemR(part, "object_factor", slider=True)
 +              sub.itemR(part, "random_factor")
 +              sub.itemR(part, "tangent_factor")
 +              sub.itemR(part, "tangent_phase", slider=True)
 +              
 +              sub = split.column()
 +              sub.itemL(text="TODO:")
 +              sub.itemL(text="Object aligned")
 +              sub.itemL(text="direction: X, Y, Z")
 +              
 +              if part.type=='REACTOR':
 +                      sub.itemR(part, "reactor_factor")
 +                      sub.itemR(part, "reaction_shape", slider=True)
 +              else:
 +                      sub.itemL(text="")
 +              
 +              layout.row().itemL(text="Rotation:")
 +              split = layout.split()
 +                      
 +              sub = split.column()
 +              
 +              sub.itemR(part, "rotation_mode", text="Axis")
 +              split = layout.split()
 +                      
 +              sub = split.column()
 +              sub.itemR(part, "rotation_dynamic")
 +              sub.itemR(part, "random_rotation_factor", slider=True)
 +              sub = split.column()
 +              sub.itemR(part, "phase_factor", slider=True)
 +              sub.itemR(part, "random_phase_factor", text="Random", slider=True)
 +
 +              layout.row().itemL(text="Angular velocity:")
 +              layout.row().itemR(part, "angular_velocity_mode", expand=True)
 +              split = layout.split()
 +                      
 +              sub = split.column()
 +              
 +              sub.itemR(part, "angular_velocity_factor", text="")
 +              
 +class PARTICLE_PT_physics(ParticleButtonsPanel):
 +      __label__ = "Physics"
 +      
 +      def poll(self, context):
 +              if particle_panel_poll(context):
 +                      return not context.particle_system.point_cache.external
 +              else:
 +                      return False
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +              
 +              layout.enabled = particle_panel_enabled(psys)
 +
 +              row = layout.row()
 +              row.itemR(part, "physics_type", expand=True)
 +              if part.physics_type != 'NO':
 +                      row = layout.row()
 +                      col = row.column(align=True)
 +                      col.itemR(part, "particle_size")
 +                      col.itemR(part, "random_size", slider=True)
 +                      col = row.column(align=True)
 +                      col.itemR(part, "mass")
 +                      col.itemR(part, "sizemass", text="Multiply mass with size")
 +                      
 +              if part.physics_type == 'NEWTON':
 +                      split = layout.split()
 +                      sub = split.column()
 +                      
 +                      sub.itemL(text="Forces:")
 +                      sub.itemR(part, "brownian_factor")
 +                      sub.itemR(part, "drag_factor", slider=True)
 +                      sub.itemR(part, "damp_factor", slider=True)
 +                      sub.itemR(part, "integrator")
 +                      sub = split.column()
 +                      sub.itemR(part, "acceleration")
 +                      
 +              elif part.physics_type == 'KEYED':
 +                      split = layout.split()
 +                      sub = split.column()
 +                      
 +                      row = layout.row()
 +                      col = row.column()
 +                      col.active = not psys.keyed_timing
 +                      col.itemR(part, "keyed_loops", text="Loops")
 +                      row.itemR(psys, "keyed_timing", text="Use Timing")
 +                      
 +                      layout.itemL(text="Keys:")
 +              elif part.physics_type=='BOIDS':
 +                      boids = part.boids
 +                      
 +
 +                      row = layout.row()
 +                      row.itemR(boids, "allow_flight")
 +                      row.itemR(boids, "allow_land")
 +                      row.itemR(boids, "allow_climb")
 +                      
 +                      split = layout.split()
 +                      
 +                      sub = split.column()
 +                      col = sub.column(align=True)
 +                      col.active = boids.allow_flight
 +                      col.itemR(boids, "air_max_speed")
 +                      col.itemR(boids, "air_min_speed", slider="True")
 +                      col.itemR(boids, "air_max_acc", slider="True")
 +                      col.itemR(boids, "air_max_ave", slider="True")
 +                      col.itemR(boids, "air_personal_space")
 +                      row = col.row()
 +                      row.active = (boids.allow_land or boids.allow_climb) and boids.allow_flight
 +                      row.itemR(boids, "landing_smoothness")
 +                      
 +                      sub = split.column()
 +                      col = sub.column(align=True)
 +                      col.active = boids.allow_land or boids.allow_climb
 +                      col.itemR(boids, "land_max_speed")
 +                      col.itemR(boids, "land_jump_speed")
 +                      col.itemR(boids, "land_max_acc", slider="True")
 +                      col.itemR(boids, "land_max_ave", slider="True")
 +                      col.itemR(boids, "land_personal_space")
 +                      col.itemR(boids, "land_stick_force")
 +                      
 +                      row = layout.row()
 +                      
 +                      col = row.column(align=True)
 +                      col.itemL(text="Battle:")
 +                      col.itemR(boids, "health")
 +                      col.itemR(boids, "strength")
 +                      col.itemR(boids, "aggression")
 +                      col.itemR(boids, "accuracy")
 +                      col.itemR(boids, "range")
 +                      
 +                      col = row.column()
 +                      col.itemL(text="Misc:")
 +                      col.itemR(part, "gravity")
 +                      col.itemR(boids, "banking", slider=True)
 +                      col.itemR(boids, "height", slider=True)
 +                      
 +              if part.physics_type=='NEWTON':
 +                      sub.itemR(part, "size_deflect")
 +                      sub.itemR(part, "die_on_collision")
 +              elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
 +                      if part.physics_type=='BOIDS':
 +                              layout.itemL(text="Relations:")
 +                      
 +                      row = layout.row()
 +                      row.template_list(psys, "targets", psys, "active_particle_target_index")
 +                      
 +                      col = row.column()
 +                      subrow = col.row()
 +                      subcol = subrow.column(align=True)
 +                      subcol.itemO("particle.new_target", icon='ICON_ZOOMIN', text="")
 +                      subcol.itemO("particle.remove_target", icon='ICON_ZOOMOUT', text="")
 +                      subrow = col.row()
 +                      subcol = subrow.column(align=True)
 +                      subcol.itemO("particle.target_move_up", icon='VICON_MOVE_UP', text="")
 +                      subcol.itemO("particle.target_move_down", icon='VICON_MOVE_DOWN', text="")
 +                      
 +                      key = psys.active_particle_target
 +                      if key:
 +                              row = layout.row()
 +                              if part.physics_type=='KEYED':
 +                                      col = row.column()
 +                                      #doesn't work yet
 +                                      #col.red_alert = key.valid
 +                                      col.itemR(key, "object", text="")
 +                                      col.itemR(key, "system", text="System")
 +                                      col = row.column();
 +                                      col.active = psys.keyed_timing
 +                                      col.itemR(key, "time")
 +                                      col.itemR(key, "duration")
 +                              else:
 +                                      subrow = row.row()
 +                                      #doesn't work yet
 +                                      #subrow.red_alert = key.valid
 +                                      subrow.itemR(key, "object", text="")
 +                                      subrow.itemR(key, "system", text="System")
 +                                      
 +                                      layout.itemR(key, "mode", expand=True)
 +
 +class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
 +      __label__ = "Boid Brain"
 +
 +      def poll(self, context):
 +              psys = context.particle_system
 +              if psys==None:  return False
 +              if psys.settings==None:  return False
 +              if psys.point_cache.external: return False
 +              return psys.settings.physics_type=='BOIDS'
 +      
 +      def draw(self, context):
 +              boids = context.particle_system.settings.boids
 +              layout = self.layout
 +              
 +              layout.enabled = particle_panel_enabled(psys)
 +              
 +              # Currently boids can only use the first state so these are commented out for now.
 +              #row = layout.row()
 +              #row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
 +              #col = row.row()
 +              #subrow = col.row(align=True)
 +              #subrow.itemO("boid.boidstate_add", icon='ICON_ZOOMIN', text="")
 +              #subrow.itemO("boid.boidstate_del", icon='ICON_ZOOMOUT', text="")
 +              #subrow = row.row(align=True)
 +              #subrow.itemO("boid.boidstate_move_up", icon='VICON_MOVE_UP', text="")
 +              #subrow.itemO("boid.boidstate_move_down", icon='VICON_MOVE_DOWN', text="")
 +              
 +              state = boids.active_boid_state
 +              
 +              #layout.itemR(state, "name", text="State name")
 +              
 +              row = layout.row()
 +              row.itemR(state, "ruleset_type")
 +              if state.ruleset_type=='FUZZY':
 +                      row.itemR(state, "rule_fuzziness", slider=True)
 +              else:
 +                      row.itemL(text="")
 +              
 +              row = layout.row()
 +              row.template_list(state, "rules", state, "active_boid_rule_index")
 +              
 +              col = row.column()
 +              subrow = col.row()
 +              subcol = subrow.column(align=True)
 +              subcol.item_menu_enumO("boid.boidrule_add", "type", icon='ICON_ZOOMIN', text="")
 +              subcol.itemO("boid.boidrule_del", icon='ICON_ZOOMOUT', text="")
 +              subrow = col.row()
 +              subcol = subrow.column(align=True)
 +              subcol.itemO("boid.boidrule_move_up", icon='VICON_MOVE_UP', text="")
 +              subcol.itemO("boid.boidrule_move_down", icon='VICON_MOVE_DOWN', text="")
 +              
 +              rule = state.active_boid_rule
 +              
 +              if rule:
 +                      row = layout.row()
 +                      row.itemR(rule, "name", text="")
 +                      #somebody make nice icons for boids here please! -jahka
 +                      row.itemR(rule, "in_air", icon='VICON_MOVE_UP', text="")
 +                      row.itemR(rule, "on_land", icon='VICON_MOVE_DOWN', text="")
 +                      
 +                      row = layout.row()
 +
 +                      if rule.type == 'GOAL':
 +                              row.itemR(rule, "object")
 +                              row = layout.row()
 +                              row.itemR(rule, "predict")
 +                      elif rule.type == 'AVOID':
 +                              row.itemR(rule, "object")
 +                              row = layout.row()
 +                              row.itemR(rule, "predict")
 +                              row.itemR(rule, "fear_factor")
 +                      elif rule.type == 'FOLLOW_PATH':
 +                              row.itemL(text="Not yet functional.")
 +                      elif rule.type == 'AVOID_COLLISION':
 +                              row.itemR(rule, "boids")
 +                              row.itemR(rule, "deflectors")
 +                              row.itemR(rule, "look_ahead")
 +                      elif rule.type == 'FOLLOW_LEADER':
 +                              row.itemR(rule, "object", text="")
 +                              row.itemR(rule, "distance")
 +                              row = layout.row()
 +                              row.itemR(rule, "line")
 +                              subrow = row.row()
 +                              subrow.active = rule.line
 +                              subrow.itemR(rule, "queue_size")
 +                      elif rule.type == 'AVERAGE_SPEED':
 +                              row.itemR(rule, "speed", slider=True)
 +                              row.itemR(rule, "wander", slider=True)
 +                              row.itemR(rule, "level", slider=True)
 +                      elif rule.type == 'FIGHT':
 +                              row.itemR(rule, "distance")
 +                              row.itemR(rule, "flee_distance")
 +              
 +
 +class PARTICLE_PT_render(ParticleButtonsPanel):
 +      __label__ = "Render"
 +      
 +      def poll(self, context):
 +              psys = context.particle_system
 +              if psys==None: return False
 +              if psys.settings==None: return False
 +              return True;
 +              
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +
 +              row = layout.row()
 +              row.itemR(part, "material")
 +              row.itemR(psys, "parent");
 +              
 +              split = layout.split()
 +                      
 +              sub = split.column()
 +              sub.itemR(part, "emitter");
 +              sub.itemR(part, "parent");
 +              sub = split.column()
 +              sub.itemR(part, "unborn");
 +              sub.itemR(part, "died");
 +              
 +              row = layout.row()
 +              row.itemR(part, "ren_as", expand=True)
 +              
 +              split = layout.split()
 +                      
 +              sub = split.column()
 +              
 +              if part.ren_as == 'LINE':
 +                      sub.itemR(part, "line_length_tail")
 +                      sub.itemR(part, "line_length_head")
 +                      sub = split.column()
 +                      sub.itemR(part, "velocity_length")
 +              elif part.ren_as == 'PATH':
 +              
 +                      if (part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False):
 +                              box = layout.box()
 +                              box.itemL(text="Baked or keyed particles needed for correct rendering.")
 +                              return
 +                              
 +                      sub.itemR(part, "render_strand")
 +                      colsub = sub.column()
 +                      colsub.active = part.render_strand == False
 +                      colsub.itemR(part, "render_adaptive")
 +                      colsub = sub.column()
 +                      colsub.active = part.render_adaptive or part.render_strand == True
 +                      colsub.itemR(part, "adaptive_angle")
 +                      colsub = sub.column()
 +                      colsub.active = part.render_adaptive == True and part.render_strand == False
 +                      colsub.itemR(part, "adaptive_pix")
 +                      sub.itemR(part, "hair_bspline")
 +                      sub.itemR(part, "render_step", text="Steps")
 +                      sub = split.column()    
 +
 +                      sub.itemL(text="Timing:")
 +                      sub.itemR(part, "abs_path_time")
 +                      sub.itemR(part, "path_start", text="Start", slider= not part.abs_path_time)
 +                      sub.itemR(part, "path_end", text="End", slider= not part.abs_path_time)         
 +                      sub.itemR(part, "random_length", text="Random", slider=True)
 +                      
 +                      row = layout.row()
 +                      col = row.column()
 +                      
 +                      if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
 +                              layout.itemR(part, "enable_simplify")
 +                              if part.enable_simplify==True:
 +                                      row = layout.row()
 +                                      row.itemR(part, "simplify_refsize")
 +                                      row.itemR(part, "simplify_rate")
 +                                      row.itemR(part, "simplify_transition")
 +                                      row = layout.row()
 +                                      row.itemR(part, "viewport")
 +                                      subrow = row.row()
 +                                      subrow.active = part.viewport==True
 +                                      subrow.itemR(part, "simplify_viewport")
 +                      
 +
 +              elif part.ren_as == 'OBJECT':
 +                      sub.itemR(part, "dupli_object")
 +              elif part.ren_as == 'GROUP':
 +                      sub.itemR(part, "dupli_group")
 +                      split = layout.split()
 +                      sub = split.column()
 +                      sub.itemR(part, "whole_group")
 +                      sub = split.column()
 +                      colsub = sub.column()
 +                      colsub.active = part.whole_group == False
 +                      colsub.itemR(part, "rand_group")
 +                      
 +              elif part.ren_as == 'BILLBOARD':
 +                      sub.itemL(text="Align:")
 +                      
 +                      row = layout.row()
 +                      row.itemR(part, "billboard_align", expand=True)
 +                      row.itemR(part, "billboard_lock", text="Lock")
 +                      row = layout.row()
 +                      row.itemR(part, "billboard_object")
 +              
 +                      row = layout.row()
 +                      col = row.column(align=True)
 +                      col.itemL(text="Tilt:")
 +                      col.itemR(part, "billboard_tilt", text="Angle", slider=True)
 +                      col.itemR(part, "billboard_random_tilt", slider=True)
 +                      col = row.column()
 +                      col.itemR(part, "billboard_offset")
 +                      
 +                      row = layout.row()
 +                      row.itemR(psys, "billboard_normal_uv")
 +                      row = layout.row()
 +                      row.itemR(psys, "billboard_time_index_uv")
 +                      
 +                      row = layout.row()
 +                      row.itemL(text="Split uv's:")
 +                      row.itemR(part, "billboard_uv_split", text="Number of splits")
 +                      row = layout.row()
 +                      row.itemR(psys, "billboard_split_uv")
 +                      row = layout.row()
 +                      row.itemL(text="Animate:")
 +                      row.itemR(part, "billboard_animation", expand=True)
 +                      row.itemL(text="Offset:")
 +                      row.itemR(part, "billboard_split_offset", expand=True)
 +              if part.ren_as == 'HALO' or part.ren_as == 'LINE' or part.ren_as=='BILLBOARD':
 +                      row = layout.row()
 +                      col = row.column()
 +                      col.itemR(part, "trail_count")
 +                      if part.trail_count > 1:
 +                              col.itemR(part, "abs_path_time", text="Length in frames")
 +                              col = row.column()
 +                              col.itemR(part, "path_end", text="Length", slider=not part.abs_path_time)
 +                              col.itemR(part, "random_length", text="Random", slider=True)
 +                      else:
 +                              col = row.column()
 +                              col.itemL(text="")
 +                              
 +class PARTICLE_PT_draw(ParticleButtonsPanel):
 +      __label__ = "Display"
 +      __default_closed__ = True
 +      
 +      def poll(self, context):
 +              psys = context.particle_system
 +              if psys==None: return False
 +              if psys.settings==None: return False
 +              return True;
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +              
 +              row = layout.row()
 +              row.itemR(part, "draw_as", expand=True)
 +              
 +              if part.draw_as=='NONE' or (part.ren_as=='NONE' and part.draw_as=='RENDER'):
 +                      return
 +                      
 +              path = (part.ren_as=='PATH' and part.draw_as=='RENDER') or part.draw_as=='PATH'
 +                      
 +              if path and part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False:
 +                      box = layout.box()
 +                      box.itemL(text="Baked or keyed particles needed for correct drawing.")
 +                      return
 +              
 +              row = layout.row()
 +              row.itemR(part, "display", slider=True)
 +              if part.draw_as!='RENDER' or part.ren_as=='HALO':
 +                      row.itemR(part, "draw_size")
 +              else:
 +                      row.itemL(text="")
 +              
 +              row = layout.row()
 +              col = row.column()
 +              col.itemR(part, "show_size")
 +              col.itemR(part, "velocity")
 +              col.itemR(part, "num")
 +              if part.physics_type == 'BOIDS':
 +                      col.itemR(part, "draw_health")
 +              
 +              col = row.column()
 +              col.itemR(part, "material_color", text="Use material color")
 +              
 +              if (path):                      
 +                      col.itemR(part, "draw_step")
 +              else:
 +                      subcol = col.column()
 +                      subcol.active = part.material_color==False
 +                      #subcol.itemL(text="color")
 +                      #subcol.itemL(text="Override material color")
 +
 +class PARTICLE_PT_children(ParticleButtonsPanel):
 +      __label__ = "Children"
 +      __default_closed__ = True
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +              
 +              layout.row().itemR(part, "child_type", expand=True)
 +              
 +              if part.child_type=='NONE':
 +                      return
 +              
 +              row = layout.row()
 +              
 +              col = row.column(align=True)
 +              col.itemR(part, "child_nbr", text="Display")
 +              col.itemR(part, "rendered_child_nbr", text="Render")
 +              
 +              col = row.column(align=True)
 +              
 +              if part.child_type=='FACES':
 +                      col.itemR(part, "virtual_parents", slider=True)
 +              else:
 +                      col.itemR(part, "child_radius", text="Radius")
 +                      col.itemR(part, "child_roundness", text="Roundness", slider=True)
 +              
 +                      col = row.column(align=True)
 +                      col.itemR(part, "child_size", text="Size")
 +                      col.itemR(part, "child_random_size", text="Random")
 +              
 +              layout.row().itemL(text="Effects:")
 +              
 +              row = layout.row()
 +              
 +              col = row.column(align=True)
 +              col.itemR(part, "clump_factor", slider=True)
 +              col.itemR(part, "clumppow", slider=True)
 +              
 +              col = row.column(align=True)
 +              col.itemR(part, "rough_endpoint")
 +              col.itemR(part, "rough_end_shape")
 +
 +              row = layout.row()
 +              
 +              col = row.column(align=True)
 +              col.itemR(part, "rough1")
 +              col.itemR(part, "rough1_size")
 +
 +              col = row.column(align=True)
 +              col.itemR(part, "rough2")
 +              col.itemR(part, "rough2_size")
 +              col.itemR(part, "rough2_thres", slider=True)
 +              
 +              row = layout.row()
 +              col = row.column(align=True)
 +              col.itemR(part, "child_length", slider=True)
 +              col.itemR(part, "child_length_thres", slider=True)
 +              
 +              col = row.column(align=True)
 +              col.itemL(text="Space reserved for")
 +              col.itemL(text="hair parting controls")
 +              
 +              layout.row().itemL(text="Kink:")
 +              layout.row().itemR(part, "kink", expand=True)
 +              
 +              split = layout.split()
 +              
 +              sub = split.column()
 +              sub.itemR(part, "kink_amplitude")
 +              sub.itemR(part, "kink_frequency")
 +              sub = split.column()
 +              sub.itemR(part, "kink_shape", slider=True)
 +
 +class PARTICLE_PT_effectors(ParticleButtonsPanel):
 +      __label__ = "Effectors"
 +      __default_closed__ = True
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +              
 +              layout.itemR(part, "effector_group")
 +              
 +              layout.itemR(part, "eweight_all", slider=True)
 +              
 +              layout.itemS()
 +              layout.itemR(part, "eweight_spherical", slider=True)
 +              layout.itemR(part, "eweight_vortex", slider=True)
 +              layout.itemR(part, "eweight_magnetic", slider=True)
 +              layout.itemR(part, "eweight_wind", slider=True)
 +              layout.itemR(part, "eweight_curveguide", slider=True)
 +              layout.itemR(part, "eweight_texture", slider=True)
 +              layout.itemR(part, "eweight_harmonic", slider=True)
 +              layout.itemR(part, "eweight_charge", slider=True)
 +              layout.itemR(part, "eweight_lennardjones", slider=True)
 +              
 +class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
 +      __label__ = "Vertexgroups"
 +      __default_closed__ = True
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              psys = context.particle_system
 +              part = psys.settings
 +              
 +              layout.itemL(text="Nothing here yet.")
 +
 +              #row = layout.row()
 +              #row.itemL(text="Vertex Group")
 +              #row.itemL(text="Negate")
 +
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_density")
 +              #row.itemR(psys, "vertex_group_density_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_velocity")
 +              #row.itemR(psys, "vertex_group_velocity_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_length")
 +              #row.itemR(psys, "vertex_group_length_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_clump")
 +              #row.itemR(psys, "vertex_group_clump_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_kink")
 +              #row.itemR(psys, "vertex_group_kink_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_roughness1")
 +              #row.itemR(psys, "vertex_group_roughness1_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_roughness2")
 +              #row.itemR(psys, "vertex_group_roughness2_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_roughness_end")
 +              #row.itemR(psys, "vertex_group_roughness_end_negate", text="")
 +
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_size")
 +              #row.itemR(psys, "vertex_group_size_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_tangent")
 +              #row.itemR(psys, "vertex_group_tangent_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_rotation")
 +              #row.itemR(psys, "vertex_group_rotation_negate", text="")
 +              
 +              #row = layout.row()
 +              #row.itemR(psys, "vertex_group_field")
 +              #row.itemR(psys, "vertex_group_field_negate", text="")
 +              
 +bpy.types.register(PARTICLE_PT_particles)
++bpy.types.register(PARTICLE_PT_hair_dynamics)
 +bpy.types.register(PARTICLE_PT_cache)
 +bpy.types.register(PARTICLE_PT_emission)
 +bpy.types.register(PARTICLE_PT_initial)
 +bpy.types.register(PARTICLE_PT_physics)
 +bpy.types.register(PARTICLE_PT_boidbrain)
 +bpy.types.register(PARTICLE_PT_render)
 +bpy.types.register(PARTICLE_PT_draw)
 +bpy.types.register(PARTICLE_PT_children)
 +bpy.types.register(PARTICLE_PT_effectors)
 +bpy.types.register(PARTICLE_PT_vertexgroups)
index c87f71b,0000000..6aee152
mode 100644,000000..100644
--- /dev/null
@@@ -1,226 -1,0 +1,182 @@@
- def smoke_panel_enabled_low(smd):
-       if smd.smoke_type == 'TYPE_DOMAIN':
-               return smd.domain.point_cache.baked==False
-       return True
 +
 +import bpy
 +
 +from buttons_particle import point_cache_ui
 +
-               
-                       # layout.enabled = smoke_panel_enabled(md)
 +class PhysicButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'PROPERTIES'
 +      __region_type__ = 'WINDOW'
 +      __context__ = "physics"
 +
 +      def poll(self, context):
 +              ob = context.object
 +              rd = context.scene.render_data
 +              return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
 +              
 +class PHYSICS_PT_smoke(PhysicButtonsPanel):
 +      __label__ = "Smoke"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              md = context.smoke
 +              ob = context.object
 +
 +              split = layout.split()
 +              split.operator_context = 'EXEC_DEFAULT'
 +
 +              if md:
 +                      # remove modifier + settings
 +                      split.set_context_pointer("modifier", md)
 +                      split.itemO("object.modifier_remove", text="Remove")
 +
 +                      row = split.row(align=True)
 +                      row.itemR(md, "render", text="")
 +                      row.itemR(md, "realtime", text="")
 +                      
 +              else:
 +                      # add modifier
 +                      split.item_enumO("object.modifier_add", "type", 'SMOKE', text="Add")
 +                      split.itemL()
 +
 +              if md:
-                               sub.itemR(domain, "dissolve_speed", text="Speed")
 +                      layout.itemR(md, "smoke_type", expand=True)
 +              
 +                      if md.smoke_type == 'TYPE_DOMAIN':
 +                              
 +                              domain = md.domain_settings
 +                              
 +                              split = layout.split()
 +                              
 +                              col = split.column()
 +                              col.itemL(text="Resolution:")
 +                              col.itemR(domain, "maxres", text="Divisions")
 +                              
 +                              col = split.column()
 +                              col.itemL(text="Behavior:")
 +                              col.itemR(domain, "alpha")
 +                              col.itemR(domain, "beta")
 +                              col.itemR(domain, "dissolve_smoke", text="Dissolve")
 +                              sub = col.column()
 +                              sub.active = domain.dissolve_smoke
-                                       
++                              sub.itemR(domain, "dissolve_speed", text="Time")
 +                              sub.itemR(domain, "dissolve_smoke_log", text="Slow")
 +                              
 +                      elif md.smoke_type == 'TYPE_FLOW':
 +                              
 +                              flow = md.flow_settings
 +                              
 +                              split = layout.split()
 +                              
 +                              col = split.column()
 +                              col.itemR(flow, "outflow")
 +                              col.itemL(text="Particle System:")
 +                              col.item_pointerR(flow, "psys", ob, "particle_systems", text="")
 +                              
 +                              if md.flow_settings.outflow:                            
 +                                      col = split.column()
 +                              else:
 +                                      col = split.column()
 +                                      col.itemL(text="Behavior:")
 +                                      col.itemR(flow, "temperature")
 +                                      col.itemR(flow, "density")
 +                                      
 +                      #elif md.smoke_type == 'TYPE_COLL':
 +                      #       layout.itemS()
-               return md and (md.smoke_type == 'TYPE_DOMAIN')
++
 +class PHYSICS_PT_smoke_groups(PhysicButtonsPanel):
 +      __label__ = "Smoke Groups"
 +      __default_closed__ = True
 +      
 +      def poll(self, context):
 +              md = context.smoke
-               
++              if md:
++                              return (md.smoke_type == 'TYPE_DOMAIN')
++              
++              return False
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              group = context.smoke.domain_settings
 +              
 +              split = layout.split()
 +              
 +              col = split.column()
 +              col.itemL(text="Flow Group:")
 +              col.itemR(group, "fluid_group", text="")
 +                              
 +              #col.itemL(text="Effector Group:")
 +              #col.itemR(group, "eff_group", text="")
 +                              
 +              col = split.column()
 +              col.itemL(text="Collision Group:")
 +              col.itemR(group, "coll_group", text="")
-               cache = md.point_cache
++
 +class PHYSICS_PT_smoke_cache(PhysicButtonsPanel):
 +      __label__ = "Smoke Cache"
 +      __default_closed__ = True
 +
 +      def poll(self, context):
 +              md = context.smoke
 +              return md and (md.smoke_type == 'TYPE_DOMAIN')
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              md = context.smoke.domain_settings
-               col.itemR(md, "show_highres")
++              cache = md.point_cache_low
 +                      
 +              point_cache_ui(self, cache, cache.baked==False, 0, 1)
 +                                      
 +class PHYSICS_PT_smoke_highres(PhysicButtonsPanel):
 +      __label__ = "Smoke High Resolution"
 +      __default_closed__ = True
 +      
 +      def poll(self, context):
 +              md = context.smoke
 +              return md and (md.smoke_type == 'TYPE_DOMAIN')
 +
 +      def draw_header(self, context): 
 +              high = context.smoke.domain_settings
 +      
 +              self.layout.itemR(high, "highres", text="")
 +              
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              md = context.smoke.domain_settings
 +
 +              split = layout.split()
 +                      
 +              col = split.column()
 +              col.itemL(text="Resolution:")
 +              col.itemR(md, "amplify", text="Divisions")
 +                      
 +              col = split.column()
 +              col.itemL(text="Noise Method:")
 +              col.row().itemR(md, "noise_type", text="")
 +              col.itemR(md, "strength")
-       __label__ = "Smoke Cache"
++              col.itemR(md, "viewhighres")
 +              
 +class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel):
-               return (context.smoke)
++      __label__ = "Smoke High Resolution Cache"
 +      __default_closed__ = True
 +
 +      def poll(self, context):
-               md = context.smoke
-               cache = md.point_cache
-                       
-               layout.set_context_pointer("PointCache", cache)
-                       
-               row = layout.row()
-               row.template_list(cache, "point_cache_list", cache, "active_point_cache_index")
-               col = row.column(align=True)
-               col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
-               col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
-                       
-               row = layout.row()
-               row.itemR(cache, "name")
-                       
-               row = layout.row()
-               row.itemR(cache, "start_frame")
-               row.itemR(cache, "end_frame")
-                       
-               row = layout.row()
-                       
-               if cache.baked == True:
-                       row.itemO("ptcache.free_bake", text="Free Bake")
-               else:
-                       row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
-                       
-               subrow = row.row()
-               subrow.enabled = cache.frames_skipped or cache.outdated
-               subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
-                               
-               row = layout.row()
-               #row.enabled = smoke_panel_enabled(psys)
-               row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
-               
-               row = layout.row()
-               #row.enabled = smoke_panel_enabled(psys)
-                       
-               layout.itemL(text=cache.info)
-                       
-               layout.itemS()
++              md = context.smoke
++              return md and (md.smoke_type == 'TYPE_DOMAIN') and md.domain_settings.highres
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
-               row = layout.row()
-               row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
-               row.itemO("ptcache.free_bake_all", text="Free All Bakes")
-               layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
++              md = context.smoke.domain_settings
++              cache = md.point_cache_high
 +                      
- #bpy.types.register(PHYSICS_PT_smoke_highres)
- #bpy.types.register(PHYSICS_PT_smoke_cache_highres)
++              point_cache_ui(self, cache, cache.baked==False, 0, 1)
++                                      
 +bpy.types.register(PHYSICS_PT_smoke)
 +bpy.types.register(PHYSICS_PT_smoke_cache)
++bpy.types.register(PHYSICS_PT_smoke_highres)
 +bpy.types.register(PHYSICS_PT_smoke_groups)
++bpy.types.register(PHYSICS_PT_smoke_cache_highres)
index dbf202f,0000000..136082a
mode 100644,000000..100644
--- /dev/null
@@@ -1,446 -1,0 +1,446 @@@
-       Operator documentatuon text, will be used for the operator tooltip and python docs.
 +
 +import bpy
 +
 +import bpy_ops # XXX - should not need to do this
 +del bpy_ops
 +
 +class CONSOLE_HT_header(bpy.types.Header):
 +      __space_type__ = 'CONSOLE'
 +
 +      def draw(self, context):
 +              sc = context.space_data
 +              # text = sc.text
 +              layout = self.layout
 +
 +              row= layout.row(align=True)
 +              row.template_header()
 +
 +              if context.area.show_menus:
 +                      sub = row.row(align=True)
 +
 +                      if sc.console_type == 'REPORT':
 +                              sub.itemM("CONSOLE_MT_report")
 +                      else:
 +                              sub.itemM("CONSOLE_MT_console")
 +
 +              layout.itemS()
 +              layout.itemR(sc, "console_type", expand=True)
 +
 +              if sc.console_type == 'REPORT':
 +                      row = layout.row(align=True)
 +                      row.itemR(sc, "show_report_debug", text="Debug")
 +                      row.itemR(sc, "show_report_info", text="Info")
 +                      row.itemR(sc, "show_report_operator", text="Operators")
 +                      row.itemR(sc, "show_report_warn", text="Warnings")
 +                      row.itemR(sc, "show_report_error", text="Errors")
 +                      
 +                      row = layout.row()
 +                      row.enabled = sc.show_report_operator
 +                      row.itemO("console.report_replay")
 +
 +class CONSOLE_MT_console(bpy.types.Menu):
 +      __space_type__ = 'CONSOLE'
 +      __label__ = "Console"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              sc = context.space_data
 +
 +              layout.column()
 +              layout.itemO("console.clear")
 +              layout.itemO("console.copy")
 +              layout.itemO("console.paste")
 +
 +class CONSOLE_MT_report(bpy.types.Menu):
 +      __space_type__ = 'CONSOLE'
 +      __label__ = "Report"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              sc = context.space_data
 +
 +              layout.column()
 +              layout.itemO("console.select_all_toggle")
 +              layout.itemO("console.select_border")
 +              layout.itemO("console.report_delete")
 +              layout.itemO("console.report_copy")
 +
 +def add_scrollback(text, text_type):
 +      for l in text.split('\n'):
 +              bpy.ops.console.scrollback_append(text=l.replace('\t', '    '), type=text_type)
 +
 +def get_console(console_id):
 +      '''
 +      helper function for console operators
 +      currently each text datablock gets its own console - code.InteractiveConsole()
 +      ...which is stored in this function.
 +      
 +      console_id can be any hashable type
 +      '''
 +      import sys, code
 +      
 +      try:    consoles = get_console.consoles
 +      except:consoles = get_console.consoles = {}
 +      
 +      # clear all dead consoles, use text names as IDs
 +      # TODO, find a way to clear IDs
 +      '''
 +      for console_id in list(consoles.keys()):
 +              if console_id not in bpy.data.texts:
 +                      del consoles[id]
 +      '''
 +      
 +      try:
 +              namespace, console, stdout, stderr = consoles[console_id]
 +      except:
 +              namespace = {'__builtins__':__builtins__} # locals()
 +              namespace['bpy'] = bpy
 +              
 +              console = code.InteractiveConsole(namespace)
 +              
 +              import io
 +              stdout = io.StringIO()
 +              stderr = io.StringIO()
 +      
 +              consoles[console_id]= namespace, console, stdout, stderr
 +              
 +      return namespace, console, stdout, stderr
 +
 +class CONSOLE_OT_exec(bpy.types.Operator):
 +      '''
-       Operator documentatuon text, will be used for the operator tooltip and python docs.
++      Execute the current console line as a python expression.
 +      '''
 +      __idname__ = "console.execute"
 +      __label__ = "Console Execute"
 +      __register__ = False
 +      
 +      # Both prompts must be the same length
 +      PROMPT = '>>> ' 
 +      PROMPT_MULTI = '... '
 +      
 +      # is this working???
 +      '''
 +      def poll(self, context):
 +              return (context.space_data.type == 'PYTHON')
 +      ''' # its not :|
 +      
 +      def execute(self, context):
 +              import sys
 +              
 +              sc = context.space_data
 +              
 +              try:
 +                      line = sc.history[-1].line
 +              except:
 +                      return ('CANCELLED',)
 +              
 +              if sc.console_type != 'PYTHON':
 +                      return ('CANCELLED',)
 +              
 +              namespace, console, stdout, stderr = get_console(hash(context.region))
 +              
 +              # redirect output
 +              sys.stdout = stdout
 +              sys.stderr = stderr
 +              
 +              # run the console
 +              if not line.strip():
 +                      line_exec = '\n' # executes a multiline statement
 +              else:
 +                      line_exec = line
 +              
 +              is_multiline = console.push(line_exec)
 +              
 +              stdout.seek(0)
 +              stderr.seek(0)
 +              
 +              output = stdout.read()
 +              output_err = stderr.read()
 +      
 +              # cleanup
 +              sys.stdout = sys.__stdout__
 +              sys.stderr = sys.__stderr__
 +              sys.last_traceback = None
 +              
 +              # So we can reuse, clear all data
 +              stdout.truncate(0)
 +              stderr.truncate(0)
 +              
 +              bpy.ops.console.scrollback_append(text = sc.prompt+line, type='INPUT')
 +              
 +              if is_multiline:        sc.prompt = self.PROMPT_MULTI
 +              else:                           sc.prompt = self.PROMPT
 +              
 +              # insert a new blank line
 +              bpy.ops.console.history_append(text="", current_character=0, remove_duplicates= True)
 +              
 +              # Insert the output into the editor
 +              # not quite correct because the order might have changed, but ok 99% of the time.
 +              if output:                      add_scrollback(output, 'OUTPUT')
 +              if output_err:          add_scrollback(output_err, 'ERROR')
 +              
 +              
 +              return ('FINISHED',)
 +
 +
 +def autocomp(bcon):
 +      '''
 +      This function has been taken from a BGE console autocomp I wrote a while ago
 +      the dictionaty bcon is not needed but it means I can copy and paste from the old func
 +      which works ok for now.
 +      
 +      could be moved into its own module.
 +      '''
 +      
 +      
 +      def is_delimiter(ch):
 +              '''
 +              For skipping words
 +              '''
 +              if ch == '_':
 +                      return False
 +              if ch.isalnum():
 +                      return False
 +              
 +              return True
 +      
 +      def is_delimiter_autocomp(ch):
 +              '''
 +              When autocompleteing will earch back and 
 +              '''
 +              if ch in '._[] "\'':
 +                      return False
 +              if ch.isalnum():
 +                      return False
 +              
 +              return True
 +
 +      
 +      def do_autocomp(autocomp_prefix, autocomp_members):
 +              '''
 +              return text to insert and a list of options
 +              '''
 +              autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
 +              
 +              print("AUTO: '%s'" % autocomp_prefix)
 +              print("MEMBERS: '%s'" % str(autocomp_members))
 +              
 +              if not autocomp_prefix:
 +                      return '', autocomp_members
 +              elif len(autocomp_members) > 1:
 +                      # find a common string between all members after the prefix 
 +                      # 'ge' [getA, getB, getC] --> 'get'
 +                      
 +                      # get the shortest member
 +                      min_len = min([len(v) for v in autocomp_members])
 +                      
 +                      autocomp_prefix_ret = ''
 +                      
 +                      for i in range(len(autocomp_prefix), min_len):
 +                              char_soup = set()
 +                              for v in autocomp_members:
 +                                      char_soup.add(v[i])
 +                              
 +                              if len(char_soup) > 1:
 +                                      break
 +                              else:
 +                                      autocomp_prefix_ret += char_soup.pop()
 +                              
 +                      print(autocomp_prefix_ret)
 +                      return autocomp_prefix_ret, autocomp_members
 +              elif len(autocomp_members) == 1:
 +                      return autocomp_members[0][len(autocomp_prefix):], []
 +              else:
 +                      return '', []
 +      
 +
 +      def BCon_PrevChar(bcon):
 +              cursor = bcon['cursor']-1
 +              if cursor<0:
 +                      return None
 +                      
 +              try:
 +                      return bcon['edit_text'][cursor]
 +              except:
 +                      return None
 +              
 +              
 +      def BCon_NextChar(bcon):
 +              try:
 +                      return bcon['edit_text'][bcon['cursor']]
 +              except:
 +                      return None
 +      
 +      def BCon_cursorLeft(bcon):
 +              bcon['cursor'] -= 1
 +              if bcon['cursor'] < 0:
 +                      bcon['cursor'] = 0
 +
 +      def BCon_cursorRight(bcon):
 +                      bcon['cursor'] += 1
 +                      if bcon['cursor'] > len(bcon['edit_text']):
 +                              bcon['cursor'] = len(bcon['edit_text'])
 +      
 +      def BCon_AddScrollback(bcon, text):
 +              
 +              bcon['scrollback'] = bcon['scrollback'] + text
 +              
 +      
 +      def BCon_cursorInsertChar(bcon, ch):
 +              if bcon['cursor']==0:
 +                      bcon['edit_text'] = ch + bcon['edit_text']
 +              elif bcon['cursor']==len(bcon['edit_text']):
 +                      bcon['edit_text'] = bcon['edit_text'] + ch
 +              else:
 +                      bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
 +                      
 +              bcon['cursor'] 
 +              if bcon['cursor'] > len(bcon['edit_text']):
 +                      bcon['cursor'] = len(bcon['edit_text'])
 +              BCon_cursorRight(bcon)
 +      
 +      
 +      TEMP_NAME = '___tempname___'
 +      
 +      cursor_orig = bcon['cursor']
 +      
 +      ch = BCon_PrevChar(bcon)
 +      while ch != None and (not is_delimiter(ch)):
 +              ch = BCon_PrevChar(bcon)
 +              BCon_cursorLeft(bcon)
 +      
 +      if ch != None:
 +              BCon_cursorRight(bcon)
 +      
 +      #print (cursor_orig, bcon['cursor'])
 +      
 +      cursor_base = bcon['cursor']
 +      
 +      autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
 +      
 +      print("PREFIX:'%s'" % autocomp_prefix)
 +      
 +      # Get the previous word
 +      if BCon_PrevChar(bcon)=='.':
 +              BCon_cursorLeft(bcon)
 +              ch = BCon_PrevChar(bcon)
 +              while ch != None and is_delimiter_autocomp(ch)==False:
 +                      ch = BCon_PrevChar(bcon)
 +                      BCon_cursorLeft(bcon)
 +              
 +              cursor_new = bcon['cursor']
 +              
 +              if ch != None:
 +                      cursor_new+=1
 +              
 +              pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
 +              print("AUTOCOMP EVAL: '%s'" % pytxt)
 +              #try:
 +              if pytxt:
 +                      bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
 +                      # print val
 +              else: ##except:
 +                      val = None
 +              
 +              try:
 +                      val = bcon['namespace'][TEMP_NAME]
 +                      del bcon['namespace'][TEMP_NAME]
 +              except:
 +                      val = None
 +              
 +              if val:
 +                      autocomp_members = dir(val)
 +                      
 +                      autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
 +                      
 +                      bcon['cursor'] = cursor_orig
 +                      for v in autocomp_prefix_ret:
 +                              BCon_cursorInsertChar(bcon, v)
 +                      cursor_orig = bcon['cursor']
 +                      
 +                      if autocomp_members:
 +                              BCon_AddScrollback(bcon, ', '.join(autocomp_members))
 +              
 +              del val
 +              
 +      else:
 +              # Autocomp global namespace
 +              autocomp_members = bcon['namespace'].keys()
 +              
 +              if autocomp_prefix:
 +                      autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
 +              
 +              autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
 +              
 +              bcon['cursor'] = cursor_orig
 +              for v in autocomp_prefix_ret:
 +                      BCon_cursorInsertChar(bcon, v)
 +              cursor_orig = bcon['cursor']
 +              
 +              if autocomp_members:
 +                      BCon_AddScrollback(bcon, ', '.join(autocomp_members))
 +      
 +      bcon['cursor'] = cursor_orig
 +
 +
 +class CONSOLE_OT_autocomplete(bpy.types.Operator):
 +      '''
++      Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.
 +      '''
 +      __idname__ = "console.autocomplete"
 +      __label__ = "Console Autocomplete"
 +      __register__ = False
 +      
 +      def poll(self, context):
 +              return context.space_data.type == 'PYTHON'
 +      
 +      def execute(self, context):
 +              
 +              sc = context.space_data
 +              
 +              namespace, console, stdout, stderr = get_console(hash(context.region))
 +              
 +              current_line = sc.history[-1]
 +              line = current_line.line
 +              
 +              if not console:
 +                      return ('CANCELLED',)
 +              
 +              if sc.console_type != 'PYTHON':
 +                      return ('CANCELLED',)
 +              
 +              # fake cursor, use for autocomp func.
 +              bcon = {}
 +              bcon['cursor'] = current_line.current_character
 +              bcon['console'] = console
 +              bcon['edit_text'] = line
 +              bcon['namespace'] = namespace
 +              bcon['scrollback'] = '' # nor from the BGE console
 +              
 +              
 +              # This function isnt aware of the text editor or being an operator
 +              # just does the autocomp then copy its results back
 +              autocomp(bcon)
 +              
 +              # Now we need to copy back the line from blender back into the text editor.
 +              # This will change when we dont use the text editor anymore
 +              if bcon['scrollback']:
 +                      add_scrollback(bcon['scrollback'], 'INFO')
 +              
 +              # copy back
 +              current_line.line = bcon['edit_text']
 +              current_line.current_character = bcon['cursor']
 +              
 +              context.area.tag_redraw()
 +              
 +              return ('FINISHED',)
 +
 +
 +
 +bpy.types.register(CONSOLE_HT_header)
 +bpy.types.register(CONSOLE_MT_console)
 +bpy.types.register(CONSOLE_MT_report)
 +
 +bpy.ops.add(CONSOLE_OT_exec)
 +bpy.ops.add(CONSOLE_OT_autocomplete)
 +
index 3f82727,0000000..0d0fd86
mode 100644,000000..100644
--- /dev/null
@@@ -1,377 -1,0 +1,381 @@@
-               layout.item_enumO("tfm.transform", "mode", 'TRANSLATION')
-               layout.item_enumO("tfm.transform", "mode", 'ROTATION')
-               layout.item_enumO("tfm.transform", "mode", 'RESIZE')
 +
 +import bpy
 +
 +class IMAGE_MT_view(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "View"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              sima = context.space_data
 +              uv = sima.uv_editor
 +              settings = context.tool_settings
 +
 +              show_uvedit = sima.show_uvedit
 +
 +              layout.itemO("image.properties", icon='ICON_MENU_PANEL')
 +
 +              layout.itemS()
 +
 +              layout.itemR(sima, "update_automatically")
 +              if show_uvedit:
 +                      layout.itemR(settings, "uv_local_view") # Numpad /
 +
 +              layout.itemS()
 +
 +              layout.itemO("image.view_zoom_in")
 +              layout.itemO("image.view_zoom_out")
 +
 +              layout.itemS()
 +
 +              ratios = [[1, 8], [1, 4], [1, 2], [1, 1], [2, 1], [4, 1], [8, 1]];
 +
 +              for a, b in ratios:
 +                      text = "Zoom %d:%d" % (a, b)
 +                      layout.item_floatO("image.view_zoom_ratio", "ratio", a/float(b), text=text)
 +
 +              layout.itemS()
 +
 +              if show_uvedit:
 +                      layout.itemO("image.view_selected")
 +
 +              layout.itemO("image.view_all")
 +              layout.itemO("screen.screen_full_area")
 +
 +class IMAGE_MT_select(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("uv.select_border")
 +              layout.item_booleanO("uv.select_border", "pinned", True)
 +
 +              layout.itemS()
 +              
 +              layout.itemO("uv.select_all_toggle")
 +              layout.itemO("uv.select_inverse")
 +              layout.itemO("uv.unlink_selection")
 +              
 +              layout.itemS()
 +
 +              layout.itemO("uv.select_pinned")
 +              layout.itemO("uv.select_linked")
 +
 +class IMAGE_MT_image(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "Image"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              sima = context.space_data
 +              ima = sima.image
 +
 +              layout.itemO("image.new")
 +              layout.itemO("image.open")
 +
 +              show_render = sima.show_render
 +
 +              if ima:
 +                      if not show_render:
 +                              layout.itemO("image.replace")
 +                              layout.itemO("image.reload")
 +
 +                      layout.itemO("image.save")
 +                      layout.itemO("image.save_as")
 +
 +                      if ima.source == 'SEQUENCE':
 +                              layout.itemO("image.save_sequence")
 +
 +                      if not show_render:
 +                              layout.itemS()
 +
 +                              if ima.packed_file:
 +                                      layout.itemO("image.unpack")
 +                              else:
 +                                      layout.itemO("image.pack")
 +
 +                              # only for dirty && specific image types, perhaps
 +                              # this could be done in operator poll too
 +                              if ima.dirty:
 +                                      if ima.source in ('FILE', 'GENERATED') and ima.type != 'MULTILAYER':
 +                                              layout.item_booleanO("image.pack", "as_png", True, text="Pack As PNG")
 +
 +                      layout.itemS()
 +
 +                      layout.itemR(sima, "image_painting")
 +
 +class IMAGE_MT_uvs_showhide(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "Show/Hide Faces"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("uv.reveal")
 +              layout.itemO("uv.hide")
 +              layout.item_booleanO("uv.hide", "unselected", True)
 +
 +class IMAGE_MT_uvs_transform(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "Transform"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
-               layout.item_enumO("uv.mirror", "axis", 'MIRROR_X') # "X Axis", M, 
-               layout.item_enumO("uv.mirror", "axis", 'MIRROR_Y') # "Y Axis", M, 
++              layout.itemO("tfm.translate")
++              layout.itemO("tfm.rotate")
++              layout.itemO("tfm.resize")
 +
 +class IMAGE_MT_uvs_mirror(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "Mirror"
 +
 +      def draw(self, context):
 +              layout = self.layout
++              layout.operator_context = "EXEC_REGION_WIN"
 +
-                       layout.itemR(uvedit, "pivot", text="")
++              props= layout.itemO("tfm.mirror", text="X Axis", properties=True)
++              props.constraint_axis[0]= True
++
++              props= layout.itemO("tfm.mirror", text="Y Axis", properties=True)
++              props.constraint_axis[1]= True
 +
 +class IMAGE_MT_uvs_weldalign(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "Weld/Align"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("uv.weld") # W, 1
 +              layout.items_enumO("uv.align", "axis") # W, 2/3/4
 +
 +class IMAGE_MT_uvs(bpy.types.Menu):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __label__ = "UVs"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              sima = context.space_data
 +              uv = sima.uv_editor
 +              settings = context.tool_settings
 +
 +              layout.itemR(uv, "snap_to_pixels")
 +              layout.itemR(uv, "constrain_to_image_bounds")
 +
 +              layout.itemS()
 +
 +              layout.itemR(uv, "live_unwrap")
 +              layout.itemO("uv.unwrap")
 +              layout.item_booleanO("uv.pin", "clear", True, text="Unpin")
 +              layout.itemO("uv.pin")
 +
 +              layout.itemS()
 +
 +              layout.itemO("uv.pack_islands")
 +              layout.itemO("uv.average_islands_scale")
 +              layout.itemO("uv.minimize_stretch")
 +              layout.itemO("uv.stitch")
 +
 +              layout.itemS()
 +
 +              layout.itemM("IMAGE_MT_uvs_transform")
 +              layout.itemM("IMAGE_MT_uvs_mirror")
 +              layout.itemM("IMAGE_MT_uvs_weldalign")
 +
 +              layout.itemS()
 +
 +              layout.itemR(settings, "proportional_editing")
 +              layout.item_menu_enumR(settings, "proportional_editing_falloff")
 +
 +              layout.itemS()
 +
 +              layout.itemM("IMAGE_MT_uvs_showhide")
 +
 +class IMAGE_HT_header(bpy.types.Header):
 +      __space_type__ = 'IMAGE_EDITOR'
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              sima = context.space_data
 +              ima = sima.image
 +              iuser = sima.image_user
 +              settings = context.tool_settings
 +
 +              show_render = sima.show_render
 +              show_paint = sima.show_paint
 +              show_uvedit = sima.show_uvedit
 +
 +              row = layout.row(align=True)
 +              row.template_header()
 +
 +              # menus
 +              if context.area.show_menus:
 +                      sub = row.row(align=True)
 +                      sub.itemM("IMAGE_MT_view")
 +
 +                      if show_uvedit:
 +                              sub.itemM("IMAGE_MT_select")
 +
 +                      if ima and ima.dirty:
 +                              sub.itemM("IMAGE_MT_image", text="Image*")
 +                      else:
 +                              sub.itemM("IMAGE_MT_image", text="Image")
 +
 +                      if show_uvedit:
 +                              sub.itemM("IMAGE_MT_uvs")
 +
 +              layout.template_ID(sima, "image", new="image.new")
 +
 +              # uv editing
 +              if show_uvedit:
 +                      uvedit = sima.uv_editor
 +
-                               layout.itemR(uvedit, "sticky_selection_mode", text="")
++                      layout.itemR(uvedit, "pivot", text="", icon_only=True)
 +                      layout.itemR(settings, "uv_sync_selection", text="")
 +
 +                      if settings.uv_sync_selection:
 +                              layout.itemR(settings, "mesh_selection_mode", text="", expand=True)
 +                      else:
 +                              layout.itemR(settings, "uv_selection_mode", text="", expand=True)
++                              layout.itemR(uvedit, "sticky_selection_mode", text="", icon_only=True)
 +                      pass
 +
 +                      row = layout.row(align=True)
 +                      row.itemR(settings, "snap", text="")
 +                      if settings.snap:
 +                              row.itemR(settings, "snap_mode", text="")
 +
 +                      """
 +                      mesh = context.edit_object.data
 +                      row.item_pointerR(mesh, "active_uv_layer", mesh, "uv_textures")
 +                      """
 +
 +              if ima:
 +                      # layers
 +                      layout.template_image_layers(ima, iuser)
 +
 +                      # painting
 +                      layout.itemR(sima, "image_painting", text="")
 +
 +                      # draw options
 +                      row = layout.row(align=True)
 +                      row.itemR(sima, "draw_channels", text="", expand=True)
 +
 +                      row = layout.row(align=True)
 +                      if ima.type == 'COMPOSITE':
 +                              row.itemO("image.record_composite", icon='ICON_REC')
 +                      if ima.type == 'COMPOSITE' and ima.source in ('MOVIE', 'SEQUENCE'):
 +                              row.itemO("image.play_composite", icon='ICON_PLAY')
 +              
 +              if show_uvedit or sima.image_painting:
 +                      layout.itemR(sima, "update_automatically", text="")
 +
 +class IMAGE_PT_game_properties(bpy.types.Panel):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __region_type__ = 'UI'
 +      __label__ = "Game Properties"
 +
 +      def poll(self, context):
 +              rd = context.scene.render_data
 +              sima = context.space_data
 +              return (sima and sima.image) and (rd.engine == 'BLENDER_GAME')
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              sima = context.space_data
 +              ima = sima.image
 +
 +              split = layout.split()
 +
 +              col = split.column()
 +              col.itemR(ima, "clamp_x")
 +              col.itemR(ima, "clamp_y")
 +              col.itemR(ima, "mapping", expand=True)
 +              col.itemR(ima, "tiles")
 +
 +              col = split.column()
 +
 +              sub = col.column(align=True)
 +              sub.itemR(ima, "animated")
 +
 +              subsub = sub.column()
 +              subsub.active = ima.animated
 +              subsub.itemR(ima, "animation_start", text="Start")
 +              subsub.itemR(ima, "animation_end", text="End")
 +              subsub.itemR(ima, "animation_speed", text="Speed")
 +
 +              sub = col.row(align=True)
 +              sub.active = ima.tiles or ima.animated
 +              sub.itemR(ima, "tiles_x", text="X")
 +              sub.itemR(ima, "tiles_y", text="Y")
 +
 +class IMAGE_PT_view_properties(bpy.types.Panel):
 +      __space_type__ = 'IMAGE_EDITOR'
 +      __region_type__ = 'UI'
 +      __label__ = "Display"
 +
 +      def poll(self, context):
 +              sima = context.space_data
 +              return (sima and (sima.image or sima.show_uvedit))
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              sima = context.space_data
 +              ima = sima.image
 +              show_uvedit = sima.show_uvedit
 +              uvedit = sima.uv_editor
 +
 +              split = layout.split()
 +
 +              col = split.column()
 +              if ima:
 +                      col.itemR(ima, "display_aspect", text="Aspect Ratio")
 +
 +                      col = split.column()
 +                      col.itemL(text="Coordinates:")
 +                      col.itemR(sima, "draw_repeated", text="Repeat")
 +                      if show_uvedit:
 +                              col.itemR(uvedit, "normalized_coordinates", text="Normalized")
 +              elif show_uvedit:
 +                      col.itemL(text="Coordinates:")
 +                      col.itemR(uvedit, "normalized_coordinates", text="Normalized")
 +
 +              if show_uvedit:
 +                      col = layout.column()
 +                      row = col.row()
 +                      row.itemR(uvedit, "edge_draw_type", expand=True)
 +                      
 +                      split = layout.split()
 +
 +                      col = split.column()
 +                      col.itemR(uvedit, "draw_stretch", text="Stretch")
 +                      sub = col.column()
 +                      sub.active = uvedit.draw_stretch
 +                      sub.row().itemR(uvedit, "draw_stretch_type", expand=True)
 +                      
 +                      col = split.column()
 +                      col.itemR(uvedit, "draw_smooth_edges", text="Smooth")
 +                      col.itemR(uvedit, "draw_modified_edges", text="Modified")
 +                      #col.itemR(uvedit, "draw_edges")
 +                      #col.itemR(uvedit, "draw_faces")
 +
 +bpy.types.register(IMAGE_MT_view)
 +bpy.types.register(IMAGE_MT_select)
 +bpy.types.register(IMAGE_MT_image)
 +bpy.types.register(IMAGE_MT_uvs_showhide)
 +bpy.types.register(IMAGE_MT_uvs_transform)
 +bpy.types.register(IMAGE_MT_uvs_mirror)
 +bpy.types.register(IMAGE_MT_uvs_weldalign)
 +bpy.types.register(IMAGE_MT_uvs)
 +bpy.types.register(IMAGE_HT_header)
 +bpy.types.register(IMAGE_PT_game_properties)
 +bpy.types.register(IMAGE_PT_view_properties)
index 5f9f73e,0000000..2333770
mode 100644,000000..100644
--- /dev/null
@@@ -1,254 -1,0 +1,254 @@@
-               layout.item_menu_enumO( "object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH')
-               layout.item_menu_enumO( "object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE')
-               layout.item_menu_enumO( "object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE')
-               layout.item_menu_enumO( "object.metaball_add", "type", 'META', icon='ICON_OUTLINER_OB_META')
 +
 +import bpy
 +
 +class INFO_HT_header(bpy.types.Header):
 +      __space_type__ = 'INFO'
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +              scene = context.scene
 +              rd = scene.render_data
 +
 +              row = layout.row(align=True)
 +              row.template_header()
 +
 +              if context.area.show_menus:
 +                      sub = row.row(align=True)
 +                      sub.itemM("INFO_MT_file")
 +                      sub.itemM("INFO_MT_add")
 +                      if rd.use_game_engine:
 +                              sub.itemM("INFO_MT_game")
 +                      else:
 +                              sub.itemM("INFO_MT_render")
 +                      sub.itemM("INFO_MT_help")
 +
 +              layout.template_ID(context.window, "screen", new="screen.new", unlink="screen.delete")
 +              layout.template_ID(context.screen, "scene", new="scene.new", unlink="scene.delete")
 +
 +              if rd.multiple_engines:
 +                      layout.itemR(rd, "engine", text="")
 +
 +              layout.itemS()
 +
 +              layout.template_operator_search()
 +              layout.template_running_jobs()
 +
 +              layout.itemL(text=scene.statistics())
 +                      
 +class INFO_MT_file(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "File"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.operator_context = "EXEC_AREA"
 +              layout.itemO("wm.read_homefile", text="New")
 +              layout.operator_context = "INVOKE_AREA"
 +              layout.itemO("wm.open_mainfile", text="Open...")
 +              layout.item_menu_enumO("wm.open_recentfile", "file", text="Open Recent")
 +              layout.itemO("wm.recover_last_session")
 +
 +              layout.itemS()
 +
 +              layout.operator_context = "EXEC_AREA"
 +              layout.itemO("wm.save_mainfile", text="Save")
 +              layout.operator_context = "INVOKE_AREA"
 +              layout.itemO("wm.save_as_mainfile", text="Save As...")
 +              layout.itemO("screen.userpref_show", text="User Preferences...")
 +
 +              layout.itemS()
 +
 +              layout.itemM("INFO_MT_file_import")
 +              layout.itemM("INFO_MT_file_export")
 +
 +              layout.itemS()
 +
 +              layout.itemM("INFO_MT_file_external_data")
 +
 +              layout.itemS()
 +
 +              layout.operator_context = "EXEC_AREA"
 +              layout.itemO("wm.exit_blender", text="Quit")
 +
 +class INFO_MT_file_import(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "Import"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemL(text="Nothing yet")
 +
 +              layout.itemO("WM_OT_collada_import", text="COLLADA")
 +
 +class INFO_MT_file_export(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "Export"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("export.ply", text="PLY")
 +              layout.itemO("WM_OT_collada_export", text="COLLADA")
 +
 +class INFO_MT_file_external_data(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "External Data"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("file.pack_all", text="Pack into .blend file")
 +              layout.itemO("file.unpack_all", text="Unpack into Files...")
 +
 +              layout.itemS()
 +
 +              layout.itemO("file.make_paths_relative")
 +              layout.itemO("file.make_paths_absolute")
 +              layout.itemO("file.report_missing_files")
 +              layout.itemO("file.find_missing_files")
 +
 +class INFO_MT_add(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "Add"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.operator_context = "EXEC_SCREEN"
 +
-               layout.item_enumO("object.object_add", "type", 'LATTICE', icon='ICON_OUTLINER_OB_LATTICE')
-               layout.item_enumO("object.object_add", "type", 'EMPTY', icon='ICON_OUTLINER_OB_EMPTY')
++              layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH')
++              layout.item_menu_enumO("object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE')
++              layout.item_menu_enumO("object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE')
++              layout.item_menu_enumO("object.metaball_add", "type", 'META', icon='ICON_OUTLINER_OB_META')
 +              layout.itemO("object.text_add", text="Text", icon='ICON_OUTLINER_OB_FONT')
 +
 +              layout.itemS()
 +
 +              layout.itemO("object.armature_add", text="Armature", icon='ICON_OUTLINER_OB_ARMATURE')
-               layout.item_enumO("object.object_add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
-               layout.item_enumO("object.object_add", "type", 'LAMP', icon='ICON_OUTLINER_OB_LAMP')
++              layout.item_enumO("object.add", "type", 'LATTICE', icon='ICON_OUTLINER_OB_LATTICE')
++              layout.item_enumO("object.add", "type", 'EMPTY', icon='ICON_OUTLINER_OB_EMPTY')
 +
 +              layout.itemS()
 +
++              layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
++              layout.item_enumO("object.add", "type", 'LAMP', icon='ICON_OUTLINER_OB_LAMP')
 +
 +class INFO_MT_game(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "Game"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              gs = context.scene.game_data
 +
 +              layout.itemO("view3d.game_start")
 +
 +              layout.itemS()
 +
 +              layout.itemR(gs, "show_debug_properties")
 +              layout.itemR(gs, "show_framerate_profile")
 +              layout.itemR(gs, "show_physics_visualization")
 +              layout.itemR(gs, "deprecation_warnings")
 +
 +class INFO_MT_render(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "Render"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              rd = context.scene.render_data
 +
 +              layout.itemO("screen.render", text="Render Image")
 +              layout.item_booleanO("screen.render", "animation", True, text="Render Animation")
 +
 +              layout.itemS()
 +
 +              layout.itemO("screen.render_view_show")
 +
 +class INFO_MT_help(bpy.types.Menu):
 +      __space_type__ = 'INFO'
 +      __label__ = "Help"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("help.manual")
 +              layout.itemO("help.release_logs")
 +
 +              layout.itemS()
 +
 +              layout.itemO("help.blender_website")
 +              layout.itemO("help.blender_eshop")
 +              layout.itemO("help.developer_community")
 +              layout.itemO("help.user_community")
 +
 +bpy.types.register(INFO_HT_header)
 +bpy.types.register(INFO_MT_file)
 +bpy.types.register(INFO_MT_file_import)
 +bpy.types.register(INFO_MT_file_export)
 +bpy.types.register(INFO_MT_file_external_data)
 +bpy.types.register(INFO_MT_add)
 +bpy.types.register(INFO_MT_game)
 +bpy.types.register(INFO_MT_render)
 +bpy.types.register(INFO_MT_help)
 +
 +# Help operators
 +
 +import bpy_ops # XXX - should not need to do this
 +del bpy_ops
 +
 +class HelpOperator(bpy.types.Operator):
 +      def execute(self, context):
 +              try: import webbrowser
 +              except: webbrowser = None
 +
 +              if webbrowser:
 +                      webbrowser.open(self.__URL__)
 +              else:
 +                      raise Exception("Operator requires a full Python installation")
 +
 +              return ('FINISHED',)
 +
 +class HELP_OT_manual(HelpOperator):
 +      __idname__ = "help.manual"
 +      __label__ = "Manual"
 +      __URL__ = 'http://wiki.blender.org/index.php/Manual'
 +
 +class HELP_OT_release_logs(HelpOperator):
 +      __idname__ = "help.release_logs"
 +      __label__ = "Release Logs"
 +      __URL__ = 'http://www.blender.org/development/release-logs/'
 +
 +class HELP_OT_blender_website(HelpOperator):
 +      __idname__ = "help.blender_website"
 +      __label__ = "Blender Website"
 +      __URL__ = 'http://www.blender.org/'
 +
 +class HELP_OT_blender_eshop(HelpOperator):
 +      __idname__ = "help.blender_eshop"
 +      __label__ = "Blender e-Shop"
 +      __URL__ = 'http://www.blender3d.org/e-shop'
 +
 +class HELP_OT_developer_community(HelpOperator):
 +      __idname__ = "help.developer_community"
 +      __label__ = "Developer Community"
 +      __URL__ = 'http://www.blender.org/community/get-involved/'
 +
 +class HELP_OT_user_community(HelpOperator):
 +      __idname__ = "help.user_community"
 +      __label__ = "User Community"
 +      __URL__ = 'http://www.blender.org/community/user-community/'
 +
 +bpy.ops.add(HELP_OT_manual)
 +bpy.ops.add(HELP_OT_release_logs)
 +bpy.ops.add(HELP_OT_blender_website)
 +bpy.ops.add(HELP_OT_blender_eshop)
 +bpy.ops.add(HELP_OT_developer_community)
 +bpy.ops.add(HELP_OT_user_community)
 +
index bef48f5,0000000..daae4a8
mode 100644,000000..100644
--- /dev/null
@@@ -1,603 -1,0 +1,602 @@@
-               return strip.type in ('MOVIE', 'IMAGE', 'SOUND')
 +
 +import bpy
 +
 +def act_strip(context):
 +      try:            return context.scene.sequence_editor.active_strip
 +      except: return None
 +
 +# Header
 +class SEQUENCER_HT_header(bpy.types.Header):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +
 +              row = layout.row(align=True)
 +              row.template_header()
 +              
 +              if context.area.show_menus:
 +                      sub = row.row(align=True)
 +                      sub.itemM("SEQUENCER_MT_view")
 +                      
 +                      row.itemS()
 +                      
 +                      if st.display_mode == 'SEQUENCER':
 +                              sub.itemM("SEQUENCER_MT_select")
 +                              sub.itemM("SEQUENCER_MT_marker")
 +                              sub.itemM("SEQUENCER_MT_add")
 +                              sub.itemM("SEQUENCER_MT_strip")
 +
 +              layout.itemR(st, "display_mode", text="")
 +
 +              if st.display_mode == 'SEQUENCER':
 +                      layout.itemS()
 +                      layout.itemO("sequencer.reload")
 +              else:
 +                      layout.itemR(st, "display_channel", text="Channel")
 +
 +class SEQUENCER_MT_view(bpy.types.Menu):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __label__ = "View"
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +              
 +              layout.column()
 +              
 +              """
 +      uiBlock *block= uiBeginBlock(C, ar, "seq_viewmenu", UI_EMBOSSP);
 +      short yco= 0, menuwidth=120;
 +
 +      if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
 +              uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
 +                               "Play Back Animation "
 +                               "in all Sequence Areas|Alt A", 0, yco-=20,
 +                               menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
 +      }
 +      else {
 +              uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL,
 +                               "Grease Pencil...", 0, yco-=20,
 +                               menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
 +              uiDefMenuSep(block);
 +
 +              uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
 +                               "Play Back Animation "
 +                               "in this window|Alt A", 0, yco-=20,
 +                               menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
 +      }
 +      uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
 +                       "Play Back Animation in all "
 +                       "3D Views and Sequence Areas|Alt Shift A",
 +                       0, yco-=20,
 +                       menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
 +
 +              """
 +              layout.itemS()
 +              layout.itemO("sequencer.view_all")
 +              layout.itemO("sequencer.view_selected")
 +              layout.itemS()
 +              layout.itemO("screen.screen_full_area", text="Toggle Full Screen")
 +              """
 +      
 +
 +      /* Lock Time */
 +      uiDefIconTextBut(block, BUTM, 1, (v2d->flag & V2D_VIEWSYNC_SCREEN_TIME)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
 +                      "Lock Time to Other Windows|", 0, yco-=20,
 +                      menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
 +
 +      /* Draw time or frames.*/
 +      uiDefMenuSep(block);
 +              """
 +              
 +              layout.itemR(st, "draw_frames")
 +              if st.display_mode == 'IMAGE':
 +                      layout.itemR(st, "draw_safe_margin")
 +              if st.display_mode == 'WAVEFORM':
 +                      layout.itemR(st, "seperate_color_preview")
 +              
 +              """
 +      if(!sa->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,0, "");
 +      else uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
 +
 +              """
 +
 +class SEQUENCER_MT_select(bpy.types.Menu):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +              
 +              layout.column()
 +              layout.item_enumO("sequencer.select_active_side", "side", 'LEFT', text="Strips to the Left")
 +              layout.item_enumO("sequencer.select_active_side", "side", 'RIGHT', text="Strips to the Right")
 +              layout.itemS()
 +              layout.item_enumO("sequencer.select_handles", "side", 'BOTH', text="Surrounding Handles")
 +              layout.item_enumO("sequencer.select_handles", "side", 'LEFT', text="Left Handle")
 +              layout.item_enumO("sequencer.select_handles", "side", 'RIGHT', text="Right Handle")
 +              layout.itemS()
 +              layout.itemO("sequencer.select_linked")
 +              layout.itemO("sequencer.select_all_toggle")
 +              layout.itemO("sequencer.select_inverse")
 +
 +class SEQUENCER_MT_marker(bpy.types.Menu):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __label__ = "Marker (TODO)"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +              
 +              layout.column()
 +              layout.itemO("marker.add", text="Add Marker")
 +              layout.itemO("marker.duplicate", text="Duplicate Marker")
 +              layout.itemO("marker.move", text="Grab/Move Marker")
 +              layout.itemO("marker.delete", text="Delete Marker")
 +              layout.itemS()
 +              layout.itemL(text="ToDo: Name Marker")
 +              
 +              #layout.itemO("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS)
 +
 +class SEQUENCER_MT_add(bpy.types.Menu):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __label__ = "Add"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +              
 +              layout.column()
 +              layout.itemO("sequencer.scene_strip_add", text="Scene")
 +              layout.itemO("sequencer.movie_strip_add", text="Movie")
 +              layout.itemO("sequencer.image_strip_add", text="Image")
 +              layout.itemO("sequencer.sound_strip_add", text="Sound")
 +              
 +              layout.itemM("SEQUENCER_MT_add_effect")
 +
 +class SEQUENCER_MT_add_effect(bpy.types.Menu):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __label__ = "Effect Strip..."
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +              
 +              layout.column()
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'ADD')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'SUBTRACT')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'ALPHA_OVER')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'ALPHA_UNDER')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'GAMMA_CROSS')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'MULTIPLY')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'OVER_DROP')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'PLUGIN')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'WIPE')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'GLOW')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'TRANSFORM')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'COLOR')
 +              layout.item_enumO("sequencer.effect_strip_add", 'type', 'SPEED')
 +
 +class SEQUENCER_MT_strip(bpy.types.Menu):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __label__ = "Strip"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +              
 +              layout.operator_context = 'INVOKE_REGION_WIN'
 +              
 +              layout.column()
 +              layout.item_enumO("tfm.transform", "mode", 'TRANSLATION', text="Grab/Move")
 +              layout.item_enumO("tfm.transform", "mode", 'TIME_EXTEND', text="Grab/Extend from frame")
 +              #  uiItemO(layout, NULL, 0, "sequencer.strip_snap"); // TODO - add this operator
 +              layout.itemS()
 +              
 +              layout.item_enumO("sequencer.cut", "type", 'HARD', text="Cut (hard) at frame")
 +              layout.item_enumO("sequencer.cut", "type", 'SOFT', text="Cut (soft) at frame")
 +              layout.itemO("sequencer.images_separate")
 +              layout.itemS()
 +              
 +              layout.itemO("sequencer.duplicate")
 +              layout.itemO("sequencer.delete")
 +              
 +              strip = act_strip(context)
 +              
 +              if strip:
 +                      stype = strip.type
 +                      
 +                      if      stype=='EFFECT':
 +                              layout.itemS()
 +                              layout.itemO("sequencer.effect_change")
 +                              layout.itemO("sequencer.effect_reassign_inputs")
 +                      elif stype=='IMAGE':
 +                              layout.itemS()
 +                              layout.itemO("sequencer.image_change")
 +                      elif stype=='SCENE':
 +                              layout.itemS()
 +                              layout.itemO("sequencer.scene_change", text="Change Scene")
 +                      elif stype=='MOVIE':
 +                              layout.itemS()
 +                              layout.itemO("sequencer.movie_change")
 +                      
 +              layout.itemS()
 +              
 +              layout.itemO("sequencer.meta_make")
 +              layout.itemO("sequencer.meta_separate")
 +              
 +              #if (ed && (ed->metastack.first || (ed->act_seq && ed->act_seq->type == SEQ_META))) {
 +              #       uiItemS(layout);
 +              #       uiItemO(layout, NULL, 0, "sequencer.meta_toggle");
 +              #}
 +              
 +              layout.itemS()
 +              layout.itemO("sequencer.reload")
 +              layout.itemS()
 +              layout.itemO("sequencer.lock")
 +              layout.itemO("sequencer.unlock")
 +              layout.itemO("sequencer.mute")
 +              layout.itemO("sequencer.unmute")
 +              
 +              layout.item_booleanO("sequencer.mute", "unselected", 1, text="Mute Deselected Strips")
 +
 +              layout.itemO("sequencer.snap")
 +
 +# Panels
 +class SequencerButtonsPanel(bpy.types.Panel):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __region_type__ = 'UI'
 +
 +      def poll(self, context):
 +              return context.space_data.display_mode == 'SEQUENCER' and act_strip(context) != None
 +              
 +class SequencerButtonsPanel_Output(bpy.types.Panel):
 +      __space_type__ = 'SEQUENCE_EDITOR'
 +      __region_type__ = 'UI'
 +
 +      def poll(self, context):
 +              return context.space_data.display_mode != 'SEQUENCER'
 +
 +class SEQUENCER_PT_edit(SequencerButtonsPanel):
 +      __label__ = "Edit Strip"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              strip = act_strip(context)
 +              
 +              split = layout.split(percentage=0.3)
 +              split.itemL(text="Name:")
 +              split.itemR(strip, "name", text="")
 +              
 +              split = layout.split(percentage=0.3)
 +              split.itemL(text="Type:")
 +              split.itemR(strip, "type", text="")
 +              
 +              split = layout.split(percentage=0.3)
 +              split.itemL(text="Blend:")
 +              split.itemR(strip, "blend_mode", text="")
 +              
 +              row = layout.row()
 +              if strip.mute == True:
 +                      row.itemR(strip, "mute", toggle=True, icon='ICON_RESTRICT_VIEW_ON', text="")
 +              elif strip.mute == False:
 +                      row.itemR(strip, "mute", toggle=True, icon='ICON_RESTRICT_VIEW_OFF', text="")
 +              
 +              sub = row.row()
 +              sub.active = (not strip.mute)
 +              
 +              sub.itemR(strip, "blend_opacity", text="Opacity", slider=True)
 +              
 +              row = layout.row()
 +              row.itemR(strip, "lock")
 +              row.itemR(strip, "frame_locked", text="Frame Lock")
 +              
 +              col = layout.column()
 +              col.enabled = not strip.lock    
 +              col.itemR(strip, "channel")
 +              col.itemR(strip, "start_frame")
 +              col.itemR(strip, "length")
 +              
 +              col = layout.column(align=True)
 +              col.itemL(text="Offset:")
 +              col.itemR(strip, "start_offset", text="Start")
 +              col.itemR(strip, "end_offset", text="End")
 +              
 +              col = layout.column(align=True)
 +              col.itemL(text="Still:")
 +              col.itemR(strip, "start_still", text="Start")
 +              col.itemR(strip, "end_still", text="End")
 +              
 +class SEQUENCER_PT_effect(SequencerButtonsPanel):
 +      __label__ = "Effect Strip"
 +
 +      def poll(self, context):
 +              if context.space_data.display_mode != 'SEQUENCER':
 +                      return False
 +              
 +              strip = act_strip(context)
 +              if not strip:
 +                      return False
 +              
 +              return strip.type in ('COLOR', 'WIPE', 'GLOW', 'SPEED', 'TRANSFORM')
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              strip = act_strip(context)
 +              
 +              if strip.type == 'COLOR':
 +                      layout.itemR(strip, "color")
 +                      
 +              elif strip.type == 'WIPE':
 +                      
 +                      col = layout.column()
 +                      col.itemR(strip, "transition_type")
 +                      col.itemL(text="Direction:")
 +                      col.row().itemR(strip, "direction", expand=True)
 +                      
 +                      col = layout.column()
 +                      col.itemR(strip, "blur_width", slider=True)
 +                      if strip.transition_type in ('SINGLE', 'DOUBLE'):
 +                              col.itemR(strip, "angle")
 +                              
 +              elif strip.type == 'GLOW':
 +                      flow = layout.column_flow()
 +                      flow.itemR(strip, "threshold", slider=True)
 +                      flow.itemR(strip, "clamp", slider=True)
 +                      flow.itemR(strip, "boost_factor")
 +                      flow.itemR(strip, "blur_distance")
 +                      
 +                      row = layout.row()
 +                      row.itemR(strip, "quality", slider=True)
 +                      row.itemR(strip, "only_boost")
 +                      
 +              elif strip.type == 'SPEED':
 +                      layout.itemR(strip, "global_speed")
 +                      
 +                      flow = layout.column_flow()
 +                      flow.itemR(strip, "curve_velocity")
 +                      flow.itemR(strip, "curve_compress_y")
 +                      flow.itemR(strip, "frame_blending")
 +                      
 +              elif strip.type == 'TRANSFORM':
 +                      
 +                      col = layout.column()
 +                      col.itemR(strip, "interpolation")
 +                      col.itemR(strip, "translation_unit")
 +                      
 +                      col = layout.column(align=True)
 +                      col.itemL(text="Position X:")
 +                      col.itemR(strip, "translate_start_x", text="Start")
 +                      col.itemR(strip, "translate_end_x", text="End")
 +                      
 +                      col = layout.column(align=True)
 +                      col.itemL(text="Position Y:")
 +                      col.itemR(strip, "translate_start_y", text="Start")
 +                      col.itemR(strip, "translate_end_y", text="End")
 +                      
 +                      layout.itemS()
 +                      
 +                      col = layout.column(align=True)
 +                      col.itemL(text="Scale X:")
 +                      col.itemR(strip, "scale_start_x", text="Start")
 +                      col.itemR(strip, "scale_end_x", text="End")
 +                      
 +                      col = layout.column(align=True)
 +                      col.itemL(text="Scale Y:")
 +                      col.itemR(strip, "scale_start_y", text="Start")
 +                      col.itemR(strip, "scale_end_y", text="End")
 +                      
 +                      layout.itemS()
 +                      
 +                      col = layout.column(align=True)
 +                      col.itemL(text="Rotation:")
 +                      col.itemR(strip, "rotation_start", text="Start")
 +                      col.itemR(strip, "rotation_end", text="End")
 +
 +class SEQUENCER_PT_input(SequencerButtonsPanel):
 +      __label__ = "Strip Input"
 +      
 +      def poll(self, context):
 +              if context.space_data.display_mode != 'SEQUENCER':
 +                      return False
 +              
 +              strip = act_strip(context)
 +              if not strip:
 +                      return False
 +              
-               if strip.type != 'SOUND':
-                       layout.itemR(strip, "use_translation", text="Image Offset:")
-                       if strip.transform:
-                               col = layout.column(align=True)
-                               col.active = strip.use_translation
-                               col.itemR(strip.transform, "offset_x", text="X")
-                               col.itemR(strip.transform, "offset_y", text="Y")
-               
-                       layout.itemR(strip, "use_crop", text="Image Crop:")
-                       if strip.crop:
-                               col = layout.column(align=True)
-                               col.active = strip.use_crop
-                               col.itemR(strip.crop, "top")
-                               col.itemR(strip.crop, "left")
-                               col.itemR(strip.crop, "bottom")
-                               col.itemR(strip.crop, "right")
-                       
++              return strip.type in ('MOVIE', 'IMAGE')
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              strip = act_strip(context)
 +              
 +              split = layout.split(percentage=0.2)
 +              col = split.column()
 +              col.itemL(text="Path:")
 +              col = split.column()
 +              col.itemR(strip, "directory", text="")
 +              
 +              # Current element for the filename
 +              
 +              
 +              elem = strip.getStripElem(context.scene.current_frame)
 +              if elem:
 +                      split = layout.split(percentage=0.2)
 +                      col = split.column()
 +                      col.itemL(text="File:")
 +                      col = split.column()
 +                      col.itemR(elem, "filename", text="") # strip.elements[0] could be a fallback
 +              
-                       col.itemL(text="Trim Duration:")
-                       col.itemR(strip, "animation_start_offset", text="Start")
-                       col.itemR(strip, "animation_end_offset", text="End")
++              layout.itemR(strip, "use_translation", text="Image Offset:")
++              if strip.transform:
++                      col = layout.column(align=True)
++                      col.active = strip.use_translation
++                      col.itemR(strip.transform, "offset_x", text="X")
++                      col.itemR(strip.transform, "offset_y", text="Y")
++      
++              layout.itemR(strip, "use_crop", text="Image Crop:")
++              if strip.crop:
 +                      col = layout.column(align=True)
++                      col.active = strip.use_crop
++                      col.itemR(strip.crop, "top")
++                      col.itemR(strip.crop, "left")
++                      col.itemR(strip.crop, "bottom")
++                      col.itemR(strip.crop, "right")
++              
++              col = layout.column(align=True)
++              col.itemL(text="Trim Duration:")
++              col.itemR(strip, "animation_start_offset", text="Start")
++              col.itemR(strip, "animation_end_offset", text="End")
 +
 +class SEQUENCER_PT_sound(SequencerButtonsPanel):
 +      __label__ = "Sound"
 +      
 +      def poll(self, context):
 +              if context.space_data.display_mode != 'SEQUENCER':
 +                      return False
 +              
 +              strip = act_strip(context)
 +              if not strip:
 +                      return False
 +              
 +              return strip.type in ('SOUND', )
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              strip = act_strip(context)
 +              
 +              layout.template_ID(strip, "sound", new="sound.open")
 +              
 +              layout.itemS()
 +              layout.itemR(strip.sound, "filename", text="")
 +              
 +              row = layout.row()
 +              if strip.sound.packed_file:
 +                      row.itemO("sound.unpack", icon='ICON_PACKAGE', text="Unpack")
 +              else:
 +                      row.itemO("sound.pack", icon='ICON_UGLYPACKAGE', text="Pack")
 +              
 +              row.itemR(strip.sound, "caching")
 +
 +class SEQUENCER_PT_filter(SequencerButtonsPanel):
 +      __label__ = "Filter"
 +      
 +      def poll(self, context):
 +              if context.space_data.display_mode != 'SEQUENCER':
 +                      return False
 +              
 +              strip = act_strip(context)
 +              if not strip:
 +                      return False
 +              
 +              return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META')
 +      
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              strip = act_strip(context)
 +
 +              col = layout.column()
 +              col.itemL(text="Video:")
 +              col.itemR(strip, "strobe")
 +              col.itemR(strip, "de_interlace")
 +              
 +              col = layout.column()
 +              col.itemL(text="Colors:")
 +              col.itemR(strip, "multiply_colors", text="Multiply")
 +              col.itemR(strip, "premultiply")
 +              col.itemR(strip, "convert_float")
 +
 +              col = layout.column()
 +              col.itemL(text="Flip:")
 +              col.itemR(strip, "flip_x", text="X")
 +              col.itemR(strip, "flip_y", text="Y")
 +              col.itemR(strip, "reverse_frames", text="Backwards")
 +              
 +              layout.itemR(strip, "use_color_balance")
 +              if strip.color_balance: # TODO - need to add this somehow
 +                      row = layout.row()
 +                      row.active = strip.use_color_balance
 +                      col = row.column()
 +                      col.itemR(strip.color_balance, "lift")
 +                      col.itemR(strip.color_balance, "inverse_lift", text="Inverse")
 +                      col = row.column()
 +                      col.itemR(strip.color_balance, "gamma")
 +                      col.itemR(strip.color_balance, "inverse_gamma", text="Inverse")
 +                      col = row.column()
 +                      col.itemR(strip.color_balance, "gain")
 +                      col.itemR(strip.color_balance, "inverse_gain", text="Inverse")
 +
 +class SEQUENCER_PT_proxy(SequencerButtonsPanel):
 +      __label__ = "Proxy"
 +      
 +      def poll(self, context):
 +              if context.space_data.display_mode != 'SEQUENCER':
 +                      return False
 +              
 +              strip = act_strip(context)
 +              if not strip:
 +                      return False
 +              
 +              return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META')
 +      
 +      def draw_header(self, context):
 +              layout = self.layout
 +              
 +              strip = act_strip(context)
 +              
 +              layout.itemR(strip, "use_proxy", text="")
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              strip = act_strip(context)
 +              
 +              flow = layout.column_flow()
 +              flow.itemR(strip, "proxy_custom_directory")
 +              if strip.proxy: # TODO - need to add this somehow
 +                      flow.itemR(strip.proxy, "directory")
 +                      flow.itemR(strip.proxy, "file")
 +
 +class SEQUENCER_PT_view(SequencerButtonsPanel_Output):
 +      __label__ = "View Settings"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              st = context.space_data
 +
 +              col = layout.column()
 +              col.itemR(st, "draw_overexposed") # text="Zebra"
 +              col.itemR(st, "draw_safe_margin")
 +
 +bpy.types.register(SEQUENCER_HT_header) # header/menu classes
 +bpy.types.register(SEQUENCER_MT_view)
 +bpy.types.register(SEQUENCER_MT_select)
 +bpy.types.register(SEQUENCER_MT_marker)
 +bpy.types.register(SEQUENCER_MT_add)
 +bpy.types.register(SEQUENCER_MT_add_effect)
 +bpy.types.register(SEQUENCER_MT_strip)
 +
 +bpy.types.register(SEQUENCER_PT_edit) # sequencer panels
 +bpy.types.register(SEQUENCER_PT_effect)
 +bpy.types.register(SEQUENCER_PT_input)
 +bpy.types.register(SEQUENCER_PT_sound)
 +bpy.types.register(SEQUENCER_PT_filter)
 +bpy.types.register(SEQUENCER_PT_proxy)
 +
 +bpy.types.register(SEQUENCER_PT_view) # view panels
index ae1edc0,0000000..df65795
mode 100644,000000..100644
--- /dev/null
@@@ -1,1328 -1,0 +1,1353 @@@
-               layout.itemO("object.duplicate")
 +
 +import bpy
 +
 +# ********** Header **********
 +
 +class VIEW3D_HT_header(bpy.types.Header):
 +      __space_type__ = 'VIEW_3D'
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              view = context.space_data
 +              mode_string = context.mode
 +              edit_object = context.edit_object
 +              object = context.active_object
 +              
 +              row = layout.row(align=True)
 +              row.template_header()
 +
 +              # Menus
 +              if context.area.show_menus:
 +                      sub = row.row(align=True)
 +
 +                      sub.itemM("VIEW3D_MT_view")
 +                      
 +                      # Select Menu
 +                      if mode_string not in ('EDIT_TEXT', 'SCULPT', 'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'):
 +                              sub.itemM("VIEW3D_MT_select_%s" % mode_string)
 +                      
 +                      if edit_object:
 +                              sub.itemM("VIEW3D_MT_edit_%s" % edit_object.type)
 +                      elif object:
 +                              ob_mode_string = object.mode
 +                              
 +                              if mode_string not in ['PAINT_WEIGHT', 'PAINT_TEXTURE']:
 +                                      sub.itemM("VIEW3D_MT_%s" % mode_string)
 +
 +              layout.template_header_3D()
 +
 +# ********** Menu **********
 +
 +# ********** Utilities **********
 +
 +class VIEW3D_MT_showhide(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Show/Hide"
 +      _operator_name = ""
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("%s.reveal" % self._operator_name, text="Show Hidden")
 +              layout.itemO("%s.hide" % self._operator_name, text="Hide Selected")
 +              layout.item_booleanO("%s.hide" % self._operator_name, "unselected", True, text="Hide Unselected")
 +
 +class VIEW3D_MT_snap(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Snap"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("view3d.snap_selected_to_grid", text="Selection to Grid")
 +              layout.itemO("view3d.snap_selected_to_cursor", text="Selection to Cursor")
 +              layout.itemO("view3d.snap_selected_to_center", text="Selection to Center")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("view3d.snap_cursor_to_selected", text="Cursor to Selected")
 +              layout.itemO("view3d.snap_cursor_to_grid", text="Cursor to Grid")
 +              layout.itemO("view3d.snap_cursor_to_active", text="Cursor to Active")
 +
 +# ********** View menus **********
 +
 +class VIEW3D_MT_view(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "View"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.properties", icon='ICON_MENU_PANEL')
 +              layout.itemO("view3d.toolbar", icon='ICON_MENU_PANEL')
 +              
 +              layout.itemS()
 +              
 +              layout.item_enumO("view3d.viewnumpad", "type", 'CAMERA')
 +              layout.item_enumO("view3d.viewnumpad", "type", 'TOP')
 +              layout.item_enumO("view3d.viewnumpad", "type", 'FRONT')
 +              layout.item_enumO("view3d.viewnumpad", "type", 'RIGHT')
 +              
 +              layout.itemM("VIEW3D_MT_view_cameras", text="Cameras")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("view3d.view_persportho")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_view_navigation")
 +              layout.itemM("VIEW3D_MT_view_align")
 +              
 +              layout.itemS()
 +
 +              layout.operator_context = "INVOKE_REGION_WIN"
 +              
 +              layout.itemO("view3d.clip_border", text="Clipping Border...")
 +              layout.itemO("view3d.zoom_border", text="Zoom Border...")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("view3d.view_center")
 +              layout.itemO("view3d.view_all")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("screen.region_foursplit", text="Toggle Quad View")
 +              layout.itemO("screen.screen_full_area", text="Toggle Full Screen")
 +
 +class VIEW3D_MT_view_navigation(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Navigation"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.items_enumO("view3d.view_orbit", "type")
 +              
 +              layout.itemS()
 +              
 +              layout.items_enumO("view3d.view_pan", "type")
 +              
 +              layout.itemS()
 +              
 +              layout.item_floatO("view3d.zoom", "delta", 1.0, text="Zoom In")
 +              layout.item_floatO("view3d.zoom", "delta", -1.0, text="Zoom Out")
 +
 +class VIEW3D_MT_view_align(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Align View"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("view3d.view_center")
 +              
 +class VIEW3D_MT_view_cameras(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Cameras"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +# ********** Select menus, suffix from context.mode **********
 +
 +class VIEW3D_MT_select_OBJECT(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border")
 +
 +              layout.itemS()
 +
 +              layout.itemO("object.select_all_toggle", text="Select/Deselect All")
 +              layout.itemO("object.select_inverse", text="Inverse")
 +              layout.itemO("object.select_random", text="Random")
 +              layout.itemO("object.select_mirror", text="Mirror")
 +              layout.itemO("object.select_by_layer", text="Select All by Layer")
 +              layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...")
 +              layout.itemO("object.select_grouped", text="Select Grouped...")
 +
 +class VIEW3D_MT_select_POSE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border", text="Border Select...")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("pose.select_all_toggle", text="Select/Deselect All")
 +              layout.itemO("pose.select_inverse", text="Inverse")
 +              layout.itemO("pose.select_constraint_target", text="Constraint Target")
++              layout.itemO("pose.select_linked", text="Linked")
 +              
 +              layout.itemS()
 +              
 +              layout.item_enumO("pose.select_hierarchy", "direction", 'PARENT')
 +              layout.item_enumO("pose.select_hierarchy", "direction", 'CHILD')
 +              
 +              layout.itemS()
 +              
 +              props = layout.itemO("pose.select_hierarchy", properties=True, text="Extend Parent")
 +              props.extend = True
 +              props.direction = 'PARENT'
 +
 +              props = layout.itemO("pose.select_hierarchy", properties=True, text="Extend Child")
 +              props.extend = True
 +              props.direction = 'CHILD'
 +
 +class VIEW3D_MT_select_PARTICLE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("particle.select_all_toggle", text="Select/Deselect All")
 +              layout.itemO("particle.select_linked")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("particle.select_more")
 +              layout.itemO("particle.select_less")
 +
 +class VIEW3D_MT_select_EDIT_MESH(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border", text="Border Select...")
 +
 +              layout.itemS()
 +
 +              layout.itemO("mesh.select_all_toggle", text="Select/Deselect All")
 +              layout.itemO("mesh.select_inverse", text="Inverse")
 +
 +              layout.itemS()
 +
 +              layout.itemO("mesh.select_random", text="Random...")
 +              layout.itemO("mesh.edges_select_sharp", text="Sharp Edges")
 +              layout.itemO("mesh.faces_select_linked_flat", text="Linked Flat Faces")
 +
 +              layout.itemS()
 +
 +              layout.item_enumO("mesh.select_by_number_vertices", "type", 'TRIANGLES', text="Triangles")
 +              layout.item_enumO("mesh.select_by_number_vertices", "type", 'QUADS', text="Quads")
 +              layout.item_enumO("mesh.select_by_number_vertices", "type", 'OTHER', text="Loose Verts/Edges")
 +              layout.itemO("mesh.select_similar", text="Similar...")
 +
 +              layout.itemS()
 +
 +              layout.itemO("mesh.select_less", text="Less")
 +              layout.itemO("mesh.select_more", text="More")
 +
 +              layout.itemS()
 +
 +              layout.itemO("mesh.select_linked", text="Linked")
 +              layout.itemO("mesh.select_vertex_path", text="Vertex Path")
 +              layout.itemO("mesh.loop_multi_select", text="Edge Loop")
 +              layout.item_booleanO("mesh.loop_multi_select", "ring", True, text="Edge Ring")
 +
 +              layout.itemS()
 +
 +              layout.itemO("mesh.loop_to_region")
 +              layout.itemO("mesh.region_to_loop")
 +
 +class VIEW3D_MT_select_EDIT_CURVE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border", text="Border Select...")
 +              layout.itemO("view3d.select_circle", text="Circle Select...")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("curve.select_all_toggle", text="Select/Deselect All")
 +              layout.itemO("curve.select_inverse")
 +              layout.itemO("curve.select_random")
 +              layout.itemO("curve.select_every_nth")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("curve.de_select_first")
 +              layout.itemO("curve.de_select_last")
 +              layout.itemO("curve.select_next")
 +              layout.itemO("curve.select_previous")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("curve.select_more")
 +              layout.itemO("curve.select_less")
 +
 +class VIEW3D_MT_select_EDIT_SURFACE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border", text="Border Select...")
 +              layout.itemO("view3d.select_circle", text="Circle Select...")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("curve.select_all_toggle", text="Select/Deselect All")
 +              layout.itemO("curve.select_inverse")
 +              layout.itemO("curve.select_random")
 +              layout.itemO("curve.select_every_nth")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("curve.select_row")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("curve.select_more")
 +              layout.itemO("curve.select_less")
 +
 +class VIEW3D_MT_select_EDIT_METABALL(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("mball.select_deselect_all_metaelems")
 +              layout.itemO("mball.select_inverse_metaelems")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("mball.select_random_metaelems")
 +
 +class VIEW3D_MT_select_EDIT_LATTICE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("lattice.select_all_toggle", text="Select/Deselect All")
 +
 +class VIEW3D_MT_select_EDIT_ARMATURE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("view3d.select_border", text="Border Select...")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("armature.select_all_toggle", text="Select/Deselect All")
 +              layout.itemO("armature.select_inverse", text="Inverse")
 +
 +              layout.itemS()
 +              
 +              layout.item_enumO("armature.select_hierarchy", "direction", 'PARENT', text="Parent")
 +              layout.item_enumO("armature.select_hierarchy", "direction", 'CHILD', text="Child")
 +              
 +              layout.itemS()
 +              
 +              props = layout.itemO("armature.select_hierarchy", properties=True, text="Extend Parent")
 +              props.extend = True
 +              props.direction = 'PARENT'
 +
 +              props = layout.itemO("armature.select_hierarchy", properties=True, text="Extend Child")
 +              props.extend = True
 +              props.direction = 'CHILD'
 +
 +class VIEW3D_MT_select_FACE(bpy.types.Menu):# XXX no matching enum
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Select"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.view3d_select_faceselmenu()
 +
 +# ********** Object menu **********
 +
 +class VIEW3D_MT_OBJECT(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __context__ = "objectmode"
 +      __label__ = "Object"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemM("VIEW3D_MT_OBJECT_clear")
 +              layout.itemM("VIEW3D_MT_snap")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("anim.insert_keyframe_menu", text="Insert Keyframe...")
 +              layout.itemO("anim.delete_keyframe_v3d", text="Delete Keyframe...")
 +              
 +              layout.itemS()
 +              
++              layout.itemO("object.duplicate_move")
 +              layout.item_booleanO("object.duplicate", "linked", True, text="Duplicate Linked")
 +              layout.itemO("object.delete", text="Delete...")
 +              layout.itemO("object.proxy_make", text="Make Proxy...")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_OBJECT_parent")
 +              layout.itemM("VIEW3D_MT_OBJECT_track")
 +              layout.itemM("VIEW3D_MT_OBJECT_group")
 +              layout.itemM("VIEW3D_MT_OBJECT_constraints")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("object.join")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_OBJECT_showhide")
 +              
 +class VIEW3D_MT_OBJECT_clear(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Clear"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("object.location_clear", text="Location")
 +              layout.itemO("object.rotation_clear", text="Rotation")
 +              layout.itemO("object.scale_clear", text="Scale")
 +              layout.itemO("object.origin_clear", text="Origin")
 +              
 +class VIEW3D_MT_OBJECT_parent(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Parent"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("object.parent_set", text="Set")
 +              layout.itemO("object.parent_clear", text="Clear")
 +              
 +class VIEW3D_MT_OBJECT_track(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Track"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("object.track_set", text="Set")
 +              layout.itemO("object.track_clear", text="Clear")
 +              
 +class VIEW3D_MT_OBJECT_group(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Group"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("group.group_create")
 +              layout.itemO("group.objects_remove")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("group.objects_add_active")
 +              layout.itemO("group.objects_remove_active")
 +              
 +class VIEW3D_MT_OBJECT_constraints(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Constraints"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("object.constraint_add_with_targets")
 +              layout.itemO("object.constraints_clear")
 +              
 +class VIEW3D_MT_OBJECT_showhide(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Show/Hide"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("object.restrictview_clear", text="Show Hidden")
 +              layout.itemO("object.restrictview_set", text="Hide Selected")
 +              layout.item_booleanO("object.restrictview_set", "unselected", True, text="Hide Unselected")
 +
 +# ********** Vertex paint menu **********     
 +      
 +class VIEW3D_MT_PAINT_VERTEX(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Paint"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              sculpt = context.tool_settings.sculpt
 +
 +              layout.itemO("paint.vertex_color_set")
 +              props = layout.itemO("paint.vertex_color_set", text="Set Selected Vertex Colors", properties=True)
 +              props.selected = True
 +
 +# ********** Sculpt menu **********   
 +      
 +class VIEW3D_MT_SCULPT(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Sculpt"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              sculpt = context.tool_settings.sculpt
 +              brush = context.tool_settings.sculpt.brush
 +              
 +              layout.itemR(sculpt, "symmetry_x")
 +              layout.itemR(sculpt, "symmetry_y")
 +              layout.itemR(sculpt, "symmetry_z")
 +              layout.itemS()
 +              layout.itemR(sculpt, "lock_x")
 +              layout.itemR(sculpt, "lock_y")
 +              layout.itemR(sculpt, "lock_z")
 +              layout.itemS()
 +              layout.item_menu_enumO("brush.curve_preset", property="shape")
 +              layout.itemS()
 +              
 +              if brush.sculpt_tool != 'GRAB':
 +                      layout.itemR(brush, "airbrush")
 +                      
 +                      if brush.sculpt_tool != 'LAYER':
 +                              layout.itemR(brush, "anchored")
 +                      
 +                      if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'):
 +                              layout.itemR(brush, "flip_direction")
 +
 +                      if brush.sculpt_tool == 'LAYER':
 +                              layout.itemR(brush, "persistent")
 +                              layout.itemO("sculpt.set_persistent_base")
 +
 +# ********** Particle menu ********** 
 +      
 +class VIEW3D_MT_PARTICLE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Particle"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              particle_edit = context.tool_settings.particle_edit
 +              
 +              layout.itemO("particle.mirror")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("particle.remove_doubles")
 +              layout.itemO("particle.delete")
 +              
 +              if particle_edit.selection_mode == 'POINT':
 +                      layout.itemO("particle.subdivide")
 +              
 +              layout.itemO("particle.rekey")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_PARTICLE_showhide")
 +
 +class VIEW3D_MT_PARTICLE_showhide(VIEW3D_MT_showhide):
 +      _operator_name = "particle"
 +
 +# ********** Pose Menu **********
 +
 +class VIEW3D_MT_POSE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Pose"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              arm = context.active_object.data
 +              
 +              if arm.drawtype in ('BBONE', 'ENVELOPE'):
 +                      layout.item_enumO("tfm.transform", "mode", 'BONESIZE', text="Scale Envelope Distance")
 +              
 +              layout.itemM("VIEW3D_MT_POSE_transform")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("anim.insert_keyframe_menu", text="Insert Keyframe...")
 +              layout.itemO("anim.delete_keyframe_v3d", text="Delete Keyframe...")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("pose.apply")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("pose.copy")
 +              layout.itemO("pose.paste")
 +              layout.item_booleanO("pose.paste", "flipped", True, text="Paste X-Flipped Pose")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_POSE_pose")
 +              layout.itemM("VIEW3D_MT_POSE_motion")
 +              layout.itemM("VIEW3D_MT_POSE_group")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_POSE_ik")
 +              layout.itemM("VIEW3D_MT_POSE_constraints")
 +              
 +              layout.itemS()
 +              
 +              layout.operator_context = "EXEC_AREA"
 +              layout.item_enumO("pose.autoside_names", "axis", 'XAXIS', text="AutoName Left/Right")
 +              layout.item_enumO("pose.autoside_names", "axis", 'YAXIS', text="AutoName Front/Back")
 +              layout.item_enumO("pose.autoside_names", "axis", 'ZAXIS', text="AutoName Top/Bottom")
 +              
 +              layout.itemO("pose.flip_names")
 +              
 +              layout.itemS()
 +              
 +              layout.operator_context = "INVOKE_AREA"
 +              layout.itemO("pose.armature_layers", text="Change Armature Layers...")
 +              layout.itemO("pose.bone_layers", text="Change Bone Layers...")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_POSE_showhide")
 +              layout.item_menu_enumO("pose.flags_set", 'mode', text="Bone Settings")
 +
 +class VIEW3D_MT_POSE_transform(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Clear Transform"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemL(text="User Transform")
 +              
 +              layout.itemO("pose.loc_clear", text="Location")
 +              layout.itemO("pose.rot_clear", text="Rotation")
 +              layout.itemO("pose.scale_clear", text="Scale")
 +              
 +              layout.itemL(text="Origin")
 +              
 +class VIEW3D_MT_POSE_pose(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Pose Library"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("poselib.browse_interactive", text="Browse Poses...")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("poselib.pose_add", text="Add Pose...")
 +              layout.itemO("poselib.pose_rename", text="Rename Pose...")
 +              layout.itemO("poselib.pose_remove", text="Remove Pose...")
 +
 +class VIEW3D_MT_POSE_motion(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Motion Paths"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("pose.paths_calculate", text="Calculate")
 +              layout.itemO("pose.paths_clear", text="Clear")
 +              
 +class VIEW3D_MT_POSE_group(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Bone Groups"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              layout.itemO("pose.group_add")
 +              layout.itemO("pose.group_remove")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("pose.group_assign")
 +              layout.itemO("pose.group_unassign")
 +              
 +              
 +class VIEW3D_MT_POSE_ik(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Inverse Kinematics"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("pose.ik_add")
 +              layout.itemO("pose.ik_clear")
 +              
 +class VIEW3D_MT_POSE_constraints(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Constraints"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("pose.constraint_add_with_targets", text="Add (With Targets)...")
 +              layout.itemO("pose.constraints_clear")
 +              
 +class VIEW3D_MT_POSE_showhide(VIEW3D_MT_showhide):
 +      _operator_name = "pose"
 +
 +# ********** Edit Menus, suffix from ob.type **********
 +
 +# Edit MESH
 +class VIEW3D_MT_edit_MESH(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Mesh"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              settings = context.tool_settings
 +
 +              layout.itemO("ed.undo")
 +              layout.itemO("ed.redo")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_snap")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("uv.mapping_menu", text="UV Unwrap...")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("mesh.extrude")
 +              layout.itemO("mesh.duplicate")
 +              layout.itemO("mesh.delete", text="Delete...")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_edit_MESH_vertices")
 +              layout.itemM("VIEW3D_MT_edit_MESH_edges")
 +              layout.itemM("VIEW3D_MT_edit_MESH_faces")
 +              layout.itemM("VIEW3D_MT_edit_MESH_normals")
 +              
 +              layout.itemS()
 +              
 +              layout.itemR(settings, "automerge_editing")
 +              layout.itemR(settings, "proportional_editing")
 +              layout.item_menu_enumR(settings, "proportional_editing_falloff")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_edit_MESH_showhide")
 +
 +class VIEW3D_MT_edit_MESH_vertices(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Vertices"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("mesh.merge")
 +              layout.itemO("mesh.rip")
 +              layout.itemO("mesh.split")
 +              layout.itemO("mesh.separate")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("mesh.vertices_smooth")
 +              layout.itemO("mesh.remove_doubles")
 +
 +class VIEW3D_MT_edit_MESH_edges(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Edges"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("mesh.edge_face_add")
 +              layout.itemO("mesh.subdivide")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("mesh.mark_seam")
 +              layout.item_booleanO("mesh.mark_seam", "clear", True, text="Clear Seam")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("mesh.mark_sharp")
 +              layout.item_booleanO("mesh.mark_sharp", "clear", True, text="Clear Sharp")
 +              
 +              layout.itemS()
 +              
 +              layout.item_enumO("mesh.edge_rotate", "direction", 'CW', text="Rotate Edge CW")
 +              layout.item_enumO("mesh.edge_rotate", "direction", 'CCW', text="Rotate Edge CCW")
 +
 +class VIEW3D_MT_edit_MESH_faces(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Faces"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("mesh.edge_face_add")
 +              layout.itemO("mesh.fill")
 +              layout.itemO("mesh.beauty_fill")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("mesh.quads_convert_to_tris")
 +              layout.itemO("mesh.tris_convert_to_quads")
 +              layout.itemO("mesh.edge_flip")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("mesh.faces_shade_smooth")
 +              layout.itemO("mesh.faces_shade_flat")
 +
 +class VIEW3D_MT_edit_MESH_normals(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Normals"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              layout.itemO("mesh.normals_make_consistent", text="Recalculate Outside")
 +              layout.item_booleanO("mesh.normals_make_consistent", "inside", True, text="Recalculate Inside")
 +
 +              layout.itemS()
 +              
 +              layout.itemO("mesh.flip_normals")
 +              
 +class VIEW3D_MT_edit_MESH_showhide(VIEW3D_MT_showhide):
 +      _operator_name = "mesh"
 +
 +# Edit CURVE
 +
 +# draw_CURVE is used by VIEW3D_MT_edit_CURVE and VIEW3D_MT_edit_SURFACE
 +def draw_CURVE(self, context):
 +      layout = self.layout
 +      
 +      settings = context.tool_settings
 +      
 +      layout.itemM("VIEW3D_MT_snap")
 +      
 +      layout.itemS()
 +      
 +      layout.itemO("curve.extrude")
 +      layout.itemO("curve.duplicate")
 +      layout.itemO("curve.separate")
 +      layout.itemO("curve.make_segment")
 +      layout.itemO("curve.cyclic_toggle")
 +      layout.itemO("curve.delete", text="Delete...")
 +      
 +      layout.itemS()
 +      
 +      layout.itemM("VIEW3D_MT_edit_CURVE_ctrlpoints")
 +      layout.itemM("VIEW3D_MT_edit_CURVE_segments")
 +      
 +      layout.itemS()
 +      
 +      layout.itemR(settings, "proportional_editing")
 +      layout.item_menu_enumR(settings, "proportional_editing_falloff")
 +      
 +      layout.itemS()
 +      
 +      layout.itemM("VIEW3D_MT_edit_CURVE_showhide")
 +
 +class VIEW3D_MT_edit_CURVE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Curve"
 +
 +      draw = draw_CURVE
 +      
 +class VIEW3D_MT_edit_CURVE_ctrlpoints(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Control Points"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              edit_object = context.edit_object
 +              
 +              if edit_object.type == 'CURVE':
 +                      layout.item_enumO("tfm.transform", "mode", 'TILT')
 +                      layout.itemO("curve.tilt_clear")
 +                      layout.itemO("curve.separate")
 +                      
 +                      layout.itemS()
 +                      
 +                      layout.item_menu_enumO("curve.handle_type_set", "type")
 +              
 +class VIEW3D_MT_edit_CURVE_segments(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Segments"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("curve.subdivide")
 +              layout.itemO("curve.switch_direction")
 +
 +class VIEW3D_MT_edit_CURVE_showhide(VIEW3D_MT_showhide):
 +      _operator_name = "curve"
 +
 +# Edit SURFACE
 +class VIEW3D_MT_edit_SURFACE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Surface"
 +
 +      draw = draw_CURVE
 +
 +# Edit TEXT
 +class VIEW3D_MT_edit_TEXT(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Text"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("font.file_paste")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_edit_TEXT_chars")
 +
 +class VIEW3D_MT_edit_TEXT_chars(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Special Characters"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xA9'.decode(), text="Copyright|Alt C")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xAE'.decode(), text="Registered Trademark|Alt R")
 +              
 +              layout.itemS()
 +              
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xB0'.decode(), text="Degree Sign|Alt G")
 +              layout.item_stringO("font.text_insert", "text", b'\xC3\x97'.decode(), text="Multiplication Sign|Alt x")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\x8A'.decode(), text="Circle|Alt .")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xB9'.decode(), text="Superscript 1|Alt 1")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xB2'.decode(), text="Superscript 2|Alt 2")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xB3'.decode(), text="Superscript 3|Alt 3")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xBB'.decode(), text="Double >>|Alt >")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xAB'.decode(), text="Double <<|Alt <")
 +              layout.item_stringO("font.text_insert", "text", b'\xE2\x80\xB0'.decode(), text="Promillage|Alt %")
 +              
 +              layout.itemS()
 +              
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xA4'.decode(), text="Dutch Florin|Alt F")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xA3'.decode(), text="British Pound|Alt L")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xA5'.decode(), text="Japanese Yen|Alt Y")
 +              
 +              layout.itemS()
 +              
 +              layout.item_stringO("font.text_insert", "text", b'\xC3\x9F'.decode(), text="German S|Alt S")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xBF'.decode(), text="Spanish Question Mark|Alt ?")
 +              layout.item_stringO("font.text_insert", "text", b'\xC2\xA1'.decode(), text="Spanish Exclamation Mark|Alt !")
 +
 +# Edit META
 +class VIEW3D_MT_edit_META(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Metaball"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              settings = context.tool_settings
 +
 +              layout.itemO("ed.undo")
 +              layout.itemO("ed.redo")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_snap")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("mball.delete_metaelems", text="Delete...")
 +              layout.itemO("mball.duplicate_metaelems")
 +              
 +              layout.itemS()
 +              
 +              layout.itemR(settings, "proportional_editing")
 +              layout.item_menu_enumR(settings, "proportional_editing_falloff")
 +              
 +              layout.itemS()
 +              
 +              layout.itemM("VIEW3D_MT_edit_META_showhide")
 +
 +class VIEW3D_MT_edit_META_showhide(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Show/Hide"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("mball.reveal_metaelems", text="Show Hidden")
 +              layout.itemO("mball.hide_metaelems", text="Hide Selected")
 +              layout.item_booleanO("mball.hide_metaelems", "unselected", True, text="Hide Unselected")
 +
 +# Edit LATTICE
 +class VIEW3D_MT_edit_LATTICE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Lattice"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              settings = context.tool_settings
 +
 +              layout.itemM("VIEW3D_MT_snap")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("lattice.make_regular")
 +              
 +              layout.itemS()
 +              
 +              layout.itemR(settings, "proportional_editing")
 +              layout.item_menu_enumR(settings, "proportional_editing_falloff")
 +
 +# Edit ARMATURE
 +class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Armature"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              edit_object = context.edit_object
 +              arm = edit_object.data
 +              
 +              layout.itemM("VIEW3D_MT_snap")
 +              layout.itemM("VIEW3D_MT_edit_ARMATURE_roll")
 +              
 +              if arm.drawtype == 'ENVELOPE':
 +                      layout.item_enumO("tfm.transform", "mode", 'BONESIZE', text="Scale Envelope Distance")
 +              else:
 +                      layout.item_enumO("tfm.transform", "mode", 'BONESIZE', text="Scale B-Bone Width")
 +                              
 +              layout.itemS()
 +              
 +              layout.itemO("armature.extrude")
 +              
 +              if arm.x_axis_mirror:
 +                      layout.item_booleanO("armature.extrude", "forked", True, text="Extrude Forked")
 +              
 +              layout.itemO("armature.duplicate")
 +              layout.itemO("armature.merge")
 +              layout.itemO("armature.fill")
 +              layout.itemO("armature.delete")
 +              layout.itemO("armature.separate")
 +
 +              layout.itemS()
 +
 +              layout.itemO("armature.subdivide_multi", text="Subdivide")
 +              
 +              layout.itemS()
 +              
 +              layout.operator_context = "EXEC_AREA"
 +              layout.item_enumO("armature.autoside_names", "type", 'XAXIS', text="AutoName Left/Right")
 +              layout.item_enumO("armature.autoside_names", "type", 'YAXIS', text="AutoName Front/Back")
 +              layout.item_enumO("armature.autoside_names", "type", 'ZAXIS', text="AutoName Top/Bottom")
 +              layout.itemO("armature.flip_names")
 +
 +              layout.itemS()
 +              
 +              layout.operator_context = "INVOKE_DEFAULT"
 +              layout.itemO("armature.armature_layers")
 +              layout.itemO("armature.bone_layers")
 +
 +              layout.itemS()
 +
 +              layout.itemM("VIEW3D_MT_edit_ARMATURE_parent")
 +
 +              layout.itemS()
 +              
 +              layout.item_menu_enumO("armature.flags_set", "mode", text="Bone Settings")
 +
 +class VIEW3D_MT_edit_ARMATURE_parent(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Parent"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemO("armature.parent_set", text="Make")
 +              layout.itemO("armature.parent_clear", text="Clear")
 +
 +class VIEW3D_MT_edit_ARMATURE_roll(bpy.types.Menu):
 +      __space_type__ = 'VIEW_3D'
 +      __label__ = "Bone Roll"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.item_enumO("armature.calculate_roll", "type", 'GLOBALUP', text="Clear Roll (Z-Axis Up)")
 +              layout.item_enumO("armature.calculate_roll", "type", 'CURSOR', text="Roll to Cursor")
 +              
 +              layout.itemS()
 +              
 +              layout.item_enumO("tfm.transform", "mode", 'BONE_ROLL', text="Set Roll")
 +
 +# ********** Panel **********
 +
 +class VIEW3D_PT_3dview_properties(bpy.types.Panel):
 +      __space_type__ = 'VIEW_3D'
 +      __region_type__ = 'UI'
 +      __label__ = "View"
 +
 +      def poll(self, context):
 +              view = context.space_data
 +              return (view)
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              view = context.space_data
 +              scene = context.scene
 +              
 +              col = layout.column()
 +              col.itemR(view, "camera")
 +              col.itemR(view, "lens")
 +              
 +              layout.itemL(text="Clip:")
 +              col = layout.column(align=True)
 +              col.itemR(view, "clip_start", text="Start")
 +              col.itemR(view, "clip_end", text="End")
 +              
 +              layout.itemL(text="Grid:")
 +              col = layout.column(align=True)
 +              col.itemR(view, "grid_lines", text="Lines")
 +              col.itemR(view, "grid_spacing", text="Spacing")
 +              col.itemR(view, "grid_subdivisions", text="Subdivisions")
 +              
 +              layout.column().itemR(scene, "cursor_location", text="3D Cursor:")
 +              
 +class VIEW3D_PT_3dview_display(bpy.types.Panel):
 +      __space_type__ = 'VIEW_3D'
 +      __region_type__ = 'UI'
 +      __label__ = "Display"
 +
 +      def poll(self, context):
 +              view = context.space_data
 +              return (view)
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              view = context.space_data
 +              
 +              col = layout.column()
 +              col.itemR(view, "display_floor", text="Grid Floor")
 +              col.itemR(view, "display_x_axis", text="X Axis")
 +              col.itemR(view, "display_y_axis", text="Y Axis")
 +              col.itemR(view, "display_z_axis", text="Z Axis")
 +              col.itemR(view, "outline_selected")
 +              col.itemR(view, "all_object_centers")
 +              col.itemR(view, "relationship_lines")
 +              col.itemR(view, "textured_solid")
 +              
 +              layout.itemS()
 +              
 +              layout.itemO("screen.region_foursplit")
 +              
 +              col = layout.column()
 +              col.itemR(view, "lock_rotation")
 +              col.itemR(view, "box_preview")
 +              col.itemR(view, "box_clip")
 +
 +class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel):
 +      __space_type__ = 'VIEW_3D'
 +      __region_type__ = 'UI'
 +      __label__ = "Mesh Display"
 +
 +      def poll(self, context):
 +              editmesh = context.mode == 'EDIT_MESH'
 +              return (editmesh)
 +
 +      def draw(self, context):
 +              layout = self.layout
 +
 +              mesh = context.active_object.data
 +              
 +              col = layout.column()
 +              col.itemL(text="Overlays:")
 +              col.itemR(mesh, "draw_edges", text="Edges")
 +              col.itemR(mesh, "draw_faces", text="Faces")
 +              col.itemR(mesh, "draw_creases", text="Creases")
 +              col.itemR(mesh, "draw_bevel_weights", text="Bevel Weights")
 +              col.itemR(mesh, "draw_seams", text="Seams")
 +              col.itemR(mesh, "draw_sharp", text="Sharp")
 +              
 +              col.itemS()
 +              col.itemL(text="Normals:")
 +              col.itemR(mesh, "draw_normals", text="Face")
 +              col.itemR(mesh, "draw_vertex_normals", text="Vertex")
++              col.itemR(context.scene.tool_settings, "normal_size", text="Normal Size")
 +              
 +              col.itemS()
 +              col.itemL(text="Numerics:")
 +              col.itemR(mesh, "draw_edge_lenght")
 +              col.itemR(mesh, "draw_edge_angle")
 +              col.itemR(mesh, "draw_face_area")
++
++
++class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel):
++      __space_type__ = 'VIEW_3D'
++      __region_type__ = 'UI'
++      __label__ = "Curve Display"
++
++      def poll(self, context):
++              editmesh = context.mode == 'EDIT_CURVE'
++              return (editmesh)
++
++      def draw(self, context):
++              layout = self.layout
++
++              curve = context.active_object.data
++              
++              col = layout.column()
++              col.itemL(text="Overlays:")
++              col.itemR(curve, "draw_handles", text="Handles")
++              col.itemR(curve, "draw_normals", text="Normals")
++              col.itemR(context.scene.tool_settings, "normal_size", text="Normal Size")
++              
 +      
 +class VIEW3D_PT_background_image(bpy.types.Panel):
 +      __space_type__ = 'VIEW_3D'
 +      __region_type__ = 'UI'
 +      __label__ = "Background Image"
 +      __default_closed__ = True
 +
 +      def poll(self, context):
 +              view = context.space_data
 +              bg = context.space_data.background_image
 +              return (view)
 +
 +      def draw_header(self, context):
 +              layout = self.layout
 +              view = context.space_data
 +
 +              layout.itemR(view, "display_background_image", text="")
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              view = context.space_data
 +              bg = view.background_image
 +
 +              if bg:
 +                      layout.active = view.display_background_image
 +
 +                      col = layout.column()
 +                      col.itemR(bg, "image", text="")
 +                      #col.itemR(bg, "image_user")
 +                      col.itemR(bg, "size")
 +                      col.itemR(bg, "transparency", slider=True)
 +                      col.itemL(text="Offset:")
 +                      
 +                      col = layout.column(align=True)
 +                      col.itemR(bg, "offset_x", text="X")
 +                      col.itemR(bg, "offset_y", text="Y")
 +
 +bpy.types.register(VIEW3D_HT_header) # Header
 +
 +bpy.types.register(VIEW3D_MT_view) #View Menus
 +bpy.types.register(VIEW3D_MT_view_navigation)
 +bpy.types.register(VIEW3D_MT_view_align)
 +bpy.types.register(VIEW3D_MT_view_cameras)
 +
 +bpy.types.register(VIEW3D_MT_select_OBJECT) # Select Menus
 +bpy.types.register(VIEW3D_MT_select_POSE)
 +bpy.types.register(VIEW3D_MT_select_PARTICLE)
 +bpy.types.register(VIEW3D_MT_select_EDIT_MESH)
 +bpy.types.register(VIEW3D_MT_select_EDIT_CURVE)
 +bpy.types.register(VIEW3D_MT_select_EDIT_SURFACE)
 +bpy.types.register(VIEW3D_MT_select_EDIT_METABALL)
 +bpy.types.register(VIEW3D_MT_select_EDIT_LATTICE)
 +bpy.types.register(VIEW3D_MT_select_EDIT_ARMATURE)
 +bpy.types.register(VIEW3D_MT_select_FACE) # XXX todo
 +
 +bpy.types.register(VIEW3D_MT_OBJECT) # Object Menu
 +bpy.types.register(VIEW3D_MT_OBJECT_clear)
 +bpy.types.register(VIEW3D_MT_OBJECT_parent)
 +bpy.types.register(VIEW3D_MT_OBJECT_track)
 +bpy.types.register(VIEW3D_MT_OBJECT_group)
 +bpy.types.register(VIEW3D_MT_OBJECT_constraints)
 +bpy.types.register(VIEW3D_MT_OBJECT_showhide)
 +
 +bpy.types.register(VIEW3D_MT_SCULPT) # Sculpt Menu
 +
 +bpy.types.register(VIEW3D_MT_PAINT_VERTEX)
 +
 +bpy.types.register(VIEW3D_MT_PARTICLE) # Particle Menu
 +bpy.types.register(VIEW3D_MT_PARTICLE_showhide)
 +
 +bpy.types.register(VIEW3D_MT_POSE) # POSE Menu
 +bpy.types.register(VIEW3D_MT_POSE_transform)
 +bpy.types.register(VIEW3D_MT_POSE_pose)
 +bpy.types.register(VIEW3D_MT_POSE_motion)
 +bpy.types.register(VIEW3D_MT_POSE_group)
 +bpy.types.register(VIEW3D_MT_POSE_ik)
 +bpy.types.register(VIEW3D_MT_POSE_constraints)
 +bpy.types.register(VIEW3D_MT_POSE_showhide)
 +
 +bpy.types.register(VIEW3D_MT_snap) # Edit Menus
 +
 +bpy.types.register(VIEW3D_MT_edit_MESH)
 +bpy.types.register(VIEW3D_MT_edit_MESH_vertices)
 +bpy.types.register(VIEW3D_MT_edit_MESH_edges)
 +bpy.types.register(VIEW3D_MT_edit_MESH_faces)
 +bpy.types.register(VIEW3D_MT_edit_MESH_normals)
 +bpy.types.register(VIEW3D_MT_edit_MESH_showhide)
 +
 +bpy.types.register(VIEW3D_MT_edit_CURVE)
 +bpy.types.register(VIEW3D_MT_edit_CURVE_ctrlpoints)
 +bpy.types.register(VIEW3D_MT_edit_CURVE_segments)
 +bpy.types.register(VIEW3D_MT_edit_CURVE_showhide)
 +
 +bpy.types.register(VIEW3D_MT_edit_SURFACE)
 +
 +bpy.types.register(VIEW3D_MT_edit_TEXT)
 +bpy.types.register(VIEW3D_MT_edit_TEXT_chars)
 +
 +bpy.types.register(VIEW3D_MT_edit_META)
 +bpy.types.register(VIEW3D_MT_edit_META_showhide)
 +
 +bpy.types.register(VIEW3D_MT_edit_LATTICE)
 +
 +bpy.types.register(VIEW3D_MT_edit_ARMATURE)
 +bpy.types.register(VIEW3D_MT_edit_ARMATURE_parent)
 +bpy.types.register(VIEW3D_MT_edit_ARMATURE_roll)
 +
 +bpy.types.register(VIEW3D_PT_3dview_properties) # Panels
 +bpy.types.register(VIEW3D_PT_3dview_display)
 +bpy.types.register(VIEW3D_PT_3dview_meshdisplay)
++bpy.types.register(VIEW3D_PT_3dview_curvedisplay)
 +bpy.types.register(VIEW3D_PT_background_image)
index 0b7ccb1,0000000..9dd2df1
mode 100644,000000..100644
--- /dev/null
@@@ -1,676 -1,0 +1,748 @@@
 +
 +import bpy
 +
 +class View3DPanel(bpy.types.Panel):
 +      __space_type__ = 'VIEW_3D'
 +      __region_type__ = 'TOOLS'
 +
 +# ********** default tools for objectmode ****************
 +
 +class VIEW3D_PT_tools_objectmode(View3DPanel):
 +      __context__ = "objectmode"
 +      __label__ = "Object Tools"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemL(text="Transform:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("tfm.translate")
 +              col.itemO("tfm.rotate")
 +              col.itemO("tfm.resize", text="Scale")
 +              
 +              layout.itemL(text="Object:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("object.duplicate")
 +              col.itemO("object.delete")
 +              
 +              active_object= context.active_object
 +              if active_object and active_object.type == 'MESH':
 +                      layout.itemL(text="Shading:")
 +              
 +                      col = layout.column(align=True)
 +                      col.itemO("object.shade_smooth", text="Smooth")
 +                      col.itemO("object.shade_flat", text="Flat")
 +              
 +              layout.itemL(text="Keyframes:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("anim.insert_keyframe_menu", text="Insert")
 +              col.itemO("anim.delete_keyframe_v3d", text="Remove")
++              
++              layout.itemL(text="Repeat:")
++              
++              col = layout.column(align=True)
++              col.itemO("screen.repeat_last")
++              col.itemO("screen.repeat_history", text="History...")
++              col.itemO("screen.redo_last", text="Tweak...")
 +
 +# ********** default tools for editmode_mesh ****************
 +
 +class VIEW3D_PT_tools_meshedit(View3DPanel):
 +      __context__ = "mesh_edit"
 +      __label__ = "Mesh Tools"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemL(text="Transform:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("tfm.translate")
 +              col.itemO("tfm.rotate")
 +              col.itemO("tfm.resize", text="Scale")
 +              
 +              layout.itemL(text="Mesh:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("mesh.duplicate")
 +              col.itemO("mesh.delete")
 +              
 +              layout.itemL(text="Modeling:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("mesh.extrude")
 +              col.itemO("mesh.subdivide")
 +              col.itemO("mesh.spin")
 +              col.itemO("mesh.screw")
 +              
 +              layout.itemL(text="Shading:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("mesh.faces_shade_smooth", text="Smooth")
 +              col.itemO("mesh.faces_shade_flat", text="Flat")
 +              
 +              layout.itemL(text="UV Mapping:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("uv.mapping_menu", text="Unwrap")
 +              col.itemO("mesh.uvs_rotate")
 +              col.itemO("mesh.uvs_mirror")
++              
++              layout.itemL(text="Repeat:")
++              
++              col = layout.column(align=True)
++              col.itemO("screen.repeat_last")
++              col.itemO("screen.repeat_history", text="History...")
++              col.itemO("screen.redo_last", text="Tweak...")
 +
 +# ********** default tools for editmode_curve ****************
 +
 +class VIEW3D_PT_tools_curveedit(View3DPanel):
 +      __context__ = "curve_edit"
 +      __label__ = "Curve Tools"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemL(text="Transform:")
 +              
 +              col = layout.column(align=True)
 +              col.itemO("tfm.translate")
 +              col.itemO("tfm.rotate")
 +              col.itemO("tfm.resize", text="Scale")
 +              
 +              layout.itemL(text="Curve:")
 +
 +              col = layout.column(align=True)
 +              col.itemO("curve.duplicate")
 +              col.itemO("curve.delete")
 +              col.itemO("curve.cyclic_toggle")
 +              col.itemO("curve.switch_direction")
++              col.itemO("curve.spline_type_set")
 +              
 +              layout.itemL(text="Modeling:")
 +
 +              col = layout.column(align=True)
 +              col.itemO("curve.extrude")
 +              col.itemO("curve.subdivide")
++              
++              layout.itemL(text="Repeat:")
++              
++              col = layout.column(align=True)
++              col.itemO("screen.repeat_last")
++              col.itemO("screen.repeat_history", text="History...")
++              col.itemO("screen.redo_last", text="Tweak...")
 +
 +# ********** default tools for editmode_surface ****************
 +
 +class VIEW3D_PT_tools_surfaceedit(View3DPanel):
 +      __context__ = "surface_edit"
 +      __label__ = "Surface Tools"
 +
 +      def draw(self, context):
 +              layout = self.layout
 +              
 +              layout.itemL(text="Transform:")
 +
 +              col = layout.column(align=True)
 +              col.itemO("tfm.translate")
 +              col.itemO("tfm.rotate")
 +              col.itemO("tfm.resize", text="Scale")
 +              
 +              layout.itemL(text="Curve:")
 +
 +              col = layout.column(align=True)
 +              col.itemO("curve.duplicate")
 +              col.itemO("curve.delete")
 +              col.itemO("curve.cyclic_toggle")
 +              col.itemO("curve.switch_direction")
 +              
 +              layout.itemL(text="Modeling:")
 +
 +              col = layout.column(align=True)
 +              col.itemO("curve.extrude")
 +              col.itemO("curve.subdivide")
++              
++              layout.itemL(text="Repeat:")
++              
++              col = layout.column(align=True)
++              col.itemO("screen.repeat_last")
++              col.itemO("screen.repeat_history", text="History...")
++              col.itemO("screen.redo_last", text="Tweak...")
 +
 +# ********** default tools for editmode_text ****************
 +
 +class VIEW3D_PT_tools_textedit(View3DPanel):
 +      __context__ = "text_edit"
 +      __label__ = "Text Tools"
 +
 +      def draw(self, context):
 +              layout = self.layout
-               col = layout.column()
++              
++              layout.itemL(text="Text Edit:")
++              
 +              col = layout.column(align=True)
 +              col.itemO("font.text_copy", text="Copy")
++              col.itemO("font.text_cut", text="Cut")
 +              col.itemO("font.text_paste", text="Paste")
 +              
-                       row.itemR(brush, "size_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="")
++              layout.itemL(text="Style:")
++              
++              col = layout.column(align=True)
 +              col.itemO("font.case_set")
 +              col.itemO("font.style_toggle")
++              
++              layout.itemL(text="Repeat:")
++              
++              col = layout.column(align=True)
++              col.itemO("screen.repeat_last")
++              col.itemO("screen.repeat_history", text="History...")
++              col.itemO("screen.redo_last", text="Tweak...