From aac8bab1729e55f0e77ca43373d44d614f2cb828 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 3 Aug 2011 12:20:07 +0000 Subject: [PATCH 01/41] Fixing terrible typo. --- build_files/buildbot/slave_compile.py | 2 +- build_files/buildbot/slave_pack.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index 5aa39db68f9..55e418ec733 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -126,7 +126,7 @@ else: for lib in all_ffmpeg_libs: ffmpeg_lib.append(lib + '.lib') - ffmpeg_dll.append('${BF_FFMPEG_LIBPATH}/' + lib + '.lib') + ffmpeg_dll.append('${BF_FFMPEG_LIBPATH}/' + lib + '.dll') scons_options.append('BF_FFMPEG=' + LCGDIR + '/ffmpeg-0.8') scons_options.append('BF_FFMPEG_LIB=' + (' '.join(ffmpeg_lib))) diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index 3a3fffc02b4..fd3ff1fbee7 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -90,7 +90,7 @@ if builder.find('scons') != -1: for lib in all_ffmpeg_libs: ffmpeg_lib.append(lib + '.lib') - ffmpeg_dll.append('${BF_FFMPEG_LIBPATH}/' + lib + '.lib') + ffmpeg_dll.append('${BF_FFMPEG_LIBPATH}/' + lib + '.dll') scons_options.append('BF_FFMPEG=' + LCGDIR + '/ffmpeg-0.8') scons_options.append('BF_FFMPEG_LIB=' + (' '.join(ffmpeg_lib))) From 36887bbc8205daa96b4ee3844a14ec5543f1f051 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 3 Aug 2011 12:57:38 +0000 Subject: [PATCH 02/41] Add BF_BITNESS for win32/win64 --- build_files/buildbot/slave_compile.py | 4 ++++ build_files/buildbot/slave_pack.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index 55e418ec733..9dd39ccd308 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -108,12 +108,14 @@ else: sys.exit(0) else: + bitness = '32' # Switch to new FFmpeg library if builder.find('win') != -1: if builder.find('win32') != -1: LCGDIR = '#../lib/windows' elif builder.find('win64') != -1: LCGDIR = '#../lib/win64' + bitness = '64' all_ffmpeg_libs = ['avcodec-53', 'avdevice-53', @@ -132,5 +134,7 @@ else: scons_options.append('BF_FFMPEG_LIB=' + (' '.join(ffmpeg_lib))) scons_options.append('BF_FFMPEG_DLL=' + (' '.join(ffmpeg_dll))) + scons_options.append('BF_BITNESS='+bitness) + retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options) sys.exit(retcode) diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index fd3ff1fbee7..e779b10bd2a 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -72,12 +72,14 @@ if builder.find('scons') != -1: retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options) sys.exit(retcode) else: + bitness = '32' # Switch to new FFmpeg library if builder.find('win') != -1: if builder.find('win32') != -1: LCGDIR = '#../lib/windows' elif builder.find('win64') != -1: LCGDIR = '#../lib/win64' + bitness = '64' all_ffmpeg_libs = ['avcodec-53', 'avdevice-53', @@ -96,6 +98,8 @@ if builder.find('scons') != -1: scons_options.append('BF_FFMPEG_LIB=' + (' '.join(ffmpeg_lib))) scons_options.append('BF_FFMPEG_DLL=' + (' '.join(ffmpeg_dll))) + scons_options.append('BF_BITNESS='+bitness) + retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options) sys.exit(retcode) From 289ef16fcf94573e8bef9def40a3f48afaf3077c Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 3 Aug 2011 13:00:11 +0000 Subject: [PATCH 03/41] Add win64_scons builder --- build_files/buildbot/master.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index fd712f1b832..1e70ec5e13e 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -116,6 +116,7 @@ add_builder(c, 'linux_x86_64_scons', '', generic_builder) add_builder(c, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad') add_builder(c, 'win32_scons', 'windows', generic_builder) add_builder(c, 'salad_win32_scons', 'windows', generic_builder, 'soc-2011-salad') +add_builder(c, 'win64_scons', 'windows', generic_builder) #add_builder(c, 'freebsd_i386_cmake', '', generic_builder) #add_builder(c, 'freebsd_x86_64_cmake', '', generic_builder) From 01b105faa5a11cbb8f3cf2cc09430b2d1218e6fd Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 3 Aug 2011 13:31:33 +0000 Subject: [PATCH 04/41] Cmake: compile with NDOF default off. This is a dependency on code that's not in our svn. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d104ebfcea..aba96f6dd85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,7 @@ option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON) # Misc -option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON) +option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" OFF) option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON) if(UNIX AND NOT APPLE) option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON) From d795a78cb72d4c002af321dffde470dc5e3b267f Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 3 Aug 2011 14:04:48 +0000 Subject: [PATCH 05/41] Default to False for WITH_BF_3DMOUSE, since needs separate package installed. --- build_files/scons/config/darwin-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index 4a4bc4acd67..00b0c6ebf00 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -266,7 +266,7 @@ elif MACOSX_ARCHITECTURE == 'x86_64': BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2'] # SpaceNavigator and related 3D mice -WITH_BF_3DMOUSE = True +WITH_BF_3DMOUSE = False ############################################################################# ################### various compile settings and flags ################## From 48a699d15bf2c2cf366b4361a24bda55fe5bbd3e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 3 Aug 2011 14:18:02 +0000 Subject: [PATCH 06/41] enable NDOF by default with cmake again, but check if it can be found on OSX, if not disable. I cant test this but at least if I made a mistake it will just not find the SDK and disable. an osx dev needs to test. --- CMakeLists.txt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aba96f6dd85..a0a0359d8d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,7 @@ option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON) # Misc -option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" OFF) +option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON) option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON) if(UNIX AND NOT APPLE) option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON) @@ -998,9 +998,24 @@ elseif(APPLE) elseif(WITH_CODEC_QUICKTIME) set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime") endif() + + # XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED! + # ALSO SHOULD BE MOVED INTO OWN MODULE WHEN FUNCTIONAL + if(WITH_INPUT_NDOF) + # This thread it *should* work and check the framework - campbell + # http://www.cmake.org/pipermail/cmake/2005-December/007740.html + find_library(3D_CONNEXION_CLIENT_LIBRARY + NAMES 3DconnexionClient + ) + if(NOT 3D_CONNEXION_CLIENT_LIBRARY) + set(WITH_INPUT_NDOF OFF) + endif() + endif() + else() set(PLATFORM_CFLAGS "-pipe -funsigned-char") set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime") + set(WITH_INPUT_NDOF OFF) # unsupported endif() if(WITH_OPENCOLLADA) From 9eef0646d4fc5344e85e8e4eae63795ffd4b766b Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 3 Aug 2011 14:21:49 +0000 Subject: [PATCH 07/41] Crash in MMB moves (etc): commit of today was reading NULL pointer. --- source/blender/editors/transform/transform_generics.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index f8df4e4ee75..c81c398e696 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -887,6 +887,7 @@ void resetTransRestrictions(TransInfo *t) t->flag &= ~T_ALL_RESTRICTIONS; } +/* the *op can be NULL */ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) { Scene *sce = CTX_data_scene(C); @@ -1015,7 +1016,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } /* initialize UV transform from */ - if (RNA_struct_find_property(op->ptr, "correct_uv")) { + if (op && RNA_struct_find_property(op->ptr, "correct_uv")) { if(RNA_property_is_set(op->ptr, "correct_uv")) { if(RNA_boolean_get(op->ptr, "correct_uv")) { t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT; From 79c87852d2a2b07ba3cb411e00fd0fb4aaee008a Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Wed, 3 Aug 2011 17:58:06 +0000 Subject: [PATCH 08/41] Add .py extension if it is missing from keymap file. This is for bug #28141 While not really a bug, it makes it a lot easyer to use if it has the exension. (Isn't hidden from the user when they try to load it...) Kent --- release/scripts/startup/bl_ui/space_userpref_keymap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index 8fed3a934d9..585c3cffcb9 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -592,6 +592,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator): if not self.filepath: raise Exception("Filepath not set") + if not self.filepath.endswith('.py'): + self.filepath += '.py' + f = open(self.filepath, "w") if not f: raise Exception("Could not open file") From e5e6f91856efe3d78eab747c25be4e1d0a5988ef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Aug 2011 01:56:36 +0000 Subject: [PATCH 09/41] fix [#28114] Render Crash existing check for driver to use GIL was not thread safe and could cause, details in the report. This bug was caused by a check to avoid hanging, a fix for [#27683] that worked in 2.4x because the UI didn't use python to draw while rendering. Apply a different fix for [#27683], when calling an operator, call PyEval_SaveThread(), then PyEval_RestoreThread() so the GIL can be aquired by threads started by the operator - in this case bake starting a thread that evaluates drivers. --- source/blender/python/intern/bpy_driver.c | 17 ++++++++++------- source/blender/python/intern/bpy_operator.c | 21 ++++++++++++++++++++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index bcd5df97c2c..d68fd9a9111 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -41,8 +41,6 @@ #include "bpy_driver.h" -#include "../generic/py_capi_utils.h" - /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */ PyObject *bpy_pydriver_Dict= NULL; @@ -89,7 +87,7 @@ int bpy_pydriver_create_dict(void) void BPY_driver_reset(void) { PyGILState_STATE gilstate; - int use_gil= !PYC_INTERPRETER_ACTIVE; + int use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */ if(use_gil) gilstate= PyGILState_Ensure(); @@ -120,9 +118,14 @@ static void pydriver_error(ChannelDriver *driver) /* This evals py driver expressions, 'expr' is a Python expression that * should evaluate to a float number, which is returned. * - * note: PyGILState_Ensure() isnt always called because python can call the - * bake operator which intern starts a thread which calls scene update which - * does a driver update. to avoid a deadlock check PYC_INTERPRETER_ACTIVE if PyGILState_Ensure() is needed. + * (old)note: PyGILState_Ensure() isnt always called because python can call + * the bake operator which intern starts a thread which calls scene update + * which does a driver update. to avoid a deadlock check PYC_INTERPRETER_ACTIVE + * if PyGILState_Ensure() is needed - see [#27683] + * + * (new)note: checking if python is running is not threadsafe [#28114] + * now release the GIL on python operator execution instead, using + * PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender. */ float BPY_driver_exec(ChannelDriver *driver) { @@ -149,7 +152,7 @@ float BPY_driver_exec(ChannelDriver *driver) return 0.0f; } - use_gil= !PYC_INTERPRETER_ACTIVE; + use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */ if(use_gil) gilstate= PyGILState_Ensure(); diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index b8883e655f2..4a17c45ae38 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -55,6 +55,10 @@ #include "BKE_report.h" #include "BKE_context.h" +/* so operators called can spawn threads which aquire the GIL */ +#define BPY_RELEASE_GIL + + static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args) { wmOperatorType *ot; @@ -219,7 +223,22 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these dont move into global reports */ - operator_ret= WM_operator_call_py(C, ot, context, &ptr, reports); +#ifdef BPY_RELEASE_GIL + /* release GIL, since a thread could be started from an operator + * that updates a driver */ + /* note: I havve not seen any examples of code that does this + * so it may not be officially supported but seems to work ok. */ + { + PyThreadState *ts= PyEval_SaveThread(); +#endif + + operator_ret= WM_operator_call_py(C, ot, context, &ptr, reports); + +#ifdef BPY_RELEASE_GIL + /* regain GIL */ + PyEval_RestoreThread(ts); + } +#endif error_val= BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE); From a6fed14da4569380cecac3154482d0e6e54d1433 Mon Sep 17 00:00:00 2001 From: Mike Erwin Date: Thu, 4 Aug 2011 03:14:00 +0000 Subject: [PATCH 10/41] stricter guards for disabling NDOF code (will test in 3.. 2.. 1..) --- .../ghost/intern/GHOST_NDOFManagerWin32.cpp | 6 ++- intern/ghost/intern/GHOST_NDOFManagerWin32.h | 8 +++- intern/ghost/intern/GHOST_SystemWin32.cpp | 45 ++++++++++--------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp index 57d84ec14d4..fd62e845f7d 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp +++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp @@ -22,7 +22,9 @@ * * ***** END GPL LICENSE BLOCK ***** */ - + +#ifdef WITH_INPUT_NDOF // use contents of this file + #include "GHOST_NDOFManagerWin32.h" @@ -39,3 +41,5 @@ bool GHOST_NDOFManagerWin32::available() // always available since RawInput is built into Windows return true; } + +#endif // WITH_INPUT_NDOF diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h index 31f7e074cd6..9f3eddeb3c8 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerWin32.h +++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.h @@ -22,10 +22,13 @@ * * ***** END GPL LICENSE BLOCK ***** */ - + + #ifndef _GHOST_NDOFMANAGERWIN32_H_ #define _GHOST_NDOFMANAGERWIN32_H_ +#ifdef WITH_INPUT_NDOF + #include "GHOST_NDOFManager.h" @@ -37,4 +40,5 @@ public: }; -#endif +#endif // WITH_INPUT_NDOF +#endif // #include guard diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index bbf8efeaee3..38f3985b139 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -62,7 +62,6 @@ #endif #endif -#include "GHOST_Debug.h" #include "GHOST_DisplayManagerWin32.h" #include "GHOST_EventButton.h" #include "GHOST_EventCursor.h" @@ -72,7 +71,10 @@ #include "GHOST_TimerManager.h" #include "GHOST_WindowManager.h" #include "GHOST_WindowWin32.h" + +#ifdef WITH_INPUT_NDOF #include "GHOST_NDOFManagerWin32.h" +#endif // Key code values not found in winuser.h #ifndef VK_MINUS @@ -127,22 +129,32 @@ static void initRawInput() { - RAWINPUTDEVICE devices[2]; - memset(devices, 0, 2 * sizeof(RAWINPUTDEVICE)); +#ifdef WITH_INPUT_NDOF +#define DEVICE_COUNT 2 +#else +#define DEVICE_COUNT 1 +#endif - // multi-axis mouse (SpaceNavigator, etc.) - devices[0].usUsagePage = 0x01; - devices[0].usUsage = 0x08; + RAWINPUTDEVICE devices[DEVICE_COUNT]; + memset(devices, 0, DEVICE_COUNT * sizeof(RAWINPUTDEVICE)); // Initiates WM_INPUT messages from keyboard // That way GHOST can retrieve true keys - devices[1].usUsagePage = 0x01; - devices[1].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ + devices[0].usUsagePage = 0x01; + devices[0].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ - if (RegisterRawInputDevices(devices, 2, sizeof(RAWINPUTDEVICE))) - puts("registered for RawInput (spacenav & keyboard)"); +#ifdef WITH_INPUT_NDOF + // multi-axis mouse (SpaceNavigator, etc.) + devices[1].usUsagePage = 0x01; + devices[1].usUsage = 0x08; +#endif + + if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE))) + ; // yay! else printf("could not register for RawInput: %d\n", (int)GetLastError()); + +#undef DEVICE_COUNT } GHOST_SystemWin32::GHOST_SystemWin32() @@ -808,6 +820,7 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const& raw) case 1: // translation { short* axis = (short*)(data + 1); + // massage into blender view coords (same goes for rotation) short t[3] = {axis[0], -axis[2], axis[1]}; m_ndofManager->updateTranslation(t, now); @@ -830,14 +843,6 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const& raw) } case 3: // buttons { -#if 0 - // I'm getting garbage bits -- examine whole report: - printf("ndof: HID report for buttons ["); - for (int i = 0; i < raw.data.hid.dwSizeHid; ++i) - printf(" %02X", data[i]); - printf(" ]\n"); -#endif - int button_bits; memcpy(&button_bits, data + 1, sizeof(button_bits)); m_ndofManager->updateButtons(button_bits, now); @@ -892,12 +897,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, GHOST_PRINT(" key ignored\n") } break; - case RIM_TYPEHID: #ifdef WITH_INPUT_NDOF + case RIM_TYPEHID: if (system->processNDOF(raw)) eventHandled = true; -#endif break; +#endif } break; } From af786843b05ce434d46c2036643aefb7bbaa92b6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Aug 2011 08:46:17 +0000 Subject: [PATCH 11/41] patch from jensverwiebe to disable ndof if header is not found. --- SConstruct | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SConstruct b/SConstruct index 529f6daeef1..4f920190276 100644 --- a/SConstruct +++ b/SConstruct @@ -253,6 +253,15 @@ if 'blenderlite' in B.targets: if k not in B.arguments: env[k] = v +# detect presence of 3D_CONNEXION_CLIENT_LIBRARY for OSX +if env['OURPLATFORM']=='darwin': + envi = Environment() + conf = Configure(envi) + if not conf.CheckCHeader('ConnexionClientAPI.h'): # CheckCXXHeader if it is c++ ! + print "3D_CONNEXION_CLIENT_LIBRARY not found, disabling WITH_BF_3DMOUSE" # avoid build errors ! + env['WITH_BF_3DMOUSE'] = 0 + envi = conf.Finish() + if env['WITH_BF_OPENMP'] == 1: if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): From 0578d55f1ef700b96ae8a8c33c1f8b54a200c7d9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Aug 2011 09:47:09 +0000 Subject: [PATCH 12/41] when appending with a NULL context dont print warnigns about scene not being set - was annoying for BGE LibLoad. --- source/blender/blenloader/intern/readfile.c | 36 ++++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0633794c6ed..0a24dfaed72 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -13047,10 +13047,10 @@ static void append_do_cursor(Scene *scene, Library *curlib, short flag) } } +/* Context == NULL signifies not to do any scene manipulation */ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag) { Main *mainvar; - Scene *scene= CTX_data_scene(C); Library *curlib; /* make main consistent */ @@ -13079,22 +13079,28 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in lib_verify_nodetree(mainvar, FALSE); fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */ - /* give a base to loose objects. If group append, do it for objects too */ - if(scene) { - const short is_link= (flag & FILE_LINK) != 0; - if(idcode==ID_SCE) { - /* dont instance anything when linking in scenes, assume the scene its self instances the data */ - } - else { - give_base_to_objects(mainvar, scene, curlib, idcode, is_link); + if(C) { + Scene *scene= CTX_data_scene(C); - if (flag & FILE_GROUP_INSTANCE) { - give_base_to_groups(mainvar, scene); + /* give a base to loose objects. If group append, do it for objects too */ + if(scene) { + const short is_link= (flag & FILE_LINK) != 0; + if(idcode==ID_SCE) { + /* dont instance anything when linking in scenes, assume the scene its self instances the data */ + } + else { + give_base_to_objects(mainvar, scene, curlib, idcode, is_link); + + if (flag & FILE_GROUP_INSTANCE) { + give_base_to_groups(mainvar, scene); + } } } - } - else { - printf("library_append_end, scene is NULL (objects wont get bases)\n"); + else { + printf("library_append_end, scene is NULL (objects wont get bases)\n"); + } + + append_do_cursor(scene, curlib, flag); } /* has been removed... erm, why? s..ton) */ /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */ @@ -13105,8 +13111,6 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in blo_freefiledata( *fd ); *fd = NULL; } - - append_do_cursor(scene, curlib, flag); } void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag) From f3c40df5e334f8a1f106fe71e44c8035ddcac7b1 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 4 Aug 2011 09:47:40 +0000 Subject: [PATCH 13/41] rst API doc fixes: literalincluding bge.texture and bge.constraints examples + bgl fixes --- doc/python_api/rst/bge.constraints.rst | 4 ++++ doc/python_api/rst/bge.texture.rst | 4 ++++ doc/python_api/rst/bgl.rst | 7 +++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/python_api/rst/bge.constraints.rst b/doc/python_api/rst/bge.constraints.rst index 12ce8617457..da0a358dfed 100644 --- a/doc/python_api/rst/bge.constraints.rst +++ b/doc/python_api/rst/bge.constraints.rst @@ -2,6 +2,10 @@ Physics Constraints (bge.constraints) ===================================== +.. module:: bge.constraints + +.. literalinclude:: ../examples/bge.constraints.py + .. function:: createConstraint(physicsid, physicsid2, constrainttype, [pivotX, pivotY, pivotZ, [axisX, axisY, axisZ, [flag]]]]) Creates a constraint. diff --git a/doc/python_api/rst/bge.texture.rst b/doc/python_api/rst/bge.texture.rst index f3e9f98dded..0b32c7a393b 100644 --- a/doc/python_api/rst/bge.texture.rst +++ b/doc/python_api/rst/bge.texture.rst @@ -36,6 +36,10 @@ When the texture object is deleted, the new texture is deleted and the old textu .. module:: bge.texture +.. literalinclude:: ../examples/bge.texture.py + +.. literalinclude:: ../examples/bge.texture.1.py + .. class:: VideoFFmpeg(file [, capture=-1, rate=25.0, width=0, height=0]) FFmpeg video source diff --git a/doc/python_api/rst/bgl.rst b/doc/python_api/rst/bgl.rst index 236bfafb295..5f3158bf5dd 100644 --- a/doc/python_api/rst/bgl.rst +++ b/doc/python_api/rst/bgl.rst @@ -15,7 +15,7 @@ collections of tutorials. The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning OpenGL}" and the online NeHe tutorials are two of the best resources. -..note:: +.. note:: You can use the :class:`Image` type to load and set textures. See :class:`Image.gl_load` and :class:`Image.gl_load`, for example. @@ -1386,7 +1386,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources. bgl.glGetFloatv(bgl.GL_MODELVIEW_MATRIX, view_matrix) f = 1.0 / view_matrix[0] - # Instead of the usual glRasterPos2i(xval, yval) + # Instead of the usual glRasterPos2i(xval, yval) bgl.glRasterPos2f(xval * f, yval * f) @@ -1848,10 +1848,13 @@ class Buffer: .. code-block:: python import bgl + myByteBuffer = bgl.Buffer(bgl.GL_BYTE, [32, 32]) bgl.glGetPolygonStipple(myByteBuffer) + print(myByteBuffer.dimensions) print(myByteBuffer.to_list()) + sliceBuffer = myByteBuffer[0:16] print(sliceBuffer) From 9da70f74d37c7c0001a2705afc8fe5044f63bb0a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 4 Aug 2011 10:05:14 +0000 Subject: [PATCH 14/41] UserPref/Node editor feature: Change the level of noodle curving. Some people like curved lines, other hate them. This commit will let the user change the level of curving. In UserPreferences=>Themes=>Node editor=>Noodle curving the level can be modified. Allowed range is 0-10 with the default on 5 The patch will default everything to the way blender works ATM. File subversion has been increased otherwise older 258 files got straight lines. The data is stored in the ThemeSpace.noodle_curving the bezierdrawing is done in the drawnode. Also tested the Line cut tool --- source/blender/editors/include/UI_resources.h | 4 +++- source/blender/editors/interface/resources.c | 14 ++++++++++++-- source/blender/editors/space_node/drawnode.c | 4 ++-- source/blender/makesdna/DNA_userdef_types.h | 2 +- source/blender/makesrna/intern/rna_userdef.c | 7 +++++++ 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 2311aafbb17..d0c2b387445 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -242,7 +242,9 @@ enum { TH_DRAWEXTRA_EDGELEN, TH_DRAWEXTRA_FACEAREA, - TH_DRAWEXTRA_FACEANG + TH_DRAWEXTRA_FACEANG, + + TH_NODE_CURVING }; /* XXX WARNING: previous is saved in file, so do not change order! */ diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 0c755180b3a..f58383830cb 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -360,7 +360,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp= ts->syntaxv; break; case TH_NODE_GROUP: cp= ts->syntaxc; break; - + case TH_NODE_CURVING: + cp= &ts->noodle_curving; break; + case TH_SEQ_MOVIE: cp= ts->movie; break; case TH_SEQ_IMAGE: @@ -787,6 +789,7 @@ void ui_theme_init_default(void) SETCOL(btheme->tnode.syntaxb, 108, 105, 111, 255); /* operator */ SETCOL(btheme->tnode.syntaxv, 104, 106, 117, 255); /* generator */ SETCOL(btheme->tnode.syntaxc, 105, 117, 110, 255); /* group */ + btheme->tnode.noodle_curving = 5; /* space logic */ btheme->tlogic= btheme->tv3d; @@ -1553,7 +1556,14 @@ void init_userdef_do_versions(void) /* clear "AUTOKEY_FLAG_ONLYKEYINGSET" flag from userprefs, so that it doesn't linger around from old configs like a ghost */ U.autokey_flag &= ~AUTOKEY_FLAG_ONLYKEYINGSET; } - + + if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 2)) { + bTheme *btheme; + for(btheme= U.themes.first; btheme; btheme= btheme->next) { + btheme->tnode.noodle_curving = 5; + } + } + /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { U.texcollectrate = 60; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 50e657bbb61..c32d05e9c30 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1768,8 +1768,8 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa vec[3][0]= snode->mx; vec[3][1]= snode->my; } - - dist= 0.5f*ABS(vec[0][0] - vec[3][0]); + + dist= UI_GetThemeValue(TH_NODE_CURVING)*0.10f*ABS(vec[0][0] - vec[3][0]); /* check direction later, for top sockets */ vec[1][0]= vec[0][0]+dist; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 0bf812f1ec2..aa6da3aaeca 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -220,7 +220,7 @@ typedef struct ThemeSpace { char console_cursor[4]; char vertex_size, outline_width, facedot_size; - char bpad; + char noodle_curving; char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes char syntaxv[4], syntaxc[4]; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 7a9193571fd..a1a99c34e70 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1351,6 +1351,13 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Group Node", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "noodle_curving", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "noodle_curving"); + RNA_def_property_int_default(prop, 5); + RNA_def_property_range(prop, 0, 10); + RNA_def_property_ui_text(prop, "Noodle curving", "Curving of the noodle"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) From cdea64e32cbe1a8b9c9312b04cf15b0ac3daf685 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Aug 2011 11:27:13 +0000 Subject: [PATCH 15/41] remove append to cursor code, wasnt used and made some naive assumptions about object locations. --- source/blender/blenloader/intern/readfile.c | 49 --------------------- source/blender/makesdna/DNA_space_types.h | 2 +- 2 files changed, 1 insertion(+), 50 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0a24dfaed72..d60ac492f97 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12999,53 +12999,6 @@ Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, const char * return library_append_begin(C, &fd, filepath); } -static void append_do_cursor(Scene *scene, Library *curlib, short flag) -{ - Base *centerbase; - Object *ob; - float *curs, centerloc[3], vec[3], min[3], max[3]; - int count= 0; - - /* when not linking (appending)... */ - if(flag & FILE_LINK) - return; - - /* we're not appending at cursor */ - if((flag & FILE_ATCURSOR) == 0) - return; - - /* find the center of everything appended */ - INIT_MINMAX(min, max); - centerbase= (scene->base.first); - while(centerbase) { - if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) { - VECCOPY(vec, centerbase->object->loc); - DO_MINMAX(vec, min, max); - count++; - } - centerbase= centerbase->next; - } - /* we haven't found any objects to move to cursor */ - if(!count) - return; - - /* move from the center of the appended objects to cursor */ - mid_v3_v3v3(centerloc, min, max); - curs = scene->cursor; - VECSUB(centerloc,curs,centerloc); - - /* now translate the center of the objects */ - centerbase= (scene->base.first); - while(centerbase) { - if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) { - ob= centerbase->object; - ob->loc[0] += centerloc[0]; - ob->loc[1] += centerloc[1]; - ob->loc[2] += centerloc[2]; - } - centerbase= centerbase->next; - } -} /* Context == NULL signifies not to do any scene manipulation */ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag) @@ -13099,8 +13052,6 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in else { printf("library_append_end, scene is NULL (objects wont get bases)\n"); } - - append_do_cursor(scene, curlib, flag); } /* has been removed... erm, why? s..ton) */ /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index ff9f2269f53..1549bd71748 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -703,7 +703,7 @@ enum FileSortTypeE { #define FILE_HIDE_DOT (1<<3) #define FILE_AUTOSELECT (1<<4) #define FILE_ACTIVELAY (1<<5) -#define FILE_ATCURSOR (1<<6) +/* #define FILE_ATCURSOR (1<<6) */ /* deprecated */ #define FILE_DIRSEL_ONLY (1<<7) #define FILE_FILTER (1<<8) #define FILE_BOOKMARKS (1<<9) From 26fe903502368f1a255f44bbc75e308e08a5d659 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 4 Aug 2011 12:19:50 +0000 Subject: [PATCH 16/41] Typo when reading line curving. The subversion is 1, so smaller than 1 should be converted --- source/blender/editors/interface/resources.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index f58383830cb..32e87b3a793 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1557,7 +1557,7 @@ void init_userdef_do_versions(void) U.autokey_flag &= ~AUTOKEY_FLAG_ONLYKEYINGSET; } - if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 2)) { + if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 1)) { bTheme *btheme; for(btheme= U.themes.first; btheme; btheme= btheme->next) { btheme->tnode.noodle_curving = 5; From 36bf4385c2c2a1d3f462d30138b6815287d8e548 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Aug 2011 13:22:38 +0000 Subject: [PATCH 17/41] fix for building with clang. makesrna wasnt linking with sqrt --- source/blender/makesrna/intern/rna_object_api.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 21fa28af01a..d48f1c93da8 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -45,9 +45,9 @@ // #include "ED_mesh.h" -#include "BLI_math.h" #ifdef RNA_RUNTIME +#include "BLI_math.h" #include "BKE_main.h" #include "BKE_global.h" @@ -544,7 +544,8 @@ void RNA_api_object(StructRNA *srna) /* location of point for test and max distance */ parm= RNA_def_float_vector(func, "point", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4); RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_float(func, "max_dist", sqrt(FLT_MAX), 0.0, FLT_MAX, "", "", 0.0, FLT_MAX); + /* default is sqrt(FLT_MAX) */ + RNA_def_float(func, "max_dist", 1.844674352395373e+19, 0.0, FLT_MAX, "", "", 0.0, FLT_MAX); /* return location and normal */ parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The location on the object closest to the point", -1e4, 1e4); From f77af0a8cef8e7be6245c6f4c52dd05f6c7a387f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 05:26:19 +0000 Subject: [PATCH 18/41] change BLO_library_append_begin to take a main argument rather then a context, means the BGE doesnt need to make a new empty context just to pass as an arg. added doxygen description too. this quiets the print when the BGE does linking. --- source/blender/blenloader/BLO_readfile.h | 16 ++++++++++------ source/blender/blenloader/intern/readfile.c | 7 +++---- source/blender/python/intern/bpy_library.c | 3 ++- .../blender/windowmanager/intern/wm_operators.c | 2 +- .../Converter/KX_BlenderSceneConverter.cpp | 14 +++++--------- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 85d4b936c51..47931477728 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -211,7 +211,16 @@ int BLO_has_bfile_extension(char *str); */ int BLO_is_a_library(const char *path, char *dir, char *group); -struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, const char *filepath); + +/** + * Initialize the BlendHandle for appending or linking library data. + * + * @param mainvar The current main database eg G.main or CTX_data_main(C). + * @param bh A blender file handle as returned by BLO_blendhandle_from_file or BLO_blendhandle_from_memory. + * @param filepath Used for relative linking, copied to the lib->name + * @return the library Main, to be passed to BLO_library_append_named_part as mainl. + */ +struct Main* BLO_library_append_begin(struct Main *mainvar, BlendHandle** bh, const char *filepath); /** @@ -243,11 +252,6 @@ void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendH void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname); -/* deprecated */ -#if 1 -void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Main *mainvar, struct Scene *scene, struct ReportList *reports); -#endif - BlendFileData* blo_read_blendafterruntime(int file, char *name, int actualsize, struct ReportList *reports); #ifdef __cplusplus diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d60ac492f97..44c8ca97be9 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12975,9 +12975,8 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r) /* common routine to append/link something from a library */ -static Main* library_append_begin(const bContext *C, FileData **fd, const char *filepath) +static Main* library_append_begin(Main *mainvar, FileData **fd, const char *filepath) { - Main *mainvar= CTX_data_main(C); Main *mainl; /* make mains */ @@ -12993,10 +12992,10 @@ static Main* library_append_begin(const bContext *C, FileData **fd, const char * return mainl; } -Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, const char *filepath) +Main* BLO_library_append_begin(Main *mainvar, BlendHandle** bh, const char *filepath) { FileData *fd= (FileData*)(*bh); - return library_append_begin(C, &fd, filepath); + return library_append_begin(mainvar, &fd, filepath); } diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c index 85bffb5a8cc..4ce3e0356e2 100644 --- a/source/blender/python/intern/bpy_library.c +++ b/source/blender/python/intern/bpy_library.c @@ -39,6 +39,7 @@ #include "BKE_library.h" #include "BKE_idcode.h" #include "BKE_report.h" +#include "BKE_context.h" #include "BLI_utildefines.h" #include "BLI_string.h" @@ -317,7 +318,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) flag_all_listbases_ids(LIB_PRE_EXISTING, 1); /* here appending/linking starts */ - mainl= BLO_library_append_begin(BPy_GetContext(), &(self->blo_handle), self->relpath); + mainl= BLO_library_append_begin(CTX_data_main(BPy_GetContext()), &(self->blo_handle), self->relpath); { int i= 0, code; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a47dfacf358..5a05be0fefc 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1690,7 +1690,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) flag_all_listbases_ids(LIB_PRE_EXISTING, 1); /* here appending/linking starts */ - mainl = BLO_library_append_begin(C, &bh, libname); + mainl = BLO_library_append_begin(bmain, &bh, libname); if(totfiles == 0) { BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag); } diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 58089cc4b2d..b04a0d24e78 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -950,7 +950,6 @@ bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) { - bContext *C; Main *main_newlib; /* stored as a dynamic 'main' until we free it */ Main *main_tmp= NULL; /* created only for linking, then freed */ LinkNode *names = NULL; @@ -981,12 +980,10 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha } main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain"); - C= CTX_create(); - CTX_data_main_set(C, main_newlib); BKE_reports_init(&reports, RPT_STORE); /* here appending/linking starts */ - main_tmp = BLO_library_append_begin(C, &bpy_openlib, (char *)path); + main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); int totnames_dummy; names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy); @@ -1000,11 +997,11 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha } BLI_linklist_free(names, free); /* free linklist *and* each node's data */ - BLO_library_append_end(C, main_tmp, &bpy_openlib, idcode, flag); + BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag); /* now do another round of linking for Scenes so all actions are properly loaded */ if (idcode==ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) { - main_tmp = BLO_library_append_begin(C, &bpy_openlib, (char *)path); + main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); int totnames_dummy; names = BLO_blendhandle_get_datablock_names( bpy_openlib, ID_AC, &totnames_dummy); @@ -1018,12 +1015,11 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha } BLI_linklist_free(names, free); /* free linklist *and* each node's data */ - BLO_library_append_end(C, main_tmp, &bpy_openlib, ID_AC, flag); + BLO_library_append_end(NULL, main_tmp, &bpy_openlib, ID_AC, flag); } BLO_blendhandle_close(bpy_openlib); - - CTX_free(C); + BKE_reports_clear(&reports); /* done linking */ From 82e863bdae70b1297318aa7fd98f72cab074ef66 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 06:06:15 +0000 Subject: [PATCH 19/41] fix [#28102] Typing 'C:' into the file selector's directory asks to make a new directory. --- source/blender/editors/space_file/file_ops.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 77524c7e117..d4253495e97 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -64,6 +64,7 @@ #include #include #include +#include /* for events */ #define NOTACTIVEFILE 0 @@ -1079,8 +1080,18 @@ static void file_expand_directory(bContext *C) } #ifdef WIN32 - if (sfile->params->dir[0] == '\0') + if (sfile->params->dir[0] == '\0') { get_default_root(sfile->params->dir); + } + /* change "C:" --> "C:\", [#28102] */ + else if ( (isalpha(sfile->params->dir[0]) && + (sfile->params->dir[1] == ':')) && + (sfile->params->dir[2] == '\0') + + ) { + sfile->params->dir[2]= '\\'; + sfile->params->dir[3]= '\0'; + } #endif } } From c946969bb90c177319c183e7155c6f360230ea2f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 06:09:30 +0000 Subject: [PATCH 20/41] fix for possible uninitialized RNA strings, when RNA_string_get property is not found, initialize the string to "". --- source/blender/makesrna/intern/rna_access.c | 7 +++++-- source/blender/windowmanager/intern/wm_operators.c | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index e71be8c153e..f1056c86a4c 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -4007,10 +4007,13 @@ void RNA_string_get(PointerRNA *ptr, const char *name, char *value) { PropertyRNA *prop= RNA_struct_find_property(ptr, name); - if(prop) + if(prop) { RNA_property_string_get(ptr, prop, value); - else + } + else { printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name); + value[0]= '\0'; + } } char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5a05be0fefc..7238cede2cc 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1621,7 +1621,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) int idcode, totfiles=0; short flag; - name[0] = '\0'; RNA_string_get(op->ptr, "filename", name); RNA_string_get(op->ptr, "directory", dir); From f48631e9a4afb8d7d4ab4e15963b38ba75605f68 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 06:26:54 +0000 Subject: [PATCH 21/41] fix [#28160] Pressing Y on an image sequence to seperate the images takes them out of their meta strips dont show a popup anymore, was silly because you had to change the value for before anything was done, can use f6 redo popup instead, sequencer should eventually have a view3d operator redo panel. --- source/blender/editors/space_sequencer/sequencer_edit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index b7a7b6b5412..6a69d32d307 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1785,7 +1785,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) se = give_stripelem(seq, cfra); seq_new= seq_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME); - BLI_addtail(&ed->seqbase, seq_new); + BLI_addtail(ed->seqbasep, seq_new); seq_new->start= start_ofs; seq_new->type= SEQ_IMAGE; @@ -1839,7 +1839,6 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot) ot->description="On image sequences strips, it return a strip for each image"; /* api callbacks */ - ot->invoke= WM_operator_props_popup; ot->exec= sequencer_separate_images_exec; ot->poll= sequencer_edit_poll; From ad7ea2f89205dd67b84ec76d70352ad56004293a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 09:04:11 +0000 Subject: [PATCH 22/41] get a tad more vertical space in the toolbar. --- release/scripts/startup/bl_ui/space_view3d_toolbar.py | 10 ++++++---- source/blender/editors/curve/editfont.c | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 91cfd22b3d6..85dd6f7da5e 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -88,8 +88,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel): col = layout.column(align=True) col.label(text="Shading:") - col.operator("object.shade_smooth", text="Smooth") - col.operator("object.shade_flat", text="Flat") + row = col.row(align=True) + row.operator("object.shade_smooth", text="Smooth") + row.operator("object.shade_flat", text="Flat") draw_keyframing_tools(context, layout) @@ -155,8 +156,9 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, bpy.types.Panel): col = layout.column(align=True) col.label(text="Shading:") - col.operator("mesh.faces_shade_smooth", text="Smooth") - col.operator("mesh.faces_shade_flat", text="Flat") + row = col.row(align=True) + row.operator("mesh.faces_shade_smooth", text="Smooth") + row.operator("mesh.faces_shade_flat", text="Flat") draw_repeat_tools(context, layout) diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 649ff9e953a..6c95df53d39 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1649,10 +1649,10 @@ static int open_exec(bContext *C, wmOperator *op) VFont *font; PropertyPointerRNA *pprop; PointerRNA idptr; - char str[FILE_MAX]; - RNA_string_get(op->ptr, "filepath", str); + char filepath[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filepath); - font = load_vfont(str); + font= load_vfont(filepath); if(!font) { if(op->customdata) MEM_freeN(op->customdata); From a157112ac5c6465fd8d9518af87ce86a5250eeba Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 10:45:32 +0000 Subject: [PATCH 23/41] fix for icon scaling with the DPI setting - icons were scaling by the sqrt(dpi)/8.48528, but infact they only need to be scaled by (dpi/72). - UI_icon_get_width value was being used without multiplying by dpi scale. --- source/blender/editors/include/UI_interface.h | 3 +++ .../editors/interface/interface_handlers.c | 2 +- .../blender/editors/interface/interface_icons.c | 3 ++- .../blender/editors/interface/interface_widgets.c | 15 +++++++-------- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 61e19655f8d..1bae6ce0214 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -164,6 +164,9 @@ typedef struct uiLayout uiLayout; /* scale fixed button widths by this to account for DPI * 8.4852 == sqrtf(72.0f)) */ #define UI_DPI_FAC (sqrtf((float)U.dpi) / 8.48528137423857f) +#define UI_DPI_ICON_FAC (((float)U.dpi) / 72.0f) +/* 16 to copy ICON_DEFAULT_HEIGHT */ +#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC) /* Button types, bits stored in 1 value... and a short even! - bits 0-4: bitnr (0-31) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c5275ea98b5..b3272a2e3d4 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1290,7 +1290,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho else if(ELEM(but->type, TEX, SEARCH_MENU)) { startx += 5; if (but->flag & UI_HAS_ICON) - startx += 16; + startx += UI_DPI_ICON_SIZE; } /* mouse dragged outside the widget to the left */ diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 3bf2a9ddd02..412c0233c35 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -742,6 +742,7 @@ static DrawInfo *icon_create_drawinfo(void) return di; } +/* note!, returns unscaled by DPI, may need to multiply result by UI_DPI_ICON_FAC */ int UI_icon_get_width(int icon_id) { Icon *icon = NULL; @@ -952,7 +953,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al Icon *icon = NULL; DrawInfo *di = NULL; IconImage *iimg; - float fdraw_size= UI_DPI_FAC*draw_size; + float fdraw_size= UI_DPI_ICON_FAC*draw_size; int w, h; icon = BKE_icon_get(icon_id); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 25a64994f5c..d235fd0c16a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -771,7 +771,6 @@ static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect) /* icons have been standardized... and this call draws in untransformed coordinates */ -#define ICON_HEIGHT UI_DPI_FAC*16.0f static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect) { @@ -791,15 +790,15 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect if(aspect != but->aspect) { /* prevent scaling up icon in pupmenu */ if (aspect < 1.0f) { - height= ICON_HEIGHT; + height= UI_DPI_ICON_SIZE; aspect = 1.0f; } else - height= ICON_HEIGHT/aspect; + height= UI_DPI_ICON_SIZE/aspect; } else - height= ICON_HEIGHT; + height= UI_DPI_ICON_SIZE; /* calculate blend color */ if ELEM4(but->type, TOG, ROW, TOGN, LISTROW) { @@ -866,7 +865,7 @@ static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect) int border= (but->flag & UI_BUT_ALIGN_RIGHT)? 8: 10; int okwidth= rect->xmax-rect->xmin - border; - if (but->flag & UI_HAS_ICON) okwidth -= 16; + if (but->flag & UI_HAS_ICON) okwidth -= UI_DPI_ICON_SIZE; /* need to set this first */ uiStyleFontSet(fstyle); @@ -1149,7 +1148,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB if (but->flag & UI_HAS_ICON) { widget_draw_icon(but, but->icon+but->iconadd, 1.0f, rect); - rect->xmin += UI_icon_get_width(but->icon+but->iconadd); + rect->xmin += (int)((float)UI_icon_get_width(but->icon+but->iconadd) * UI_DPI_ICON_FAC); if(but->editstr || (but->flag & UI_TEXT_LEFT)) rect->xmin += 5; @@ -3133,7 +3132,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic /* text location offset */ rect->xmin+=5; - if(iconid) rect->xmin+= ICON_HEIGHT; + if(iconid) rect->xmin+= UI_DPI_ICON_SIZE; /* cut string in 2 parts? */ cpoin= strchr(name, '|'); @@ -3158,7 +3157,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic if(iconid) { int xs= rect->xmin+4; - int ys= 1 + (rect->ymin+rect->ymax- ICON_HEIGHT)/2; + int ys= 1 + (rect->ymin+rect->ymax- UI_DPI_ICON_SIZE)/2; glEnable(GL_BLEND); UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */ glDisable(GL_BLEND); From a6b677c81d3eb64c66b23ba83b268748b7f09009 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 12:07:05 +0000 Subject: [PATCH 24/41] patch from jensverwiebe to scons to be compatible with gcc llvm. people who copy the darwin-config.py to their user-config.py should update. --- build_files/scons/config/darwin-config.py | 28 +++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index 00b0c6ebf00..2df2e1ae956 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -21,14 +21,16 @@ cmd = 'uname -p' MAC_PROC=commands.getoutput(cmd) cmd = 'uname -r' cmd_res=commands.getoutput(cmd) -if cmd_res[0]=='7': +if cmd_res[:2]=='7': MAC_CUR_VER='10.3' -elif cmd_res[0]=='8': +elif cmd_res[:2]=='8': MAC_CUR_VER='10.4' -elif cmd_res[0]=='9': +elif cmd_res[:2]=='9': MAC_CUR_VER='10.5' -elif cmd_res[0]=='10': +elif cmd_res[:2]=='10': MAC_CUR_VER='10.6' +elif cmd_res[:2]=='11': + MAC_CUR_VER='10.7' if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64': USE_QTKIT=True # Carbon quicktime is not available for 64bit @@ -37,8 +39,8 @@ if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64': # Default target OSX settings per architecture # Can be customized -if MACOSX_ARCHITECTURE == 'ppc': -# ppc release are now made for 10.4 +if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4': +# all releases are now made for 10.5 ! # MAC_MIN_VERS = '10.3' # MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk' # LCGDIR = '#../lib/darwin-6.1-powerpc' @@ -50,13 +52,21 @@ if MACOSX_ARCHITECTURE == 'ppc': LCGDIR = '#../lib/darwin-8.0.0-powerpc' CC = 'gcc-4.0' CXX = 'g++-4.0' -elif MACOSX_ARCHITECTURE == 'i386': +elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4': MAC_MIN_VERS = '10.4' MACOSX_DEPLOYMENT_TARGET = '10.4' MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk' LCGDIR = '#../lib/darwin-8.x.i386' CC = 'gcc-4.0' CXX = 'g++-4.0' +elif MAC_CUR_VER >= '10.6': + # OSX 10.6 and 10.7 developer tools don“t come with sdk < 10.6 anymore ! + MAC_MIN_VERS = '10.6' + MACOSX_DEPLOYMENT_TARGET = '10.6' + MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk' + LCGDIR = '#../lib/darwin-9.x.universal' + CC = 'llvm-gcc-4.2' + CXX = 'llvm-g++-4.2' else : MAC_MIN_VERS = '10.5' MACOSX_DEPLOYMENT_TARGET = '10.5' @@ -71,8 +81,8 @@ LIBDIR = '${LCGDIR}' ################### Dependency settings ################## ############################################################################# -#Defaults openMP to true if compiler (currently only gcc 4.2) handles it -if CC == 'gcc-4.2': +#Defaults openMP to true if compiler handles it +if CC == 'gcc-4.2' or CC == 'llvm-gcc-4.2': WITH_BF_OPENMP = True # multithreading for fluids, cloth and smoke else: WITH_BF_OPENMP = False From db319f8544a908a280a92550fc4c2cc706fc12e2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 14:53:13 +0000 Subject: [PATCH 25/41] move the ndof menu into the userpref's since it adjusts preferences, also renamed VIEW3D_MT_ndof_settings -> USERPREF_MT_ndof_settings since it has no view3d specific settings. --- .../scripts/startup/bl_ui/space_userpref.py | 25 +++++++++++++++++++ release/scripts/startup/bl_ui/space_view3d.py | 24 ------------------ .../windowmanager/intern/wm_operators.c | 2 +- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 1feb1eec0c5..e27bd8ef07a 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -755,6 +755,31 @@ class USERPREF_PT_file(bpy.types.Panel): from bl_ui.space_userpref_keymap import InputKeyMapPanel +class USERPREF_MT_ndof_settings(bpy.types.Menu): + # accessed from the window keybindings in C (only) + bl_label = "3D Mouse Settings" + + def draw(self, context): + layout = self.layout + input_prefs = context.user_preferences.inputs + + layout.separator() + layout.prop(input_prefs, "ndof_sensitivity") + + if context.space_data.type == 'VIEW_3D': + layout.separator() + layout.prop(input_prefs, "ndof_show_guide") + + layout.separator() + layout.label(text="orbit options") + layout.prop(input_prefs, "ndof_orbit_invert_axes") + + layout.separator() + layout.label(text="fly options") + layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY') + layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM') + + class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel): bl_space_type = 'USER_PREFERENCES' bl_label = "Input" diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index f96a758e7ce..083c330f61d 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -349,30 +349,6 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu): layout.operator("view3d.fly") -class VIEW3D_MT_ndof_settings(bpy.types.Menu): - bl_label = "3D Mouse Settings" - - def draw(self, context): - layout = self.layout - input_prefs = context.user_preferences.inputs - - layout.separator() - layout.prop(input_prefs, "ndof_sensitivity") - - if context.space_data.type == 'VIEW_3D': - layout.separator() - layout.prop(input_prefs, "ndof_show_guide") - - layout.separator() - layout.label(text="orbit options") - layout.prop(input_prefs, "ndof_orbit_invert_axes") - - layout.separator() - layout.label(text="fly options") - layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY') - layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM') - - class VIEW3D_MT_view_align(bpy.types.Menu): bl_label = "Align View" diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7238cede2cc..cea2d6b3fe5 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3719,7 +3719,7 @@ void wm_window_keymap(wmKeyConfig *keyconf) /* menus that can be accessed anywhere in blender */ WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0); - WM_keymap_add_menu(keymap, "VIEW3D_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0); + WM_keymap_add_menu(keymap, "USERPREF_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0); /* Space switching */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */ From 85fe36ab611aae8b47089c24110d4d176bc8143c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 16:21:37 +0000 Subject: [PATCH 26/41] pyrna - add own callable function type rather then using a standard python method, gives small speedup drawing buttons since every layout.prop/col/operator/menu etc creates and throws away one of these. --- source/blender/python/intern/bpy_rna.c | 135 +++++++++++++++++++------ source/blender/python/intern/bpy_rna.h | 10 ++ 2 files changed, 115 insertions(+), 30 deletions(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 502b25842de..d517205e2fe 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -908,6 +908,13 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) return ret; } + +static PyObject *pyrna_func_repr(BPy_FunctionRNA *self) +{ + return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>", Py_TYPE(self)->tp_name, RNA_struct_identifier(self->ptr.type), RNA_function_identifier(self->func)); +} + + static long pyrna_struct_hash(BPy_StructRNA *self) { return _Py_HashPointer(self->ptr.data); @@ -1344,36 +1351,16 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha return error_val; } -static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw); -static PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func) +static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) { - static PyMethodDef func_meth= {"", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"}; - PyObject *self; - PyObject *ret; - - if(func==NULL) { - PyErr_Format(PyExc_RuntimeError, - "%.200s: type attempted to get NULL function", - RNA_struct_identifier(pyrna->ptr.type)); - return NULL; - } - - self= PyTuple_New(2); - - PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna); - Py_INCREF(pyrna); - - PyTuple_SET_ITEM(self, 1, PyCapsule_New((void *)func, NULL, NULL)); - - ret= PyCFunction_New(&func_meth, self); - Py_DECREF(self); - - return ret; + BPy_FunctionRNA* pyfunc= (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); + pyfunc->ptr= *ptr; + pyfunc->func= func; + return (PyObject *)pyfunc; } - static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) { /* XXX hard limits should be checked here */ @@ -3001,7 +2988,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) } /* RNA function only if callback is declared (no optional functions) */ else if ((func= RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) { - ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self, func); + ret= pyrna_func_to_py(&self->ptr, func); } else if (self->ptr.type == &RNA_Context) { bContext *C= self->ptr.data; @@ -3303,7 +3290,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject } else if ((func= RNA_struct_find_function(&r_ptr, name))) { PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr); - ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func); + ret= pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); Py_DECREF(self_collection); return ret; @@ -4257,11 +4244,11 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat return ret; } -static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) +static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) { /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */ - PointerRNA *self_ptr= &(((BPy_DummyPointerRNA *)PyTuple_GET_ITEM(self, 0))->ptr); - FunctionRNA *self_func= PyCapsule_GetPointer(PyTuple_GET_ITEM(self, 1), NULL); + PointerRNA *self_ptr= &self->ptr; + FunctionRNA *self_func= self->func; PointerRNA funcptr; ParameterList parms; @@ -5045,6 +5032,91 @@ static PyTypeObject pyrna_prop_collection_idprop_Type= { NULL }; +/*-----------------------BPy_PropertyRNA method def------------------------------*/ +PyTypeObject pyrna_func_Type= { + PyVarObject_HEAD_INIT(NULL, 0) + "bpy_func", /* tp_name */ + sizeof(BPy_FunctionRNA), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + NULL, /* tp_dealloc */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */ + (reprfunc) pyrna_func_repr, /* tp_repr */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + (ternaryfunc)pyrna_func_call, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + + /* will only use these if this is a subtype of a py class */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ +#ifdef USE_WEAKREFS + offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */ +#else + 0, +#endif + + /*** Added in release 2.2 ***/ + /* Iterators */ + NULL, /* getiterfunc tp_iter; */ + NULL, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + NULL, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + #ifdef USE_PYRNA_ITER /* --- collection iterator: start --- */ /* wrap rna collection iterator functions */ @@ -5516,6 +5588,9 @@ void BPY_rna_init(void) if(PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0) return; + if(PyType_Ready(&pyrna_func_Type) < 0) + return; + #ifdef USE_PYRNA_ITER if(PyType_Ready(&pyrna_prop_collection_iter_Type) < 0) return; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 5db352af53d..3796984ea81 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -71,6 +71,7 @@ extern PyTypeObject pyrna_struct_Type; extern PyTypeObject pyrna_prop_Type; extern PyTypeObject pyrna_prop_array_Type; extern PyTypeObject pyrna_prop_collection_Type; +extern PyTypeObject pyrna_func_Type; #define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type)) #define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type) @@ -142,6 +143,15 @@ typedef struct { CollectionPropertyIterator iter; } BPy_PropertyCollectionIterRNA; +typedef struct { + PyObject_HEAD /* required python macro */ +#ifdef USE_WEAKREFS + PyObject *in_weakreflist; +#endif + PointerRNA ptr; + FunctionRNA *func; +} BPy_FunctionRNA; + /* cheap trick */ #define BPy_BaseTypeRNA BPy_PropertyRNA From 3a82a690abca993866c30f03696e8d2415455f64 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 16:29:38 +0000 Subject: [PATCH 27/41] ifdef out support for for python owning and freeing BPy_StructRNA because this is only used for doc generation and it makes _every_ blender/python instance 4 bytes bigger - vertex/bezier point/object/scene/group etc. --- source/blender/python/intern/bpy_operator.c | 2 ++ source/blender/python/intern/bpy_rna.c | 4 ++++ source/blender/python/intern/bpy_rna.h | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 4a17c45ae38..4b05a9c0c72 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -397,7 +397,9 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); +#ifdef PYRNA_FREE_SUPPORT pyrna->freeptr= TRUE; +#endif return (PyObject *)pyrna; } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d517205e2fe..4447a0476f4 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -957,11 +957,13 @@ static int pyrna_struct_clear(BPy_StructRNA *self) /* use our own dealloc so we can free a property if we use one */ static void pyrna_struct_dealloc(BPy_StructRNA *self) { +#ifdef PYRNA_FREE_SUPPORT if (self->freeptr && self->ptr.data) { IDP_FreeProperty(self->ptr.data); MEM_freeN(self->ptr.data); self->ptr.data= NULL; } +#endif /* PYRNA_FREE_SUPPORT */ #ifdef USE_WEAKREFS if (self->in_weakreflist != NULL) { @@ -5495,7 +5497,9 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) } pyrna->ptr= *ptr; +#ifdef PYRNA_FREE_SUPPORT pyrna->freeptr= FALSE; +#endif #ifdef USE_PYRNA_STRUCT_REFERENCE pyrna->reference= NULL; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 3796984ea81..30f6c02115a 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -62,6 +62,11 @@ #if defined(USE_PYRNA_INVALIDATE_GC) && defined(USE_PYRNA_INVALIDATE_WEAKREF) #error "Only 1 reference check method at a time!" #endif + +/* only used by operator introspection get_rna(), this is only used for doc gen + * so prefer the leak to the memory bloat for now. */ +// #define PYRNA_FREE_SUPPORT + /* --- end bpy build options --- */ struct ID; @@ -108,7 +113,10 @@ typedef struct { * hold onto the collection iterator to prevent it from freeing allocated data we may use */ PyObject *reference; #endif /* !USE_PYRNA_STRUCT_REFERENCE */ + +#ifdef PYRNA_FREE_SUPPORT int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ +#endif /* PYRNA_FREE_SUPPORT */ } BPy_StructRNA; typedef struct { From 4d319f8059fb66cd05ef42defc967f6bc7f93859 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Aug 2011 17:39:44 +0000 Subject: [PATCH 28/41] fix for GHOST/SDL key input with uppercase keys. --- intern/ghost/intern/GHOST_SystemSDL.cpp | 43 ++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index 2c61acc2d93..69a9f936cf6 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -180,6 +180,7 @@ convertSDLKey(SDL_Scancode key) GXMAP(type,SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl); GXMAP(type,SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt); GXMAP(type,SDL_SCANCODE_RALT, GHOST_kKeyRightAlt); + GXMAP(type,SDL_SCANCODE_LGUI, GHOST_kKeyOS); GXMAP(type,SDL_SCANCODE_RGUI, GHOST_kKeyOS); GXMAP(type,SDL_SCANCODE_INSERT, GHOST_kKeyInsert); @@ -228,6 +229,7 @@ convertSDLKey(SDL_Scancode key) GXMAP(type,SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast); default: + printf("Unknown\n"); type= GHOST_kKeyUnknown; break; } @@ -372,6 +374,7 @@ GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) case SDL_KEYUP: { SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key; + SDL_Keycode sym= sdl_sub_evt.keysym.sym; GHOST_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); @@ -379,7 +382,45 @@ GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) GHOST_TKey gkey= convertSDLKey(sdl_sub_evt.keysym.scancode); /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */ - g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sdl_sub_evt.keysym.sym); + if(sym > 127) { + sym= 0; + } + else { + if(sdl_sub_evt.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT)) { + /* lame US keyboard assumptions */ + if(sym >= 'a' && sym <= ('a' + 32)) { + sym -= 32; + } + else { + switch(sym) { + case '`': sym= '~'; break; + case '1': sym= '!'; break; + case '2': sym= '@'; break; + case '3': sym= '#'; break; + case '4': sym= '$'; break; + case '5': sym= '%'; break; + case '6': sym= '^'; break; + case '7': sym= '&'; break; + case '8': sym= '*'; break; + case '9': sym= '('; break; + case '0': sym= ')'; break; + case '-': sym= '_'; break; + case '=': sym= '+'; break; + case '[': sym= '{'; break; + case ']': sym= '}'; break; + case '\\': sym= '|'; break; + case ';': sym= ':'; break; + case '\'': sym= '"'; break; + case ',': sym= '<'; break; + case '.': sym= '>'; break; + case '/': sym= '?'; break; + default: break; + } + } + } + } + + g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym); } break; } From 7368298a45f96667a548e10cfe9d227fcf18e114 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 5 Aug 2011 19:55:36 +0000 Subject: [PATCH 29/41] Messed up char was causing problems on windows even though it was in the comments. Kent --- build_files/scons/config/darwin-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index 2df2e1ae956..560b6d9cb60 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -60,7 +60,7 @@ elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4': CC = 'gcc-4.0' CXX = 'g++-4.0' elif MAC_CUR_VER >= '10.6': - # OSX 10.6 and 10.7 developer tools don“t come with sdk < 10.6 anymore ! + # OSX 10.6 and 10.7 developer tools do not come with sdk < 10.6 anymore ! MAC_MIN_VERS = '10.6' MACOSX_DEPLOYMENT_TARGET = '10.6' MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk' From e6e4c7ef8bd53b06c879302bbfd3d6a00c6c48af Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 5 Aug 2011 20:45:26 +0000 Subject: [PATCH 30/41] KEYMAP REFACTORING Diff Keymaps User edited keymaps now no longer override the builtin keymaps entirely, but rather save only the difference and reapply those changes. This means they can stay better in sync when the builtin keymaps change. The diff/patch algorithm is not perfect, but better for the common case where only a few items are changed rather than entire keymaps The main weakness is that if a builtin keymap item changes, user modification of that item may need to be redone in some cases. Keymap Editor The most noticeable change here is that there is no longer an "Edit" button for keymaps, all are editable immediately, but a "Restore" buttons shows for keymaps and items that have been edited. Shortcuts for addons can also be edited in the keymap editor. Addons Addons now should only modify the new addon keyconfiguration, the keymap items there will be added to the builtin ones for handling events, and not get lost when starting new files. Example code of register/unregister: km = wm.keyconfigs.addon.keymaps.new("3D View", space_type="VIEW_3D") km.keymap_items.new('my.operator', 'ESC', 'PRESS') km = wm.keyconfigs.addon.keymaps["3D View"] km.keymap_items.remove(km.keymap_items["my.operator"]) Compatibility The changes made are not forward compatible, i.e. if you save user preferences with newer versions, older versions will not have key configuration changes that were made. --- .../startup/bl_ui/space_userpref_keymap.py | 53 +- source/blender/blenkernel/intern/blender.c | 33 +- source/blender/blenloader/intern/readfile.c | 40 +- source/blender/blenloader/intern/writefile.c | 24 +- .../editors/interface/interface_handlers.c | 25 +- source/blender/editors/interface/resources.c | 2 +- source/blender/makesdna/DNA_userdef_types.h | 3 +- .../makesdna/DNA_windowmanager_types.h | 24 +- source/blender/makesrna/intern/rna_internal.h | 3 + source/blender/makesrna/intern/rna_scene.c | 2 +- source/blender/makesrna/intern/rna_userdef.c | 6 - source/blender/makesrna/intern/rna_wm.c | 247 ++---- source/blender/makesrna/intern/rna_wm_api.c | 183 ++++- source/blender/windowmanager/WM_api.h | 44 +- source/blender/windowmanager/WM_keymap.h | 104 +++ source/blender/windowmanager/intern/wm.c | 10 +- .../windowmanager/intern/wm_event_system.c | 6 + .../blender/windowmanager/intern/wm_files.c | 13 +- .../blender/windowmanager/intern/wm_keymap.c | 734 +++++++++++++----- .../bad_level_call_stubs/stubs.c | 2 + 20 files changed, 1051 insertions(+), 507 deletions(-) create mode 100644 source/blender/windowmanager/WM_keymap.h diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index 585c3cffcb9..5658cc96281 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -188,10 +188,10 @@ class InputKeyMapPanel: if km.is_modal: row.label(text="", icon='LINKED') - if km.is_user_defined: + if km.is_user_modified: row.operator("wm.keymap_restore", text="Restore") else: - row.operator("wm.keymap_edit", text="Edit") + row.label() if km.show_expanded_children: if children: @@ -212,7 +212,6 @@ class InputKeyMapPanel: # "Add New" at end of keymap item list col = self.indented_layout(col, level + 1) subcol = col.split(percentage=0.2).column() - subcol.enabled = km.is_user_defined subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN') col.separator() @@ -243,7 +242,7 @@ class InputKeyMapPanel: col = self.indented_layout(layout, level) - if km.is_user_defined: + if kmi.show_expanded: col = col.column(align=True) box = col.box() else: @@ -256,7 +255,6 @@ class InputKeyMapPanel: row.prop(kmi, "show_expanded", text="", emboss=False) row = split.row() - row.enabled = km.is_user_defined row.prop(kmi, "active", text="", emboss=False) if km.is_modal: @@ -265,7 +263,6 @@ class InputKeyMapPanel: row.label(text=kmi.name) row = split.row() - row.enabled = km.is_user_defined row.prop(kmi, "map_type", text="") if map_type == 'KEYBOARD': row.prop(kmi, "type", text="", full_event=True) @@ -282,18 +279,17 @@ class InputKeyMapPanel: else: row.label() - if not kmi.is_user_defined: + if (not kmi.is_user_defined) and kmi.is_user_modified: op = row.operator("wm.keyitem_restore", text="", icon='BACK') op.item_id = kmi.id - op = row.operator("wm.keyitem_remove", text="", icon='X') - op.item_id = kmi.id + else: + op = row.operator("wm.keyitem_remove", text="", icon='X') + op.item_id = kmi.id # Expanded, additional event settings if kmi.show_expanded: box = col.box() - box.enabled = km.is_user_defined - if map_type not in {'TEXTINPUT', 'TIMER'}: split = box.split(percentage=0.4) sub = split.row() @@ -352,10 +348,10 @@ class InputKeyMapPanel: row.label() row.label() - if km.is_user_defined: + if km.is_user_modified: row.operator("wm.keymap_restore", text="Restore") else: - row.operator("wm.keymap_edit", text="Edit") + row.label() for kmi in filtered_items: self.draw_kmi(display_keymaps, kc, km, kmi, col, 1) @@ -363,7 +359,6 @@ class InputKeyMapPanel: # "Add New" at end of keymap item list col = self.indented_layout(layout, 1) subcol = col.split(percentage=0.2).column() - subcol.enabled = km.is_user_defined subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN') def draw_hierarchy(self, display_keymaps, layout): @@ -372,8 +367,7 @@ class InputKeyMapPanel: def draw_keymaps(self, context, layout): wm = context.window_manager - kc = wm.keyconfigs.active - defkc = wm.keyconfigs.default + kc = wm.keyconfigs.user col = layout.column() sub = col.column() @@ -398,7 +392,7 @@ class InputKeyMapPanel: col.separator() - display_keymaps = _merge_keymaps(kc, defkc) + display_keymaps = _merge_keymaps(kc, kc) if context.space_data.filter_text != "": filter_text = context.space_data.filter_text.lower() self.draw_filtered(display_keymaps, filter_text, col) @@ -609,7 +603,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator): # Generate a list of keymaps to export: # - # First add all user_defined keymaps (found in inputs.edited_keymaps list), + # First add all user_modified keymaps (found in keyconfigs.user.keymaps list), # then add all remaining keymaps from the currently active custom keyconfig. # # This will create a final list of keymaps that can be used as a 'diff' against @@ -619,7 +613,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator): class FakeKeyConfig(): keymaps = [] edited_kc = FakeKeyConfig() - edited_kc.keymaps.extend(context.user_preferences.inputs.edited_keymaps) + for km in wm.keyconfigs.user.keymaps: + if km.is_user_modified: + edited_kc.keymaps.append(km) # merge edited keymaps with non-default keyconfig, if it exists if kc != wm.keyconfigs.default: export_keymaps = _merge_keymaps(edited_kc, kc) @@ -669,17 +665,6 @@ class WM_OT_keyconfig_export(bpy.types.Operator): return {'RUNNING_MODAL'} -class WM_OT_keymap_edit(bpy.types.Operator): - "Edit stored key map" - bl_idname = "wm.keymap_edit" - bl_label = "Edit Key Map" - - def execute(self, context): - km = context.keymap - km.copy_to_user() - return {'FINISHED'} - - class WM_OT_keymap_restore(bpy.types.Operator): "Restore key map(s)" bl_idname = "wm.keymap_restore" @@ -691,7 +676,7 @@ class WM_OT_keymap_restore(bpy.types.Operator): wm = context.window_manager if self.all: - for km in wm.keyconfigs.default.keymaps: + for km in wm.keyconfigs.user.keymaps: km.restore_to_default() else: km = context.keymap @@ -710,13 +695,13 @@ class WM_OT_keyitem_restore(bpy.types.Operator): @classmethod def poll(cls, context): keymap = getattr(context, "keymap", None) - return keymap and keymap.is_user_defined + return keymap def execute(self, context): km = context.keymap kmi = km.keymap_items.from_id(self.item_id) - if not kmi.is_user_defined: + if (not kmi.is_user_defined) and kmi.is_user_modified: km.restore_item_to_default(kmi) return {'FINISHED'} @@ -753,7 +738,7 @@ class WM_OT_keyitem_remove(bpy.types.Operator): @classmethod def poll(cls, context): - return hasattr(context, "keymap") and context.keymap.is_user_defined + return hasattr(context, "keymap") def execute(self, context): km = context.keymap diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 8b4bbbd3c83..7e2097d1233 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -330,28 +330,45 @@ static int handle_subversion_warning(Main *main) return 1; } +static void keymap_item_free(wmKeyMapItem *kmi) +{ + if(kmi->properties) { + IDP_FreeProperty(kmi->properties); + MEM_freeN(kmi->properties); + } + if(kmi->ptr) + MEM_freeN(kmi->ptr); +} + void BKE_userdef_free(void) { wmKeyMap *km; wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; - for(km=U.keymaps.first; km; km=km->next) { - for(kmi=km->items.first; kmi; kmi=kmi->next) { - if(kmi->properties) { - IDP_FreeProperty(kmi->properties); - MEM_freeN(kmi->properties); + for(km=U.user_keymaps.first; km; km=km->next) { + for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) { + if(kmdi->add_item) { + keymap_item_free(kmdi->add_item); + MEM_freeN(kmdi->add_item); + } + if(kmdi->remove_item) { + keymap_item_free(kmdi->remove_item); + MEM_freeN(kmdi->remove_item); } - if(kmi->ptr) - MEM_freeN(kmi->ptr); } + for(kmi=km->items.first; kmi; kmi=kmi->next) + keymap_item_free(kmi); + + BLI_freelistN(&km->diff_items); BLI_freelistN(&km->items); } BLI_freelistN(&U.uistyles); BLI_freelistN(&U.uifonts); BLI_freelistN(&U.themes); - BLI_freelistN(&U.keymaps); + BLI_freelistN(&U.user_keymaps); BLI_freelistN(&U.addons); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 44c8ca97be9..bd12677485c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4726,6 +4726,8 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) wm->keyconfigs.first= wm->keyconfigs.last= NULL; wm->defaultconf= NULL; + wm->addonconf= NULL; + wm->userconf= NULL; wm->jobs.first= wm->jobs.last= NULL; wm->drags.first= wm->drags.last= NULL; @@ -11762,33 +11764,57 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_library(fd, main); /* only init users */ } +static void direct_link_keymapitem(FileData *fd, wmKeyMapItem *kmi) +{ + kmi->properties= newdataadr(fd, kmi->properties); + if(kmi->properties) + IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + kmi->ptr= NULL; + kmi->flag &= ~KMI_UPDATE; +} static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) { UserDef *user; wmKeyMap *keymap; wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; bfd->user= user= read_struct(fd, bhead, "user def"); /* read all data into fd->datamap */ bhead= read_data_into_oldnewmap(fd, bhead, "user def"); + if(user->keymaps.first) { + /* backwards compatibility */ + user->user_keymaps= user->keymaps; + user->keymaps.first= user->keymaps.last= NULL; + } + link_list(fd, &user->themes); - link_list(fd, &user->keymaps); + link_list(fd, &user->user_keymaps); link_list(fd, &user->addons); - for(keymap=user->keymaps.first; keymap; keymap=keymap->next) { + for(keymap=user->user_keymaps.first; keymap; keymap=keymap->next) { keymap->modal_items= NULL; keymap->poll= NULL; + keymap->flag &= ~KEYMAP_UPDATE; + link_list(fd, &keymap->diff_items); link_list(fd, &keymap->items); - for(kmi=keymap->items.first; kmi; kmi=kmi->next) { - kmi->properties= newdataadr(fd, kmi->properties); - if(kmi->properties) - IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); - kmi->ptr= NULL; + + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) { + kmdi->remove_item= newdataadr(fd, kmdi->remove_item); + kmdi->add_item= newdataadr(fd, kmdi->add_item); + + if(kmdi->remove_item) + direct_link_keymapitem(fd, kmdi->remove_item); + if(kmdi->add_item) + direct_link_keymapitem(fd, kmdi->add_item); } + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) + direct_link_keymapitem(fd, kmi); } // XXX diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index bf86527b9d3..7d65248c0e9 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -717,11 +717,19 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon } } +static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi) +{ + writestruct(wd, DATA, "wmKeyMapItem", 1, kmi); + if(kmi->properties) + IDP_WriteProperty(kmi->properties, wd); +} + static void write_userdef(WriteData *wd) { bTheme *btheme; wmKeyMap *keymap; wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; bAddon *bext; uiStyle *style; @@ -730,15 +738,19 @@ static void write_userdef(WriteData *wd) for(btheme= U.themes.first; btheme; btheme=btheme->next) writestruct(wd, DATA, "bTheme", 1, btheme); - for(keymap= U.keymaps.first; keymap; keymap=keymap->next) { + for(keymap= U.user_keymaps.first; keymap; keymap=keymap->next) { writestruct(wd, DATA, "wmKeyMap", 1, keymap); - for(kmi=keymap->items.first; kmi; kmi=kmi->next) { - writestruct(wd, DATA, "wmKeyMapItem", 1, kmi); - - if(kmi->properties) - IDP_WriteProperty(kmi->properties, wd); + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) { + writestruct(wd, DATA, "wmKeyMapDiffItem", 1, kmdi); + if(kmdi->remove_item) + write_keymapitem(wd, kmdi->remove_item); + if(kmdi->add_item) + write_keymapitem(wd, kmdi->add_item); } + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) + write_keymapitem(wd, kmi); } for(bext= U.addons.first; bext; bext=bext->next) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b3272a2e3d4..d8d8354b0b9 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4067,7 +4067,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) /* complex code to change name of button */ if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) { - wmKeyMap *km= NULL; char *butstr_orig; // XXX but->str changed... should not, remove the hotkey from it @@ -4080,10 +4079,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) but->str= but->strdata; ui_check_but(but); - - /* set the keymap editable else the key wont save */ - WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km); - WM_keymap_copy_to_user(km); } else { /* shortcut was removed */ @@ -4095,6 +4090,7 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) { + wmWindowManager *wm= CTX_wm_manager(C); uiBlock *block; uiBut *but = (uiBut *)arg; wmKeyMap *km; @@ -4107,7 +4103,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) kmi = WM_keymap_item_find_id(km, kmi_id); - RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr); + RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); uiBlockSetHandleFunc(block, but_shortcut_name_func, but); @@ -4126,6 +4122,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) { + wmWindowManager *wm= CTX_wm_manager(C); uiBlock *block; uiBut *but = (uiBut *)arg; wmKeyMap *km; @@ -4134,19 +4131,25 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) uiLayout *layout; uiStyle *style= U.uistyles.first; IDProperty *prop= (but->opptr)? but->opptr->data: NULL; + int kmi_id; /* XXX this guess_opname can potentially return a different keymap than being found on adding later... */ km = WM_keymap_guess_opname(C, but->optype->idname); kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0); + kmi_id = kmi->id; - if (prop) { + /* copy properties, prop can be NULL for reset */ + if(prop) prop= IDP_CopyProperty(prop); - } - - /* prop can be NULL */ WM_keymap_properties_reset(kmi, prop); - RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr); + /* update and get pointers again */ + WM_keyconfig_update(wm); + + km = WM_keymap_guess_opname(C, but->optype->idname); + kmi = WM_keymap_item_find_id(km, kmi_id); + + RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); uiBlockSetHandleFunc(block, but_shortcut_name_func, but); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 32e87b3a793..f3db6ad11ae 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1425,7 +1425,7 @@ void init_userdef_do_versions(void) if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 8)) { wmKeyMap *km; - for(km=U.keymaps.first; km; km=km->next) { + for(km=U.user_keymaps.first; km; km=km->next) { if (strcmp(km->idname, "Armature_Sketch")==0) strcpy(km->idname, "Armature Sketch"); else if (strcmp(km->idname, "View3D")==0) diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index aa6da3aaeca..a555a196060 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -341,7 +341,8 @@ typedef struct UserDef { struct ListBase themes; struct ListBase uifonts; struct ListBase uistyles; - struct ListBase keymaps; + struct ListBase keymaps; /* deprecated in favor of user_keymaps */ + struct ListBase user_keymaps; struct ListBase addons; char keyconfigstr[64]; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 31e59f18626..1f0ae28a00d 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -144,7 +144,9 @@ typedef struct wmWindowManager { ListBase drags; /* active dragged items */ ListBase keyconfigs; /* known key configurations */ - struct wmKeyConfig *defaultconf; /* default configuration, not saved */ + struct wmKeyConfig *defaultconf; /* default configuration */ + struct wmKeyConfig *addonconf; /* addon configuration */ + struct wmKeyConfig *userconf; /* user configuration */ ListBase timers; /* active timers */ struct wmTimer *autosavetimer; /* timer for auto save */ @@ -239,15 +241,26 @@ typedef struct wmKeyMapItem { struct PointerRNA *ptr; /* rna pointer to access properties */ } wmKeyMapItem; +/* used instead of wmKeyMapItem for diff keymaps */ +typedef struct wmKeyMapDiffItem { + struct wmKeyMapDiffItem *next, *prev; + + wmKeyMapItem *remove_item; + wmKeyMapItem *add_item; +} wmKeyMapDiffItem; + /* wmKeyMapItem.flag */ -#define KMI_INACTIVE 1 -#define KMI_EXPANDED 2 +#define KMI_INACTIVE 1 +#define KMI_EXPANDED 2 +#define KMI_USER_MODIFIED 4 +#define KMI_UPDATE 8 /* stored in WM, the actively used keymaps */ typedef struct wmKeyMap { struct wmKeyMap *next, *prev; ListBase items; + ListBase diff_items; char idname[64]; /* global editor keymaps, or for more per space/region */ short spaceid; /* same IDs as in DNA_space_types.h */ @@ -263,9 +276,12 @@ typedef struct wmKeyMap { /* wmKeyMap.flag */ #define KEYMAP_MODAL 1 /* modal map, not using operatornames */ -#define KEYMAP_USER 2 /* user created keymap */ +#define KEYMAP_USER 2 /* user keymap */ #define KEYMAP_EXPANDED 4 #define KEYMAP_CHILDREN_EXPANDED 8 +#define KEYMAP_DIFF 16 /* diff keymap for user preferences */ +#define KEYMAP_USER_MODIFIED 32 /* keymap has user modifications */ +#define KEYMAP_UPDATE 64 typedef struct wmKeyConfig { struct wmKeyConfig *next, *prev; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 9175806e2bb..c0ae7b02b1a 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -238,9 +238,12 @@ void RNA_api_image(struct StructRNA *srna); void RNA_api_operator(struct StructRNA *srna); void RNA_api_macro(struct StructRNA *srna); void RNA_api_keyconfig(struct StructRNA *srna); +void RNA_api_keyconfigs(struct StructRNA *srna); void RNA_api_keyingset(struct StructRNA *srna); void RNA_api_keymap(struct StructRNA *srna); +void RNA_api_keymaps(struct StructRNA *srna); void RNA_api_keymapitem(struct StructRNA *srna); +void RNA_api_keymapitems(struct StructRNA *srna); void RNA_api_area(struct StructRNA *srna); void RNA_api_main(struct StructRNA *srna); void RNA_api_material(StructRNA *srna); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b3d8bc8ea18..29cfc695911 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1409,7 +1409,7 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) prop= RNA_def_property(srna, "layers_zmask", PROP_BOOLEAN, PROP_LAYER); RNA_def_property_boolean_sdna(prop, NULL, "lay_zmask", 1); RNA_def_property_array(prop, 20); - RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers"); + RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers for solid faces"); if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index a1a99c34e70..b3dbafeab7d 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2795,12 +2795,6 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_range(prop, 0, 32); RNA_def_property_ui_text(prop, "Wheel Scroll Lines", "The number of lines scrolled at a time with the mouse wheel"); - /* U.keymaps - custom keymaps that have been edited from default configs */ - prop= RNA_def_property(srna, "edited_keymaps", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "keymaps", NULL); - RNA_def_property_struct_type(prop, "KeyMap"); - RNA_def_property_ui_text(prop, "Edited Keymaps", ""); - prop= RNA_def_property(srna, "active_keyconfig", PROP_STRING, PROP_DIRPATH); RNA_def_property_string_sdna(prop, NULL, "keyconfigstr"); RNA_def_property_ui_text(prop, "Key Config", "The name of the active key configuration"); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index a046be59ab5..307cf0e175a 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -578,22 +578,6 @@ static EnumPropertyItem *rna_KeyMapItem_propvalue_itemf(bContext *C, PointerRNA wmKeyConfig *kc; wmKeyMap *km; - /* check user keymaps */ - for(km=U.keymaps.first; km; km=km->next) { - wmKeyMapItem *kmi; - for (kmi=km->items.first; kmi; kmi=kmi->next) { - if (kmi == ptr->data) { - if (!km->modal_items) { - if (!WM_keymap_user_init(wm, km)) { - return keymap_propvalue_items; /* ERROR */ - } - } - - return km->modal_items; - } - } - } - for(kc=wm->keyconfigs.first; kc; kc=kc->next) { for(km=kc->keymaps.first; km; km=km->next) { /* only check if it's a modal keymap */ @@ -654,12 +638,13 @@ static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_KeyConfig, kc); } -static void rna_WindowManager_active_keyconfig_set(PointerRNA *UNUSED(ptr), PointerRNA value) +static void rna_WindowManager_active_keyconfig_set(PointerRNA *ptr, PointerRNA value) { + wmWindowManager *wm= ptr->data; wmKeyConfig *kc= value.data; if(kc) - BLI_strncpy(U.keyconfigstr, kc->idname, sizeof(U.keyconfigstr)); + WM_keyconfig_set_active(wm, kc->idname); } static void rna_wmKeyMapItem_idname_get(PointerRNA *ptr, char *value) @@ -1130,93 +1115,6 @@ static StructRNA* rna_MacroOperator_refine(PointerRNA *opr) return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Macro; } -static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) -{ -// wmWindowManager *wm = CTX_wm_manager(C); - char idname_bl[OP_MAX_TYPENAME]; - int modifier= 0; - - /* only on non-modal maps */ - if (km->flag & KEYMAP_MODAL) { - BKE_report(reports, RPT_ERROR, "Not a non-modal keymap."); - return NULL; - } - - WM_operator_bl_idname(idname_bl, idname); - - if(shift) modifier |= KM_SHIFT; - if(ctrl) modifier |= KM_CTRL; - if(alt) modifier |= KM_ALT; - if(oskey) modifier |= KM_OSKEY; - - if(any) modifier = KM_ANY; - - return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier); -} - -static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, bContext *C, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) -{ - wmWindowManager *wm = CTX_wm_manager(C); - int modifier= 0; - int propvalue = 0; - - /* only modal maps */ - if ((km->flag & KEYMAP_MODAL) == 0) { - BKE_report(reports, RPT_ERROR, "Not a modal keymap."); - return NULL; - } - - if (!km->modal_items) { - if(!WM_keymap_user_init(wm, km)) { - BKE_report(reports, RPT_ERROR, "User defined keymap doesn't correspond to a system keymap."); - return NULL; - } - } - - if (!km->modal_items) { - BKE_report(reports, RPT_ERROR, "No property values defined."); - return NULL; - } - - - if(RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue)==0) { - BKE_report(reports, RPT_WARNING, "Property value not in enumeration."); - } - - if(shift) modifier |= KM_SHIFT; - if(ctrl) modifier |= KM_CTRL; - if(alt) modifier |= KM_ALT; - if(oskey) modifier |= KM_OSKEY; - - if(any) modifier = KM_ANY; - - return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue); -} - -static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal) -{ - if (modal == 0) { - return WM_keymap_find(keyconf, idname, spaceid, regionid); - } else { - return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */ - } -} - -static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid) -{ - return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); -} - -static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname) -{ - wmOperatorType *ot = WM_operatortype_find(idname, 0); - - if (!ot) - return NULL; - else - return ot->modalkeymap; -} - /* just to work around 'const char *' warning and to ensure this is a python op */ static void rna_Operator_bl_idname_set(PointerRNA *ptr, const char *value) { @@ -1242,6 +1140,12 @@ static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value) else assert(!"setting the bl_description on a non-builtin operator"); } +static void rna_KeyMapItem_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + wmKeyMapItem *kmi= ptr->data; + WM_keyconfig_update_tag(NULL, kmi); +} + #else /* RNA_RUNTIME */ static void rna_def_operator(BlenderRNA *brna) @@ -1566,9 +1470,6 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; PropertyRNA *prop; - FunctionRNA *func; - PropertyRNA *parm; - RNA_def_property_srna(cprop, "KeyConfigurations"); srna= RNA_def_struct(brna, "KeyConfigurations", NULL); RNA_def_struct_sdna(srna, "wmWindowManager"); @@ -1578,23 +1479,24 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_struct_type(prop, "KeyConfig"); RNA_def_property_pointer_funcs(prop, "rna_WindowManager_active_keyconfig_get", "rna_WindowManager_active_keyconfig_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Active KeyConfig", "Active wm KeyConfig"); + RNA_def_property_ui_text(prop, "Active KeyConfig", "Active key configuration (preset)"); prop= RNA_def_property(srna, "default", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "defaultconf"); RNA_def_property_struct_type(prop, "KeyConfig"); - RNA_def_property_ui_text(prop, "Default Key Configuration", ""); - - /* funcs */ - func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig - parm= RNA_def_string(func, "name", "", 0, "Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration."); - RNA_def_function_return(func, parm); + RNA_def_property_ui_text(prop, "Default Key Configuration", "Default builtin key configuration"); - func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig - parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration."); - RNA_def_property_flag(parm, PROP_REQUIRED); + prop= RNA_def_property(srna, "addon", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "addonconf"); + RNA_def_property_struct_type(prop, "KeyConfig"); + RNA_def_property_ui_text(prop, "Addon Key Configuration", "Key configuration that can be extended by addons, and is added to the active configuration when handling events"); + + prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "userconf"); + RNA_def_property_struct_type(prop, "KeyConfig"); + RNA_def_property_ui_text(prop, "User Key Configuration", "Final key configuration that combines keymaps from the active and addon configurations, and can be edited by the user"); + + RNA_api_keyconfigs(srna); } static void rna_def_windowmanager(BlenderRNA *brna) @@ -1631,107 +1533,30 @@ static void rna_def_windowmanager(BlenderRNA *brna) static void rna_def_keymap_items(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; -// PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; RNA_def_property_srna(cprop, "KeyMapItems"); srna= RNA_def_struct(brna, "KeyMapItems", NULL); RNA_def_struct_sdna(srna, "wmKeyMap"); RNA_def_struct_ui_text(srna, "KeyMap Items", "Collection of keymap items"); - func= RNA_def_function(srna, "new", "rna_KeyMap_item_new"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "any", 0, "Any", ""); - RNA_def_boolean(func, "shift", 0, "Shift", ""); - RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); - RNA_def_boolean(func, "alt", 0, "Alt", ""); - RNA_def_boolean(func, "oskey", 0, "OS Key", ""); - RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "any", 0, "Any", ""); - RNA_def_boolean(func, "shift", 0, "Shift", ""); - RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); - RNA_def_boolean(func, "alt", 0, "Alt", ""); - RNA_def_boolean(func, "oskey", 0, "OS Key", ""); - RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "remove", "WM_keymap_remove_item"); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id"); - parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_property_ui_text(parm, "id", "ID of the item"); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); - RNA_def_function_return(func, parm); - + RNA_api_keymapitems(srna); } static void rna_def_wm_keymaps(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; - //PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; - RNA_def_property_srna(cprop, "KeyMaps"); srna= RNA_def_struct(brna, "KeyMaps", NULL); RNA_def_struct_sdna(srna, "wmKeyConfig"); RNA_def_struct_ui_text(srna, "Key Maps", "Collection of keymaps"); - func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap - parm= RNA_def_string(func, "name", "", 0, "Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); - RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); - RNA_def_boolean(func, "modal", 0, "Modal", ""); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap - parm= RNA_def_string(func, "name", "", 0, "Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); - RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal - parm= RNA_def_string(func, "name", "", 0, "Operator Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); - RNA_def_function_return(func, parm); - + RNA_api_keymaps(srna); } static void rna_def_keyconfig(BlenderRNA *brna) { StructRNA *srna; - // FunctionRNA *func; - // PropertyRNA *parm; PropertyRNA *prop; static EnumPropertyItem map_type_items[] = { @@ -1794,8 +1619,8 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Items", "Items in the keymap, linking an operator to an input event"); rna_def_keymap_items(brna, prop); - prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NEVER_NULL); - RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER); + prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NEVER_NULL); + RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER_MODIFIED); RNA_def_property_ui_text(prop, "User Defined", "Keymap is defined by the user"); prop= RNA_def_property(srna, "is_modal", PROP_BOOLEAN, PROP_NONE); @@ -1826,6 +1651,7 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Identifier", "Identifier of operator to call on input event"); RNA_def_property_string_funcs(prop, "rna_wmKeyMapItem_idname_get", "rna_wmKeyMapItem_idname_length", "rna_wmKeyMapItem_idname_set"); RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -1836,62 +1662,73 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_struct_type(prop, "OperatorProperties"); RNA_def_property_pointer_funcs(prop, "rna_KeyMapItem_properties_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Properties", "Properties to set when the operator is called"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "map_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "maptype"); RNA_def_property_enum_items(prop, map_type_items); RNA_def_property_enum_funcs(prop, "rna_wmKeyMapItem_map_type_get", "rna_wmKeyMapItem_map_type_set", NULL); RNA_def_property_ui_text(prop, "Map Type", "Type of event mapping"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, event_type_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_type_itemf"); RNA_def_property_ui_text(prop, "Type", "Type of event"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "val"); RNA_def_property_enum_items(prop, event_value_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_value_itemf"); RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "id", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "id"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "id", "ID of the item"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "any", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_any_getf", "rna_KeyMapItem_any_setf"); RNA_def_property_ui_text(prop, "Any", "Any modifier keys pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shift", 0); // RNA_def_property_enum_sdna(prop, NULL, "shift"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Shift", "Shift key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 0); // RNA_def_property_enum_sdna(prop, NULL, "ctrl"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Ctrl", "Control key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "alt", 0); // RNA_def_property_enum_sdna(prop, NULL, "alt"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Alt", "Alt key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "oskey", 0); // RNA_def_property_enum_sdna(prop, NULL, "oskey"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "keymodifier"); RNA_def_property_enum_items(prop, event_type_items); RNA_def_property_ui_text(prop, "Key Modifier", "Regular key pressed as a modifier"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_EXPANDED); @@ -1903,15 +1740,21 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_enum_items(prop, keymap_propvalue_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_propvalue_itemf"); RNA_def_property_ui_text(prop, "Property Value", "The value this event translates to in a modal keymap"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", KMI_INACTIVE); RNA_def_property_ui_text(prop, "Active", "Activate or deactivate item"); RNA_def_property_ui_icon(prop, ICON_CHECKBOX_DEHLT, 1); + prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_USER_MODIFIED); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "User Modified", "Is this keymap item modified by the user"); + prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just override a builtin item)"); + RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just replace a builtin item)"); RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_userdefined_get", NULL); RNA_api_keymapitem(srna); diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index d44b68950f7..89e946f498a 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -84,6 +84,85 @@ void rna_event_timer_remove(struct wmWindowManager *wm, wmTimer *timer) WM_event_remove_timer(wm, timer->win, timer); } +static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) +{ +// wmWindowManager *wm = CTX_wm_manager(C); + char idname_bl[OP_MAX_TYPENAME]; + int modifier= 0; + + /* only on non-modal maps */ + if (km->flag & KEYMAP_MODAL) { + BKE_report(reports, RPT_ERROR, "Not a non-modal keymap."); + return NULL; + } + + WM_operator_bl_idname(idname_bl, idname); + + if(shift) modifier |= KM_SHIFT; + if(ctrl) modifier |= KM_CTRL; + if(alt) modifier |= KM_ALT; + if(oskey) modifier |= KM_OSKEY; + + if(any) modifier = KM_ANY; + + return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier); +} + +static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) +{ + int modifier= 0; + int propvalue = 0; + + /* only modal maps */ + if ((km->flag & KEYMAP_MODAL) == 0) { + BKE_report(reports, RPT_ERROR, "Not a modal keymap."); + return NULL; + } + + if (!km->modal_items) { + BKE_report(reports, RPT_ERROR, "No property values defined."); + return NULL; + } + + + if(RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue)==0) { + BKE_report(reports, RPT_WARNING, "Property value not in enumeration."); + } + + if(shift) modifier |= KM_SHIFT; + if(ctrl) modifier |= KM_CTRL; + if(alt) modifier |= KM_ALT; + if(oskey) modifier |= KM_OSKEY; + + if(any) modifier = KM_ANY; + + return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue); +} + +static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal) +{ + if (modal == 0) { + return WM_keymap_find(keyconf, idname, spaceid, regionid); + } else { + return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */ + } +} + +static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid) +{ + return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); +} + +static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname) +{ + wmOperatorType *ot = WM_operatortype_find(idname, 0); + + if (!ot) + return NULL; + else + return ot->modalkeymap; +} + #else #define WM_GEN_INVOKE_EVENT (1<<0) @@ -301,11 +380,8 @@ void RNA_api_keymap(StructRNA *srna) parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Active key map."); RNA_def_function_return(func, parm); - func= RNA_def_function(srna, "copy_to_user", "WM_keymap_copy_to_user"); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "User editable key map."); - RNA_def_function_return(func, parm); - - RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default"); + func= RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); func= RNA_def_function(srna, "restore_item_to_default", "rna_keymap_restore_item_to_default"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); @@ -324,5 +400,102 @@ void RNA_api_keymapitem(StructRNA *srna) parm= RNA_def_boolean(func, "result", 0, "Comparison result", ""); RNA_def_function_return(func, parm); } + +void RNA_api_keymapitems(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "new", "rna_KeyMap_item_new"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_boolean(func, "any", 0, "Any", ""); + RNA_def_boolean(func, "shift", 0, "Shift", ""); + RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); + RNA_def_boolean(func, "alt", 0, "Alt", ""); + RNA_def_boolean(func, "oskey", 0, "OS Key", ""); + RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_boolean(func, "any", 0, "Any", ""); + RNA_def_boolean(func, "shift", 0, "Shift", ""); + RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); + RNA_def_boolean(func, "alt", 0, "Alt", ""); + RNA_def_boolean(func, "oskey", 0, "OS Key", ""); + RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "remove", "WM_keymap_remove_item"); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id"); + parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_ui_text(parm, "id", "ID of the item"); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); + RNA_def_function_return(func, parm); +} + +void RNA_api_keymaps(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); + RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); + RNA_def_boolean(func, "modal", 0, "Modal", ""); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); + RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal + parm= RNA_def_string(func, "name", "", 0, "Operator Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); + RNA_def_function_return(func, parm); +} + +void RNA_api_keyconfigs(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig + parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration."); + RNA_def_property_flag(parm, PROP_REQUIRED); +} + #endif diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index e6325e2101a..42c3096dfc9 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -41,6 +41,7 @@ /* dna-savable wmStructs here */ #include "DNA_windowmanager_types.h" +#include "WM_keymap.h" #ifdef __cplusplus extern "C" { @@ -114,50 +115,9 @@ void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle); void WM_cursor_warp (struct wmWindow *win, int x, int y); - /* keyconfig and keymap */ -wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname); -wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname); -void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf); -void WM_keyconfig_free (struct wmKeyConfig *keyconf); -void WM_keyconfig_userdef(void); - -void WM_keymap_init (struct bContext *C); -void WM_keymap_free (struct wmKeyMap *keymap); - -wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type, - int val, int modifier, int keymodifier); -wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type, - int val, int modifier, int keymodifier); -wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type, - int val, int modifier, int keymodifier); - -void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); -char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); - -wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid); -wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid); -wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid); -wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap); -wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname); -int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap); -wmKeyMap *WM_keymap_copy_to_user(struct wmKeyMap *keymap); -void WM_keymap_restore_to_default(struct wmKeyMap *keymap); -void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties); -void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); - -wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id); -int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2); + /* event map */ int WM_userdef_event_map(int kmitype); -wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items); -wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname); -wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); -void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname); - -const char *WM_key_event_string(short type); -int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r); -char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); - /* handlers */ struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap); diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h new file mode 100644 index 00000000000..e00cd288c9a --- /dev/null +++ b/source/blender/windowmanager/WM_keymap.h @@ -0,0 +1,104 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef WM_KEYMAP_H +#define WM_KEYMAP_H + +/** \file WM_keymap.h + * \ingroup wm + */ + +/* dna-savable wmStructs here */ +#include "DNA_windowmanager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct EnumPropertyItem; + +/* Key Configuration */ + +wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname); +wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname); +void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf); +void WM_keyconfig_free (struct wmKeyConfig *keyconf); + +void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname); + +void WM_keyconfig_update(struct wmWindowManager *wm); +void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); + +/* Keymap */ + +void WM_keymap_init (struct bContext *C); +void WM_keymap_free (struct wmKeyMap *keymap); + +wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type, + int val, int modifier, int keymodifier); +wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type, + int val, int modifier, int keymodifier); +wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type, + int val, int modifier, int keymodifier); + +void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); +char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); + +wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid); +wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid); +wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid); +wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap); +wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname); + +wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id); +int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2); + +/* Modal Keymap */ + +wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items); +wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname); +wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); +void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname); + +/* Keymap Editor */ + +void WM_keymap_restore_to_default(struct wmKeyMap *keymap, struct bContext *C); +void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties); +void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); + +/* Key Event */ + +const char *WM_key_event_string(short type); +int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r); +char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); + +#ifdef __cplusplus +} +#endif + +#endif /* WM_KEYMAP_H */ + diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index a535c0bc1f8..1d5cf1cdc53 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -210,12 +210,18 @@ void WM_keymap_init(bContext *C) if(!wm->defaultconf) wm->defaultconf= WM_keyconfig_new(wm, "Blender"); + if(!wm->addonconf) + wm->addonconf= WM_keyconfig_new(wm, "Blender Addon"); + if(!wm->userconf) + wm->userconf= WM_keyconfig_new(wm, "Blender User"); - if(wm && CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) { + if(CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) { /* create default key config */ wm_window_keymap(wm->defaultconf); ED_spacetypes_keymap(wm->defaultconf); - WM_keyconfig_userdef(); + + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); wm->initialized |= WM_INIT_KEYMAP; } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2f0c1a72be9..0dac0bd7401 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1735,6 +1735,9 @@ void wm_event_do_handlers(bContext *C) wmWindowManager *wm= CTX_wm_manager(C); wmWindow *win; + /* update key configuration before handling events */ + WM_keyconfig_update(wm); + for(win= wm->windows.first; win; win= win->next) { wmEvent *event; @@ -1938,6 +1941,9 @@ void wm_event_do_handlers(bContext *C) CTX_wm_window_set(C, NULL); } + + /* update key configuration after handling events */ + WM_keyconfig_update(wm); } /* ********** filesector handling ************ */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 27fc0caeccc..20f9d2237c2 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -224,6 +224,14 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) oldwm= oldwmlist->first; wm= G.main->wm.first; + /* move addon key configuration to new wm, to preserve their keymaps */ + if(oldwm->addonconf) { + wm->addonconf= oldwm->addonconf; + BLI_remlink(&oldwm->keyconfigs, oldwm->addonconf); + oldwm->addonconf= NULL; + BLI_addtail(&wm->keyconfigs, wm->addonconf); + } + /* ensure making new keymaps and set space types */ wm->initialized= 0; wm->winactive= NULL; @@ -794,11 +802,14 @@ int WM_write_homefile(bContext *C, wmOperator *op) wmWindow *win= CTX_wm_window(C); char filepath[FILE_MAXDIR+FILE_MAXFILE]; int fileflags; - + /* check current window and close it if temp */ if(win->screen->temp) wm_window_close(C, wm, win); + /* update keymaps in user preferences */ + WM_keyconfig_update(wm); + BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); printf("trying to save homefile at %s ", filepath); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 1720c738dd7..bf48f0e21e4 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -61,14 +61,67 @@ #include "wm_event_system.h" #include "wm_event_types.h" -/* ********************* key config ***********************/ +/******************************* Keymap Item ********************************** + * Item in a keymap, that maps from an event to an operator or modal map item */ -static void keymap_properties_set(wmKeyMapItem *kmi) +static wmKeyMapItem *wm_keymap_item_copy(wmKeyMapItem *kmi) +{ + wmKeyMapItem *kmin = MEM_dupallocN(kmi); + + kmin->prev= kmin->next= NULL; + kmin->flag &= ~KMI_UPDATE; + + if(kmin->properties) { + kmin->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr"); + WM_operator_properties_create(kmin->ptr, kmin->idname); + + kmin->properties= IDP_CopyProperty(kmin->properties); + kmin->ptr->data= kmin->properties; + } + + return kmin; +} + +static void wm_keymap_item_free(wmKeyMapItem *kmi) +{ + /* not kmi itself */ + if(kmi->ptr) { + WM_operator_properties_free(kmi->ptr); + MEM_freeN(kmi->ptr); + } +} + +static void wm_keymap_item_properties_set(wmKeyMapItem *kmi) { WM_operator_properties_alloc(&(kmi->ptr), &(kmi->properties), kmi->idname); WM_operator_properties_sanitize(kmi->ptr, 1); } +static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b) +{ + if(strcmp(a->idname, b->idname) != 0) + return 0; + + if(!((a->ptr==NULL && b->ptr==NULL) || + (a->ptr && b->ptr && IDP_EqualsProperties(a->ptr->data, b->ptr->data)))) + return 0; + + return (a->propvalue == b->propvalue); +} + +static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b) +{ + return (wm_keymap_item_equals_result(a, b) && + a->type == b->type && + a->val == b->val && + a->shift == b->shift && + a->ctrl == b->ctrl && + a->alt == b->alt && + a->oskey == b->oskey && + a->keymodifier == b->keymodifier && + a->maptype == b->maptype); +} + /* properties can be NULL, otherwise the arg passed is used and ownership is given to the kmi */ void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties) { @@ -78,9 +131,41 @@ void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties kmi->ptr = NULL; kmi->properties = properties; - keymap_properties_set(kmi); + wm_keymap_item_properties_set(kmi); } +/**************************** Keymap Diff Item ********************************* + * Item in a diff keymap, used for saving diff of keymaps in user preferences */ + +static wmKeyMapDiffItem *wm_keymap_diff_item_copy(wmKeyMapDiffItem *kmdi) +{ + wmKeyMapDiffItem *kmdin = MEM_dupallocN(kmdi); + + kmdin->next = kmdin->prev = NULL; + if(kmdi->add_item) + kmdin->add_item = wm_keymap_item_copy(kmdi->add_item); + if(kmdi->remove_item) + kmdin->remove_item = wm_keymap_item_copy(kmdi->remove_item); + + return kmdin; +} + +static void wm_keymap_diff_item_free(wmKeyMapDiffItem *kmdi) +{ + if(kmdi->remove_item) { + wm_keymap_item_free(kmdi->remove_item); + MEM_freeN(kmdi->remove_item); + } + if(kmdi->add_item) { + wm_keymap_item_free(kmdi->add_item); + MEM_freeN(kmdi->add_item); + } +} + +/***************************** Key Configuration ****************************** + * List of keymaps for all editors, modes, ... . There is a builtin default key + * configuration, a user key configuration, and other preset configurations. */ + wmKeyConfig *WM_keyconfig_new(wmWindowManager *wm, const char *idname) { wmKeyConfig *keyconf; @@ -106,6 +191,7 @@ void WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf) if (keyconf) { if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) { BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr)); + WM_keyconfig_update_tag(NULL, NULL); } BLI_remlink(&wm->keyconfigs, keyconf); @@ -125,21 +211,6 @@ void WM_keyconfig_free(wmKeyConfig *keyconf) MEM_freeN(keyconf); } -void WM_keyconfig_userdef(void) -{ - wmKeyMap *km; - wmKeyMapItem *kmi; - - for(km=U.keymaps.first; km; km=km->next) { - /* modal keymaps don't have operator properties */ - if ((km->flag & KEYMAP_MODAL) == 0) { - for(kmi=km->items.first; kmi; kmi=kmi->next) { - keymap_properties_set(kmi); - } - } - } -} - static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname) { wmKeyConfig *kc; @@ -151,24 +222,85 @@ static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname) return NULL; } -/* ************************ free ************************* */ +wmKeyConfig *WM_keyconfig_active(wmWindowManager *wm) +{ + wmKeyConfig *keyconf; + + /* first try from preset */ + keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); + if(keyconf) + return keyconf; + + /* otherwise use default */ + return wm->defaultconf; +} + +void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname) +{ + /* setting a different key configuration as active: we ensure all is + updated properly before and after making the change */ + + WM_keyconfig_update(wm); + + BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr)); + + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); +} + +/********************************** Keymap ************************************* + * List of keymap items for one editor, mode, modal operator, ... */ + +static wmKeyMap *wm_keymap_new(const char *idname, int spaceid, int regionid) +{ + wmKeyMap *km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); + + BLI_strncpy(km->idname, idname, KMAP_MAX_NAME); + km->spaceid= spaceid; + km->regionid= regionid; + + return km; +} + +static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap) +{ + wmKeyMap *keymapn = MEM_dupallocN(keymap); + wmKeyMapItem *kmi, *kmin; + wmKeyMapDiffItem *kmdi, *kmdin; + + keymapn->modal_items= keymap->modal_items; + keymapn->poll= keymap->poll; + keymapn->items.first= keymapn->items.last= NULL; + keymapn->flag &= ~(KEYMAP_UPDATE|KEYMAP_EXPANDED); + + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) { + kmdin= wm_keymap_diff_item_copy(kmdi); + BLI_addtail(&keymapn->items, kmdin); + } + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) { + kmin= wm_keymap_item_copy(kmi); + BLI_addtail(&keymapn->items, kmin); + } + + return keymapn; +} void WM_keymap_free(wmKeyMap *keymap) { wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; - for(kmi=keymap->items.first; kmi; kmi=kmi->next) { - if(kmi->ptr) { - WM_operator_properties_free(kmi->ptr); - MEM_freeN(kmi->ptr); - } - } + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) + wm_keymap_diff_item_free(kmdi); + for(kmi=keymap->items.first; kmi; kmi=kmi->next) + wm_keymap_item_free(kmi); + + BLI_freelistN(&keymap->diff_items); BLI_freelistN(&keymap->items); } -/* ***************** generic call, exported **************** */ - static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier) { kmi->type= type; @@ -229,7 +361,7 @@ wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int ty keymap_item_set_id(keymap, kmi); keymap_event_set(kmi, type, val, modifier, keymodifier); - keymap_properties_set(kmi); + wm_keymap_item_properties_set(kmi); } return kmi; } @@ -243,10 +375,12 @@ wmKeyMapItem *WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type, BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); - keymap_properties_set(kmi); + wm_keymap_item_properties_set(kmi); keymap_item_set_id(keymap, kmi); + WM_keyconfig_update_tag(keymap, kmi); + return kmi; } @@ -266,6 +400,232 @@ void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) MEM_freeN(kmi->ptr); } BLI_freelinkN(&keymap->items, kmi); + + WM_keyconfig_update_tag(keymap, kmi); + } +} + +/************************** Keymap Diff and Patch **************************** + * Rather than saving the entire keymap for user preferences, we only save a + * diff so that changes in the defaults get synced. This system is not perfect + * but works better than overriding the keymap entirely when only few items + * are changed. */ + +static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap) +{ + wmKeyMapItem *kmi, *kmin; + + for(kmi=addonmap->items.first; kmi; kmi=kmi->next) { + kmin = wm_keymap_item_copy(kmi); + keymap_item_set_id(keymap, kmin); + BLI_addhead(&keymap->items, kmin); + } +} + +static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *needle) +{ + wmKeyMapItem *kmi; + + for(kmi=km->items.first; kmi; kmi=kmi->next) + if(wm_keymap_item_equals(kmi, needle)) + return kmi; + + return NULL; +} + +static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapItem *needle) +{ + wmKeyMapItem *kmi; + + for(kmi=km->items.first; kmi; kmi=kmi->next) + if(wm_keymap_item_equals_result(kmi, needle)) + return kmi; + + return NULL; +} + +static void wm_keymap_diff(wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km) +{ + wmKeyMapItem *kmi, *to_kmi, *orig_kmi; + wmKeyMapDiffItem *kmdi; + + for(kmi=from_km->items.first; kmi; kmi=kmi->next) { + to_kmi = WM_keymap_item_find_id(to_km, kmi->id); + + if(!to_kmi) { + /* remove item */ + kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem"); + kmdi->remove_item = wm_keymap_item_copy(kmi); + BLI_addtail(&diff_km->diff_items, kmdi); + } + else if(to_kmi && !wm_keymap_item_equals(kmi, to_kmi)) { + /* replace item */ + kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem"); + kmdi->remove_item = wm_keymap_item_copy(kmi); + kmdi->add_item = wm_keymap_item_copy(to_kmi); + BLI_addtail(&diff_km->diff_items, kmdi); + } + + /* sync expanded flag back to original so we don't loose it on repatch */ + if(to_kmi) { + orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id); + + if(!orig_kmi) + orig_kmi = wm_keymap_find_item_equals(addon_km, kmi); + + if(orig_kmi) { + orig_kmi->flag &= ~KMI_EXPANDED; + orig_kmi->flag |= (to_kmi->flag & KMI_EXPANDED); + } + } + } + + for(kmi=to_km->items.first; kmi; kmi=kmi->next) { + if(kmi->id < 0) { + /* add item */ + kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem"); + kmdi->add_item = wm_keymap_item_copy(kmi); + BLI_addtail(&diff_km->diff_items, kmdi); + } + } +} + +static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km) +{ + wmKeyMapDiffItem *kmdi; + wmKeyMapItem *kmi_remove, *kmi_add; + + for(kmdi=diff_km->diff_items.first; kmdi; kmdi=kmdi->next) { + /* find item to remove */ + kmi_remove = NULL; + if(kmdi->remove_item) { + kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item); + if(!kmi_remove) + kmi_remove = wm_keymap_find_item_equals_result(km, kmdi->remove_item); + } + + /* add item */ + if(kmdi->add_item) { + /* only if nothing to remove or item to remove found */ + if(!kmdi->remove_item || kmi_remove) { + kmi_add = wm_keymap_item_copy(kmdi->add_item); + kmi_add->flag |= KMI_USER_MODIFIED; + + if(kmi_remove) { + kmi_add->flag &= ~KMI_EXPANDED; + kmi_add->flag |= (kmi_remove->flag & KMI_EXPANDED); + kmi_add->id = kmi_remove->id; + BLI_insertlinkbefore(&km->items, kmi_remove, kmi_add); + } + else { + keymap_item_set_id(km, kmi_add); + BLI_addtail(&km->items, kmi_add); + } + } + } + + /* remove item */ + if(kmi_remove) { + wm_keymap_item_free(kmi_remove); + BLI_freelinkN(&km->items, kmi_remove); + } + } +} + +static void wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap) +{ + wmKeyMap *km; + int expanded = 0; + + /* remove previous keymap in list, we will replace it */ + km = WM_keymap_list_find(lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid); + if(km) { + expanded = (km->flag & (KEYMAP_EXPANDED|KEYMAP_CHILDREN_EXPANDED)); + WM_keymap_free(km); + BLI_freelinkN(lb, km); + } + + /* copy new keymap from an existing one */ + if(usermap && !(usermap->flag & KEYMAP_DIFF)) { + /* for compatibiltiy with old user preferences with non-diff + keymaps we override the original entirely */ + wmKeyMapItem *kmi, *orig_kmi; + + km = wm_keymap_copy(usermap); + km->modal_items = defaultmap->modal_items; + km->poll = defaultmap->poll; + + /* try to find corresponding id's for items */ + for(kmi=km->items.first; kmi; kmi=kmi->next) { + orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi); + if(!orig_kmi) + orig_kmi = wm_keymap_find_item_equals_result(defaultmap, kmi); + + if(orig_kmi) + kmi->id = orig_kmi->id; + else + kmi->id = -(km->kmi_id++); + } + + km->flag |= KEYMAP_UPDATE; /* update again to create diff */ + } + else + km = wm_keymap_copy(defaultmap); + + /* add addon keymap items */ + if(addonmap) + wm_keymap_addon_add(km, addonmap); + + /* tag as being user edited */ + if(usermap) + km->flag |= KEYMAP_USER_MODIFIED; + km->flag |= KEYMAP_USER|expanded; + + /* apply user changes of diff keymap */ + if(usermap && (usermap->flag & KEYMAP_DIFF)) + wm_keymap_patch(km, usermap); + + /* add to list */ + BLI_addtail(lb, km); +} + +static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *km) +{ + wmKeyMap *diffmap, *prevmap, *origmap; + + /* create temporary default + addon keymap for diff */ + origmap = defaultmap; + + if(addonmap) { + defaultmap = wm_keymap_copy(defaultmap); + wm_keymap_addon_add(defaultmap, addonmap); + } + + /* remove previous diff keymap in list, we will replace it */ + prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid); + if(prevmap) { + WM_keymap_free(prevmap); + BLI_freelinkN(lb, prevmap); + } + + /* create diff keymap */ + diffmap= wm_keymap_new(km->idname, km->spaceid, km->regionid); + diffmap->flag |= KEYMAP_DIFF; + wm_keymap_diff(diffmap, defaultmap, km, origmap, addonmap); + + /* add to list if not empty */ + if(diffmap->diff_items.first) { + BLI_addtail(lb, diffmap); + } + else { + WM_keymap_free(diffmap); + MEM_freeN(diffmap); + } + + /* free temporary default map */ + if(addonmap) { + WM_keymap_free(defaultmap); + MEM_freeN(defaultmap); } } @@ -292,11 +652,10 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, wmKeyMap *km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); if(km==NULL) { - km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); - BLI_strncpy(km->idname, idname, KMAP_MAX_NAME); - km->spaceid= spaceid; - km->regionid= regionid; + km= wm_keymap_new(idname, spaceid, regionid); BLI_addtail(&keyconf->keymaps, km); + + WM_keyconfig_update_tag(km, NULL); } return km; @@ -304,29 +663,9 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, wmKeyMap *WM_keymap_find_all(const bContext *C, const char *idname, int spaceid, int regionid) { - wmWindowManager *wm = CTX_wm_manager(C); - wmKeyConfig *keyconf; - wmKeyMap *km; - - /* first user defined keymaps */ - km= WM_keymap_list_find(&U.keymaps, idname, spaceid, regionid); - if (km) - return km; - - /* then user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); - if (km) - return km; - } - - /* then use default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, idname, spaceid, regionid); - if (km) - return km; - else - return NULL; + wmWindowManager *wm= CTX_wm_manager(C); + + return WM_keymap_list_find(&wm->userconf->keymaps, idname, spaceid, regionid); } /* ****************** modal keymaps ************ */ @@ -366,6 +705,8 @@ wmKeyMapItem *WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modif keymap_item_set_id(km, kmi); + WM_keyconfig_update_tag(km, kmi); + return kmi; } @@ -588,169 +929,209 @@ int WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2) return 1; } -/* ***************** user preferences ******************* */ +/************************* Update Final Configuration ************************* + * On load or other changes, the final user key configuration is rebuilt from + * the preset, addon and user preferences keymaps. We also test if the final + * configuration changed and write the changes to the user preferences. */ -int WM_keymap_user_init(wmWindowManager *wm, wmKeyMap *keymap) +static int WM_KEYMAP_UPDATE = 0; + +void WM_keyconfig_update_tag(wmKeyMap *km, wmKeyMapItem *kmi) { - wmKeyConfig *keyconf; - wmKeyMap *km; + /* quick tag to do delayed keymap updates */ + WM_KEYMAP_UPDATE= 1; + if(km) + km->flag |= KEYMAP_UPDATE; + if(kmi) + kmi->flag |= KMI_UPDATE; +} + +static int wm_keymap_test_and_clear_update(wmKeyMap *km) +{ + wmKeyMapItem *kmi; + int update; + + update= (km->flag & KEYMAP_UPDATE); + km->flag &= ~KEYMAP_UPDATE; + + for(kmi=km->items.first; kmi; kmi=kmi->next) { + update= update || (kmi->flag & KMI_UPDATE); + kmi->flag &= ~KMI_UPDATE; + } + + return update; +} + +static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km) +{ + wmKeyConfig *keyconf= WM_keyconfig_active(wm); + wmKeyMap *keymap; + + keymap= WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid); if(!keymap) - return 0; + keymap= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid); - /* init from user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - keymap->poll= km->poll; /* lazy init */ - keymap->modal_items= km->modal_items; - return 1; + return keymap; +} + +void WM_keyconfig_update(wmWindowManager *wm) +{ + wmKeyMap *km, *defaultmap, *addonmap, *usermap; + wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; + int compat_update = 0; + + if(!WM_KEYMAP_UPDATE) + return; + + /* update operator properties for non-modal user keymaps */ + for(km=U.user_keymaps.first; km; km=km->next) { + if((km->flag & KEYMAP_MODAL) == 0) { + for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) { + if(kmdi->add_item) + wm_keymap_item_properties_set(kmdi->add_item); + if(kmdi->remove_item) + wm_keymap_item_properties_set(kmdi->remove_item); + } + + for(kmi=km->items.first; kmi; kmi=kmi->next) + wm_keymap_item_properties_set(kmi); } } - /* or from default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - keymap->poll= km->poll; /* lazy init */ - keymap->modal_items= km->modal_items; - return 1; + /* update U.user_keymaps with user key configuration changes */ + for(km=wm->userconf->keymaps.first; km; km=km->next) { + /* only diff if the user keymap was modified */ + if(wm_keymap_test_and_clear_update(km)) { + /* find keymaps */ + defaultmap= wm_keymap_preset(wm, km); + addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); + + /* diff */ + wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km); + } } - return 0; + /* create user key configuration from preset + addon + user preferences */ + for(km=wm->defaultconf->keymaps.first; km; km=km->next) { + /* find keymaps */ + defaultmap= wm_keymap_preset(wm, km); + addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); + usermap= WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid); + + /* add */ + wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap); + + /* in case of old non-diff keymaps, force extra update to create diffs */ + compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF)); + } + + WM_KEYMAP_UPDATE= 0; + + if(compat_update) { + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); + } } +/********************************* Event Handling ***************************** + * Handlers have pointers to the keymap in the default configuration. During + * event handling this function is called to get the keymap from the final + * configuration. */ + wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) { - wmKeyConfig *keyconf; wmKeyMap *km; if(!keymap) return NULL; /* first user defined keymaps */ - km= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - km->poll= keymap->poll; /* lazy init */ - km->modal_items= keymap->modal_items; + km= WM_keymap_list_find(&wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + + if(km) return km; - } - - /* then user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - km->poll= keymap->poll; /* lazy init */ - km->modal_items= keymap->modal_items; - return km; - } - } - /* then use default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - return km; + return keymap; } -wmKeyMap *WM_keymap_copy_to_user(wmKeyMap *keymap) -{ - wmKeyMap *usermap; - wmKeyMapItem *kmi; - - usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - - /* XXX this function is only used by RMB setting hotkeys, and it clears maps on 2nd try this way */ - if(keymap==usermap) - return keymap; - - if(!usermap) { - /* not saved yet, duplicate existing */ - usermap= MEM_dupallocN(keymap); - usermap->modal_items= NULL; - usermap->poll= NULL; - usermap->flag |= KEYMAP_USER; - - BLI_addtail(&U.keymaps, usermap); - } - else { - /* already saved, free items for re-copy */ - WM_keymap_free(usermap); - } - - BLI_duplicatelist(&usermap->items, &keymap->items); - - for(kmi=usermap->items.first; kmi; kmi=kmi->next) { - if(kmi->properties) { - kmi->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr"); - WM_operator_properties_create(kmi->ptr, kmi->idname); - - kmi->properties= IDP_CopyProperty(kmi->properties); - kmi->ptr->data= kmi->properties; - } - } - - for(kmi=keymap->items.first; kmi; kmi=kmi->next) - kmi->flag &= ~KMI_EXPANDED; - - return usermap; -} +/******************************* Keymap Editor ******************************** + * In the keymap editor the user key configuration is edited. */ void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapItem *kmi) { wmWindowManager *wm = CTX_wm_manager(C); - wmKeyConfig *keyconf; - wmKeyMap *km = NULL; + wmKeyMap *defaultmap, *addonmap; + wmKeyMapItem *orig; - /* look in user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + if(!keymap) + return; + + /* construct default keymap from preset + addons */ + defaultmap= wm_keymap_preset(wm, keymap); + addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + + if(addonmap) { + defaultmap = wm_keymap_copy(defaultmap); + wm_keymap_addon_add(defaultmap, addonmap); } - if (!km) { - /* or from default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - } - - if (km) { - wmKeyMapItem *orig = WM_keymap_item_find_id(km, kmi->id); - - if (orig) { - if(strcmp(orig->idname, kmi->idname) != 0) { - BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname)); - - WM_keymap_properties_reset(kmi, NULL); - } - - if (orig->properties) { - kmi->properties= IDP_CopyProperty(orig->properties); - kmi->ptr->data= kmi->properties; - } - - kmi->propvalue = orig->propvalue; - kmi->type = orig->type; - kmi->val = orig->val; - kmi->shift = orig->shift; - kmi->ctrl = orig->ctrl; - kmi->alt = orig->alt; - kmi->oskey = orig->oskey; - kmi->keymodifier = orig->keymodifier; - kmi->maptype = orig->maptype; + /* find original item */ + orig = WM_keymap_item_find_id(defaultmap, kmi->id); + if(orig) { + /* restore to original */ + if(strcmp(orig->idname, kmi->idname) != 0) { + BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname)); + WM_keymap_properties_reset(kmi, NULL); } + if (orig->properties) { + if(kmi->properties) { + IDP_FreeProperty(kmi->properties); + MEM_freeN(kmi->properties); + kmi->properties= NULL; + } + + kmi->properties= IDP_CopyProperty(orig->properties); + kmi->ptr->data= kmi->properties; + } + + kmi->propvalue = orig->propvalue; + kmi->type = orig->type; + kmi->val = orig->val; + kmi->shift = orig->shift; + kmi->ctrl = orig->ctrl; + kmi->alt = orig->alt; + kmi->oskey = orig->oskey; + kmi->keymodifier = orig->keymodifier; + kmi->maptype = orig->maptype; + + WM_keyconfig_update_tag(keymap, kmi); + } + + /* free temporary keymap */ + if(addonmap) { + WM_keymap_free(defaultmap); + MEM_freeN(defaultmap); } } -void WM_keymap_restore_to_default(wmKeyMap *keymap) +void WM_keymap_restore_to_default(wmKeyMap *keymap, bContext *C) { + wmWindowManager *wm = CTX_wm_manager(C); wmKeyMap *usermap; - usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + /* remove keymap from U.user_keymaps and update */ + usermap= WM_keymap_list_find(&U.user_keymaps, keymap->idname, keymap->spaceid, keymap->regionid); if(usermap) { WM_keymap_free(usermap); - BLI_freelinkN(&U.keymaps, usermap); + BLI_freelinkN(&U.user_keymaps, usermap); + + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); } } @@ -951,3 +1332,4 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname) return km; } + diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 548d272ffd2..983d4ecf5f8 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -208,10 +208,12 @@ struct wmKeyMap *WM_keymap_list_find(struct ListBase *lb, char *idname, int spac struct wmKeyConfig *WM_keyconfig_new(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;} struct wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;} void WM_keyconfig_remove(struct wmWindowManager *wm, char *idname){} +void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname) {} void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){} void WM_keymap_restore_to_default(struct wmKeyMap *keymap){} void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){} void WM_keymap_properties_reset(struct wmKeyMapItem *kmi){} +void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi) {} int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap) {return 0;} int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2){return 0;} From d78be1f76209bed9924ff2439ac3f817aee7966c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 6 Aug 2011 04:19:30 +0000 Subject: [PATCH 31/41] remove copy modifiers function, now handled in link data operator. --- source/blender/editors/object/object_edit.c | 107 +------------------- 1 file changed, 3 insertions(+), 104 deletions(-) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 395705dc029..c8d38218533 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1049,109 +1049,6 @@ static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob) } } -static void copymenu_modifiers(Main *bmain, Scene *scene, View3D *v3d, Object *ob) -{ - Base *base; - int i, event; - char str[512]; - const char *errorstr= NULL; - - strcpy(str, "Copy Modifiers %t"); - - sprintf(str+strlen(str), "|All%%x%d|%%l", NUM_MODIFIER_TYPES); - - for (i=eModifierType_None+1; iflags&eModifierTypeFlag_AcceptsCVs) || - (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { - sprintf(str+strlen(str), "|%s%%x%d", mti->name, i); - } - } - - event = pupmenu(str); - if(event<=0) return; - - for (base= FIRSTBASE; base; base= base->next) { - if(base->object != ob) { - if(TESTBASELIB(v3d, base)) { - - base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA; - - if (base->object->type==ob->type) { - /* copy all */ - if (event==NUM_MODIFIER_TYPES) { - ModifierData *md; - object_free_modifiers(base->object); - - for (md=ob->modifiers.first; md; md=md->next) { - ModifierData *nmd = NULL; - - if(ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue; - - if(md->type == eModifierType_Collision) - continue; - - nmd = modifier_new(md->type); - modifier_copyData(md, nmd); - BLI_addtail(&base->object->modifiers, nmd); - modifier_unique_name(&base->object->modifiers, nmd); - } - - copy_object_particlesystems(base->object, ob); - copy_object_softbody(base->object, ob); - } else { - /* copy specific types */ - ModifierData *md, *mdn; - - /* remove all with type 'event' */ - for (md=base->object->modifiers.first; md; md=mdn) { - mdn= md->next; - if(md->type==event) { - BLI_remlink(&base->object->modifiers, md); - modifier_free(md); - } - } - - /* copy all with type 'event' */ - for (md=ob->modifiers.first; md; md=md->next) { - if (md->type==event) { - - mdn = modifier_new(event); - BLI_addtail(&base->object->modifiers, mdn); - modifier_unique_name(&base->object->modifiers, mdn); - - modifier_copyData(md, mdn); - } - } - - if(event == eModifierType_ParticleSystem) { - object_free_particlesystems(base->object); - copy_object_particlesystems(base->object, ob); - } - else if(event == eModifierType_Softbody) { - object_free_softbody(base->object); - copy_object_softbody(base->object, ob); - } - } - } - else - errorstr= "Did not copy modifiers to other Object types"; - } - } - } - -// if(errorstr) notice(errorstr); - - DAG_scene_sort(bmain, scene); - -} - /* both pointers should exist */ static void copy_texture_space(Object *to, Object *ob) { @@ -1196,6 +1093,7 @@ static void copy_texture_space(Object *to, Object *ob) } +/* UNUSED, keep incase we want to copy functionality for use elsewhere */ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) { Object *ob; @@ -1221,7 +1119,8 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) return; } else if(event==24) { - copymenu_modifiers(bmain, scene, v3d, ob); + /* moved to object_link_modifiers */ + /* copymenu_modifiers(bmain, scene, v3d, ob); */ return; } From dc4dede8029801580683551b39f967c206720736 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 6 Aug 2011 06:38:18 +0000 Subject: [PATCH 32/41] for UI text drawing use BLF_ascender(fs->uifont_id) rather then BLF_height(fs->uifont_id, "2"), while profiling draw noticed that the hash lookup on the character and utf8 next were being called on every text draw, use BLF_ascender since it doesn't do any lookups. --- source/blender/editors/interface/interface_style.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 5f2a757d2e3..8d4b4209120 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -149,9 +149,9 @@ void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str, int xofs=0, yofs; uiStyleFontSet(fs); - - height= BLF_height(fs->uifont_id, "2"); /* correct offset is on baseline, the j is below that */ - yofs= floor( 0.5f*(rect->ymax - rect->ymin - height)); + + height= BLF_ascender(fs->uifont_id); + yofs= ceil( 0.5f*(rect->ymax - rect->ymin - height)); if(fs->align==UI_STYLE_TEXT_CENTER) { xofs= floor( 0.5f*(rect->xmax - rect->xmin - BLF_width(fs->uifont_id, str))); @@ -206,9 +206,9 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str) uiStyleFontSet(fs); - height= BLF_height(fs->uifont_id, "2"); /* correct offset is on baseline, the j is below that */ + height= BLF_ascender(fs->uifont_id); /* becomes x-offset when rotated */ - xofs= floor( 0.5f*(rect->ymax - rect->ymin - height)) + 1; + xofs= ceil( 0.5f*(rect->ymax - rect->ymin - height)); /* ignore UI_STYLE, always aligned to top */ From 2f5809d8317e8dd7a3e4edc30a6f709fb632bb83 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 6 Aug 2011 14:57:55 +0000 Subject: [PATCH 33/41] make ui_def_but_rna into 2 functions, once which takes a prop, another which takes a propname, no functional change yet but lets us avoid duplicate hash lookups. --- source/blender/editors/interface/interface.c | 244 ++++++++++--------- 1 file changed, 131 insertions(+), 113 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 8aed0d58a07..78e24c3bccb 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2490,138 +2490,141 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, return but; } -static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) +/* ui_def_but_rna_propname and ui_def_but_rna + * both take the same args except for propname vs prop, this is done so we can + * avoid an extra lookup on 'prop' when its already available. + * + * When this kind of change won't disrupt branches, best look into making more + * of our UI functions take prop rather then propname. + */ + +#define UI_DEF_BUT_RNA_DISABLE(but) \ + but->flag |= UI_BUT_DISABLED; \ + but->lock = 1; \ + but->lockstr = "" + + +static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; - PropertyRNA *prop; PropertyType proptype; int freestr= 0, icon= 0; - prop= RNA_struct_find_property(ptr, propname); + proptype= RNA_property_type(prop); - if(prop) { - proptype= RNA_property_type(prop); + /* use rna values if parameters are not specified */ + if(!str) { + if(type == MENU && proptype == PROP_ENUM) { + EnumPropertyItem *item; + DynStr *dynstr; + int i, totitem, value, free; - /* use rna values if parameters are not specified */ - if(!str) { - if(type == MENU && proptype == PROP_ENUM) { - EnumPropertyItem *item; - DynStr *dynstr; - int i, totitem, value, free; + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); + value= RNA_property_enum_get(ptr, prop); - RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); - value= RNA_property_enum_get(ptr, prop); - - dynstr= BLI_dynstr_new(); - BLI_dynstr_appendf(dynstr, "%s%%t", RNA_property_ui_name(prop)); - for(i=0; ievil_C, ptr, prop, &item, &totitem, &free); - for(i=0; ievil_C, ptr, prop, &item, &totitem, &free); + for(i=0; itype), propname); - str= propname; + + if(!tip && proptype != PROP_ENUM) + tip= RNA_property_ui_description(prop); + + if(min == max || a1 == -1 || a2 == -1) { + if(proptype == PROP_INT) { + int hardmin, hardmax, softmin, softmax, step; + + RNA_property_int_range(ptr, prop, &hardmin, &hardmax); + RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step); + + if(!ELEM(type, ROW, LISTROW) && min == max) { + min= hardmin; + max= hardmax; + } + if(a1 == -1) + a1= step; + if(a2 == -1) + a2= 0; + } + else if(proptype == PROP_FLOAT) { + float hardmin, hardmax, softmin, softmax, step, precision; + + RNA_property_float_range(ptr, prop, &hardmin, &hardmax); + RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); + + if(!ELEM(type, ROW, LISTROW) && min == max) { + min= hardmin; + max= hardmax; + } + if(a1 == -1) + a1= step; + if(a2 == -1) + a2= precision; + } + else if(proptype == PROP_STRING) { + min= 0; + max= RNA_property_string_maxlength(prop); + if(max == 0) /* interface code should ideally support unlimited length */ + max= UI_MAX_DRAW_STR; + } } /* now create button */ but= ui_def_but(block, type, retval, str, x1, y1, x2, y2, NULL, min, max, a1, a2, tip); - if(prop) { - but->rnapoin= *ptr; - but->rnaprop= prop; + but->rnapoin= *ptr; + but->rnaprop= prop; - if(RNA_property_array_length(&but->rnapoin, but->rnaprop)) - but->rnaindex= index; - else - but->rnaindex= 0; - } + if(RNA_property_array_length(&but->rnapoin, but->rnaprop)) + but->rnaindex= index; + else + but->rnaindex= 0; if(icon) { but->icon= (BIFIconID)icon; @@ -2629,10 +2632,8 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s but->flag|= UI_ICON_LEFT; } - if (!prop || !RNA_property_editable(&but->rnapoin, prop)) { - but->flag |= UI_BUT_DISABLED; - but->lock = 1; - but->lockstr = ""; + if (!RNA_property_editable(&but->rnapoin, prop)) { + UI_DEF_BUT_RNA_DISABLE(but); } /* If this button uses units, calculate the step from this */ @@ -2645,6 +2646,23 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s return but; } +static uiBut *ui_def_but_rna_propname(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); + uiBut *but; + + if(prop) { + but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + } + else { + but= ui_def_but(block, type, retval, propname, x1, y1, x2, y2, NULL, min, max, a1, a2, tip); + + UI_DEF_BUT_RNA_DISABLE(but); + } + + return but; +} + static uiBut *ui_def_but_operator(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; @@ -2857,7 +2875,7 @@ uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, { uiBut *but; - but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); + but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); if(but) ui_check_but(but); @@ -2942,7 +2960,7 @@ uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int { uiBut *but; - but= ui_def_but_rna(block, type, retval, "", x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); + but= ui_def_but_rna_propname(block, type, retval, "", x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); if(but) { if(icon) { but->icon= (BIFIconID) icon; @@ -3027,7 +3045,7 @@ uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const c { uiBut *but; - but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); + but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); if(but) { if(icon) { but->icon= (BIFIconID) icon; From 79e359f92af3b26d10c3f65ba9548863b7010546 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 6 Aug 2011 16:00:00 +0000 Subject: [PATCH 34/41] rna/ui: avoid duplicate property gHash lookups by passing the property when its already been found. added _prop suffix to ui functions which take a prop rather then a propname, may change this later since its not that nice but for gsoc branches this keeps existing UI functions working the same. --- source/blender/editors/include/UI_interface.h | 3 + source/blender/editors/interface/interface.c | 102 ++++++++---------- .../editors/interface/interface_layout.c | 18 ++-- .../editors/interface/interface_regions.c | 29 +++-- .../editors/interface/interface_templates.c | 14 +-- .../editors/interface/interface_utils.c | 43 ++++---- 6 files changed, 95 insertions(+), 114 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 1bae6ce0214..3fe012ea73e 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -410,6 +410,7 @@ uiBut *uiDefButBitS(uiBlock *block, int type, int bit, int retval, const char *s uiBut *uiDefButC(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); +uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip); @@ -429,6 +430,7 @@ uiBut *uiDefIconButBitS(uiBlock *block, int type, int bit, int retval, int icon, uiBut *uiDefIconButC(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); +uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefIconTextBut(uiBlock *block, @@ -447,6 +449,7 @@ uiBut *uiDefIconTextButBitS(uiBlock *block, int type, int bit, int retval, int i uiBut *uiDefIconTextButC(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); +uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip); /* for passing inputs to ButO buttons */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 78e24c3bccb..e31e3a26b40 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2830,6 +2830,16 @@ static void autocomplete_id(bContext *C, char *str, void *arg_v) } } +static void ui_check_but_and_iconize(uiBut *but, int icon) +{ + if(icon) { + but->icon= (BIFIconID) icon; + but->flag|= UI_HAS_ICON; + } + + ui_check_but(but); +} + static uiBut *uiDefButBit(uiBlock *block, int type, int bit, int retval, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { int bitIdx= findBitIndex(bit); @@ -2874,31 +2884,29 @@ uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *s uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; - but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); - if(but) - ui_check_but(but); - + ui_check_but(but); + return but; +} +uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) +{ + uiBut *but; + but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + ui_check_but(but); return but; } uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); - if(but) - ui_check_but(but); - + ui_check_but(but); return but; } uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but= ui_def_but_operator_text(block, type, opname, opcontext, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip); - - if(but) - ui_check_but(but); - + ui_check_but(but); return but; } @@ -2906,12 +2914,7 @@ uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but= ui_def_but(block, type, retval, "", x1, y1, x2, y2, poin, min, max, a1, a2, tip); - - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - - ui_check_but(but); - + ui_check_but_and_iconize(but, icon); return but; } static uiBut *uiDefIconButBit(uiBlock *block, int type, int bit, int retval, int icon, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -2959,29 +2962,22 @@ uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon, uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; - but= ui_def_but_rna_propname(block, type, retval, "", x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); - if(but) { - if(icon) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - } - ui_check_but(but); - } - + ui_check_but_and_iconize(but, icon); + return but; +} +uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) +{ + uiBut *but; + but= ui_def_but_rna(block, type, retval, "", x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + ui_check_but_and_iconize(but, icon); return but; } uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, "", x1, y1, x2, y2, tip); - if(but) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - ui_check_but(but); - } - + ui_check_but_and_iconize(but, icon); return but; } @@ -2989,14 +2985,8 @@ uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but= ui_def_but(block, type, retval, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip); - - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - + ui_check_but_and_iconize(but, icon); but->flag|= UI_ICON_LEFT; - - ui_check_but(but); - return but; } static uiBut *uiDefIconTextButBit(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -3044,31 +3034,25 @@ uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int i uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; - but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); - if(but) { - if(icon) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - } - but->flag|= UI_ICON_LEFT; - ui_check_but(but); - } - + ui_check_but_and_iconize(but, icon); + but->flag|= UI_ICON_LEFT; + return but; +} +uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) +{ + uiBut *but; + but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + ui_check_but_and_iconize(but, icon); + but->flag|= UI_ICON_LEFT; return but; } uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); - if(but) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - but->flag|= UI_ICON_LEFT; - ui_check_but(but); - } - + ui_check_but_and_iconize(but, icon); + but->flag|= UI_ICON_LEFT; return but; } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 2f0bcc9d5b4..85cc944f03b 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -419,7 +419,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in } } else if(subtype == PROP_DIRECTION) { - uiDefButR(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X*3, UI_UNIT_Y*3, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL); + uiDefButR_prop(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X*3, UI_UNIT_Y*3, ptr, prop, 0, 0, 0, -1, -1, NULL); } else { if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand) @@ -461,11 +461,9 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt { uiBut *but; EnumPropertyItem *item; - const char *identifier; const char *name; int a, totitem, itemw, icon, value, free; - identifier= RNA_property_identifier(prop); RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1)); @@ -479,11 +477,11 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt itemw= ui_text_icon_width(block->curlayout, name, icon, 0); if(icon && name[0] && !icon_only) - but= uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); else if(icon) - but= uiDefIconButR(block, ROW, 0, icon, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + but= uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); else - but= uiDefButR(block, ROW, 0, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + but= uiDefButR_prop(block, ROW, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); if(ui_layout_local_dir(layout) != UI_LAYOUT_HORIZONTAL) but->flag |= UI_TEXT_LEFT; @@ -540,7 +538,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); } else if(flag & UI_ITEM_R_EVENT) { - uiDefButR(block, KEYEVT, 0, name, x, y, w, h, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL); + uiDefButR_prop(block, KEYEVT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); } else if(flag & UI_ITEM_R_FULL_EVENT) { if(RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) { @@ -548,7 +546,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n WM_keymap_item_to_string(ptr->data, buf, sizeof(buf)); - but= uiDefButR(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, prop, 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, ui_keymap_but_cb, but, NULL); if (flag & UI_ITEM_R_IMMEDIATE) uiButSetFlag(but, UI_BUT_IMMEDIATE); @@ -1008,11 +1006,11 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index const char *identifier= RNA_property_identifier(prop); if(icon && name[0] && !icon_only) - uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); else if(icon) uiDefIconButR(block, ROW, 0, icon, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); else - uiDefButR(block, ROW, 0, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + uiDefButR_prop(block, ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); } /* expanded enum */ else if(type == PROP_ENUM && (expand || RNA_property_flag(prop) & PROP_ENUM_FLAG)) diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 9e7717260e6..f7460e77030 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1934,31 +1934,31 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a #define PICKER_TOTAL_W (PICKER_W+PICKER_SPACE+PICKER_BAR) -static void circle_picker(uiBlock *block, PointerRNA *ptr, const char *propname) +static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop) { uiBut *bt; /* HS circle */ - bt= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, propname, 0, 0.0, 0.0, 0, 0, "Color"); + bt= uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, 0, 0.0, 0.0, 0, 0, "Color"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* value */ - bt= uiDefButR(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, propname, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value"); + bt= uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, prop, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } -static void square_picker(uiBlock *block, PointerRNA *ptr, const char *propname, int type) +static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type) { uiBut *bt; int bartype = type + 3; /* HS square */ - bt= uiDefButR(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, propname, 0, 0.0, 0.0, type, 0, "Color"); + bt= uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, 0, 0.0, 0.0, type, 0, "Color"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* value */ - bt= uiDefButR(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, propname, 0, 0.0, 0.0, bartype, 0, "Value"); + bt= uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, 0, 0.0, 0.0, bartype, 0, "Value"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } @@ -1973,7 +1973,6 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR static char hexcol[128]; float rgb_gamma[3]; float min, max, step, precision; - const char *propname = RNA_property_identifier(prop); float *hsv= ui_block_hsv_get(block); ui_block_hsv_get(block); @@ -1999,16 +1998,16 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR switch (U.color_picker_type) { case USER_CP_CIRCLE: - circle_picker(block, ptr, propname); + circle_picker(block, ptr, prop); break; case USER_CP_SQUARE_SV: - square_picker(block, ptr, propname, UI_GRAD_SV); + square_picker(block, ptr, prop, UI_GRAD_SV); break; case USER_CP_SQUARE_HS: - square_picker(block, ptr, propname, UI_GRAD_HS); + square_picker(block, ptr, prop, UI_GRAD_HS); break; case USER_CP_SQUARE_HV: - square_picker(block, ptr, propname, UI_GRAD_HV); + square_picker(block, ptr, prop, UI_GRAD_HV); break; } @@ -2027,11 +2026,11 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR /* RGB values */ uiBlockBeginAlign(block); - bt= uiDefButR(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 3, "Red"); + bt= uiDefButR_prop(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, "Red"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt= uiDefButR(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 3, "Green"); + bt= uiDefButR_prop(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, "Green"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt= uiDefButR(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 3, "Blue"); + bt= uiDefButR_prop(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, "Blue"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); // could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE); @@ -2048,7 +2047,7 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR uiBlockEndAlign(block); if(rgb[3] != FLT_MAX) { - bt= uiDefButR(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, propname, 3, 0.0, 0.0, 0, 0, "Alpha"); + bt= uiDefButR_prop(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, "Alpha"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } else { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 34315494e14..2d443bbfcd0 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1884,7 +1884,7 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, const char *propnam col = uiLayoutColumn(layout, 0); row= uiLayoutRow(col, 1); - but= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, 0, ""); + but= uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, 0, 0, ""); if(lock) { but->flag |= UI_BUT_COLOR_LOCK; @@ -1903,7 +1903,7 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, const char *propnam uiItemS(row); if (value_slider) - uiDefButR(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, propname, -1, softmin, softmax, UI_GRAD_V_ALT, 0, ""); + uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, prop, -1, softmin, softmax, UI_GRAD_V_ALT, 0, ""); } /********************* Layer Buttons Template ************************/ @@ -2034,7 +2034,7 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon, int return rnaicon; } -static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, const char *activepropname) +static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, PropertyRNA *activeprop) { uiBlock *block= uiLayoutGetBlock(layout); uiBut *but; @@ -2048,7 +2048,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe /* list item behind label & other buttons */ sub= uiLayoutRow(overlap, 0); - but= uiDefButR(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, ""); + but= uiDefButR_prop(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, ""); uiButSetFlag(but, UI_BUT_NO_TOOLTIP); sub= uiLayoutRow(overlap, 0); @@ -2201,7 +2201,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * row= uiLayoutRow(col, 0); icon= list_item_icon_get(C, &itemptr, rnaicon, 1); - but= uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, ""); + but= uiDefIconButR_prop(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, ""); uiButSetFlag(but, UI_BUT_NO_TOOLTIP); @@ -2241,7 +2241,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * /* next/prev button */ sprintf(str, "%d :", i); - but= uiDefIconTextButR(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activepropname, 0, 0, 0, 0, 0, ""); + but= uiDefIconTextButR_prop(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activeprop, 0, 0, 0, 0, 0, ""); if(i == 0) uiButSetFlag(but, UI_BUT_DISABLED); } @@ -2280,7 +2280,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * /* create list items */ RNA_PROP_BEGIN(ptr, itemptr, prop) { if(i >= pa->list_scroll && ilist_scroll+items) - list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activepropname); + list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activeprop); i++; } diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 1ec125c2f26..f660dbb9edd 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -51,56 +51,53 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2) { uiBut *but=NULL; - const char *propname= RNA_property_identifier(prop); - char prop_item[MAX_IDPROP_NAME+4]; /* size of the ID prop name + room for [""] */ - int arraylen= RNA_property_array_length(ptr, prop); - - /* support for custom props */ - if(RNA_property_is_idprop(prop)) { - sprintf(prop_item, "[\"%s\"]", propname); - propname= prop_item; - } switch(RNA_property_type(prop)) { - case PROP_BOOLEAN: { + case PROP_BOOLEAN: + { + int arraylen= RNA_property_array_length(ptr, prop); if(arraylen && index == -1) return NULL; if(icon && name && name[0] == '\0') - but= uiDefIconButR(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconButR_prop(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if(icon) - but= uiDefIconTextButR(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, OPTION, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, OPTION, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; } case PROP_INT: case PROP_FLOAT: + { + int arraylen= RNA_property_array_length(ptr, prop); + if(arraylen && index == -1) { if(ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) - but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, COL, 0, name, x1, y1, x2, y2, ptr, prop, 0, 0, 0, -1, -1, NULL); } else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) - but= uiDefButR(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; + } case PROP_ENUM: if(icon && name && name[0] == '\0') - but= uiDefIconButR(block, MENU, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconButR_prop(block, MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if(icon) - but= uiDefIconTextButR(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; case PROP_STRING: if(icon && name && name[0] == '\0') - but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconButR_prop(block, TEX, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if(icon) - but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, TEX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; case PROP_POINTER: { PointerRNA pptr; @@ -112,7 +109,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind if(icon == ICON_DOT) icon= 0; - but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; } case PROP_COLLECTION: { From 5dd2b3e06f0164bf4313a172240ad7f4d37bacbe Mon Sep 17 00:00:00 2001 From: Mike Erwin Date: Sat, 6 Aug 2011 22:31:16 +0000 Subject: [PATCH 35/41] fixed crash when NDOF operators were called without an NDOF_MOTION event --- .../blender/editors/space_image/image_ops.c | 49 +-- .../editors/space_view3d/view3d_edit.c | 318 +++++++++--------- 2 files changed, 185 insertions(+), 182 deletions(-) diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index e0ebde589a8..ea8c7fc0cfa 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -447,34 +447,41 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot) static int view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { - SpaceImage *sima= CTX_wm_space_image(C); - ARegion *ar= CTX_wm_region(C); + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + SpaceImage *sima= CTX_wm_space_image(C); + ARegion *ar= CTX_wm_region(C); - wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; + wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; - float dt = ndof->dt; - /* tune these until it feels right */ - const float zoom_sensitivity = 0.5f; // 50% per second (I think) - const float pan_sensitivity = 300.f; // screen pixels per second + float dt = ndof->dt; + /* tune these until it feels right */ + const float zoom_sensitivity = 0.5f; // 50% per second (I think) + const float pan_sensitivity = 300.f; // screen pixels per second - float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom; - float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom; + float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom; + float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom; - /* "mouse zoom" factor = 1 + (dx + dy) / 300 - * what about "ndof zoom" factor? should behave like this: - * at rest -> factor = 1 - * move forward -> factor > 1 - * move backward -> factor < 1 - */ - float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2]; + /* "mouse zoom" factor = 1 + (dx + dy) / 300 + * what about "ndof zoom" factor? should behave like this: + * at rest -> factor = 1 + * move forward -> factor > 1 + * move backward -> factor < 1 + */ + float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2]; - sima_zoom_set_factor(sima, ar, zoom_factor); - sima->xof += pan_x; - sima->yof += pan_y; + if (U.ndof_flag & NDOF_ZOOM_INVERT) + zoom_factor = -zoom_factor; - ED_region_tag_redraw(ar); + sima_zoom_set_factor(sima, ar, zoom_factor); + sima->xof += pan_x; + sima->yof += pan_y; - return OPERATOR_FINISHED; + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; + } } void IMAGE_OT_view_ndof(wmOperatorType *ot) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e6fd9e8867b..3e6bbc13334 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -949,134 +949,125 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event // -- zooming // -- panning in rotationally-locked views { - RegionView3D* rv3d = CTX_wm_region_view3d(C); - wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + RegionView3D* rv3d = CTX_wm_region_view3d(C); + wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; - rv3d->rot_angle = 0.f; // off by default, until changed later this function + rv3d->rot_angle = 0.f; // off by default, until changed later this function - if (ndof->progress != P_FINISHING) { - const float dt = ndof->dt; - - // tune these until everything feels right - const float rot_sensitivity = 1.f; - const float zoom_sensitivity = 1.f; - const float pan_sensitivity = 1.f; - - // rather have bool, but... - int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec); - - float view_inv[4]; - invert_qt_qt(view_inv, rv3d->viewquat); - - //#define DEBUG_NDOF_MOTION - #ifdef DEBUG_NDOF_MOTION - printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n", - ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); - #endif - - if (ndof->tvec[2]) { - // Zoom! - // velocity should be proportional to the linear velocity attained by rotational motion of same strength - // [got that?] - // proportional to arclength = radius * angle - - float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2]; - rv3d->dist += zoom_distance; - } - - if (rv3d->viewlock == RV3D_LOCKED) { - /* rotation not allowed -- explore panning options instead */ - float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f}; - mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); - - /* transform motion from view to world coordinates */ + if (ndof->progress != P_FINISHING) { + const float dt = ndof->dt; + + // tune these until everything feels right + const float rot_sensitivity = 1.f; + const float zoom_sensitivity = 1.f; + const float pan_sensitivity = 1.f; + + // rather have bool, but... + int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec); + + float view_inv[4]; invert_qt_qt(view_inv, rv3d->viewquat); - mul_qt_v3(view_inv, pan_vec); - - /* move center of view opposite of hand motion (this is camera mode, not object mode) */ - sub_v3_v3(rv3d->ofs, pan_vec); - } - - if (has_rotation) { - - const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; - - rv3d->view = RV3D_VIEW_USER; - - if (U.flag & USER_TRACKBALL) { - float rot[4]; - #if 0 // -------------------------- Mike's nifty original version - float view_inv_conj[4]; - - ndof_to_quat(ndof, rot); - // mul_qt_fl(rot, rot_sensitivity); - // ^^ no apparent effect - - if (invert) - invert_qt(rot); - - copy_qt_qt(view_inv_conj, view_inv); - conjugate_qt(view_inv_conj); - - // transform rotation from view to world coordinates - mul_qt_qtqt(rot, view_inv, rot); - mul_qt_qtqt(rot, rot, view_inv_conj); - #else // ---------------------------------------- Mike's revised version - float axis[3]; - float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); - - if (invert) - angle = -angle; - - // transform rotation axis from view to world coordinates - mul_qt_v3(view_inv, axis); - - // update the onscreen doo-dad - rv3d->rot_angle = angle; - copy_v3_v3(rv3d->rot_axis, axis); - - axis_angle_to_quat(rot, axis, angle); - #endif // -------------------------------------------- - // apply rotation - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); - } else { - /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ - float angle, rot[4]; - float xvec[3] = {1,0,0}; - - /* Determine the direction of the x vector (for rotating up and down) */ - mul_qt_v3(view_inv, xvec); - - /* Perform the up/down rotation */ - angle = rot_sensitivity * dt * ndof->rvec[0]; - if (invert) - angle = -angle; - rot[0] = cos(angle); - mul_v3_v3fl(rot+1, xvec, sin(angle)); - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); - - /* Perform the orbital rotation */ - angle = rot_sensitivity * dt * ndof->rvec[1]; - if (invert) - angle = -angle; - - // update the onscreen doo-dad - rv3d->rot_angle = angle; - rv3d->rot_axis[0] = 0; - rv3d->rot_axis[1] = 0; - rv3d->rot_axis[2] = 1; - - rot[0] = cos(angle); - rot[1] = rot[2] = 0.0; - rot[3] = sin(angle); - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + //#define DEBUG_NDOF_MOTION + #ifdef DEBUG_NDOF_MOTION + printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n", + ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); + #endif + + if (ndof->tvec[2]) { + // Zoom! + // velocity should be proportional to the linear velocity attained by rotational motion of same strength + // [got that?] + // proportional to arclength = radius * angle + + float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2]; + + if (U.ndof_flag & NDOF_ZOOM_INVERT) + zoom_distance = -zoom_distance; + + rv3d->dist += zoom_distance; + } + + if (rv3d->viewlock == RV3D_LOCKED) { + /* rotation not allowed -- explore panning options instead */ + float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f}; + mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); + + /* transform motion from view to world coordinates */ + invert_qt_qt(view_inv, rv3d->viewquat); + mul_qt_v3(view_inv, pan_vec); + + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ + sub_v3_v3(rv3d->ofs, pan_vec); + } + + if (has_rotation) { + + const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; + + rv3d->view = RV3D_VIEW_USER; + + if (U.flag & USER_TRACKBALL) { + float rot[4]; + float axis[3]; + float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); + + if (invert) + angle = -angle; + + // transform rotation axis from view to world coordinates + mul_qt_v3(view_inv, axis); + + // update the onscreen doo-dad + rv3d->rot_angle = angle; + copy_v3_v3(rv3d->rot_axis, axis); + + axis_angle_to_quat(rot, axis, angle); + + // apply rotation + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + } else { + /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ + float angle, rot[4]; + float xvec[3] = {1,0,0}; + + /* Determine the direction of the x vector (for rotating up and down) */ + mul_qt_v3(view_inv, xvec); + + /* Perform the up/down rotation */ + angle = rot_sensitivity * dt * ndof->rvec[0]; + if (invert) + angle = -angle; + rot[0] = cos(angle); + mul_v3_v3fl(rot+1, xvec, sin(angle)); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + /* Perform the orbital rotation */ + angle = rot_sensitivity * dt * ndof->rvec[1]; + if (invert) + angle = -angle; + + // update the onscreen doo-dad + rv3d->rot_angle = angle; + rv3d->rot_axis[0] = 0; + rv3d->rot_axis[1] = 0; + rv3d->rot_axis[2] = 1; + + rot[0] = cos(angle); + rot[1] = rot[2] = 0.0; + rot[3] = sin(angle); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + } } } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; } - - ED_region_tag_redraw(CTX_wm_region(C)); - - return OPERATOR_FINISHED; } void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot) @@ -1098,57 +1089,62 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) // -- "pan" navigation // -- zoom or dolly? { - RegionView3D* rv3d = CTX_wm_region_view3d(C); - wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + RegionView3D* rv3d = CTX_wm_region_view3d(C); + wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; - rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators - if (ndof->progress != P_FINISHING) { - const float dt = ndof->dt; - float view_inv[4]; + rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators + + if (ndof->progress != P_FINISHING) { + const float dt = ndof->dt; + float view_inv[4]; #if 0 // ------------------------------------------- zoom with Z - // tune these until everything feels right - const float zoom_sensitivity = 1.f; - const float pan_sensitivity = 1.f; + // tune these until everything feels right + const float zoom_sensitivity = 1.f; + const float pan_sensitivity = 1.f; - float pan_vec[3] = { - ndof->tx, ndof->ty, 0 - }; + float pan_vec[3] = { + ndof->tx, ndof->ty, 0 + }; - // "zoom in" or "translate"? depends on zoom mode in user settings? - if (ndof->tz) { - float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; - rv3d->dist += zoom_distance; - } - - mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); + // "zoom in" or "translate"? depends on zoom mode in user settings? + if (ndof->tz) { + float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; + rv3d->dist += zoom_distance; + } + + mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); #else // ------------------------------------------------------- dolly with Z - float speed = 10.f; // blender units per second - // ^^ this is ok for default cube scene, but should scale with.. something + float speed = 10.f; // blender units per second + // ^^ this is ok for default cube scene, but should scale with.. something - // tune these until everything feels right - const float forward_sensitivity = 1.f; - const float vertical_sensitivity = 0.4f; - const float lateral_sensitivity = 0.6f; + // tune these until everything feels right + const float forward_sensitivity = 1.f; + const float vertical_sensitivity = 0.4f; + const float lateral_sensitivity = 0.6f; - float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0], - vertical_sensitivity * ndof->tvec[1], - forward_sensitivity * ndof->tvec[2] - }; + float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0], + vertical_sensitivity * ndof->tvec[1], + forward_sensitivity * ndof->tvec[2] + }; - mul_v3_fl(pan_vec, speed * dt); + mul_v3_fl(pan_vec, speed * dt); #endif - /* transform motion from view to world coordinates */ - invert_qt_qt(view_inv, rv3d->viewquat); - mul_qt_v3(view_inv, pan_vec); + /* transform motion from view to world coordinates */ + invert_qt_qt(view_inv, rv3d->viewquat); + mul_qt_v3(view_inv, pan_vec); - /* move center of view opposite of hand motion (this is camera mode, not object mode) */ - sub_v3_v3(rv3d->ofs, pan_vec); + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ + sub_v3_v3(rv3d->ofs, pan_vec); + } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; } - - ED_region_tag_redraw(CTX_wm_region(C)); - - return OPERATOR_FINISHED; } void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot) From 6c821f4078414c81128ebf0d35187054df238371 Mon Sep 17 00:00:00 2001 From: Mike Erwin Date: Sat, 6 Aug 2011 23:13:36 +0000 Subject: [PATCH 36/41] stricter NDOF guards for Windows (forgot in earlier commit) --- build_files/scons/config/darwin-config.py | 1 + intern/ghost/intern/GHOST_SystemWin32.h | 2 ++ source/blender/makesdna/DNA_userdef_types.h | 2 +- source/blender/makesrna/intern/rna_userdef.c | 13 +++++++++++++ .../blender/windowmanager/intern/wm_event_system.c | 12 +++++++----- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index 560b6d9cb60..97e8e90e574 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -21,6 +21,7 @@ cmd = 'uname -p' MAC_PROC=commands.getoutput(cmd) cmd = 'uname -r' cmd_res=commands.getoutput(cmd) +MAC_CUR_VER='10.5' # by default (test below fails on my 10.5 PowerPC) if cmd_res[:2]=='7': MAC_CUR_VER='10.3' elif cmd_res[:2]=='8': diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index c5dff27dace..858312b3eb1 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -302,6 +302,7 @@ protected: */ static void processMinMaxInfo(MINMAXINFO * minmax); +#ifdef WITH_INPUT_NDOF /** * Handles Motion and Button events from a SpaceNavigator or related device. * Instead of returning an event object, this function communicates directly @@ -310,6 +311,7 @@ protected: * @return Whether an event was generated and sent. */ bool processNDOF(RAWINPUT const& raw); +#endif /** * Returns the local state of the modifier keys (from the message queue). diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index a555a196060..556f554eb98 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -603,7 +603,7 @@ extern UserDef U; /* from blenkernel blender.c */ #define NDOF_ORBIT_INVERT_AXES (1 << 6) /* zoom is up/down if this flag is set (otherwise forward/backward) */ #define NDOF_ZOOM_UPDOWN (1 << 7) -#define NDOF_INVERT_ZOOM (1 << 8) +#define NDOF_ZOOM_INVERT (1 << 8) #ifdef __cplusplus diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index b3dbafeab7d..57044188dd9 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2746,19 +2746,32 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Drag Threshold", "Amount of pixels you have to drag before dragging UI items happens"); /* 3D mouse settings */ + /* global options */ prop= RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.25f, 4.0f); RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse"); + prop= RNA_def_property(srna, "ndof_zoom_updown", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_UPDOWN); + RNA_def_property_ui_text(prop, "Zoom = Up/Down", "Zoom using up/down on the device (otherwise forward/backward)"); + + prop= RNA_def_property(srna, "ndof_zoom_invert", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_INVERT); + RNA_def_property_ui_text(prop, "Invert Zoom", "Zoom using opposite direction"); + + /* 3D view */ prop= RNA_def_property(srna, "ndof_show_guide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_SHOW_GUIDE); RNA_def_property_ui_text(prop, "Show Navigation Guide", "Display the center and axis during rotation"); /* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/ + /* 3D view: orbit */ prop= RNA_def_property(srna, "ndof_orbit_invert_axes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ORBIT_INVERT_AXES); RNA_def_property_ui_text(prop, "Invert Axes", "Toggle between moving the viewpoint or moving the scene being viewed"); + /* in 3Dx docs, this is called 'object mode' vs. 'target camera mode' + /* 3D view: fly */ prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON); RNA_def_property_ui_text(prop, "Lock Horizon", "Keep horizon level while flying with 3D Mouse"); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 0dac0bd7401..258d6bbc025 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2330,26 +2330,28 @@ static void attach_ndof_data(wmEvent* event, const GHOST_TEventNDOFMotionData* g const float s = U.ndof_sensitivity; data->tvec[0]= s * ghost->tx; + data->rvec[0]= s * ghost->rx; + data->rvec[1]= s * ghost->ry; + data->rvec[2]= s * ghost->rz; if (U.ndof_flag & NDOF_ZOOM_UPDOWN) { - // swap Y and Z + // rotate so Y is where Z was (maintain handed-ness) data->tvec[1]= s * ghost->tz; - data->tvec[2]= s * ghost->ty; + data->tvec[2]= s * -ghost->ty; // should this affect rotation also? // initial guess is 'yes', but get user feedback immediately! +#if 0 // after turning this on, my guess becomes 'no' data->rvec[1]= s * ghost->rz; data->rvec[2]= s * ghost->ry; +#endif } else { data->tvec[1]= s * ghost->ty; data->tvec[2]= s * ghost->tz; - - data->rvec[1]= s * ghost->ry; - data->rvec[2]= s * ghost->rz; } data->dt = ghost->dt; From 117ec4a91ac996480611788998645bd6de40d706 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Aug 2011 04:22:33 +0000 Subject: [PATCH 37/41] comment unused vars --- .../editors/interface/interface_handlers.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index d8d8354b0b9..6f3ca2bf003 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2856,7 +2856,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) { - int mx, my, click= 0; + int mx, my /*, click= 0 */; int retval= WM_UI_HANDLER_CONTINUE; int horizontal= (but->x2 - but->x1 > but->y2 - but->y1); @@ -2878,8 +2878,10 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval= WM_UI_HANDLER_BREAK; } - else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS) + /* UNUSED - otherwise code is ok, add back if needed */ + /* else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS) click= 1; + */ } } else if(data->state == BUTTON_STATE_NUM_EDITING) { @@ -3677,6 +3679,9 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt return WM_UI_HANDLER_BREAK; } + /* UNUSED but keep for now */ + (void)changed; + return WM_UI_HANDLER_CONTINUE; } @@ -3691,12 +3696,12 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx Histogram *hist = (Histogram *)but->poin; /* rcti rect; */ int changed= 1; - float dx, dy, yfac=1.f; + float /* dx, */ dy, yfac=1.f; /* UNUSED */ /* rect.xmin= but->x1; rect.xmax= but->x2; */ /* rect.ymin= but->y1; rect.ymax= but->y2; */ - dx = mx - data->draglastx; + /* dx = mx - data->draglastx; */ /* UNUSED */ dy = my - data->draglasty; @@ -3774,12 +3779,12 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, Scopes *scopes = (Scopes *)but->poin; /* rcti rect; */ int changed= 1; - float dx, dy, yfac=1.f; + float /* dx, */ dy /* , yfac=1.f */; /* UNUSED */ /* rect.xmin= but->x1; rect.xmax= but->x2; */ /* rect.ymin= but->y1; rect.ymax= but->y2; */ - dx = mx - data->draglastx; + /* dx = mx - data->draglastx; */ /* UNUSED */ dy = my - data->draglasty; @@ -3788,7 +3793,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, scopes->wavefrm_height = (but->y2 - but->y1) + (data->dragstarty - my); } else { /* scale waveform values */ - yfac = scopes->wavefrm_yfac; + /* yfac = scopes->wavefrm_yfac; */ /* UNUSED */ scopes->wavefrm_yfac += dy/200.0f; CLAMP(scopes->wavefrm_yfac, 0.5f, 2.f); From 38280ba38ed48d45e782e989a32b33510432d172 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Aug 2011 04:55:58 +0000 Subject: [PATCH 38/41] fix [#28172] Cannot restore Add-ons tab in user preferences after a failed attempt to install an add-on. non utf8 addons would make the addon UI vanish, now give a message in the console and UI. --- release/scripts/modules/addon_utils.py | 25 +++++++++++++++++-- .../scripts/startup/bl_ui/space_userpref.py | 6 +++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 22936f4c209..0c5ef69e805 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -32,6 +32,7 @@ import bpy as _bpy error_duplicates = False +error_encoding = False def paths(): @@ -51,14 +52,18 @@ def paths(): def modules(module_cache): global error_duplicates + global error_encoding import os error_duplicates = False + error_encoding = False path_list = paths() # fake module importing def fake_module(mod_name, mod_path, speedy=True): + global error_encoding + if _bpy.app.debug: print("fake_module", mod_path, mod_name) import ast @@ -69,12 +74,28 @@ def modules(module_cache): line_iter = iter(file_mod) l = "" while not l.startswith("bl_info"): - l = line_iter.readline() + try: + l = line_iter.readline() + except UnicodeDecodeError as e: + if not error_encoding: + error_encoding = True + print("Error reading file as UTF-8:", mod_path, e) + file_mod.close() + return None + if len(l) == 0: break while l.rstrip(): lines.append(l) - l = line_iter.readline() + try: + l = line_iter.readline() + except UnicodeDecodeError as e: + if not error_encoding: + error_encoding = True + print("Error reading file as UTF-8:", mod_path, e) + file_mod.close() + return None + data = "".join(lines) else: diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index e27bd8ef07a..e6fd8dcb949 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -949,6 +949,12 @@ class USERPREF_PT_addons(bpy.types.Panel): "(see console for details)", ) + if addon_utils.error_encoding: + self.draw_error(col, + "One or more addons do not have UTF-8 encoding\n" + "(see console for details)", + ) + filter = context.window_manager.addon_filter search = context.window_manager.addon_search.lower() support = context.window_manager.addon_support From a02d7c1ba76adbf3ff432111af4c3c81a0812c3a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 7 Aug 2011 11:01:55 +0000 Subject: [PATCH 39/41] Fix #28169: keymap bug when using a preset configuration, e.g. object mode keymap was also being used in edit mode. --- source/blender/windowmanager/intern/wm_keymap.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index bf48f0e21e4..2fb0a1b2ab9 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -532,7 +532,7 @@ static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km) } } -static void wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap) +static wmKeyMap *wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap) { wmKeyMap *km; int expanded = 0; @@ -552,8 +552,6 @@ static void wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap wmKeyMapItem *kmi, *orig_kmi; km = wm_keymap_copy(usermap); - km->modal_items = defaultmap->modal_items; - km->poll = defaultmap->poll; /* try to find corresponding id's for items */ for(kmi=km->items.first; kmi; kmi=kmi->next) { @@ -587,6 +585,8 @@ static void wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap /* add to list */ BLI_addtail(lb, km); + + return km; } static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *km) @@ -977,7 +977,7 @@ static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km) void WM_keyconfig_update(wmWindowManager *wm) { - wmKeyMap *km, *defaultmap, *addonmap, *usermap; + wmKeyMap *km, *defaultmap, *addonmap, *usermap, *kmn; wmKeyMapItem *kmi; wmKeyMapDiffItem *kmdi; int compat_update = 0; @@ -1021,7 +1021,12 @@ void WM_keyconfig_update(wmWindowManager *wm) usermap= WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid); /* add */ - wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap); + kmn= wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap); + + if(kmn) { + kmn->modal_items= km->modal_items; + kmn->poll= km->poll; + } /* in case of old non-diff keymaps, force extra update to create diffs */ compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF)); From 0dea4df76442ffce1e0e7162fab103f6cca99b12 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 7 Aug 2011 14:57:25 +0000 Subject: [PATCH 40/41] Changed do_version condition for noodle_curving. It should be re-set to 5 for files saved in 2.58.1 release. --- source/blender/editors/interface/resources.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index f3db6ad11ae..e71f709f89b 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1557,7 +1557,7 @@ void init_userdef_do_versions(void) U.autokey_flag &= ~AUTOKEY_FLAG_ONLYKEYINGSET; } - if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 1)) { + if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 2)) { bTheme *btheme; for(btheme= U.themes.first; btheme; btheme= btheme->next) { btheme->tnode.noodle_curving = 5; From bf23acf3bb8ae43e6a50108a00e7572fe35edea4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Aug 2011 15:06:35 +0000 Subject: [PATCH 41/41] fix for building ndof with cmake on osx --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0a0359d8d7..cf083b87bc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1010,6 +1010,10 @@ elseif(APPLE) if(NOT 3D_CONNEXION_CLIENT_LIBRARY) set(WITH_INPUT_NDOF OFF) endif() + + if(WITH_INPUT_NDOF) + set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient") + endif() endif() else()