2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2007-12-24 18:27:28 +00:00
|
|
|
* ***** 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2007-12-24 18:27:28 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2007 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Contributor(s): Blender Foundation
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-02-25 14:04:21 +00:00
|
|
|
/** \file blender/windowmanager/intern/wm_operators.c
|
|
|
|
* \ingroup wm
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-01-24 16:59:55 +00:00
|
|
|
#include <float.h>
|
2007-12-24 18:27:28 +00:00
|
|
|
#include <string.h>
|
2009-07-17 12:26:40 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdio.h>
|
2010-08-13 15:26:37 +00:00
|
|
|
#include <stddef.h>
|
2010-10-31 14:43:30 +00:00
|
|
|
#include <assert.h>
|
2010-11-11 20:32:28 +00:00
|
|
|
|
2011-05-02 08:07:24 +00:00
|
|
|
#include "GHOST_C-api.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2008-01-14 19:44:20 +00:00
|
|
|
#include "DNA_ID.h"
|
2009-09-14 10:56:40 +00:00
|
|
|
#include "DNA_object_types.h"
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
#include "DNA_screen_types.h"
|
2009-05-19 15:37:50 +00:00
|
|
|
#include "DNA_scene_types.h"
|
2008-12-19 18:28:37 +00:00
|
|
|
#include "DNA_userdef_types.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "DNA_windowmanager_types.h"
|
2011-12-28 13:50:33 +00:00
|
|
|
#include "DNA_mesh_types.h" /* only for USE_BMESH_SAVE_AS_COMPAT */
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2011-09-20 07:39:25 +00:00
|
|
|
#include "BLF_translation.h"
|
2010-01-08 05:51:51 +00:00
|
|
|
|
2009-05-19 12:54:54 +00:00
|
|
|
#include "PIL_time.h"
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "BLI_blenlib.h"
|
2008-12-26 03:56:52 +00:00
|
|
|
#include "BLI_dynstr.h" /*for WM_operator_pystring */
|
2010-01-26 11:25:39 +00:00
|
|
|
#include "BLI_math.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2011-08-11 06:06:17 +00:00
|
|
|
#include "BLI_ghash.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2009-09-12 19:54:39 +00:00
|
|
|
#include "BLO_readfile.h"
|
|
|
|
|
2013-06-18 18:11:52 +00:00
|
|
|
#include "BKE_autoexec.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "BKE_blender.h"
|
2011-05-12 01:57:47 +00:00
|
|
|
#include "BKE_brush.h"
|
2008-12-18 02:56:48 +00:00
|
|
|
#include "BKE_context.h"
|
2009-09-12 19:54:39 +00:00
|
|
|
#include "BKE_depsgraph.h"
|
2.5: work on bringing back SpaceTime options
- RMB select, also with SHIFT
- RMB tweak for translate
- SHIFT+D dupli
- BKEY border select/deselect
- AKEY (de)select all
- XKEY delete
- GKEY grab
Added some XXX comments for future todos, especially for when other
spaces come back with time markers.
Also added ED_util for putting in all to-be-cleaned cruft
Context conflict: input methods for Markers can conflict with other
spacetypes. It was solved in pre-2.5 with manually tweaking it all over,
but I would prefer one keymap for all marker stuff. Needs some thinking...
could be solved with a boundbox check for bottom part of 2d window.
Tweak issue: both tweak styles are possible:
- Hold mouse button, move, operator ends on mouse release
- Hold mouse button, move, operator ends on mouse click
Problem is that modally handled operators use fixed keymaps... like ESC,
SPACE, ENTER, or press/release mousebutton for 'assign'. There's a lot
to say for making this all consistant, or become part of 1 general keymap?
Should also be possibe to define 'tweak' defaults for Tablet different
than for mouse...
2008-11-29 15:10:31 +00:00
|
|
|
#include "BKE_idprop.h"
|
2012-04-24 02:01:23 +00:00
|
|
|
#include "BKE_image.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "BKE_library.h"
|
2008-12-19 18:28:37 +00:00
|
|
|
#include "BKE_global.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "BKE_main.h"
|
2013-01-22 04:24:01 +00:00
|
|
|
#include "BKE_material.h"
|
2009-09-12 19:54:39 +00:00
|
|
|
#include "BKE_report.h"
|
2009-05-19 15:37:50 +00:00
|
|
|
#include "BKE_scene.h"
|
2009-10-06 13:04:31 +00:00
|
|
|
#include "BKE_screen.h" /* BKE_ST_MAXNAME */
|
2012-11-07 04:13:03 +00:00
|
|
|
#include "BKE_utildefines.h"
|
2011-01-07 19:18:31 +00:00
|
|
|
|
2010-08-10 15:14:19 +00:00
|
|
|
#include "BKE_idcode.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2009-01-24 16:59:55 +00:00
|
|
|
#include "BIF_gl.h"
|
|
|
|
#include "BIF_glutil.h" /* for paint cursor */
|
2011-06-10 04:36:51 +00:00
|
|
|
#include "BLF_api.h"
|
2009-05-19 12:54:54 +00:00
|
|
|
|
2012-10-09 11:31:25 +00:00
|
|
|
#include "IMB_colormanagement.h"
|
2009-01-24 22:58:22 +00:00
|
|
|
#include "IMB_imbuf_types.h"
|
2011-09-17 16:57:37 +00:00
|
|
|
#include "IMB_imbuf.h"
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2009-01-06 14:42:54 +00:00
|
|
|
#include "ED_screen.h"
|
2009-04-01 14:02:06 +00:00
|
|
|
#include "ED_util.h"
|
2012-05-03 01:07:16 +00:00
|
|
|
#include "ED_object.h"
|
2012-12-09 10:48:18 +00:00
|
|
|
#include "ED_view3d.h"
|
2009-01-06 14:42:54 +00:00
|
|
|
|
2008-11-21 19:14:38 +00:00
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_define.h"
|
2011-02-13 14:16:36 +00:00
|
|
|
#include "RNA_enum_types.h"
|
2008-11-21 19:14:38 +00:00
|
|
|
|
2008-12-15 19:19:39 +00:00
|
|
|
#include "UI_interface.h"
|
2008-12-17 15:38:40 +00:00
|
|
|
#include "UI_resources.h"
|
2008-12-15 19:19:39 +00:00
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
|
2008-11-24 10:45:36 +00:00
|
|
|
#include "wm.h"
|
2009-05-19 12:54:54 +00:00
|
|
|
#include "wm_draw.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "wm_event_system.h"
|
2009-11-05 17:32:06 +00:00
|
|
|
#include "wm_event_types.h"
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
#include "wm_files.h"
|
2009-05-19 12:54:54 +00:00
|
|
|
#include "wm_subwindow.h"
|
|
|
|
#include "wm_window.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
static GHash *global_ops_hash = NULL;
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2013-02-28 15:31:20 +00:00
|
|
|
#define UNDOCUMENTED_OPERATOR_TIP N_("(undocumented operator)")
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
/* ************ operator API, exported ********** */
|
|
|
|
|
2009-07-17 12:26:40 +00:00
|
|
|
|
2013-04-04 02:05:11 +00:00
|
|
|
wmOperatorType *WM_operatortype_find(const char *idname, bool quiet)
|
2007-12-24 18:27:28 +00:00
|
|
|
{
|
2012-03-24 06:24:53 +00:00
|
|
|
if (idname[0]) {
|
2011-09-02 08:01:01 +00:00
|
|
|
wmOperatorType *ot;
|
|
|
|
|
|
|
|
/* needed to support python style names without the _OT_ syntax */
|
|
|
|
char idname_bl[OP_MAX_TYPENAME];
|
|
|
|
WM_operator_bl_idname(idname_bl, idname);
|
2010-08-13 06:30:04 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
ot = BLI_ghash_lookup(global_ops_hash, idname_bl);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ot) {
|
2010-08-13 06:30:04 +00:00
|
|
|
return ot;
|
2009-09-08 02:09:14 +00:00
|
|
|
}
|
2011-09-02 08:01:01 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!quiet) {
|
2011-09-02 08:01:01 +00:00
|
|
|
printf("search for unknown operator '%s', '%s'\n", idname_bl, idname);
|
|
|
|
}
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
2011-09-02 08:01:01 +00:00
|
|
|
else {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!quiet) {
|
2011-09-02 08:01:01 +00:00
|
|
|
printf("search for empty operator\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-08-11 06:06:17 +00:00
|
|
|
/* caller must free */
|
|
|
|
GHashIterator *WM_operatortype_iter(void)
|
2008-12-21 08:53:36 +00:00
|
|
|
{
|
2011-08-11 06:06:17 +00:00
|
|
|
return BLI_ghashIterator_new(global_ops_hash);
|
2008-12-21 08:53:36 +00:00
|
|
|
}
|
|
|
|
|
2008-01-07 18:03:41 +00:00
|
|
|
/* all ops in 1 list (for time being... needs evaluation later) */
|
2012-03-27 01:24:16 +00:00
|
|
|
void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
|
2008-01-07 18:03:41 +00:00
|
|
|
{
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
wmOperatorType *ot;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
|
2013-01-09 05:32:15 +00:00
|
|
|
ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
|
2012-03-16 15:39:25 +00:00
|
|
|
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
|
Fixed another bunch of i18n bugs (thx to Leon Cheung for spotting them), among which:
* Drag'n'drop translation in Outliner
* "Execute" button in file window
* "Labels" of spacing elements, in multi-column enums
* A glitch with nodes "Value to RGB", they where called "ColorRamp" in node_type_base() call. This is not definitive, though, as it appears that UI node names are determined by this call, while it should be by "defines" in rna_nodetrre_types.h, I guess... Anyway, not good to have such things in two different places!
Also moved default context name under BLF_translation.h, much better to have those all in one place, accessible from whole Blender code!
2012-04-14 15:06:41 +00:00
|
|
|
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
opfunc(ot);
|
2009-07-19 14:57:20 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (ot->name == NULL) {
|
2009-07-19 14:57:20 +00:00
|
|
|
fprintf(stderr, "ERROR: Operator %s has no name property!\n", ot->idname);
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = N_("Dummy Name");
|
2009-07-19 14:57:20 +00:00
|
|
|
}
|
|
|
|
|
2012-06-17 11:36:28 +00:00
|
|
|
/* XXX All ops should have a description but for now allow them not to. */
|
2013-02-28 15:31:20 +00:00
|
|
|
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
|
2008-12-19 04:06:24 +00:00
|
|
|
RNA_def_struct_identifier(ot->srna, ot->idname);
|
2011-08-11 06:06:17 +00:00
|
|
|
|
|
|
|
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
|
2008-01-07 18:03:41 +00:00
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
{
|
|
|
|
wmOperatorType *ot;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
|
2013-01-09 05:32:15 +00:00
|
|
|
ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
|
2012-03-16 15:39:25 +00:00
|
|
|
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
|
Fixed another bunch of i18n bugs (thx to Leon Cheung for spotting them), among which:
* Drag'n'drop translation in Outliner
* "Execute" button in file window
* "Labels" of spacing elements, in multi-column enums
* A glitch with nodes "Value to RGB", they where called "ColorRamp" in node_type_base() call. This is not definitive, though, as it appears that UI node names are determined by this call, while it should be by "defines" in rna_nodetrre_types.h, I guess... Anyway, not good to have such things in two different places!
Also moved default context name under BLF_translation.h, much better to have those all in one place, accessible from whole Blender code!
2012-04-14 15:06:41 +00:00
|
|
|
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
opfunc(ot, userdata);
|
2013-02-28 15:31:20 +00:00
|
|
|
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
RNA_def_struct_identifier(ot->srna, ot->idname);
|
2011-08-11 06:06:17 +00:00
|
|
|
|
|
|
|
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
}
|
|
|
|
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
/* ********************* macro operator ******************** */
|
|
|
|
|
2009-11-21 19:49:11 +00:00
|
|
|
typedef struct {
|
|
|
|
int retval;
|
|
|
|
} MacroData;
|
|
|
|
|
|
|
|
static void wm_macro_start(wmOperator *op)
|
|
|
|
{
|
|
|
|
if (op->customdata == NULL) {
|
|
|
|
op->customdata = MEM_callocN(sizeof(MacroData), "MacroData");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_macro_end(wmOperator *op, int retval)
|
|
|
|
{
|
|
|
|
if (retval & OPERATOR_CANCELLED) {
|
|
|
|
MacroData *md = op->customdata;
|
|
|
|
|
|
|
|
if (md->retval & OPERATOR_FINISHED) {
|
|
|
|
retval |= OPERATOR_FINISHED;
|
|
|
|
retval &= ~OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if modal is ending, free custom data */
|
2012-03-27 01:24:16 +00:00
|
|
|
if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) {
|
2009-11-21 19:49:11 +00:00
|
|
|
if (op->customdata) {
|
|
|
|
MEM_freeN(op->customdata);
|
2010-01-04 20:18:13 +00:00
|
|
|
op->customdata = NULL;
|
2009-11-21 19:49:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
/* macro exec only runs exec calls */
|
|
|
|
static int wm_macro_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
wmOperator *opm;
|
2012-03-27 01:24:16 +00:00
|
|
|
int retval = OPERATOR_FINISHED;
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2009-11-21 19:49:11 +00:00
|
|
|
wm_macro_start(op);
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (opm = op->macro.first; opm; opm = opm->next) {
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (opm->type->exec) {
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = opm->type->exec(C, opm);
|
2011-08-25 16:42:42 +00:00
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2009-11-21 19:49:11 +00:00
|
|
|
if (retval & OPERATOR_FINISHED) {
|
|
|
|
MacroData *md = op->customdata;
|
|
|
|
md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
|
2012-03-24 06:24:53 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-11-21 19:49:11 +00:00
|
|
|
break; /* operator didn't finish, end macro */
|
|
|
|
}
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
}
|
2013-04-26 18:12:05 +00:00
|
|
|
else {
|
|
|
|
printf("%s: '%s' cant exec macro\n", __func__, opm->type->idname);
|
|
|
|
}
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
}
|
|
|
|
|
2009-11-21 19:49:11 +00:00
|
|
|
return wm_macro_end(op, retval);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_macro_invoke_internal(bContext *C, wmOperator *op, const wmEvent *event, wmOperator *opm)
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
int retval = OPERATOR_FINISHED;
|
2009-11-17 22:19:48 +00:00
|
|
|
|
|
|
|
/* start from operator received as argument */
|
2012-03-27 01:24:16 +00:00
|
|
|
for (; opm; opm = opm->next) {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (opm->type->invoke)
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = opm->type->invoke(C, opm, event);
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (opm->type->exec)
|
2012-03-27 01:24:16 +00:00
|
|
|
retval = opm->type->exec(C, opm);
|
2009-11-17 22:19:48 +00:00
|
|
|
|
2011-08-25 16:42:42 +00:00
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
|
|
|
|
2010-12-21 14:49:34 +00:00
|
|
|
BLI_movelisttolist(&op->reports->list, &opm->reports->list);
|
2010-12-21 14:08:58 +00:00
|
|
|
|
2009-11-21 19:49:11 +00:00
|
|
|
if (retval & OPERATOR_FINISHED) {
|
|
|
|
MacroData *md = op->customdata;
|
|
|
|
md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
|
2012-03-24 06:24:53 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-11-21 19:49:11 +00:00
|
|
|
break; /* operator didn't finish, end macro */
|
|
|
|
}
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
}
|
2009-11-17 22:19:48 +00:00
|
|
|
|
2009-11-21 19:49:11 +00:00
|
|
|
return wm_macro_end(op, retval);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_macro_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-11-17 22:19:48 +00:00
|
|
|
{
|
2009-11-21 19:49:11 +00:00
|
|
|
wm_macro_start(op);
|
2009-11-17 22:19:48 +00:00
|
|
|
return wm_macro_invoke_internal(C, op, event, op->macro.first);
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
{
|
2009-11-17 22:19:48 +00:00
|
|
|
wmOperator *opm = op->opm;
|
2012-03-27 01:24:16 +00:00
|
|
|
int retval = OPERATOR_FINISHED;
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (opm == NULL)
|
2011-11-07 04:36:37 +00:00
|
|
|
printf("%s: macro error, calling NULL modal()\n", __func__);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
else {
|
2009-11-17 22:19:48 +00:00
|
|
|
retval = opm->type->modal(C, opm, event);
|
2011-08-25 16:42:42 +00:00
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
2009-11-17 22:19:48 +00:00
|
|
|
|
2013-11-29 16:01:03 +11:00
|
|
|
/* if we're halfway through using a tool and cancel it, clear the options [#37149] */
|
|
|
|
if (retval & OPERATOR_CANCELLED) {
|
|
|
|
WM_operator_properties_clear(opm->ptr);
|
|
|
|
}
|
|
|
|
|
2009-11-17 22:19:48 +00:00
|
|
|
/* if this one is done but it's not the last operator in the macro */
|
|
|
|
if ((retval & OPERATOR_FINISHED) && opm->next) {
|
2009-11-21 19:49:11 +00:00
|
|
|
MacroData *md = op->customdata;
|
|
|
|
|
|
|
|
md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
|
2011-05-04 20:42:34 +00:00
|
|
|
|
|
|
|
retval = wm_macro_invoke_internal(C, op, event, opm->next);
|
|
|
|
|
|
|
|
/* if new operator is modal and also added its own handler */
|
|
|
|
if (retval & OPERATOR_RUNNING_MODAL && op->opm != opm) {
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2013-07-19 10:39:55 +00:00
|
|
|
wmEventHandler *handler;
|
2011-05-04 20:42:34 +00:00
|
|
|
|
2013-07-19 10:39:55 +00:00
|
|
|
handler = BLI_findptr(&win->modalhandlers, op, offsetof(wmEventHandler, op));
|
2011-05-04 20:42:34 +00:00
|
|
|
if (handler) {
|
|
|
|
BLI_remlink(&win->modalhandlers, handler);
|
|
|
|
wm_event_free_handler(handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if operator is blocking, grab cursor
|
|
|
|
* This may end up grabbing twice, but we don't care.
|
|
|
|
* */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->opm->type->flag & OPTYPE_BLOCKING) {
|
2012-03-27 01:24:16 +00:00
|
|
|
int bounds[4] = {-1, -1, -1, -1};
|
2011-05-04 20:42:34 +00:00
|
|
|
int wrap = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->opm->flag & OP_GRAB_POINTER) || (op->opm->type->flag & OPTYPE_GRAB_POINTER));
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (wrap) {
|
2012-03-27 01:24:16 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ar) {
|
2012-03-27 01:24:16 +00:00
|
|
|
bounds[0] = ar->winrct.xmin;
|
|
|
|
bounds[1] = ar->winrct.ymax;
|
|
|
|
bounds[2] = ar->winrct.xmax;
|
|
|
|
bounds[3] = ar->winrct.ymin;
|
2009-11-19 19:27:10 +00:00
|
|
|
}
|
|
|
|
}
|
2011-05-04 20:42:34 +00:00
|
|
|
|
2013-04-04 15:16:29 +00:00
|
|
|
WM_cursor_grab_enable(CTX_wm_window(C), wrap, false, bounds);
|
2009-11-19 19:27:10 +00:00
|
|
|
}
|
2009-11-17 22:19:48 +00:00
|
|
|
}
|
|
|
|
}
|
2009-11-21 19:49:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return wm_macro_end(op, retval);
|
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
static void wm_macro_cancel(bContext *C, wmOperator *op)
|
2009-11-21 19:49:11 +00:00
|
|
|
{
|
|
|
|
/* call cancel on the current modal operator, if any */
|
|
|
|
if (op->opm && op->opm->type->cancel) {
|
|
|
|
op->opm->type->cancel(C, op->opm);
|
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
wm_macro_end(op, OPERATOR_CANCELLED);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Names have to be static for now */
|
2012-05-05 19:26:53 +00:00
|
|
|
wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag)
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
{
|
|
|
|
wmOperatorType *ot;
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (WM_operatortype_find(idname, TRUE)) {
|
2011-11-07 04:36:37 +00:00
|
|
|
printf("%s: macro error: operator %s exists\n", __func__, idname);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
|
2013-01-09 05:32:15 +00:00
|
|
|
ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = idname;
|
|
|
|
ot->name = name;
|
2012-05-05 19:26:53 +00:00
|
|
|
ot->description = description;
|
2012-03-27 01:24:16 +00:00
|
|
|
ot->flag = OPTYPE_MACRO | flag;
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = wm_macro_exec;
|
|
|
|
ot->invoke = wm_macro_invoke;
|
|
|
|
ot->modal = wm_macro_modal;
|
|
|
|
ot->cancel = wm_macro_cancel;
|
|
|
|
ot->poll = NULL;
|
2010-01-21 21:58:40 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!ot->description) /* XXX All ops should have a description but for now allow them not to. */
|
2013-02-28 15:31:20 +00:00
|
|
|
ot->description = UNDOCUMENTED_OPERATOR_TIP;
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2012-03-16 15:39:25 +00:00
|
|
|
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
RNA_def_struct_identifier(ot->srna, ot->idname);
|
2013-03-15 14:32:29 +00:00
|
|
|
/* Use i18n context from ext.srna if possible (py operators). */
|
|
|
|
RNA_def_struct_translation_context(ot->srna, ot->ext.srna ? RNA_struct_translation_context(ot->ext.srna) :
|
|
|
|
BLF_I18NCONTEXT_OPERATOR_DEFAULT);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
2011-08-11 06:06:17 +00:00
|
|
|
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
|
|
|
|
return ot;
|
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
|
2009-12-05 19:27:26 +00:00
|
|
|
{
|
|
|
|
wmOperatorType *ot;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
|
2013-01-09 05:32:15 +00:00
|
|
|
ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
|
2009-12-05 19:27:26 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = OPTYPE_MACRO;
|
|
|
|
ot->exec = wm_macro_exec;
|
|
|
|
ot->invoke = wm_macro_invoke;
|
|
|
|
ot->modal = wm_macro_modal;
|
|
|
|
ot->cancel = wm_macro_cancel;
|
|
|
|
ot->poll = NULL;
|
2009-12-05 19:27:26 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!ot->description)
|
2013-02-28 15:31:20 +00:00
|
|
|
ot->description = UNDOCUMENTED_OPERATOR_TIP;
|
2010-01-21 21:58:40 +00:00
|
|
|
|
2012-03-16 15:39:25 +00:00
|
|
|
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
|
Fixed another bunch of i18n bugs (thx to Leon Cheung for spotting them), among which:
* Drag'n'drop translation in Outliner
* "Execute" button in file window
* "Labels" of spacing elements, in multi-column enums
* A glitch with nodes "Value to RGB", they where called "ColorRamp" in node_type_base() call. This is not definitive, though, as it appears that UI node names are determined by this call, while it should be by "defines" in rna_nodetrre_types.h, I guess... Anyway, not good to have such things in two different places!
Also moved default context name under BLF_translation.h, much better to have those all in one place, accessible from whole Blender code!
2012-04-14 15:06:41 +00:00
|
|
|
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
|
2009-12-05 19:27:26 +00:00
|
|
|
opfunc(ot, userdata);
|
|
|
|
|
2010-01-21 21:58:40 +00:00
|
|
|
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
|
2009-12-05 19:27:26 +00:00
|
|
|
RNA_def_struct_identifier(ot->srna, ot->idname);
|
|
|
|
|
2011-08-11 06:06:17 +00:00
|
|
|
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
|
2009-12-05 19:27:26 +00:00
|
|
|
}
|
|
|
|
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOperatorTypeMacro *otmacro = MEM_callocN(sizeof(wmOperatorTypeMacro), "wmOperatorTypeMacro");
|
2011-02-25 04:15:45 +00:00
|
|
|
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
BLI_strncpy(otmacro->idname, idname, OP_MAX_TYPENAME);
|
|
|
|
|
|
|
|
/* do this on first use, since operatordefinitions might have been not done yet */
|
2009-10-12 12:54:08 +00:00
|
|
|
WM_operator_properties_alloc(&(otmacro->ptr), &(otmacro->properties), idname);
|
2010-02-01 18:26:45 +00:00
|
|
|
WM_operator_properties_sanitize(otmacro->ptr, 1);
|
2011-02-25 04:15:45 +00:00
|
|
|
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
BLI_addtail(&ot->macro, otmacro);
|
2010-01-21 21:58:40 +00:00
|
|
|
|
|
|
|
{
|
2012-03-18 07:38:51 +00:00
|
|
|
/* operator should always be found but in the event its not. don't segfault */
|
2010-01-21 21:58:40 +00:00
|
|
|
wmOperatorType *otsub = WM_operatortype_find(idname, 0);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (otsub) {
|
2011-02-25 04:15:45 +00:00
|
|
|
RNA_def_pointer_runtime(ot->srna, otsub->idname, otsub->srna,
|
2012-03-27 01:24:16 +00:00
|
|
|
otsub->name, otsub->description);
|
2011-02-25 04:15:45 +00:00
|
|
|
}
|
2010-01-21 21:58:40 +00:00
|
|
|
}
|
2011-02-25 04:15:45 +00:00
|
|
|
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
return otmacro;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wm_operatortype_free_macro(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
wmOperatorTypeMacro *otmacro;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (otmacro = ot->macro.first; otmacro; otmacro = otmacro->next) {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (otmacro->ptr) {
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
WM_operator_properties_free(otmacro->ptr);
|
|
|
|
MEM_freeN(otmacro->ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BLI_freelistN(&ot->macro);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
int WM_operatortype_remove(const char *idname)
|
|
|
|
{
|
2009-07-13 08:33:51 +00:00
|
|
|
wmOperatorType *ot = WM_operatortype_find(idname, 0);
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (ot == NULL)
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
RNA_struct_free(&BLENDER_RNA, ot->srna);
|
2012-03-21 06:33:31 +00:00
|
|
|
|
|
|
|
if (ot->last_properties) {
|
|
|
|
IDP_FreeProperty(ot->last_properties);
|
|
|
|
MEM_freeN(ot->last_properties);
|
|
|
|
}
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ot->macro.first)
|
2.5
Operator goodies!
--- Macro operators
Operators now can consist of multiple operators. Such a macro operator
is identical and behaves identical to other opererators. Macros can
also be constructed of macros even! Currently only hardcoded macros are
implemented, this to solve combined operators such as 'add duplicate' or
'extrude' (both want a transform appended).
Usage is simple:
- WM_operatortype_append_macro() : add new operatortype, name, flags
- WM_operatortype_macro_define() : add existing operator to macro
(Note: macro_define will also allow properties to be set, doesnt work
right now)
On converting the macro wmOperatorType to a real operator, it makes a
list of all operators, and the standard macro callbacks (exec, invoke,
modal, poll) just will use all.
Important note; switching to a modal operator only works as last in the
chain now!
Macros implemented for duplicate, extrude and rip. Tool menu works fine
for it, also the redo hotkey F4 works properly.
--- Operator redo fix
The operators use the undo system to switch back, but this could give
errors if other actions added undo pushes (buttons, outliner). Now the
redo for operator searches back for the correct undo level.
This fixes issues with many redos.
Note for brecht: removed the ED_undo_push for buttons... it was called
on *every* button now, which is probably too much? For example, using
the 'toolbar' redo also caused this...
2009-07-29 17:56:38 +00:00
|
|
|
wm_operatortype_free_macro(ot);
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
|
2011-08-11 06:06:17 +00:00
|
|
|
BLI_ghash_remove(global_ops_hash, (void *)ot->idname, NULL, NULL);
|
|
|
|
|
|
|
|
MEM_freeN(ot);
|
python operators (in bpy_opwrapper.*)
This means you can define an operator in python that is called from C or Python - like any other operator.
Python functions for invoke and exec can be registered with an operator name.
keywords are read from the python exec() function, then used to create operator properties. The default python values are used to set the property type and defaults.
def exec(size=2.0, text="blah"): ...
is equivalent to...
prop = RNA_def_property(ot->srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 2.0f);
prop = RNA_def_property(ot->srna, "size", PROP_STRING, PROP_NONE);
RNA_def_property_string_default(prop, "blah");
TODO -
* make use of events
* return OPERATOR_CANCELLED/OPERATOR_FINISHED.. etc
* add support for array args
* more testing
2008-12-27 14:52:49 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-07-17 12:26:40 +00:00
|
|
|
/* SOME_OT_op -> some.op */
|
2009-07-18 19:42:13 +00:00
|
|
|
void WM_operator_py_idname(char *to, const char *from)
|
2009-07-17 12:26:40 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
char *sep = strstr(from, "_OT_");
|
2012-03-24 06:24:53 +00:00
|
|
|
if (sep) {
|
2012-03-27 01:24:16 +00:00
|
|
|
int ofs = (sep - from);
|
2011-05-26 09:58:22 +00:00
|
|
|
|
|
|
|
/* note, we use ascii tolower instead of system tolower, because the
|
2012-03-09 18:28:30 +00:00
|
|
|
* latter depends on the locale, and can lead to idname mistmatch */
|
2012-03-27 01:24:16 +00:00
|
|
|
memcpy(to, from, sizeof(char) * ofs);
|
2011-05-26 09:58:22 +00:00
|
|
|
BLI_ascii_strtolower(to, ofs);
|
2009-07-17 12:26:40 +00:00
|
|
|
|
|
|
|
to[ofs] = '.';
|
2013-07-15 05:11:14 +00:00
|
|
|
BLI_strncpy(to + (ofs + 1), sep + 4, OP_MAX_TYPENAME - (ofs + 1));
|
2009-07-17 12:26:40 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-09 00:41:09 +00:00
|
|
|
/* should not happen but support just in case */
|
2009-07-17 12:26:40 +00:00
|
|
|
BLI_strncpy(to, from, OP_MAX_TYPENAME);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* some.op -> SOME_OT_op */
|
2009-07-18 19:42:13 +00:00
|
|
|
void WM_operator_bl_idname(char *to, const char *from)
|
2009-07-17 12:26:40 +00:00
|
|
|
{
|
2009-09-08 02:09:14 +00:00
|
|
|
if (from) {
|
2012-03-27 01:24:16 +00:00
|
|
|
char *sep = strchr(from, '.');
|
2009-07-17 12:26:40 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (sep) {
|
2012-03-27 01:24:16 +00:00
|
|
|
int ofs = (sep - from);
|
2009-07-17 12:26:40 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
memcpy(to, from, sizeof(char) * ofs);
|
2011-05-26 09:58:22 +00:00
|
|
|
BLI_ascii_strtoupper(to, ofs);
|
2013-07-15 05:11:14 +00:00
|
|
|
strcpy(to + ofs, "_OT_");
|
|
|
|
strcpy(to + (ofs + 4), sep + 1);
|
2009-09-08 02:09:14 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-09 00:41:09 +00:00
|
|
|
/* should not happen but support just in case */
|
2009-09-08 02:09:14 +00:00
|
|
|
BLI_strncpy(to, from, OP_MAX_TYPENAME);
|
|
|
|
}
|
2009-07-17 12:26:40 +00:00
|
|
|
}
|
2009-09-08 02:09:14 +00:00
|
|
|
else
|
2012-03-27 01:24:16 +00:00
|
|
|
to[0] = 0;
|
2009-07-17 12:26:40 +00:00
|
|
|
}
|
|
|
|
|
2013-11-06 20:56:18 +00:00
|
|
|
/* Print a string representation of the operator, with the args that it runs so python can run it again.
|
2009-07-29 23:12:30 +00:00
|
|
|
*
|
2013-11-06 20:56:18 +00:00
|
|
|
* When calling from an existing wmOperator, better to use simple version:
|
|
|
|
* WM_operator_pystring(C, op);
|
|
|
|
*
|
|
|
|
* Note: both op and opptr may be NULL (op is only used for macro operators).
|
2009-07-29 23:12:30 +00:00
|
|
|
*/
|
2013-11-26 08:59:14 +11:00
|
|
|
char *WM_operator_pystring_ex(bContext *C, wmOperator *op, const bool all_args, const bool macro_args,
|
|
|
|
wmOperatorType *ot, PointerRNA *opptr)
|
2008-12-26 03:56:52 +00:00
|
|
|
{
|
2009-07-17 12:26:40 +00:00
|
|
|
char idname_py[OP_MAX_TYPENAME];
|
2008-12-26 03:56:52 +00:00
|
|
|
|
|
|
|
/* for building the string */
|
2012-03-27 01:24:16 +00:00
|
|
|
DynStr *dynstr = BLI_dynstr_new();
|
2012-03-20 07:41:47 +00:00
|
|
|
char *cstring;
|
|
|
|
char *cstring_args;
|
2009-07-29 23:48:06 +00:00
|
|
|
|
2013-05-15 14:37:01 +00:00
|
|
|
/* arbitrary, but can get huge string with stroke painting otherwise */
|
|
|
|
int max_prop_length = 10;
|
|
|
|
|
2013-11-06 20:56:18 +00:00
|
|
|
WM_operator_py_idname(idname_py, ot->idname);
|
|
|
|
BLI_dynstr_appendf(dynstr, "bpy.ops.%s(", idname_py);
|
|
|
|
|
|
|
|
if (op && op->macro.first) {
|
|
|
|
/* Special handling for macros, else we only get default values in this case... */
|
|
|
|
wmOperator *opm;
|
|
|
|
bool first_op = true;
|
2013-11-26 08:59:14 +11:00
|
|
|
|
|
|
|
opm = macro_args ? op->macro.first : NULL;
|
|
|
|
|
|
|
|
for (; opm; opm = opm->next) {
|
2013-11-06 20:56:18 +00:00
|
|
|
PointerRNA *opmptr = opm->ptr;
|
|
|
|
PointerRNA opmptr_default;
|
|
|
|
if (opmptr == NULL) {
|
|
|
|
WM_operator_properties_create_ptr(&opmptr_default, opm->type);
|
|
|
|
opmptr = &opmptr_default;
|
|
|
|
}
|
|
|
|
|
|
|
|
cstring_args = RNA_pointer_as_string_id(C, opmptr);
|
|
|
|
if (first_op) {
|
|
|
|
BLI_dynstr_appendf(dynstr, "%s=%s", opm->type->idname, cstring_args);
|
|
|
|
first_op = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BLI_dynstr_appendf(dynstr, ", %s=%s", opm->type->idname, cstring_args);
|
|
|
|
}
|
|
|
|
MEM_freeN(cstring_args);
|
2012-03-20 07:41:47 +00:00
|
|
|
|
2013-11-06 20:56:18 +00:00
|
|
|
if (opmptr == &opmptr_default) {
|
|
|
|
WM_operator_properties_free(&opmptr_default);
|
|
|
|
}
|
|
|
|
}
|
2009-07-29 23:48:06 +00:00
|
|
|
}
|
2013-11-06 20:56:18 +00:00
|
|
|
else {
|
|
|
|
/* only to get the orginal props for comparisons */
|
|
|
|
PointerRNA opptr_default;
|
2013-11-26 08:59:14 +11:00
|
|
|
const bool macro_args_test = ot->macro.first ? macro_args : true;
|
2009-07-29 23:48:06 +00:00
|
|
|
|
2013-11-06 20:56:18 +00:00
|
|
|
if (opptr == NULL) {
|
|
|
|
WM_operator_properties_create_ptr(&opptr_default, ot);
|
|
|
|
opptr = &opptr_default;
|
|
|
|
}
|
2008-12-26 03:56:52 +00:00
|
|
|
|
2013-11-26 08:59:14 +11:00
|
|
|
cstring_args = RNA_pointer_as_string_keywords(C, opptr, false, all_args, macro_args_test, max_prop_length);
|
2013-11-06 20:56:18 +00:00
|
|
|
BLI_dynstr_append(dynstr, cstring_args);
|
|
|
|
MEM_freeN(cstring_args);
|
2008-12-26 03:56:52 +00:00
|
|
|
|
2013-11-06 20:56:18 +00:00
|
|
|
if (opptr == &opptr_default) {
|
|
|
|
WM_operator_properties_free(&opptr_default);
|
|
|
|
}
|
|
|
|
}
|
2009-07-29 23:48:06 +00:00
|
|
|
|
2008-12-26 03:56:52 +00:00
|
|
|
BLI_dynstr_append(dynstr, ")");
|
|
|
|
|
|
|
|
cstring = BLI_dynstr_get_cstring(dynstr);
|
|
|
|
BLI_dynstr_free(dynstr);
|
|
|
|
return cstring;
|
|
|
|
}
|
|
|
|
|
2013-11-26 08:59:14 +11:00
|
|
|
char *WM_operator_pystring(bContext *C, wmOperator *op,
|
|
|
|
const bool all_args, const bool macro_args)
|
2013-11-06 20:56:18 +00:00
|
|
|
{
|
2013-11-26 08:59:14 +11:00
|
|
|
return WM_operator_pystring_ex(C, op, all_args, macro_args, op->type, op->ptr);
|
2013-11-06 20:56:18 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 14:20:53 +11:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \return true if the string was shortened
|
|
|
|
*/
|
|
|
|
bool WM_operator_pystring_abbreviate(char *str, int str_len_max)
|
|
|
|
{
|
|
|
|
const int str_len = strlen(str);
|
|
|
|
const char *parens_start = strchr(str, '(');
|
|
|
|
|
|
|
|
if (parens_start) {
|
|
|
|
const int parens_start_pos = parens_start - str;
|
|
|
|
const char *parens_end = strrchr(parens_start + 1, ')');
|
|
|
|
|
|
|
|
if (parens_end) {
|
|
|
|
const int parens_len = parens_end - parens_start;
|
|
|
|
|
|
|
|
if (parens_len > str_len_max) {
|
|
|
|
const char *comma_first = strchr(parens_start, ',');
|
|
|
|
|
|
|
|
/* truncate after the first comma */
|
|
|
|
if (comma_first) {
|
|
|
|
const char end_str[] = " ... )";
|
|
|
|
const int end_str_len = sizeof(end_str) - 1;
|
|
|
|
|
|
|
|
/* leave a place for the first argument*/
|
|
|
|
const int new_str_len = (comma_first - parens_start) + 1;
|
|
|
|
|
|
|
|
if (str_len >= new_str_len + parens_start_pos + end_str_len + 1) {
|
|
|
|
/* append " ... )" to the string after the comma */
|
|
|
|
memcpy(str + new_str_len + parens_start_pos, end_str, end_str_len + 1);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-12-18 16:20:30 +00:00
|
|
|
/* return NULL if no match is found */
|
2013-01-22 04:24:01 +00:00
|
|
|
#if 0
|
2012-12-18 16:20:30 +00:00
|
|
|
static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* loop over all context items and do 2 checks
|
|
|
|
*
|
|
|
|
* - see if the pointer is in the context.
|
|
|
|
* - see if the pointers ID is in the context.
|
|
|
|
*/
|
|
|
|
|
2012-12-19 02:08:58 +00:00
|
|
|
/* don't get from the context store since this is normally set only for the UI and not usable elsewhere */
|
|
|
|
ListBase lb = CTX_data_dir_get_ex(C, FALSE, TRUE, TRUE);
|
2012-12-18 16:20:30 +00:00
|
|
|
LinkData *link;
|
|
|
|
|
|
|
|
const char *member_found = NULL;
|
|
|
|
const char *member_id = NULL;
|
|
|
|
|
|
|
|
char *prop_str = NULL;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
for (link = lb.first; link; link = link->next) {
|
|
|
|
const char *identifier = link->data;
|
2013-01-22 04:24:01 +00:00
|
|
|
PointerRNA ctx_item_ptr = {{0}} // CTX_data_pointer_get(C, identifier); // XXX, this isnt working
|
2012-12-18 16:20:30 +00:00
|
|
|
|
2012-12-19 02:08:58 +00:00
|
|
|
if (ctx_item_ptr.type == NULL) {
|
2012-12-18 16:52:46 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-12-19 02:08:58 +00:00
|
|
|
if (ptr->id.data == ctx_item_ptr.id.data) {
|
|
|
|
if ((ptr->data == ctx_item_ptr.data) &&
|
|
|
|
(ptr->type == ctx_item_ptr.type))
|
2012-12-18 16:20:30 +00:00
|
|
|
{
|
|
|
|
/* found! */
|
|
|
|
member_found = identifier;
|
|
|
|
break;
|
|
|
|
}
|
2012-12-19 02:08:58 +00:00
|
|
|
else if (RNA_struct_is_ID(ctx_item_ptr.type)) {
|
2012-12-18 16:20:30 +00:00
|
|
|
/* we found a reference to this ID,
|
|
|
|
* so fallback to it if there is no direct reference */
|
|
|
|
member_id = identifier;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (member_found) {
|
|
|
|
prop_str = RNA_path_property_py(ptr, prop, index);
|
2012-12-18 17:06:31 +00:00
|
|
|
if (prop_str) {
|
|
|
|
ret = BLI_sprintfN("bpy.context.%s.%s", member_found, prop_str);
|
|
|
|
MEM_freeN(prop_str);
|
|
|
|
}
|
2012-12-18 16:20:30 +00:00
|
|
|
}
|
|
|
|
else if (member_id) {
|
|
|
|
prop_str = RNA_path_struct_property_py(ptr, prop, index);
|
2012-12-18 17:06:31 +00:00
|
|
|
if (prop_str) {
|
|
|
|
ret = BLI_sprintfN("bpy.context.%s.%s", member_id, prop_str);
|
|
|
|
MEM_freeN(prop_str);
|
|
|
|
}
|
2012-12-18 16:20:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BLI_freelistN(&lb);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2013-01-22 04:24:01 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
/* use hard coded checks for now */
|
|
|
|
static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
|
|
|
|
{
|
|
|
|
const char *member_id = NULL;
|
|
|
|
|
|
|
|
char *prop_str = NULL;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
if (ptr->id.data) {
|
|
|
|
|
|
|
|
#define CTX_TEST_PTR_ID(C, member, idptr) \
|
|
|
|
{ \
|
|
|
|
const char *ctx_member = member; \
|
|
|
|
PointerRNA ctx_item_ptr = CTX_data_pointer_get(C, ctx_member); \
|
|
|
|
if (ctx_item_ptr.id.data == idptr) { \
|
|
|
|
member_id = ctx_member; \
|
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
} (void)0
|
|
|
|
|
|
|
|
#define CTX_TEST_PTR_ID_CAST(C, member, member_full, cast, idptr) \
|
|
|
|
{ \
|
|
|
|
const char *ctx_member = member; \
|
|
|
|
const char *ctx_member_full = member_full; \
|
|
|
|
PointerRNA ctx_item_ptr = CTX_data_pointer_get(C, ctx_member); \
|
|
|
|
if (ctx_item_ptr.id.data && cast(ctx_item_ptr.id.data) == idptr) { \
|
|
|
|
member_id = ctx_member_full; \
|
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
} (void)0
|
|
|
|
|
2013-06-03 00:46:20 +00:00
|
|
|
#define CTX_TEST_PTR_DATA_TYPE(C, member, rna_type, rna_ptr, dataptr_cmp) \
|
|
|
|
{ \
|
|
|
|
const char *ctx_member = member; \
|
|
|
|
if (RNA_struct_is_a((ptr)->type, &(rna_type)) && (ptr)->data == (dataptr_cmp)) { \
|
|
|
|
member_id = ctx_member; \
|
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
} (void)0
|
|
|
|
|
|
|
|
switch (GS(((ID *)ptr->id.data)->name)) {
|
2013-01-22 04:24:01 +00:00
|
|
|
case ID_SCE:
|
|
|
|
{
|
|
|
|
CTX_TEST_PTR_ID(C, "scene", ptr->id.data);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ID_OB:
|
|
|
|
{
|
|
|
|
CTX_TEST_PTR_ID(C, "object", ptr->id.data);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* from rna_Main_objects_new */
|
|
|
|
case OB_DATA_SUPPORT_ID_CASE:
|
|
|
|
{
|
|
|
|
#define ID_CAST_OBDATA(id_pt) (((Object *)(id_pt))->data)
|
|
|
|
CTX_TEST_PTR_ID_CAST(C, "object", "object.data", ID_CAST_OBDATA, ptr->id.data);
|
|
|
|
break;
|
|
|
|
#undef ID_CAST_OBDATA
|
|
|
|
}
|
|
|
|
case ID_MA:
|
|
|
|
{
|
|
|
|
#define ID_CAST_OBMATACT(id_pt) (give_current_material(((Object *)id_pt), ((Object *)id_pt)->actcol))
|
|
|
|
CTX_TEST_PTR_ID_CAST(C, "object", "object.active_material", ID_CAST_OBMATACT, ptr->id.data);
|
|
|
|
break;
|
|
|
|
#undef ID_CAST_OBMATACT
|
|
|
|
}
|
|
|
|
case ID_WO:
|
|
|
|
{
|
|
|
|
#define ID_CAST_SCENEWORLD(id_pt) (((Scene *)(id_pt))->world)
|
|
|
|
CTX_TEST_PTR_ID_CAST(C, "scene", "scene.world", ID_CAST_SCENEWORLD, ptr->id.data);
|
|
|
|
break;
|
|
|
|
#undef ID_CAST_SCENEWORLD
|
|
|
|
}
|
|
|
|
case ID_SCR:
|
|
|
|
{
|
|
|
|
CTX_TEST_PTR_ID(C, "screen", ptr->id.data);
|
2013-06-03 00:46:20 +00:00
|
|
|
|
|
|
|
CTX_TEST_PTR_DATA_TYPE(C, "space_data", RNA_Space, ptr, CTX_wm_space_data(C));
|
|
|
|
CTX_TEST_PTR_DATA_TYPE(C, "area", RNA_Area, ptr, CTX_wm_area(C));
|
|
|
|
CTX_TEST_PTR_DATA_TYPE(C, "region", RNA_Region, ptr, CTX_wm_region(C));
|
|
|
|
|
2013-01-22 04:24:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (member_id) {
|
|
|
|
prop_str = RNA_path_struct_property_py(ptr, prop, index);
|
|
|
|
if (prop_str) {
|
|
|
|
ret = BLI_sprintfN("bpy.context.%s.%s", member_id, prop_str);
|
|
|
|
MEM_freeN(prop_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#undef CTX_TEST_PTR_ID
|
|
|
|
#undef CTX_TEST_PTR_ID_CAST
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
2012-12-18 16:20:30 +00:00
|
|
|
|
2012-12-18 15:22:06 +00:00
|
|
|
char *WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
|
2012-12-18 14:11:19 +00:00
|
|
|
{
|
2012-12-18 15:22:06 +00:00
|
|
|
char *lhs, *rhs, *ret;
|
2012-12-18 14:11:19 +00:00
|
|
|
|
2012-12-18 16:20:30 +00:00
|
|
|
lhs = C ? wm_prop_pystring_from_context(C, ptr, prop, index) : NULL;
|
|
|
|
|
|
|
|
if (lhs == NULL) {
|
|
|
|
/* fallback to bpy.data.foo[id] if we dont find in the context */
|
|
|
|
lhs = RNA_path_full_property_py(ptr, prop, index);
|
|
|
|
}
|
|
|
|
|
2012-12-18 15:22:06 +00:00
|
|
|
if (!lhs) {
|
2012-12-18 14:11:19 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-05-15 14:37:01 +00:00
|
|
|
rhs = RNA_property_as_string(C, ptr, prop, index, INT_MAX);
|
2012-12-18 15:22:06 +00:00
|
|
|
if (!rhs) {
|
|
|
|
MEM_freeN(lhs);
|
2012-12-18 14:11:19 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = BLI_sprintfN("%s = %s", lhs, rhs);
|
|
|
|
MEM_freeN(lhs);
|
|
|
|
MEM_freeN(rhs);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-11-24 16:19:15 +00:00
|
|
|
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
RNA_pointer_create(NULL, ot->srna, NULL, ptr);
|
|
|
|
}
|
|
|
|
|
2009-01-01 20:44:40 +00:00
|
|
|
void WM_operator_properties_create(PointerRNA *ptr, const char *opstring)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOperatorType *ot = WM_operatortype_find(opstring, 0);
|
2009-01-01 20:44:40 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ot)
|
2009-11-24 16:19:15 +00:00
|
|
|
WM_operator_properties_create_ptr(ptr, ot);
|
2009-01-01 20:44:40 +00:00
|
|
|
else
|
2009-01-15 04:13:38 +00:00
|
|
|
RNA_pointer_create(NULL, &RNA_OperatorProperties, NULL, ptr);
|
2009-01-01 20:44:40 +00:00
|
|
|
}
|
|
|
|
|
2009-10-12 12:54:08 +00:00
|
|
|
/* similar to the function above except its uses ID properties
|
|
|
|
* used for keymaps and macros */
|
|
|
|
void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *opstring)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
if (*properties == NULL) {
|
2009-10-12 12:54:08 +00:00
|
|
|
IDPropertyTemplate val = {0};
|
2012-03-27 01:24:16 +00:00
|
|
|
*properties = IDP_New(IDP_GROUP, &val, "wmOpItemProp");
|
2009-10-12 12:54:08 +00:00
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (*ptr == NULL) {
|
|
|
|
*ptr = MEM_callocN(sizeof(PointerRNA), "wmOpItemPtr");
|
2009-10-12 12:54:08 +00:00
|
|
|
WM_operator_properties_create(*ptr, opstring);
|
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
(*ptr)->data = *properties;
|
2009-10-12 12:54:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-04-04 02:05:11 +00:00
|
|
|
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
|
2010-01-27 21:19:39 +00:00
|
|
|
{
|
2013-08-24 10:05:29 +00:00
|
|
|
RNA_STRUCT_BEGIN (ptr, prop)
|
2012-04-30 16:22:40 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
switch (RNA_property_type(prop)) {
|
|
|
|
case PROP_ENUM:
|
|
|
|
if (no_context)
|
|
|
|
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
|
|
|
|
else
|
|
|
|
RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
|
|
|
|
break;
|
|
|
|
case PROP_POINTER:
|
2010-01-27 21:19:39 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
|
2010-01-27 21:19:39 +00:00
|
|
|
|
|
|
|
/* recurse into operator properties */
|
|
|
|
if (RNA_struct_is_a(ptype, &RNA_OperatorProperties)) {
|
|
|
|
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
|
2010-11-23 12:05:35 +00:00
|
|
|
WM_operator_properties_sanitize(&opptr, no_context);
|
2010-01-27 21:19:39 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
default:
|
|
|
|
break;
|
2010-01-27 21:19:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
RNA_STRUCT_END;
|
|
|
|
}
|
2009-10-12 12:54:08 +00:00
|
|
|
|
2012-10-31 20:29:32 +00:00
|
|
|
|
|
|
|
/** set all props to their default,
|
|
|
|
* \param do_update Only update un-initialized props.
|
|
|
|
*
|
2012-11-12 07:33:01 +00:00
|
|
|
* \note, theres nothing specific to operators here.
|
2012-10-31 20:29:32 +00:00
|
|
|
* this could be made a general function.
|
|
|
|
*/
|
2013-11-26 06:39:14 +11:00
|
|
|
bool WM_operator_properties_default(PointerRNA *ptr, const bool do_update)
|
2012-10-31 20:29:32 +00:00
|
|
|
{
|
2013-11-26 06:39:14 +11:00
|
|
|
bool changed = false;
|
2013-08-24 10:05:29 +00:00
|
|
|
RNA_STRUCT_BEGIN (ptr, prop)
|
2012-10-31 20:29:32 +00:00
|
|
|
{
|
|
|
|
switch (RNA_property_type(prop)) {
|
|
|
|
case PROP_POINTER:
|
|
|
|
{
|
|
|
|
StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
|
|
|
|
if (ptype != &RNA_Struct) {
|
|
|
|
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
|
2013-11-26 06:39:14 +11:00
|
|
|
changed |= WM_operator_properties_default(&opptr, do_update);
|
2012-10-31 20:29:32 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
2013-04-04 02:05:11 +00:00
|
|
|
if ((do_update == false) || (RNA_property_is_set(ptr, prop) == FALSE)) {
|
2012-10-31 20:29:32 +00:00
|
|
|
if (RNA_property_reset(ptr, prop, -1)) {
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = true;
|
2012-10-31 20:29:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RNA_STRUCT_END;
|
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
return changed;
|
2012-10-31 20:29:32 +00:00
|
|
|
}
|
|
|
|
|
2012-01-11 19:33:14 +00:00
|
|
|
/* remove all props without PROP_SKIP_SAVE */
|
|
|
|
void WM_operator_properties_reset(wmOperator *op)
|
|
|
|
{
|
|
|
|
if (op->ptr->data) {
|
|
|
|
PropertyRNA *iterprop;
|
2012-03-27 01:24:16 +00:00
|
|
|
iterprop = RNA_struct_iterator_property(op->type->srna);
|
2012-01-11 19:33:14 +00:00
|
|
|
|
2013-08-24 10:05:29 +00:00
|
|
|
RNA_PROP_BEGIN (op->ptr, itemptr, iterprop)
|
2012-04-30 16:22:40 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
PropertyRNA *prop = itemptr.data;
|
2012-01-11 19:33:14 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if ((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
|
2012-01-11 19:33:14 +00:00
|
|
|
const char *identifier = RNA_property_identifier(prop);
|
|
|
|
RNA_struct_idprops_unset(op->ptr, identifier);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RNA_PROP_END;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-29 16:01:03 +11:00
|
|
|
void WM_operator_properties_clear(PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
IDProperty *properties = ptr->data;
|
|
|
|
|
|
|
|
if (properties) {
|
|
|
|
IDP_ClearProperty(properties);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-01 20:44:40 +00:00
|
|
|
void WM_operator_properties_free(PointerRNA *ptr)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
IDProperty *properties = ptr->data;
|
2009-01-01 20:44:40 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (properties) {
|
2009-01-01 20:44:40 +00:00
|
|
|
IDP_FreeProperty(properties);
|
|
|
|
MEM_freeN(properties);
|
2012-03-27 01:24:16 +00:00
|
|
|
ptr->data = NULL; /* just in case */
|
2009-01-01 20:44:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5: work on bringing back SpaceTime options
- RMB select, also with SHIFT
- RMB tweak for translate
- SHIFT+D dupli
- BKEY border select/deselect
- AKEY (de)select all
- XKEY delete
- GKEY grab
Added some XXX comments for future todos, especially for when other
spaces come back with time markers.
Also added ED_util for putting in all to-be-cleaned cruft
Context conflict: input methods for Markers can conflict with other
spacetypes. It was solved in pre-2.5 with manually tweaking it all over,
but I would prefer one keymap for all marker stuff. Needs some thinking...
could be solved with a boundbox check for bottom part of 2d window.
Tweak issue: both tweak styles are possible:
- Hold mouse button, move, operator ends on mouse release
- Hold mouse button, move, operator ends on mouse click
Problem is that modally handled operators use fixed keymaps... like ESC,
SPACE, ENTER, or press/release mousebutton for 'assign'. There's a lot
to say for making this all consistant, or become part of 1 general keymap?
Should also be possibe to define 'tweak' defaults for Tablet different
than for mouse...
2008-11-29 15:10:31 +00:00
|
|
|
/* ************ default op callbacks, exported *********** */
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2013-09-16 04:19:48 +00:00
|
|
|
void WM_operator_view3d_unit_defaults(struct bContext *C, struct wmOperator *op)
|
2012-12-09 10:48:18 +00:00
|
|
|
{
|
2013-09-16 04:19:48 +00:00
|
|
|
if (op->flag & OP_IS_INVOKE) {
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-12-09 10:48:18 +00:00
|
|
|
|
2013-09-16 04:19:48 +00:00
|
|
|
const float dia = v3d ? ED_view3d_grid_scale(scene, v3d, NULL) : ED_scene_grid_scale(scene, NULL);
|
2012-12-09 10:48:18 +00:00
|
|
|
|
2013-09-16 04:19:48 +00:00
|
|
|
/* always run, so the values are initialized,
|
|
|
|
* otherwise we may get differ behavior when (dia != 1.0) */
|
|
|
|
RNA_STRUCT_BEGIN (op->ptr, prop)
|
|
|
|
{
|
|
|
|
if (RNA_property_type(prop) == PROP_FLOAT) {
|
|
|
|
PropertySubType pstype = RNA_property_subtype(prop);
|
|
|
|
if (pstype == PROP_DISTANCE) {
|
|
|
|
/* we don't support arrays yet */
|
|
|
|
BLI_assert(RNA_property_array_check(prop) == FALSE);
|
|
|
|
/* initialize */
|
|
|
|
if (!RNA_property_is_set_ex(op->ptr, prop, FALSE)) {
|
|
|
|
const float value = RNA_property_float_get_default(op->ptr, prop) * dia;
|
|
|
|
RNA_property_float_set(op->ptr, prop, value);
|
|
|
|
}
|
2012-12-09 10:48:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-16 04:19:48 +00:00
|
|
|
RNA_STRUCT_END;
|
2012-12-09 10:48:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-16 04:04:44 +00:00
|
|
|
int WM_operator_smooth_viewtx_get(const wmOperator *op)
|
|
|
|
{
|
|
|
|
return (op->flag & OP_IS_INVOKE) ? U.smooth_viewtx : 0;
|
|
|
|
}
|
|
|
|
|
2008-12-24 18:06:51 +00:00
|
|
|
/* invoke callback, uses enum property named "type" */
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2008-12-17 15:38:40 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
PropertyRNA *prop = op->type->prop;
|
2009-04-22 18:39:44 +00:00
|
|
|
uiPopupMenu *pup;
|
|
|
|
uiLayout *layout;
|
2009-02-01 02:37:12 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (prop == NULL) {
|
2011-11-07 04:36:37 +00:00
|
|
|
printf("%s: %s has no enum property set\n", __func__, op->type->idname);
|
2009-02-01 02:37:12 +00:00
|
|
|
}
|
2009-04-19 13:37:59 +00:00
|
|
|
else if (RNA_property_type(prop) != PROP_ENUM) {
|
2011-11-07 04:36:37 +00:00
|
|
|
printf("%s: %s \"%s\" is not an enum property\n",
|
|
|
|
__func__, op->type->idname, RNA_property_identifier(prop));
|
2009-02-01 02:37:12 +00:00
|
|
|
}
|
2012-01-11 16:48:22 +00:00
|
|
|
else if (RNA_property_is_set(op->ptr, prop)) {
|
2012-03-27 01:24:16 +00:00
|
|
|
const int retval = op->type->exec(C, op);
|
2011-08-25 16:42:42 +00:00
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
|
|
|
return retval;
|
2009-12-10 23:22:43 +00:00
|
|
|
}
|
2009-02-01 02:37:12 +00:00
|
|
|
else {
|
2012-04-13 19:59:29 +00:00
|
|
|
pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
|
2012-03-27 01:24:16 +00:00
|
|
|
layout = uiPupMenuLayout(pup);
|
2012-10-26 06:22:54 +00:00
|
|
|
/* set this so the default execution context is the same as submenus */
|
|
|
|
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
|
2011-10-21 08:16:15 +00:00
|
|
|
uiItemsFullEnumO(layout, op->type->idname, RNA_property_identifier(prop), op->ptr->data, WM_OP_EXEC_REGION_WIN, 0);
|
2009-04-22 18:39:44 +00:00
|
|
|
uiPupMenuEnd(C, pup);
|
2008-12-24 18:06:51 +00:00
|
|
|
}
|
2009-02-04 11:52:16 +00:00
|
|
|
|
2008-12-24 18:06:51 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2008-12-17 15:38:40 +00:00
|
|
|
}
|
|
|
|
|
2010-01-15 17:23:16 +00:00
|
|
|
|
2010-01-15 22:40:33 +00:00
|
|
|
/* generic enum search invoke popup */
|
2010-01-15 17:23:16 +00:00
|
|
|
static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
static char search[256] = "";
|
2010-01-15 17:23:16 +00:00
|
|
|
wmEvent event;
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2010-01-15 17:23:16 +00:00
|
|
|
uiBlock *block;
|
|
|
|
uiBut *but;
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOperator *op = (wmOperator *)arg_op;
|
2010-01-15 17:23:16 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
|
2012-10-24 21:57:07 +00:00
|
|
|
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
|
2010-01-15 17:23:16 +00:00
|
|
|
|
2012-04-13 19:59:29 +00:00
|
|
|
#if 0 /* ok, this isn't so easy... */
|
|
|
|
uiDefBut(block, LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, 180, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
|
|
|
#endif
|
2013-04-15 15:01:12 +00:00
|
|
|
but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
|
|
|
|
10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
|
2010-01-15 17:23:16 +00:00
|
|
|
|
|
|
|
/* fake button, it holds space for search items */
|
2012-11-26 13:23:37 +00:00
|
|
|
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
2010-01-15 17:23:16 +00:00
|
|
|
|
Code holiday commit:
- fix: user pref, window title was reset to 'Blender' on tab usage
- Undo history menu back:
- name "Undo History"
- hotkey alt+ctrl+z (alt+apple+z for mac)
- works like 2.4x, only for global undo, editmode and particle edit.
- Menu scroll
- for small windows or screens, popup menus now allow to display
all items, using internal scrolling
- works with a timer, scrolling 10 items per second when mouse
is over the top or bottom arrow
- if menu is too big to display, it now draws to top or bottom,
based on largest available space.
- also works for hotkey driven pop up menus.
- User pref "DPI" follows widget/layout size
- widgets & headers now become bigger and smaller, to match
'dpi' font sizes. Works well to match UI to monitor size.
- note that icons can get fuzzy, we need better mipmaps for it
2011-06-04 17:03:46 +00:00
|
|
|
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
2010-01-15 17:23:16 +00:00
|
|
|
uiEndBlock(C, block);
|
|
|
|
|
2013-07-29 08:29:04 +00:00
|
|
|
wm_event_init_from_window(win, &event);
|
2012-03-27 01:24:16 +00:00
|
|
|
event.type = EVT_BUT_OPEN;
|
|
|
|
event.val = KM_PRESS;
|
|
|
|
event.customdata = but;
|
|
|
|
event.customdatafree = FALSE;
|
2010-01-15 17:23:16 +00:00
|
|
|
wm_event_add(win, &event);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2010-01-15 17:23:16 +00:00
|
|
|
{
|
|
|
|
uiPupBlock(C, wm_enum_search_menu, op);
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2009-10-10 12:29:11 +00:00
|
|
|
/* Can't be used as an invoke directly, needs message arg (can be NULL) */
|
2010-12-03 17:05:21 +00:00
|
|
|
int WM_operator_confirm_message(bContext *C, wmOperator *op, const char *message)
|
2007-12-24 18:27:28 +00:00
|
|
|
{
|
2009-04-22 18:39:44 +00:00
|
|
|
uiPopupMenu *pup;
|
|
|
|
uiLayout *layout;
|
2012-03-27 01:24:16 +00:00
|
|
|
IDProperty *properties = op->ptr->data;
|
2009-12-22 11:59:30 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (properties && properties->len)
|
2012-03-27 01:24:16 +00:00
|
|
|
properties = IDP_CopyProperty(op->ptr->data);
|
2009-12-22 11:59:30 +00:00
|
|
|
else
|
2012-03-27 01:24:16 +00:00
|
|
|
properties = NULL;
|
2009-02-04 11:52:16 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
pup = uiPupMenuBegin(C, IFACE_("OK?"), ICON_QUESTION);
|
|
|
|
layout = uiPupMenuLayout(pup);
|
2012-01-22 03:30:07 +00:00
|
|
|
uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0);
|
2009-04-22 18:39:44 +00:00
|
|
|
uiPupMenuEnd(C, pup);
|
2008-12-17 15:38:40 +00:00
|
|
|
|
2009-02-04 11:52:16 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
2008-12-17 15:38:40 +00:00
|
|
|
|
2009-10-10 12:29:11 +00:00
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_operator_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-10-10 12:29:11 +00:00
|
|
|
{
|
|
|
|
return WM_operator_confirm_message(C, op, NULL);
|
|
|
|
}
|
|
|
|
|
2009-09-12 19:54:39 +00:00
|
|
|
/* op->invoke, opens fileselect if path property not set, otherwise executes */
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-01-26 09:13:15 +00:00
|
|
|
{
|
2012-01-11 16:32:12 +00:00
|
|
|
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
2011-12-12 18:52:18 +00:00
|
|
|
return WM_operator_call_notest(C, op); /* call exec direct */
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2009-02-16 12:14:04 +00:00
|
|
|
else {
|
|
|
|
WM_event_add_fileselect(C, op);
|
2009-01-26 09:13:15 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-18 15:30:51 +00:00
|
|
|
bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
|
2012-04-24 02:01:23 +00:00
|
|
|
{
|
|
|
|
PropertyRNA *prop;
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
/* dont NULL check prop, this can only run on ops with a 'filepath' */
|
|
|
|
prop = RNA_struct_find_property(op->ptr, "filepath");
|
|
|
|
RNA_property_string_get(op->ptr, prop, filepath);
|
2012-12-23 13:57:09 +00:00
|
|
|
if (BKE_add_image_extension(filepath, im_format)) {
|
2012-04-24 02:01:23 +00:00
|
|
|
RNA_property_string_set(op->ptr, prop, filepath);
|
|
|
|
/* note, we could check for and update 'filename' here,
|
|
|
|
* but so far nothing needs this. */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-28 16:46:14 +00:00
|
|
|
/* default properties for fileselect */
|
2012-01-24 18:18:51 +00:00
|
|
|
void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, short action, short flag, short display)
|
2009-07-28 16:46:14 +00:00
|
|
|
{
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
PropertyRNA *prop;
|
2009-07-28 16:46:14 +00:00
|
|
|
|
2012-01-24 18:18:51 +00:00
|
|
|
static EnumPropertyItem file_display_items[] = {
|
|
|
|
{FILE_DEFAULTDISPLAY, "FILE_DEFAULTDISPLAY", 0, "Default", "Automatically determine display type for files"},
|
|
|
|
{FILE_SHORTDISPLAY, "FILE_SHORTDISPLAY", ICON_SHORTDISPLAY, "Short List", "Display files as short list"},
|
|
|
|
{FILE_LONGDISPLAY, "FILE_LONGDISPLAY", ICON_LONGDISPLAY, "Long List", "Display files as a detailed list"},
|
|
|
|
{FILE_IMGDISPLAY, "FILE_IMGDISPLAY", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"},
|
2012-03-27 01:24:16 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
};
|
2012-01-24 18:18:51 +00:00
|
|
|
|
2010-07-01 19:28:45 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (flag & WM_FILESEL_FILEPATH)
|
2014-01-16 21:43:22 +11:00
|
|
|
RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path", "Path to file");
|
2010-07-01 19:28:45 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (flag & WM_FILESEL_DIRECTORY)
|
2014-01-16 21:43:22 +11:00
|
|
|
RNA_def_string_dir_path(ot->srna, "directory", NULL, FILE_MAX, "Directory", "Directory of the file");
|
2010-07-01 19:28:45 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (flag & WM_FILESEL_FILENAME)
|
2014-01-16 21:43:22 +11:00
|
|
|
RNA_def_string_file_name(ot->srna, "filename", NULL, FILE_MAX, "File Name", "Name of the file");
|
2009-09-12 19:54:39 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (flag & WM_FILESEL_FILES)
|
2011-08-12 03:53:26 +00:00
|
|
|
RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
|
|
|
|
|
2010-01-27 02:20:24 +00:00
|
|
|
if (action == FILE_SAVE) {
|
2012-10-31 17:03:31 +00:00
|
|
|
/* note, this is only used to check if we should highlight the filename area red when the
|
|
|
|
* filepath is an existing file. */
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "check_existing", 1, "Check Existing", "Check and warn on overwriting existing files");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2010-01-27 02:20:24 +00:00
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-11-06 20:29:14 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_backup", (filter & BLENDERFILE_BACKUP), "Filter .blend files", "");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_movie", (filter & MOVIEFILE), "Filter movie files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_python", (filter & PYSCRIPTFILE), "Filter python files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_font", (filter & FTFONTFILE), "Filter font files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_btx", (filter & BTXFILE), "Filter btx files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_collada", (filter & COLLADAFILE), "Filter COLLADA files", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL,
|
|
|
|
"File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file",
|
|
|
|
FILE_LOADLIB, FILE_SPECIAL);
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2010-06-09 14:04:34 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (flag & WM_FILESEL_RELPATH)
|
2011-10-12 00:15:19 +00:00
|
|
|
RNA_def_boolean(ot->srna, "relative_path", TRUE, "Relative Path", "Select the file relative to the blend file");
|
2012-01-24 18:18:51 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_enum(ot->srna, "display_type", file_display_items, display, "Display Type", "");
|
2012-04-23 06:37:16 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2009-07-28 16:46:14 +00:00
|
|
|
}
|
|
|
|
|
2014-01-13 20:36:38 +11:00
|
|
|
static void wm_operator_properties_select_action_ex(wmOperatorType *ot, int default_action,
|
|
|
|
const EnumPropertyItem *select_actions)
|
|
|
|
{
|
|
|
|
RNA_def_enum(ot->srna, "action", select_actions, default_action, "Action", "Selection action to execute");
|
|
|
|
}
|
|
|
|
|
2013-05-16 00:07:01 +00:00
|
|
|
void WM_operator_properties_select_action(wmOperatorType *ot, int default_action)
|
2011-09-28 05:53:40 +00:00
|
|
|
{
|
2013-05-16 00:07:01 +00:00
|
|
|
static EnumPropertyItem select_actions[] = {
|
2012-03-27 01:24:16 +00:00
|
|
|
{SEL_TOGGLE, "TOGGLE", 0, "Toggle", "Toggle selection for all elements"},
|
|
|
|
{SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
|
|
|
|
{SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
|
|
|
|
{SEL_INVERT, "INVERT", 0, "Invert", "Invert selection of all elements"},
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
2009-11-29 22:16:29 +00:00
|
|
|
};
|
|
|
|
|
2014-01-13 20:36:38 +11:00
|
|
|
wm_operator_properties_select_action_ex(ot, default_action, select_actions);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* only SELECT/DESELECT
|
|
|
|
*/
|
|
|
|
void WM_operator_properties_select_action_simple(wmOperatorType *ot, int default_action)
|
|
|
|
{
|
|
|
|
static EnumPropertyItem select_actions[] = {
|
|
|
|
{SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
|
|
|
|
{SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
wm_operator_properties_select_action_ex(ot, default_action, select_actions);
|
2013-05-16 00:07:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WM_operator_properties_select_all(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
WM_operator_properties_select_action(ot, SEL_TOGGLE);
|
2009-11-29 22:16:29 +00:00
|
|
|
}
|
|
|
|
|
2012-08-08 20:38:55 +00:00
|
|
|
void WM_operator_properties_border(wmOperatorType *ot)
|
2009-11-06 22:51:08 +00:00
|
|
|
{
|
2013-08-29 19:02:07 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
|
|
prop = RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2012-08-08 20:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
|
|
|
|
{
|
|
|
|
rect->xmin = RNA_int_get(op->ptr, "xmin");
|
|
|
|
rect->ymin = RNA_int_get(op->ptr, "ymin");
|
|
|
|
rect->xmax = RNA_int_get(op->ptr, "xmax");
|
|
|
|
rect->ymax = RNA_int_get(op->ptr, "ymax");
|
|
|
|
}
|
2009-11-06 22:51:08 +00:00
|
|
|
|
2013-03-19 23:17:44 +00:00
|
|
|
void WM_operator_properties_gesture_border(wmOperatorType *ot, bool extend)
|
2012-08-08 20:38:55 +00:00
|
|
|
{
|
|
|
|
RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX);
|
|
|
|
|
|
|
|
WM_operator_properties_border(ot);
|
|
|
|
|
|
|
|
if (extend) {
|
2011-10-20 20:38:26 +00:00
|
|
|
RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first");
|
2012-08-08 20:38:55 +00:00
|
|
|
}
|
2009-11-06 22:51:08 +00:00
|
|
|
}
|
|
|
|
|
2012-05-28 05:45:19 +00:00
|
|
|
void WM_operator_properties_mouse_select(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first");
|
|
|
|
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from selection");
|
2012-05-28 14:01:42 +00:00
|
|
|
RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Selection", "Toggle the selection");
|
2012-05-28 05:45:19 +00:00
|
|
|
}
|
|
|
|
|
2013-07-04 18:58:00 +00:00
|
|
|
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
|
2010-04-04 00:21:37 +00:00
|
|
|
{
|
2013-08-29 19:02:07 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
|
|
prop = RNA_def_int(ot->srna, "xstart", 0, INT_MIN, INT_MAX, "X Start", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_int(ot->srna, "xend", 0, INT_MIN, INT_MAX, "X End", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_int(ot->srna, "ystart", 0, INT_MIN, INT_MAX, "Y Start", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_int(ot->srna, "yend", 0, INT_MIN, INT_MAX, "Y End", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
2010-04-04 00:21:37 +00:00
|
|
|
|
2013-02-11 06:58:38 +00:00
|
|
|
if (cursor) {
|
|
|
|
prop = RNA_def_int(ot->srna, "cursor", cursor, 0, INT_MAX,
|
|
|
|
"Cursor", "Mouse cursor style to use during the modal operator", 0, INT_MAX);
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
}
|
2010-04-04 00:21:37 +00:00
|
|
|
}
|
|
|
|
|
2009-11-06 22:51:08 +00:00
|
|
|
|
2008-12-24 14:52:17 +00:00
|
|
|
/* op->poll */
|
2007-12-24 18:27:28 +00:00
|
|
|
int WM_operator_winactive(bContext *C)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
if (CTX_wm_window(C) == NULL) return 0;
|
2007-12-24 18:27:28 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-12-11 19:23:02 +00:00
|
|
|
/* return FALSE, if the UI should be disabled */
|
2013-04-04 02:05:11 +00:00
|
|
|
bool WM_operator_check_ui_enabled(const bContext *C, const char *idname)
|
2011-12-11 19:23:02 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2011-12-11 19:23:02 +00:00
|
|
|
|
2012-08-15 09:42:06 +00:00
|
|
|
return !(ED_undo_valid(C, idname) == 0 || WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY));
|
2011-12-11 19:23:02 +00:00
|
|
|
}
|
|
|
|
|
2011-05-23 10:14:07 +00:00
|
|
|
wmOperator *WM_operator_last_redo(const bContext *C)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2011-05-23 10:14:07 +00:00
|
|
|
wmOperator *op;
|
|
|
|
|
|
|
|
/* only for operators that are registered and did an undo push */
|
2012-03-27 01:24:16 +00:00
|
|
|
for (op = wm->operators.last; op; op = op->prev)
|
2012-03-24 06:24:53 +00:00
|
|
|
if ((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
|
2011-05-23 10:14:07 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
return op;
|
|
|
|
}
|
|
|
|
|
2013-02-19 13:41:58 +00:00
|
|
|
static void wm_block_redo_cb(bContext *C, void *arg_op, int UNUSED(arg_event))
|
2012-11-28 16:42:39 +00:00
|
|
|
{
|
|
|
|
wmOperator *op = arg_op;
|
|
|
|
|
|
|
|
if (op == WM_operator_last_redo(C)) {
|
|
|
|
/* operator was already executed once? undo & repeat */
|
|
|
|
ED_undo_operator_repeat(C, op);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* operator not executed yet, call it */
|
|
|
|
ED_undo_push_op(C, op);
|
|
|
|
wm_operator_register(C, op);
|
|
|
|
|
|
|
|
WM_operator_repeat(C, op);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-19 13:37:48 +00:00
|
|
|
static void wm_block_redo_cancel_cb(bContext *C, void *arg_op)
|
|
|
|
{
|
|
|
|
wmOperator *op = arg_op;
|
|
|
|
|
|
|
|
/* if operator never got executed, free it */
|
|
|
|
if (op != WM_operator_last_redo(C))
|
|
|
|
WM_operator_free(op);
|
|
|
|
}
|
|
|
|
|
2009-04-01 14:02:06 +00:00
|
|
|
static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOperator *op = arg_op;
|
2009-04-01 14:02:06 +00:00
|
|
|
uiBlock *block;
|
2009-05-19 17:13:33 +00:00
|
|
|
uiLayout *layout;
|
2012-03-27 01:24:16 +00:00
|
|
|
uiStyle *style = UI_GetStyle();
|
2012-12-14 15:09:59 +00:00
|
|
|
int width = 15 * UI_UNIT_X;
|
2009-11-23 00:56:19 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
|
2009-04-01 14:02:06 +00:00
|
|
|
uiBlockClearFlag(block, UI_BLOCK_LOOP);
|
2012-10-24 21:57:07 +00:00
|
|
|
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
|
2010-10-31 14:43:30 +00:00
|
|
|
|
|
|
|
/* if register is not enabled, the operator gets freed on OPERATOR_FINISHED
|
2012-04-22 11:54:53 +00:00
|
|
|
* ui_apply_but_funcs_after calls ED_undo_operator_repeate_cb and crashes */
|
2010-10-31 14:43:30 +00:00
|
|
|
assert(op->type->flag & OPTYPE_REGISTER);
|
|
|
|
|
2012-11-28 16:42:39 +00:00
|
|
|
uiBlockSetHandleFunc(block, wm_block_redo_cb, arg_op);
|
2014-01-17 00:23:00 +01:00
|
|
|
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, 0, style);
|
2010-12-15 04:06:19 +00:00
|
|
|
|
2012-11-28 16:42:39 +00:00
|
|
|
if (op == WM_operator_last_redo(C))
|
|
|
|
if (!WM_operator_check_ui_enabled(C, op->type->name))
|
|
|
|
uiLayoutSetEnabled(layout, FALSE);
|
2011-01-12 18:00:23 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->type->flag & OPTYPE_MACRO) {
|
2012-03-27 01:24:16 +00:00
|
|
|
for (op = op->macro.first; op; op = op->next) {
|
2012-04-13 19:59:29 +00:00
|
|
|
uiItemL(layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
|
2011-06-09 15:26:05 +00:00
|
|
|
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
|
|
|
|
}
|
|
|
|
|
2011-04-03 13:17:07 +00:00
|
|
|
uiPopupBoundsBlock(block, 4, 0, 0);
|
2009-04-01 14:02:06 +00:00
|
|
|
uiEndBlock(C, block);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
typedef struct wmOpPopUp {
|
2011-06-24 03:30:50 +00:00
|
|
|
wmOperator *op;
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
int free_op;
|
|
|
|
} wmOpPopUp;
|
|
|
|
|
|
|
|
/* Only invoked by OK button in popups created with wm_block_dialog_create() */
|
2010-03-20 18:03:59 +00:00
|
|
|
static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOpPopUp *data = arg1;
|
|
|
|
uiBlock *block = arg2;
|
2010-03-20 18:03:59 +00:00
|
|
|
|
2011-06-24 03:30:50 +00:00
|
|
|
WM_operator_call(C, data->op);
|
|
|
|
|
|
|
|
/* let execute handle freeing it */
|
2012-05-27 19:40:36 +00:00
|
|
|
//data->free_op = FALSE;
|
|
|
|
//data->op = NULL;
|
2011-06-24 03:30:50 +00:00
|
|
|
|
|
|
|
/* in this case, wm_operator_ui_popup_cancel wont run */
|
|
|
|
MEM_freeN(data);
|
2010-03-20 18:03:59 +00:00
|
|
|
|
|
|
|
uiPupBlockClose(C, block);
|
|
|
|
}
|
|
|
|
|
2011-02-13 14:16:36 +00:00
|
|
|
static void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
|
2010-09-17 09:27:31 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOperator *op = op_ptr;
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->type->check) {
|
|
|
|
if (op->type->check(C, op)) {
|
2010-09-17 09:27:31 +00:00
|
|
|
/* refresh */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-20 18:03:59 +00:00
|
|
|
/* Dialogs are popups that require user verification (click OK) before exec */
|
2011-06-24 03:30:50 +00:00
|
|
|
static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
|
2010-03-20 18:03:59 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOpPopUp *data = userData;
|
|
|
|
wmOperator *op = data->op;
|
2010-03-20 18:03:59 +00:00
|
|
|
uiBlock *block;
|
|
|
|
uiLayout *layout;
|
2012-03-27 01:24:16 +00:00
|
|
|
uiStyle *style = UI_GetStyle();
|
2010-03-20 18:03:59 +00:00
|
|
|
|
2012-01-11 09:33:44 +00:00
|
|
|
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
|
2010-03-20 18:03:59 +00:00
|
|
|
uiBlockClearFlag(block, UI_BLOCK_LOOP);
|
2012-06-29 20:29:13 +00:00
|
|
|
|
2013-02-11 00:49:00 +00:00
|
|
|
/* intentionally don't use 'UI_BLOCK_MOVEMOUSE_QUIT', some dialogues have many items
|
2012-06-29 20:29:13 +00:00
|
|
|
* where quitting by accident is very annoying */
|
2012-10-24 21:57:07 +00:00
|
|
|
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN);
|
2010-03-20 18:03:59 +00:00
|
|
|
|
2014-01-17 00:23:00 +01:00
|
|
|
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
|
2010-09-17 09:27:31 +00:00
|
|
|
|
|
|
|
uiBlockSetFunc(block, dialog_check_cb, op, NULL);
|
2010-03-20 18:03:59 +00:00
|
|
|
|
2010-12-15 05:42:23 +00:00
|
|
|
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
|
2010-09-17 09:27:31 +00:00
|
|
|
|
2010-12-15 05:42:23 +00:00
|
|
|
/* clear so the OK button is left alone */
|
2010-09-17 09:27:31 +00:00
|
|
|
uiBlockSetFunc(block, NULL, NULL, NULL);
|
2010-03-20 18:03:59 +00:00
|
|
|
|
2012-07-18 11:01:23 +00:00
|
|
|
/* new column so as not to interfere with custom layouts [#26436] */
|
2011-03-10 22:22:47 +00:00
|
|
|
{
|
|
|
|
uiBlock *col_block;
|
|
|
|
uiLayout *col;
|
|
|
|
uiBut *btn;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
col = uiLayoutColumn(layout, FALSE);
|
|
|
|
col_block = uiLayoutGetBlock(col);
|
2011-03-10 22:22:47 +00:00
|
|
|
/* Create OK button, the callback of which will execute op */
|
2012-03-27 01:24:16 +00:00
|
|
|
btn = uiDefBut(col_block, BUT, 0, IFACE_("OK"), 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
2011-06-24 03:30:50 +00:00
|
|
|
uiButSetFunc(btn, dialog_exec_cb, data, col_block);
|
2011-03-10 22:22:47 +00:00
|
|
|
}
|
2010-03-20 18:03:59 +00:00
|
|
|
|
2010-11-30 18:07:44 +00:00
|
|
|
/* center around the mouse */
|
2012-03-27 01:24:16 +00:00
|
|
|
uiPopupBoundsBlock(block, 4, data->width / -2, data->height / 2);
|
2010-03-20 18:03:59 +00:00
|
|
|
uiEndBlock(C, block);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
2009-12-06 04:35:00 +00:00
|
|
|
|
2011-06-24 03:30:50 +00:00
|
|
|
static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
|
2009-12-06 04:35:00 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOpPopUp *data = userData;
|
|
|
|
wmOperator *op = data->op;
|
2009-12-06 04:35:00 +00:00
|
|
|
uiBlock *block;
|
|
|
|
uiLayout *layout;
|
2012-03-27 01:24:16 +00:00
|
|
|
uiStyle *style = UI_GetStyle();
|
2009-12-06 04:35:00 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
|
2009-12-06 04:35:00 +00:00
|
|
|
uiBlockClearFlag(block, UI_BLOCK_LOOP);
|
2012-10-24 21:57:07 +00:00
|
|
|
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
|
2009-12-06 04:35:00 +00:00
|
|
|
|
2014-01-17 00:23:00 +01:00
|
|
|
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
|
2009-12-06 04:35:00 +00:00
|
|
|
|
2010-12-15 05:42:23 +00:00
|
|
|
/* since ui is defined the auto-layout args are not used */
|
|
|
|
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
|
2009-12-06 04:35:00 +00:00
|
|
|
|
2011-04-03 13:17:07 +00:00
|
|
|
uiPopupBoundsBlock(block, 4, 0, 0);
|
2009-12-06 04:35:00 +00:00
|
|
|
uiEndBlock(C, block);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
2013-10-30 23:15:27 +00:00
|
|
|
static void wm_operator_ui_popup_cancel(struct bContext *C, void *userData)
|
2011-06-24 03:30:50 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOpPopUp *data = userData;
|
2013-10-30 23:15:27 +00:00
|
|
|
wmOperator *op = data->op;
|
|
|
|
|
|
|
|
if (op) {
|
|
|
|
if (op->type->cancel) {
|
|
|
|
op->type->cancel(C, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data->free_op) {
|
|
|
|
WM_operator_free(op);
|
|
|
|
}
|
2011-06-24 03:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(data);
|
|
|
|
}
|
|
|
|
|
2011-11-24 13:51:31 +00:00
|
|
|
static void wm_operator_ui_popup_ok(struct bContext *C, void *arg, int retval)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOpPopUp *data = arg;
|
|
|
|
wmOperator *op = data->op;
|
2011-11-24 13:51:31 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op && retval > 0)
|
2011-11-24 13:51:31 +00:00
|
|
|
WM_operator_call(C, op);
|
2012-11-13 14:34:36 +00:00
|
|
|
|
|
|
|
MEM_freeN(data);
|
2011-11-24 13:51:31 +00:00
|
|
|
}
|
|
|
|
|
2011-06-24 03:30:50 +00:00
|
|
|
int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOpPopUp *data = MEM_callocN(sizeof(wmOpPopUp), "WM_operator_ui_popup");
|
|
|
|
data->op = op;
|
|
|
|
data->width = width;
|
|
|
|
data->height = height;
|
|
|
|
data->free_op = TRUE; /* if this runs and gets registered we may want not to free it */
|
2011-11-24 13:51:31 +00:00
|
|
|
uiPupBlockEx(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data);
|
2011-06-24 03:30:50 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2012-11-14 06:13:42 +00:00
|
|
|
/**
|
|
|
|
* For use by #WM_operator_props_popup_call, #WM_operator_props_popup only.
|
|
|
|
*
|
|
|
|
* \note operator menu needs undo flag enabled , for redo callback */
|
2013-10-09 14:35:25 +00:00
|
|
|
static int wm_operator_props_popup_ex(bContext *C, wmOperator *op,
|
|
|
|
const bool do_call, const bool do_redo)
|
2009-04-01 14:02:06 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
if ((op->type->flag & OPTYPE_REGISTER) == 0) {
|
2012-02-19 06:00:20 +00:00
|
|
|
BKE_reportf(op->reports, RPT_ERROR,
|
2012-10-13 15:44:50 +00:00
|
|
|
"Operator '%s' does not have register enabled, incorrect invoke function", op->type->idname);
|
2010-10-31 14:43:30 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
2012-11-14 06:13:42 +00:00
|
|
|
|
2012-11-27 16:02:15 +00:00
|
|
|
/* if we don't have global undo, we can't do undo push for automatic redo,
|
|
|
|
* so we require manual OK clicking in this popup */
|
2013-10-09 14:35:25 +00:00
|
|
|
if (!do_redo || !(U.uiflag & USER_GLOBALUNDO))
|
2012-12-14 15:09:59 +00:00
|
|
|
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y);
|
2012-11-27 16:02:15 +00:00
|
|
|
|
2013-02-19 13:37:48 +00:00
|
|
|
uiPupBlockEx(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op);
|
2009-04-01 14:02:06 +00:00
|
|
|
|
2012-11-28 16:42:39 +00:00
|
|
|
if (do_call)
|
|
|
|
wm_block_redo_cb(C, op, 0);
|
2012-11-14 06:13:42 +00:00
|
|
|
|
2011-01-19 14:19:20 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2009-04-01 14:02:06 +00:00
|
|
|
}
|
|
|
|
|
2013-10-09 14:35:25 +00:00
|
|
|
/* Same as WM_operator_props_popup but don't use operator redo.
|
|
|
|
* just wraps WM_operator_props_dialog_popup.
|
|
|
|
*/
|
|
|
|
int WM_operator_props_popup_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
|
|
{
|
|
|
|
return wm_operator_props_popup_ex(C, op, false, false);
|
|
|
|
}
|
|
|
|
|
2012-11-14 06:13:42 +00:00
|
|
|
/* Same as WM_operator_props_popup but call the operator first,
|
2012-11-18 01:22:31 +00:00
|
|
|
* This way - the button values correspond to the result of the operator.
|
2012-11-14 06:13:42 +00:00
|
|
|
* Without this, first access to a button will make the result jump,
|
|
|
|
* see [#32452] */
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_operator_props_popup_call(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2012-11-14 06:13:42 +00:00
|
|
|
{
|
2013-10-09 14:35:25 +00:00
|
|
|
return wm_operator_props_popup_ex(C, op, true, true);
|
2012-11-14 06:13:42 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2012-11-14 06:13:42 +00:00
|
|
|
{
|
2013-10-09 14:35:25 +00:00
|
|
|
return wm_operator_props_popup_ex(C, op, false, true);
|
2012-11-14 06:13:42 +00:00
|
|
|
}
|
|
|
|
|
2010-03-20 18:03:59 +00:00
|
|
|
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmOpPopUp *data = MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup");
|
2010-03-20 18:03:59 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
data->op = op;
|
|
|
|
data->width = width;
|
|
|
|
data->height = height;
|
|
|
|
data->free_op = TRUE; /* if this runs and gets registered we may want not to free it */
|
2010-03-20 18:03:59 +00:00
|
|
|
|
|
|
|
/* op is not executed until popup OK but is clicked */
|
2011-11-24 13:51:31 +00:00
|
|
|
uiPupBlockEx(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data);
|
2010-03-20 18:03:59 +00:00
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2009-04-01 14:02:06 +00:00
|
|
|
int WM_operator_redo_popup(bContext *C, wmOperator *op)
|
|
|
|
{
|
2011-04-01 12:51:04 +00:00
|
|
|
/* CTX_wm_reports(C) because operator is on stack, not active in event system */
|
2012-03-27 01:24:16 +00:00
|
|
|
if ((op->type->flag & OPTYPE_REGISTER) == 0) {
|
2012-10-13 15:44:50 +00:00
|
|
|
BKE_reportf(CTX_wm_reports(C), RPT_ERROR,
|
|
|
|
"Operator redo '%s' does not have register enabled, incorrect invoke function", op->type->idname);
|
2011-04-01 12:51:04 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
if (op->type->poll && op->type->poll(C) == 0) {
|
2012-10-13 15:44:50 +00:00
|
|
|
BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context", op->type->idname);
|
2010-10-31 14:43:30 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2009-04-01 14:02:06 +00:00
|
|
|
uiPupBlock(C, wm_block_create_redo, op);
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2009-05-22 15:02:32 +00:00
|
|
|
/* ***************** Debug menu ************************* */
|
|
|
|
|
|
|
|
static int wm_debug_menu_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2012-08-08 18:21:54 +00:00
|
|
|
G.debug_value = RNA_int_get(op->ptr, "debug_value");
|
2009-05-22 15:02:32 +00:00
|
|
|
ED_screen_refresh(CTX_wm_manager(C), CTX_wm_window(C));
|
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
2010-12-15 06:12:16 +00:00
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-05-22 15:02:32 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_debug_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-05-22 15:02:32 +00:00
|
|
|
{
|
2012-08-08 18:21:54 +00:00
|
|
|
RNA_int_set(op->ptr, "debug_value", G.debug_value);
|
2012-03-27 01:24:16 +00:00
|
|
|
return WM_operator_props_dialog_popup(C, op, 9 * UI_UNIT_X, UI_UNIT_Y);
|
2009-05-22 15:02:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_debug_menu(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Debug Menu";
|
|
|
|
ot->idname = "WM_OT_debug_menu";
|
|
|
|
ot->description = "Open a popup to set the debug level";
|
2009-05-22 15:02:32 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = wm_debug_menu_invoke;
|
|
|
|
ot->exec = wm_debug_menu_exec;
|
|
|
|
ot->poll = WM_operator_winactive;
|
2009-05-22 15:02:32 +00:00
|
|
|
|
2012-10-11 23:46:12 +00:00
|
|
|
RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000);
|
2009-05-22 15:02:32 +00:00
|
|
|
}
|
|
|
|
|
2012-11-12 21:44:48 +00:00
|
|
|
/* ***************** Operator defaults ************************* */
|
|
|
|
static int wm_operator_defaults_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
PointerRNA ptr = CTX_data_pointer_get_type(C, "active_operator", &RNA_Operator);
|
|
|
|
|
|
|
|
if (!ptr.data) {
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "No operator in context");
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
WM_operator_properties_reset((wmOperator *)ptr.data);
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* used by operator preset menu. pre-2.65 this was a 'Reset' button */
|
|
|
|
static void WM_OT_operator_defaults(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Restore Defaults";
|
|
|
|
ot->idname = "WM_OT_operator_defaults";
|
|
|
|
ot->description = "Set the active operator to its default values";
|
|
|
|
|
|
|
|
ot->exec = wm_operator_defaults_exec;
|
|
|
|
|
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
|
|
|
}
|
2009-11-23 13:58:55 +00:00
|
|
|
|
|
|
|
/* ***************** Splash Screen ************************* */
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void wm_block_splash_close(bContext *C, void *arg_block, void *UNUSED(arg))
|
2009-11-23 13:58:55 +00:00
|
|
|
{
|
|
|
|
uiPupBlockClose(C, arg_block);
|
|
|
|
}
|
|
|
|
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unused);
|
|
|
|
|
2013-09-05 19:56:49 +00:00
|
|
|
/* XXX: hack to refresh splash screen with updated preset menu name,
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
* since popup blocks don't get regenerated like panels do */
|
2012-03-27 01:24:16 +00:00
|
|
|
static void wm_block_splash_refreshmenu(bContext *UNUSED(C), void *UNUSED(arg_block), void *UNUSED(arg))
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
{
|
2010-04-14 08:08:15 +00:00
|
|
|
/* ugh, causes crashes in other buttons, disabling for now until
|
2012-03-09 18:28:30 +00:00
|
|
|
* a better fix */
|
|
|
|
#if 0
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
uiPupBlockClose(C, arg_block);
|
|
|
|
uiPupBlock(C, wm_block_create_splash, NULL);
|
2012-03-09 18:28:30 +00:00
|
|
|
#endif
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
}
|
|
|
|
|
2011-04-11 15:13:06 +00:00
|
|
|
static int wm_resource_check_prev(void)
|
|
|
|
{
|
|
|
|
|
2013-03-05 03:17:46 +00:00
|
|
|
const char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true);
|
2011-04-11 15:13:06 +00:00
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
// if (res) printf("USER: %s\n", res);
|
2011-04-11 15:13:06 +00:00
|
|
|
|
2011-04-12 14:57:02 +00:00
|
|
|
#if 0 /* ignore the local folder */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (res == NULL) {
|
2012-03-18 07:38:51 +00:00
|
|
|
/* with a local dir, copying old files isn't useful since local dir get priority for config */
|
2013-03-05 03:17:46 +00:00
|
|
|
res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true);
|
2011-04-11 15:13:06 +00:00
|
|
|
}
|
2011-04-12 14:57:02 +00:00
|
|
|
#endif
|
2011-04-11 15:13:06 +00:00
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
// if (res) printf("LOCAL: %s\n", res);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (res) {
|
2011-04-12 04:23:38 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else {
|
2013-03-05 03:17:46 +00:00
|
|
|
return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL);
|
2011-04-11 15:13:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(arg))
|
2009-11-23 13:58:55 +00:00
|
|
|
{
|
|
|
|
uiBlock *block;
|
|
|
|
uiBut *but;
|
|
|
|
uiLayout *layout, *split, *col;
|
2012-03-27 01:24:16 +00:00
|
|
|
uiStyle *style = UI_GetStyle();
|
2009-12-28 10:44:02 +00:00
|
|
|
struct RecentFile *recent;
|
2010-01-11 10:48:41 +00:00
|
|
|
int i;
|
2012-03-24 02:51:46 +00:00
|
|
|
MenuType *mt = WM_menutype_find("USERPREF_MT_splash", TRUE);
|
2011-04-12 16:20:41 +00:00
|
|
|
char url[96];
|
2012-12-15 04:44:10 +00:00
|
|
|
char file[FILE_MAX];
|
2011-09-30 07:47:45 +00:00
|
|
|
|
|
|
|
#ifndef WITH_HEADLESS
|
|
|
|
extern char datatoc_splash_png[];
|
|
|
|
extern int datatoc_splash_png_size;
|
|
|
|
|
2012-05-17 07:59:25 +00:00
|
|
|
ImBuf *ibuf = IMB_ibImageFromMemory((unsigned char *)datatoc_splash_png,
|
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces
only with OpenColorIO-based pipeline.
This introduces two configurable color spaces:
- Input color space for images and movie clips. This space is used to convert
images/movies from color space in which file is saved to Blender's linear
space (for float images, byte images are not internally converted, only input
space is stored for such images and used later).
This setting could be found in image/clip data block settings.
- Display color space which defines space in which particular display is working.
This settings could be found in scene's Color Management panel.
When render result is being displayed on the screen, apart from converting image
to display space, some additional conversions could happen.
This conversions are:
- View, which defines tone curve applying before display transformation.
These are different ways to view the image on the same display device.
For example it could be used to emulate film view on sRGB display.
- Exposure affects on image exposure before tone map is applied.
- Gamma is post-display gamma correction, could be used to match particular
display gamma.
- RGB curves are user-defined curves which are applying before display
transformation, could be used for different purposes.
All this settings by default are only applying on render result and does not
affect on other images. If some particular image needs to be affected by this
transformation, "View as Render" setting of image data block should be set to
truth. Movie clips are always affected by all display transformations.
This commit also introduces configurable color space in which sequencer is
working. This setting could be found in scene's Color Management panel and
it should be used if such stuff as grading needs to be done in color space
different from sRGB (i.e. when Film view on sRGB display is use, using VD16
space as sequencer's internal space would make grading working in space
which is close to the space using for display).
Some technical notes:
- Image buffer's float buffer is now always in linear space, even if it was
created from 16bit byte images.
- Space of byte buffer is stored in image buffer's rect_colorspace property.
- Profile of image buffer was removed since it's not longer meaningful.
- OpenGL and GLSL is supposed to always work in sRGB space. It is possible
to support other spaces, but it's quite large project which isn't so
much important.
- Legacy Color Management option disabled is emulated by using None display.
It could have some regressions, but there's no clear way to avoid them.
- If OpenColorIO is disabled on build time, it should make blender behaving
in the same way as previous release with color management enabled.
More details could be found at this page (more details would be added soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management
--
Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO
integration and to Brecht van Lommel for some further development and code/
usecase review!
2012-09-15 10:05:07 +00:00
|
|
|
datatoc_splash_png_size, IB_rect, NULL, "<splash screen>");
|
2011-09-30 07:47:45 +00:00
|
|
|
#else
|
2012-03-27 01:24:16 +00:00
|
|
|
ImBuf *ibuf = NULL;
|
2011-09-30 07:47:45 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2011-08-22 16:54:26 +00:00
|
|
|
#ifdef WITH_BUILDINFO
|
2013-11-04 13:21:39 +00:00
|
|
|
int label_delta = 0;
|
2013-11-15 17:11:59 +06:00
|
|
|
int hash_width, date_width;
|
|
|
|
char date_buf[128] = "\0";
|
2013-11-04 13:21:39 +00:00
|
|
|
char hash_buf[128] = "\0";
|
2013-11-15 17:11:59 +06:00
|
|
|
extern unsigned long build_commit_timestamp;
|
|
|
|
extern char build_hash[], build_commit_date[], build_commit_time[], build_branch[];
|
2013-11-04 13:21:39 +00:00
|
|
|
|
2013-11-15 17:11:59 +06:00
|
|
|
/* Builds made from tag only shows tag sha */
|
|
|
|
BLI_snprintf(hash_buf, sizeof(hash_buf), "Hash: %s", build_hash);
|
|
|
|
BLI_snprintf(date_buf, sizeof(date_buf), "Date: %s %s", build_commit_date, build_commit_time);
|
2010-01-08 05:51:51 +00:00
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi);
|
2014-01-01 16:04:52 +01:00
|
|
|
hash_width = (int)BLF_width(style->widgetlabel.uifont_id, hash_buf, sizeof(hash_buf)) + U.widget_unit;
|
|
|
|
date_width = (int)BLF_width(style->widgetlabel.uifont_id, date_buf, sizeof(date_buf)) + U.widget_unit;
|
2012-10-20 20:20:02 +00:00
|
|
|
#endif /* WITH_BUILDINFO */
|
2010-01-08 06:05:42 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
|
2012-10-25 02:57:55 +00:00
|
|
|
|
|
|
|
/* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized
|
|
|
|
* with the OS when the splash shows, window clipping in this case gives
|
|
|
|
* ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */
|
|
|
|
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP);
|
2009-11-23 13:58:55 +00:00
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
/* XXX splash scales with pixelsize, should become widget-units */
|
2013-01-08 02:06:16 +00:00
|
|
|
but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
|
2009-11-23 13:58:55 +00:00
|
|
|
uiButSetFunc(but, wm_block_splash_close, block, NULL);
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
|
2009-11-23 13:58:55 +00:00
|
|
|
|
2013-11-04 13:21:39 +00:00
|
|
|
#ifdef WITH_BUILDINFO
|
2013-11-15 17:11:59 +06:00
|
|
|
if (build_commit_timestamp != 0) {
|
|
|
|
uiDefBut(block, LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
2013-11-04 13:21:39 +00:00
|
|
|
label_delta = 12;
|
|
|
|
}
|
|
|
|
uiDefBut(block, LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
|
|
|
|
2013-11-15 17:11:59 +06:00
|
|
|
if (!STREQ(build_branch, "master")) {
|
2013-11-04 13:21:39 +00:00
|
|
|
char branch_buf[128] = "\0";
|
|
|
|
int branch_width;
|
|
|
|
BLI_snprintf(branch_buf, sizeof(branch_buf), "Branch: %s", build_branch);
|
2014-01-01 16:04:52 +01:00
|
|
|
branch_width = (int)BLF_width(style->widgetlabel.uifont_id, branch_buf, sizeof(branch_buf)) + U.widget_unit;
|
2013-11-04 13:21:39 +00:00
|
|
|
uiDefBut(block, LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
|
|
|
}
|
2012-10-20 20:20:02 +00:00
|
|
|
#endif /* WITH_BUILDINFO */
|
2010-01-08 06:05:42 +00:00
|
|
|
|
2014-01-17 00:23:00 +01:00
|
|
|
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style);
|
2010-01-08 05:51:51 +00:00
|
|
|
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
uiBlockSetEmboss(block, UI_EMBOSS);
|
|
|
|
/* show the splash menu (containing interaction presets), using python */
|
|
|
|
if (mt) {
|
2012-03-27 01:24:16 +00:00
|
|
|
Menu menu = {NULL};
|
|
|
|
menu.layout = layout;
|
|
|
|
menu.type = mt;
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
mt->draw(C, &menu);
|
2010-10-06 20:29:00 +00:00
|
|
|
|
2012-05-27 19:40:36 +00:00
|
|
|
// wmWindowManager *wm = CTX_wm_manager(C);
|
2011-02-27 18:03:19 +00:00
|
|
|
// uiItemM(layout, C, "USERPREF_MT_keyconfigs", U.keyconfigstr, ICON_NONE);
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
}
|
2009-11-23 13:58:55 +00:00
|
|
|
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
uiBlockSetEmboss(block, UI_EMBOSSP);
|
2009-11-23 13:58:55 +00:00
|
|
|
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
|
|
|
|
|
2012-06-19 23:08:16 +00:00
|
|
|
split = uiLayoutSplit(layout, 0.0f, FALSE);
|
|
|
|
col = uiLayoutColumn(split, FALSE);
|
2013-02-17 13:56:49 +00:00
|
|
|
uiItemL(col, IFACE_("Links"), ICON_NONE);
|
|
|
|
uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url",
|
2013-11-17 00:37:12 +01:00
|
|
|
"http://www.blender.org/foundation/donation-payment/");
|
2013-02-17 13:56:49 +00:00
|
|
|
uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url",
|
2013-11-17 00:37:12 +01:00
|
|
|
"http://www.blender.org/about/credits/");
|
2013-02-17 13:56:49 +00:00
|
|
|
uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url",
|
2013-11-17 00:37:12 +01:00
|
|
|
"http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.70");
|
2013-02-17 13:56:49 +00:00
|
|
|
uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url",
|
|
|
|
"http://wiki.blender.org/index.php/Doc:2.6/Manual");
|
2011-10-20 20:38:26 +00:00
|
|
|
uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
|
2013-02-17 13:56:49 +00:00
|
|
|
uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url",
|
|
|
|
"http://www.blender.org/community/user-community");
|
2013-03-10 06:18:03 +00:00
|
|
|
if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
|
2013-02-17 13:56:49 +00:00
|
|
|
BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d"
|
|
|
|
STRINGIFY(BLENDER_VERSION_CHAR) "_release",
|
|
|
|
BLENDER_VERSION / 100, BLENDER_VERSION % 100);
|
2011-04-12 16:20:41 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-02-17 13:56:49 +00:00
|
|
|
BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d_%d",
|
|
|
|
BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
|
2011-04-12 16:20:41 +00:00
|
|
|
}
|
2011-10-20 20:38:26 +00:00
|
|
|
uiItemStringO(col, IFACE_("Python API Reference"), ICON_URL, "WM_OT_url_open", "url", url);
|
2011-02-27 18:03:19 +00:00
|
|
|
uiItemL(col, "", ICON_NONE);
|
2010-09-11 04:23:45 +00:00
|
|
|
|
2012-06-19 23:08:16 +00:00
|
|
|
col = uiLayoutColumn(split, FALSE);
|
2011-04-11 15:13:06 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (wm_resource_check_prev()) {
|
2011-04-11 15:13:06 +00:00
|
|
|
uiItemO(col, NULL, ICON_NEW, "WM_OT_copy_prev_settings");
|
2011-04-12 04:23:38 +00:00
|
|
|
uiItemS(col);
|
|
|
|
}
|
|
|
|
|
2011-10-20 20:38:26 +00:00
|
|
|
uiItemL(col, IFACE_("Recent"), ICON_NONE);
|
2012-03-27 01:24:16 +00:00
|
|
|
for (recent = G.recent_files.first, i = 0; (i < 5) && (recent); recent = recent->next, i++) {
|
2012-11-06 20:29:14 +00:00
|
|
|
BLI_split_file_part(recent->filepath, file, sizeof(file));
|
|
|
|
if (BLO_has_bfile_extension(file))
|
|
|
|
uiItemStringO(col, BLI_path_basename(recent->filepath), ICON_FILE_BLEND, "WM_OT_open_mainfile", "filepath", recent->filepath);
|
|
|
|
else
|
|
|
|
uiItemStringO(col, BLI_path_basename(recent->filepath), ICON_FILE_BACKUP, "WM_OT_open_mainfile", "filepath", recent->filepath);
|
2011-04-11 15:13:06 +00:00
|
|
|
}
|
|
|
|
|
2010-03-18 07:05:20 +00:00
|
|
|
uiItemS(col);
|
2010-05-03 03:33:20 +00:00
|
|
|
uiItemO(col, NULL, ICON_RECOVER_LAST, "WM_OT_recover_last_session");
|
2011-02-27 18:03:19 +00:00
|
|
|
uiItemL(col, "", ICON_NONE);
|
* Interaction Presets
This adds a new presets menu in the splash screen and the Input section of
User Preferences to choose a preset interaction style, consisting of key configurations
and also other user preferences such as select mouse button, view rotation style, etc.
Currently, just 'Blender' and 'Maya' presets are included, hopefully we can have more
presets contributed (and maintained!) by the community.
It's best to keep these presets minimal to avoid too many key conflicts. In the Maya one
I changed the view manipulation key/mouse combos and also the transform
manipulator keys, not much more than that.
To save an interaction preset, open the user preferences Input section, and press the
[ + ] button next to the presets menu. It will save out a .py file containing any edited key
maps and navigation preferences to the presets/interaction folder in your scripts folder.
---
Part of this commit changes the way that key maps are exported/displayed in
preferences - now partial key configs are allowed. Previously it would export/import the
entire key configuration, regardless of whether individual key maps were edited or not
(which would make them more susceptible to conflicts in unexpected areas).
(note, in blender terminology, a key map is a category of key items, such as
'Object Mode' or 'View 2d'.)
Now, the export and the UI display work in a similar way to how key maps are
processed internally - Locally edited key maps (after pressing the 'Edit' button) are
processed first, falling back to other key maps in the current key config, and then falling
back to the default key config. So it's possible for a key config to only include a few
key maps, and the rest just gets pulled from the default key config. The preferences
UI display works like this too behind the scenes in deciding what to show users,
however using it is just like it was before, the complexity is hidden.
2010-04-14 06:27:50 +00:00
|
|
|
|
2011-04-10 09:37:04 +00:00
|
|
|
uiCenteredBoundsBlock(block, 0);
|
2009-11-23 13:58:55 +00:00
|
|
|
uiEndBlock(C, block);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
|
2009-11-23 13:58:55 +00:00
|
|
|
{
|
|
|
|
uiPupBlock(C, wm_block_create_splash, NULL);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_splash(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Splash Screen";
|
|
|
|
ot->idname = "WM_OT_splash";
|
2013-11-25 22:23:36 +01:00
|
|
|
ot->description = "Open the splash screen with release info";
|
2009-11-23 13:58:55 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = wm_splash_invoke;
|
|
|
|
ot->poll = WM_operator_winactive;
|
2009-11-23 13:58:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-06-03 18:31:37 +00:00
|
|
|
/* ***************** Search menu ************************* */
|
2010-10-16 02:40:31 +00:00
|
|
|
static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_op))
|
2009-06-03 18:31:37 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
static char search[256] = "";
|
2009-06-03 18:31:37 +00:00
|
|
|
wmEvent event;
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2009-06-03 18:31:37 +00:00
|
|
|
uiBlock *block;
|
|
|
|
uiBut *but;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
|
2012-10-24 21:57:07 +00:00
|
|
|
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
|
2009-06-03 18:31:37 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
|
2012-12-04 18:22:41 +00:00
|
|
|
uiOperatorSearch_But(but);
|
2009-06-03 18:31:37 +00:00
|
|
|
|
2009-06-05 16:11:18 +00:00
|
|
|
/* fake button, it holds space for search items */
|
2012-11-26 13:23:37 +00:00
|
|
|
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
2009-06-05 16:11:18 +00:00
|
|
|
|
Code holiday commit:
- fix: user pref, window title was reset to 'Blender' on tab usage
- Undo history menu back:
- name "Undo History"
- hotkey alt+ctrl+z (alt+apple+z for mac)
- works like 2.4x, only for global undo, editmode and particle edit.
- Menu scroll
- for small windows or screens, popup menus now allow to display
all items, using internal scrolling
- works with a timer, scrolling 10 items per second when mouse
is over the top or bottom arrow
- if menu is too big to display, it now draws to top or bottom,
based on largest available space.
- also works for hotkey driven pop up menus.
- User pref "DPI" follows widget/layout size
- widgets & headers now become bigger and smaller, to match
'dpi' font sizes. Works well to match UI to monitor size.
- note that icons can get fuzzy, we need better mipmaps for it
2011-06-04 17:03:46 +00:00
|
|
|
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
|
2009-06-03 18:31:37 +00:00
|
|
|
uiEndBlock(C, block);
|
|
|
|
|
2013-07-29 08:29:04 +00:00
|
|
|
wm_event_init_from_window(win, &event);
|
2012-03-27 01:24:16 +00:00
|
|
|
event.type = EVT_BUT_OPEN;
|
|
|
|
event.val = KM_PRESS;
|
|
|
|
event.customdata = but;
|
|
|
|
event.customdatafree = FALSE;
|
2009-06-03 18:31:37 +00:00
|
|
|
wm_event_add(win, &event);
|
|
|
|
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static int wm_search_menu_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
|
2009-06-03 18:31:37 +00:00
|
|
|
{
|
2012-05-06 15:03:31 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-06-03 18:31:37 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-06-03 18:31:37 +00:00
|
|
|
{
|
|
|
|
uiPupBlock(C, wm_block_search_menu, op);
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2009-07-28 08:50:11 +00:00
|
|
|
/* op->poll */
|
2009-09-14 16:52:06 +00:00
|
|
|
static int wm_search_menu_poll(bContext *C)
|
2009-07-28 08:50:11 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
if (CTX_wm_window(C) == NULL) {
|
2011-05-16 04:55:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else {
|
2012-03-27 01:24:16 +00:00
|
|
|
ScrArea *sa = CTX_wm_area(C);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (sa) {
|
2012-10-20 20:20:02 +00:00
|
|
|
if (sa->spacetype == SPACE_CONSOLE) return 0; /* XXX - so we can use the shortcut in the console */
|
|
|
|
if (sa->spacetype == SPACE_TEXT) return 0; /* XXX - so we can use the spacebar in the text editor */
|
2011-05-16 04:55:31 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-27 01:24:16 +00:00
|
|
|
Object *editob = CTX_data_edit_object(C);
|
2012-10-20 20:20:02 +00:00
|
|
|
if (editob && editob->type == OB_FONT) return 0; /* XXX - so we can use the spacebar for entering text */
|
2011-05-16 04:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-28 08:50:11 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-06-03 18:31:37 +00:00
|
|
|
static void WM_OT_search_menu(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Search Menu";
|
|
|
|
ot->idname = "WM_OT_search_menu";
|
2012-05-06 15:03:31 +00:00
|
|
|
ot->description = "Pop-up a search menu over all available operators in current context";
|
2009-06-03 18:31:37 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = wm_search_menu_invoke;
|
|
|
|
ot->exec = wm_search_menu_exec;
|
|
|
|
ot->poll = wm_search_menu_poll;
|
2009-06-03 18:31:37 +00:00
|
|
|
}
|
|
|
|
|
2010-02-11 21:17:05 +00:00
|
|
|
static int wm_call_menu_exec(bContext *C, wmOperator *op)
|
2009-10-06 13:04:31 +00:00
|
|
|
{
|
|
|
|
char idname[BKE_ST_MAXNAME];
|
|
|
|
RNA_string_get(op->ptr, "name", idname);
|
|
|
|
|
2009-10-08 19:06:32 +00:00
|
|
|
uiPupMenuInvoke(C, idname);
|
2009-10-06 13:04:31 +00:00
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_call_menu(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Call Menu";
|
|
|
|
ot->idname = "WM_OT_call_menu";
|
2013-02-28 15:31:20 +00:00
|
|
|
ot->description = "Call (draw) a pre-defined menu";
|
2009-10-06 13:04:31 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = wm_call_menu_exec;
|
|
|
|
ot->poll = WM_operator_winactive;
|
2009-10-06 13:04:31 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
2011-06-06 11:56:54 +00:00
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
RNA_def_string(ot->srna, "name", NULL, BKE_ST_MAXNAME, "Name", "Name of the menu");
|
2009-10-06 13:04:31 +00:00
|
|
|
}
|
2009-05-22 15:02:32 +00:00
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
/* ************ window / screen operator definitions ************** */
|
|
|
|
|
2010-01-27 09:16:28 +00:00
|
|
|
/* this poll functions is needed in place of WM_operator_winactive
|
|
|
|
* while it crashes on full screen */
|
|
|
|
static int wm_operator_winactive_normal(bContext *C)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2010-01-27 09:16:28 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (win == NULL || win->screen == NULL || win->screen->full != SCREENNORMAL)
|
2010-03-22 09:30:00 +00:00
|
|
|
return 0;
|
2010-01-27 09:16:28 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
static void WM_OT_window_duplicate(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Duplicate Window";
|
|
|
|
ot->idname = "WM_OT_window_duplicate";
|
|
|
|
ot->description = "Duplicate the current Blender window";
|
2009-09-12 17:16:12 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = wm_window_duplicate_exec;
|
|
|
|
ot->poll = wm_operator_winactive_normal;
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_save_homefile(wmOperatorType *ot)
|
|
|
|
{
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
ot->name = "Save Startup File";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "WM_OT_save_homefile";
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
ot->description = "Make the current file the default .blend file, includes preferences";
|
2009-09-12 17:16:12 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_operator_confirm;
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
ot->exec = wm_homefile_write_exec;
|
|
|
|
}
|
|
|
|
|
2013-06-18 18:11:52 +00:00
|
|
|
static int wm_userpref_autoexec_add_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
|
|
|
|
{
|
|
|
|
bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare");
|
|
|
|
BLI_addtail(&U.autoexec_paths, path_cmp);
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_userpref_autoexec_path_add(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Add Autoexec Path";
|
|
|
|
ot->idname = "WM_OT_userpref_autoexec_path_add";
|
2013-07-08 07:40:32 +00:00
|
|
|
ot->description = "Add path to exclude from autoexecution";
|
2013-06-18 18:11:52 +00:00
|
|
|
|
|
|
|
ot->exec = wm_userpref_autoexec_add_exec;
|
|
|
|
|
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int wm_userpref_autoexec_remove_exec(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
|
|
|
const int index = RNA_int_get(op->ptr, "index");
|
|
|
|
bPathCompare *path_cmp = BLI_findlink(&U.autoexec_paths, index);
|
|
|
|
if (path_cmp) {
|
|
|
|
BLI_freelinkN(&U.autoexec_paths, path_cmp);
|
|
|
|
}
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_userpref_autoexec_path_remove(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Remove Autoexec Path";
|
|
|
|
ot->idname = "WM_OT_userpref_autoexec_path_remove";
|
2013-07-08 07:40:32 +00:00
|
|
|
ot->description = "Remove path to exclude from autoexecution";
|
2013-06-18 18:11:52 +00:00
|
|
|
|
|
|
|
ot->exec = wm_userpref_autoexec_remove_exec;
|
|
|
|
|
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
|
|
|
|
|
|
|
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
|
|
|
|
}
|
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
static void WM_OT_save_userpref(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Save User Settings";
|
|
|
|
ot->idname = "WM_OT_save_userpref";
|
|
|
|
ot->description = "Save user preferences separately, overrides startup file preferences";
|
|
|
|
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
ot->exec = wm_userpref_write_exec;
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
2013-03-28 02:29:10 +00:00
|
|
|
static void WM_OT_read_history(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
ot->name = "Reload History File";
|
|
|
|
ot->idname = "WM_OT_read_history";
|
|
|
|
ot->description = "Reloads history and bookmarks";
|
|
|
|
|
|
|
|
ot->invoke = WM_operator_confirm;
|
|
|
|
ot->exec = wm_history_read_exec;
|
|
|
|
|
|
|
|
/* this operator is only used for loading settings from a previous blender install */
|
|
|
|
ot->flag = OPTYPE_INTERNAL;
|
|
|
|
}
|
|
|
|
|
2009-02-07 10:00:46 +00:00
|
|
|
static void WM_OT_read_homefile(wmOperatorType *ot)
|
|
|
|
{
|
2013-11-27 20:48:07 +01:00
|
|
|
PropertyRNA *prop;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Reload Start-Up File";
|
|
|
|
ot->idname = "WM_OT_read_homefile";
|
|
|
|
ot->description = "Open the default file (doesn't save the current file)";
|
2009-02-07 10:00:46 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_operator_confirm;
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
ot->exec = wm_homefile_read_exec;
|
2013-11-27 20:48:07 +01:00
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string_file_path(ot->srna, "filepath", NULL,
|
2013-11-27 20:48:07 +01:00
|
|
|
FILE_MAX, "File Path",
|
|
|
|
"Path to an alternative start-up file");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2011-02-01 02:54:29 +00:00
|
|
|
/* ommit poll to run in background mode */
|
2010-10-02 13:45:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_read_factory_settings(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Load Factory Settings";
|
|
|
|
ot->idname = "WM_OT_read_factory_settings";
|
|
|
|
ot->description = "Load default file and user preferences";
|
2009-02-07 10:00:46 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_operator_confirm;
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
ot->exec = wm_homefile_read_exec;
|
2011-02-01 02:54:29 +00:00
|
|
|
/* ommit poll to run in background mode */
|
2009-02-07 10:00:46 +00:00
|
|
|
}
|
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* *************** open file **************** */
|
2009-01-06 14:42:54 +00:00
|
|
|
|
2013-06-18 18:11:52 +00:00
|
|
|
/* currently fits in a pointer */
|
|
|
|
struct FileRuntime {
|
|
|
|
bool is_untrusted;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-06-10 00:42:16 +00:00
|
|
|
static void open_set_load_ui(wmOperator *op, bool use_prefs)
|
2009-08-21 14:33:53 +00:00
|
|
|
{
|
2013-06-10 00:42:16 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "load_ui");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, use_prefs ?
|
|
|
|
(U.flag & USER_FILENOUI) == 0 :
|
2013-06-10 10:55:57 +00:00
|
|
|
(G.fileflags & G_FILE_NO_UI) == 0);
|
2013-06-10 00:42:16 +00:00
|
|
|
}
|
2009-08-21 14:33:53 +00:00
|
|
|
}
|
2009-02-13 13:04:48 +00:00
|
|
|
|
2013-06-10 00:42:16 +00:00
|
|
|
static void open_set_use_scripts(wmOperator *op, bool use_prefs)
|
2010-02-27 01:27:22 +00:00
|
|
|
{
|
2013-06-10 00:42:16 +00:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
2011-05-28 13:11:24 +00:00
|
|
|
/* use G_SCRIPT_AUTOEXEC rather than the userpref because this means if
|
2011-03-15 08:04:11 +00:00
|
|
|
* the flag has been disabled from the command line, then opening
|
|
|
|
* from the menu wont enable this setting. */
|
2013-06-10 00:42:16 +00:00
|
|
|
RNA_property_boolean_set(op->ptr, prop, use_prefs ?
|
|
|
|
(U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0 :
|
|
|
|
(G.f & G_SCRIPT_AUTOEXEC) != 0);
|
2011-03-15 08:04:11 +00:00
|
|
|
}
|
2010-02-27 01:27:22 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-01-06 14:42:54 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
const char *openname = G.main->name;
|
2010-11-11 18:53:10 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (CTX_wm_window(C) == NULL) {
|
2011-06-10 09:44:27 +00:00
|
|
|
/* in rare cases this could happen, when trying to invoke in background
|
|
|
|
* mode on load for example. Don't use poll for this because exec()
|
|
|
|
* can still run without a window */
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Context window not set");
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
2010-11-11 18:53:10 +00:00
|
|
|
/* if possible, get the name of the most recently used .blend file */
|
|
|
|
if (G.recent_files.first) {
|
|
|
|
struct RecentFile *recent = G.recent_files.first;
|
|
|
|
openname = recent->filepath;
|
|
|
|
}
|
|
|
|
|
|
|
|
RNA_string_set(op->ptr, "filepath", openname);
|
2013-06-10 00:42:16 +00:00
|
|
|
open_set_load_ui(op, true);
|
|
|
|
open_set_use_scripts(op, true);
|
2013-06-18 18:11:52 +00:00
|
|
|
op->customdata = NULL;
|
2009-08-21 14:33:53 +00:00
|
|
|
|
2009-02-16 12:14:04 +00:00
|
|
|
WM_event_add_fileselect(C, op);
|
2009-01-06 14:42:54 +00:00
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2009-02-18 18:08:33 +00:00
|
|
|
static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
|
2009-01-06 14:42:54 +00:00
|
|
|
{
|
2009-09-12 19:54:39 +00:00
|
|
|
char path[FILE_MAX];
|
2009-08-21 14:33:53 +00:00
|
|
|
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
2013-06-10 00:42:16 +00:00
|
|
|
|
|
|
|
/* re-use last loaded setting so we can reload a file without changing */
|
|
|
|
open_set_load_ui(op, false);
|
|
|
|
open_set_use_scripts(op, false);
|
2009-08-21 14:33:53 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "load_ui"))
|
2009-08-21 14:33:53 +00:00
|
|
|
G.fileflags &= ~G_FILE_NO_UI;
|
|
|
|
else
|
|
|
|
G.fileflags |= G_FILE_NO_UI;
|
2010-02-27 01:27:22 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "use_scripts"))
|
2010-02-27 12:01:10 +00:00
|
|
|
G.f |= G_SCRIPT_AUTOEXEC;
|
2010-02-27 01:27:22 +00:00
|
|
|
else
|
2010-02-27 12:01:10 +00:00
|
|
|
G.f &= ~G_SCRIPT_AUTOEXEC;
|
2009-01-06 14:42:54 +00:00
|
|
|
|
2012-08-11 21:35:24 +00:00
|
|
|
/* XXX wm in context is not set correctly after WM_file_read -> crash */
|
2012-06-17 11:36:28 +00:00
|
|
|
/* do it before for now, but is this correct with multiple windows? */
|
2.5: WM Compositing
* Triple Buffer is now more complete:
- Proper handling of window resize, duplicate, etc.
- It now uses 3x3 textures (or less) if the power of two sizes
do not match well. That still has a worst case wast of 23.4%,
but better than 300%.
- It can also use the ARB/NV/EXT_texture_rectangle extension
now, which may be supported on hardware that does not support
ARB_texture_non_power_of_two.
- Gesture, menu and brushe redraws now require no redraws at all
from the area regions. So even on a high poly scene just moving
the paint cursor or opening a menu should be fast.
* Testing can be done by setting the "Window Draw Method" in the
User Preferences in the outliner. "Overlap" is still default,
since "Triple Buffer" has not been tested on computers other than
mine, would like to avoid crashing Blender on startup in case
there is a common bug, but it's ready for testing now.
- For reference "Full" draws the full window each time.
- "Triple Buffer" should work for both swap copy and swap exchange
systems, the latter still need the -E command line option for
"Overlap".
- Resizing and going fullscreen still gives flicker here but no
more than "Full" drawing.
* Partial Redraw was added. ED_region_tag_redraw_partial takes a
rect in window coordinates to define a subarea of the region.
On region draw it will then set glScissor to a smaller area, and
ar->drawrct will always be set to either the partial or full
window rect. The latter can then be used for clipping in the 3D
view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
2009-01-06 14:42:54 +00:00
|
|
|
|
2013-06-18 18:11:52 +00:00
|
|
|
/* autoexec is already set correctly for invoke() for exec() though we need to initialize */
|
|
|
|
if (!RNA_struct_property_is_set(op->ptr, "use_scripts")) {
|
|
|
|
WM_file_autoexec_init(path);
|
|
|
|
}
|
2012-08-11 21:35:24 +00:00
|
|
|
WM_file_read(C, path, op->reports);
|
2013-06-18 18:11:52 +00:00
|
|
|
|
2013-06-25 13:39:51 +00:00
|
|
|
/* for file open also popup for warnings, not only errors */
|
|
|
|
BKE_report_print_level_set(op->reports, RPT_WARNING);
|
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-01-06 14:42:54 +00:00
|
|
|
}
|
|
|
|
|
2013-06-18 18:11:52 +00:00
|
|
|
static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
|
|
|
struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
|
|
|
|
bool is_untrusted = false;
|
|
|
|
char path[FILE_MAX];
|
|
|
|
char *lslash;
|
|
|
|
|
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
|
|
|
|
|
|
|
/* get the dir */
|
|
|
|
lslash = (char *)BLI_last_slash(path);
|
|
|
|
if (lslash) *(lslash + 1) = '\0';
|
|
|
|
|
|
|
|
if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) {
|
|
|
|
if (BKE_autoexec_match(path) == true) {
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, false);
|
|
|
|
is_untrusted = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (file_info) {
|
|
|
|
file_info->is_untrusted = is_untrusted;
|
|
|
|
}
|
|
|
|
|
|
|
|
return is_untrusted;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wm_open_mainfile_ui(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
|
|
|
struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
|
|
|
|
uiLayout *layout = op->layout;
|
|
|
|
uiLayout *col = op->layout;
|
|
|
|
const char *autoexec_text = NULL;
|
|
|
|
|
|
|
|
uiItemR(layout, op->ptr, "load_ui", 0, NULL, ICON_NONE);
|
|
|
|
|
|
|
|
col = uiLayoutColumn(layout, false);
|
|
|
|
if (file_info->is_untrusted) {
|
|
|
|
autoexec_text = "Trusted Source [Untrusted Path]";
|
|
|
|
uiLayoutSetActive(col, false);
|
|
|
|
uiLayoutSetEnabled(col, false);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
autoexec_text = "Trusted Source";
|
|
|
|
}
|
|
|
|
|
|
|
|
uiItemR(col, op->ptr, "use_scripts", 0, autoexec_text, ICON_NONE);
|
|
|
|
}
|
|
|
|
|
2009-01-06 14:42:54 +00:00
|
|
|
static void WM_OT_open_mainfile(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Open Blender File";
|
|
|
|
ot->idname = "WM_OT_open_mainfile";
|
|
|
|
ot->description = "Open a Blender file";
|
2012-03-02 21:14:37 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = wm_open_mainfile_invoke;
|
|
|
|
ot->exec = wm_open_mainfile_exec;
|
2013-06-18 18:11:52 +00:00
|
|
|
ot->check = wm_open_mainfile_check;
|
|
|
|
ot->ui = wm_open_mainfile_ui;
|
2011-06-10 09:44:27 +00:00
|
|
|
/* ommit window poll so this can work in background mode */
|
2012-03-02 21:14:37 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_OPENFILE,
|
2012-03-02 21:14:37 +00:00
|
|
|
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
|
2009-08-21 14:33:53 +00:00
|
|
|
|
2011-09-15 13:20:18 +00:00
|
|
|
RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file");
|
2012-03-02 21:14:37 +00:00
|
|
|
RNA_def_boolean(ot->srna, "use_scripts", 1, "Trusted Source",
|
|
|
|
"Allow .blend file to execute scripts automatically, default available from system preferences");
|
2009-07-23 21:35:11 +00:00
|
|
|
}
|
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* **************** link/append *************** */
|
|
|
|
|
2012-09-15 01:52:28 +00:00
|
|
|
static int wm_link_append_poll(bContext *C)
|
2011-12-13 12:51:40 +00:00
|
|
|
{
|
2012-03-24 06:24:53 +00:00
|
|
|
if (WM_operator_winactive(C)) {
|
2011-12-13 12:51:40 +00:00
|
|
|
/* linking changes active object which is pretty useful in general,
|
2012-03-09 18:28:30 +00:00
|
|
|
* but which totally confuses edit mode (i.e. it becoming not so obvious
|
2013-02-11 00:49:00 +00:00
|
|
|
* to leave from edit mode and invalid tools in toolbar might be displayed)
|
2012-03-09 18:28:30 +00:00
|
|
|
* so disable link/append when in edit mode (sergey) */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (CTX_data_edit_object(C))
|
2011-12-13 12:51:40 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_link_append_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-09-12 19:54:39 +00:00
|
|
|
{
|
2012-03-24 06:24:53 +00:00
|
|
|
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
2011-12-12 18:52:18 +00:00
|
|
|
return WM_operator_call_notest(C, op);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2009-09-12 19:54:39 +00:00
|
|
|
else {
|
2009-09-20 19:10:12 +00:00
|
|
|
/* XXX TODO solve where to get last linked library from */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (G.lib[0] != '\0') {
|
2011-10-10 08:25:28 +00:00
|
|
|
RNA_string_set(op->ptr, "filepath", G.lib);
|
|
|
|
}
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (G.relbase_valid) {
|
2011-10-10 08:25:28 +00:00
|
|
|
char path[FILE_MAX];
|
|
|
|
BLI_strncpy(path, G.main->name, sizeof(G.main->name));
|
|
|
|
BLI_parent_dir(path);
|
|
|
|
RNA_string_set(op->ptr, "filepath", path);
|
|
|
|
}
|
2009-09-12 19:54:39 +00:00
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static short wm_link_append_flag(wmOperator *op)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
short flag = 0;
|
2009-09-12 19:54:39 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT;
|
|
|
|
if (RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY;
|
|
|
|
if (RNA_boolean_get(op->ptr, "relative_path")) flag |= FILE_RELPATH;
|
|
|
|
if (RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK;
|
|
|
|
if (RNA_boolean_get(op->ptr, "instance_groups")) flag |= FILE_GROUP_INSTANCE;
|
2010-04-08 11:46:52 +00:00
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
return flag;
|
|
|
|
}
|
2009-09-12 19:54:39 +00:00
|
|
|
|
|
|
|
static int wm_link_append_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
Main *mainl = NULL;
|
2009-09-12 19:54:39 +00:00
|
|
|
BlendHandle *bh;
|
|
|
|
PropertyRNA *prop;
|
2009-09-14 12:30:49 +00:00
|
|
|
char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX];
|
2012-03-27 01:24:16 +00:00
|
|
|
int idcode, totfiles = 0;
|
2009-09-12 19:54:39 +00:00
|
|
|
short flag;
|
|
|
|
|
|
|
|
RNA_string_get(op->ptr, "filename", name);
|
|
|
|
RNA_string_get(op->ptr, "directory", dir);
|
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* test if we have a valid data */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (BLO_is_a_library(dir, libname, group) == 0) {
|
2009-09-12 19:54:39 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Not a library");
|
2009-09-14 12:30:49 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (group[0] == 0) {
|
2009-09-12 19:54:39 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
|
2009-09-14 12:30:49 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (BLI_path_cmp(bmain->name, libname) == 0) {
|
2009-09-12 19:54:39 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library");
|
2009-09-14 12:30:49 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check if something is indicated for append/link */
|
|
|
|
prop = RNA_struct_find_property(op->ptr, "files");
|
2012-03-24 06:24:53 +00:00
|
|
|
if (prop) {
|
2012-03-27 01:24:16 +00:00
|
|
|
totfiles = RNA_property_collection_length(op->ptr, prop);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (totfiles == 0) {
|
|
|
|
if (name[0] == '\0') {
|
2009-09-12 19:54:39 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
|
2009-09-14 12:30:49 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-14 12:30:49 +00:00
|
|
|
}
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (name[0] == '\0') {
|
2009-09-12 19:54:39 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
|
2009-09-14 12:30:49 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
|
2011-03-12 15:15:40 +00:00
|
|
|
bh = BLO_blendhandle_from_file(libname, op->reports);
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (bh == NULL) {
|
2011-03-12 15:15:40 +00:00
|
|
|
/* unlikely since we just browsed it, but possible
|
|
|
|
* error reports will have been made by BLO_blendhandle_from_file() */
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* from here down, no error returns */
|
|
|
|
|
|
|
|
idcode = BKE_idcode_from_name(group);
|
|
|
|
|
2009-09-12 19:54:39 +00:00
|
|
|
/* now we have or selected, or an indicated file */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "autoselect"))
|
2012-05-05 14:33:36 +00:00
|
|
|
BKE_scene_base_deselect_all(scene);
|
2009-09-12 19:54:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
flag = wm_link_append_flag(op);
|
|
|
|
|
2010-04-08 11:46:52 +00:00
|
|
|
/* sanity checks for flag */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (scene->id.lib && (flag & FILE_GROUP_INSTANCE)) {
|
2010-04-08 11:46:52 +00:00
|
|
|
/* TODO, user never gets this message */
|
2012-03-27 01:24:16 +00:00
|
|
|
BKE_reportf(op->reports, RPT_WARNING, "Scene '%s' is linked, group instance disabled", scene->id.name + 2);
|
2010-04-08 11:46:52 +00:00
|
|
|
flag &= ~FILE_GROUP_INSTANCE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-07 16:19:38 +00:00
|
|
|
/* tag everything, all untagged data can be made local
|
|
|
|
* its also generally useful to know what is new
|
|
|
|
*
|
2013-12-30 13:25:27 +11:00
|
|
|
* take extra care BKE_main_id_flag_all(LIB_LINK_TAG, false) is called after! */
|
|
|
|
BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, 1);
|
2009-09-12 19:54:39 +00:00
|
|
|
|
|
|
|
/* here appending/linking starts */
|
2011-08-05 05:26:19 +00:00
|
|
|
mainl = BLO_library_append_begin(bmain, &bh, libname);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (totfiles == 0) {
|
2011-05-26 20:45:19 +00:00
|
|
|
BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
|
2009-09-14 12:30:49 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-08-24 10:05:29 +00:00
|
|
|
RNA_BEGIN (op->ptr, itemptr, "files")
|
2012-04-30 16:22:40 +00:00
|
|
|
{
|
2009-09-12 19:54:39 +00:00
|
|
|
RNA_string_get(&itemptr, "name", name);
|
2011-05-26 20:45:19 +00:00
|
|
|
BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
|
2009-09-12 19:54:39 +00:00
|
|
|
}
|
|
|
|
RNA_END;
|
|
|
|
}
|
|
|
|
BLO_library_append_end(C, mainl, &bh, idcode, flag);
|
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* mark all library linked objects to be updated */
|
2013-12-30 13:25:27 +11:00
|
|
|
BKE_main_lib_objects_recalc_all(bmain);
|
2012-10-09 11:31:25 +00:00
|
|
|
IMB_colormanagement_check_file_config(bmain);
|
2009-09-12 19:54:39 +00:00
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* append, rather than linking */
|
2012-03-27 01:24:16 +00:00
|
|
|
if ((flag & FILE_LINK) == 0) {
|
|
|
|
Library *lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
|
2013-03-10 05:46:24 +00:00
|
|
|
if (lib) BKE_library_make_local(bmain, lib, true);
|
2012-03-27 01:24:16 +00:00
|
|
|
else BLI_assert(!"cant find name of just added library!");
|
library loading api.
this is not well suited to RNA so this is a native python api.
This uses:
bpy.data.libraries.load(filepath, link=False, relative=False)
however the return value needs to use pythons context manager, this means the library loading is confined to a block of code and python cant leave a half loaded library state.
eg, load a single scene we know the name of:
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = ["Scene"]
eg, load all scenes:
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = data_from.scenes
eg, load all objects starting with 'A'
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.objects = [name for name in data_from.objects if name.startswith("A")]
As you can see gives 2 objects like 'bpy.data', but containing lists of strings which can be moved from one into another.
2011-03-12 16:06:37 +00:00
|
|
|
}
|
2009-09-12 19:54:39 +00:00
|
|
|
|
2010-01-07 16:19:38 +00:00
|
|
|
/* important we unset, otherwise these object wont
|
|
|
|
* link into other scenes from this blend file */
|
2013-12-30 13:25:27 +11:00
|
|
|
BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, false);
|
2010-01-07 16:19:38 +00:00
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* recreate dependency graph to include new objects */
|
2013-02-21 19:33:04 +00:00
|
|
|
DAG_scene_relations_rebuild(bmain, scene);
|
2009-09-12 19:54:39 +00:00
|
|
|
|
|
|
|
BLO_blendhandle_close(bh);
|
2009-09-20 19:10:12 +00:00
|
|
|
|
|
|
|
/* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */
|
2009-09-12 19:54:39 +00:00
|
|
|
BLI_strncpy(G.lib, dir, FILE_MAX);
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_link_append(wmOperatorType *ot)
|
|
|
|
{
|
2012-08-15 11:53:49 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Link/Append from Library";
|
|
|
|
ot->idname = "WM_OT_link_append";
|
|
|
|
ot->description = "Link or Append from a Library .blend file";
|
2009-09-12 19:54:39 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = wm_link_append_invoke;
|
|
|
|
ot->exec = wm_link_append_exec;
|
|
|
|
ot->poll = wm_link_append_poll;
|
2009-09-12 19:54:39 +00:00
|
|
|
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
ot->flag |= OPTYPE_UNDO;
|
|
|
|
|
2012-02-19 06:00:20 +00:00
|
|
|
WM_operator_properties_filesel(
|
2012-08-04 12:54:27 +00:00
|
|
|
ot, FOLDERFILE | BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE,
|
|
|
|
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES,
|
|
|
|
FILE_DEFAULTDISPLAY);
|
2009-09-12 19:54:39 +00:00
|
|
|
|
2012-08-15 11:53:49 +00:00
|
|
|
/* better not save _any_ settings for this operator */
|
|
|
|
/* properties */
|
|
|
|
prop = RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending");
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects");
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer");
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
prop = RNA_def_boolean(ot->srna, "instance_groups", 1, "Instance Groups", "Create instances for each group as a DupliGroup");
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
}
|
2009-09-12 19:54:39 +00:00
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* *************** recover last session **************** */
|
|
|
|
|
2013-04-13 12:03:20 +00:00
|
|
|
void WM_recover_last_session(bContext *C, ReportList *reports)
|
2009-07-23 21:35:11 +00:00
|
|
|
{
|
2009-10-20 13:58:53 +00:00
|
|
|
char filename[FILE_MAX];
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
|
2012-12-13 02:40:49 +00:00
|
|
|
BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
/* if reports==NULL, it's called directly without operator, we add a quick check here */
|
|
|
|
if (reports || BLI_exists(filename)) {
|
|
|
|
G.fileflags |= G_FILE_RECOVER;
|
|
|
|
|
|
|
|
/* XXX wm in context is not set correctly after WM_file_read -> crash */
|
|
|
|
/* do it before for now, but is this correct with multiple windows? */
|
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
|
|
|
|
|
|
|
/* load file */
|
2013-06-18 18:11:52 +00:00
|
|
|
WM_file_autoexec_init(filename);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
WM_file_read(C, filename, reports);
|
|
|
|
|
|
|
|
G.fileflags &= ~G_FILE_RECOVER;
|
|
|
|
|
|
|
|
/* XXX bad global... fixme */
|
|
|
|
if (G.main->name[0])
|
|
|
|
G.file_loaded = 1; /* prevents splash to show */
|
2013-01-02 16:10:03 +00:00
|
|
|
else {
|
2012-12-14 18:54:22 +00:00
|
|
|
G.relbase_valid = 0;
|
2013-01-02 16:10:03 +00:00
|
|
|
G.save_over = 0; /* start with save preference untitled.blend */
|
|
|
|
}
|
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-23 21:35:11 +00:00
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2013-04-13 12:03:20 +00:00
|
|
|
WM_recover_last_session(C, op->reports);
|
2009-10-20 13:58:53 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-07-23 21:35:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_recover_last_session(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Recover Last Session";
|
|
|
|
ot->idname = "WM_OT_recover_last_session";
|
2012-12-13 02:40:49 +00:00
|
|
|
ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")";
|
2009-07-23 21:35:11 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = wm_recover_last_session_exec;
|
2009-07-23 21:35:11 +00:00
|
|
|
}
|
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
/* *************** recover auto save **************** */
|
|
|
|
|
|
|
|
static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
char path[FILE_MAX];
|
|
|
|
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
2009-10-20 13:58:53 +00:00
|
|
|
|
|
|
|
G.fileflags |= G_FILE_RECOVER;
|
|
|
|
|
2012-08-11 21:35:24 +00:00
|
|
|
/* XXX wm in context is not set correctly after WM_file_read -> crash */
|
2012-06-17 11:36:28 +00:00
|
|
|
/* do it before for now, but is this correct with multiple windows? */
|
2009-10-20 13:58:53 +00:00
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
|
|
|
|
|
|
|
/* load file */
|
2013-06-18 18:11:52 +00:00
|
|
|
WM_file_autoexec_init(path);
|
2012-08-11 21:35:24 +00:00
|
|
|
WM_file_read(C, path, op->reports);
|
2009-10-20 13:58:53 +00:00
|
|
|
|
|
|
|
G.fileflags &= ~G_FILE_RECOVER;
|
2013-01-02 16:10:03 +00:00
|
|
|
|
2009-10-20 13:58:53 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-10-20 13:58:53 +00:00
|
|
|
{
|
|
|
|
char filename[FILE_MAX];
|
|
|
|
|
|
|
|
wm_autosave_location(filename);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(op->ptr, "filepath", filename);
|
2009-10-20 13:58:53 +00:00
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_recover_auto_save(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Recover Auto Save";
|
|
|
|
ot->idname = "WM_OT_recover_auto_save";
|
|
|
|
ot->description = "Open an automatically saved file to recover it";
|
2009-10-20 13:58:53 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = wm_recover_auto_save_exec;
|
|
|
|
ot->invoke = wm_recover_auto_save_invoke;
|
2009-10-20 13:58:53 +00:00
|
|
|
|
2012-08-04 12:54:27 +00:00
|
|
|
WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE,
|
|
|
|
WM_FILESEL_FILEPATH, FILE_LONGDISPLAY);
|
2009-10-20 13:58:53 +00:00
|
|
|
}
|
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* *************** save file as **************** */
|
|
|
|
|
2013-08-29 05:34:58 +00:00
|
|
|
static void wm_filepath_default(char *filepath)
|
2009-09-14 12:30:49 +00:00
|
|
|
{
|
2013-08-29 05:34:58 +00:00
|
|
|
if (G.save_over == false) {
|
|
|
|
BLI_ensure_filename(filepath, FILE_MAX, "untitled.blend");
|
2009-09-14 12:30:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-23 21:35:11 +00:00
|
|
|
static void save_set_compress(wmOperator *op)
|
|
|
|
{
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!RNA_struct_property_is_set(op->ptr, "compress")) {
|
|
|
|
if (G.save_over) /* keep flag for existing file */
|
2009-07-23 21:35:11 +00:00
|
|
|
RNA_boolean_set(op->ptr, "compress", G.fileflags & G_FILE_COMPRESS);
|
|
|
|
else /* use userdef for new file */
|
|
|
|
RNA_boolean_set(op->ptr, "compress", U.flag & USER_FILECOMPRESS);
|
|
|
|
}
|
2009-01-06 14:42:54 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-01-21 19:28:28 +00:00
|
|
|
{
|
2009-02-13 13:04:48 +00:00
|
|
|
char name[FILE_MAX];
|
2009-07-23 21:35:11 +00:00
|
|
|
|
|
|
|
save_set_compress(op);
|
2009-01-21 19:28:28 +00:00
|
|
|
|
2011-02-05 15:05:17 +00:00
|
|
|
/* if not saved before, get the name of the most recently used .blend file */
|
2012-03-27 01:24:16 +00:00
|
|
|
if (G.main->name[0] == 0 && G.recent_files.first) {
|
2011-02-05 15:05:17 +00:00
|
|
|
struct RecentFile *recent = G.recent_files.first;
|
|
|
|
BLI_strncpy(name, recent->filepath, FILE_MAX);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BLI_strncpy(name, G.main->name, FILE_MAX);
|
|
|
|
|
2013-08-29 05:34:58 +00:00
|
|
|
wm_filepath_default(name);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(op->ptr, "filepath", name);
|
2009-02-16 12:14:04 +00:00
|
|
|
|
|
|
|
WM_event_add_fileselect(C, op);
|
2009-01-21 19:28:28 +00:00
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2009-02-08 19:15:59 +00:00
|
|
|
/* function used for WM_OT_save_mainfile too */
|
2009-01-21 19:28:28 +00:00
|
|
|
static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2009-09-12 19:54:39 +00:00
|
|
|
char path[FILE_MAX];
|
2009-10-20 13:58:53 +00:00
|
|
|
int fileflags;
|
2009-07-23 21:35:11 +00:00
|
|
|
|
|
|
|
save_set_compress(op);
|
2009-01-21 19:28:28 +00:00
|
|
|
|
2013-08-29 05:34:58 +00:00
|
|
|
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
2013-08-29 05:34:58 +00:00
|
|
|
}
|
2009-02-18 13:29:54 +00:00
|
|
|
else {
|
2013-04-10 09:49:44 +00:00
|
|
|
BLI_strncpy(path, G.main->name, FILE_MAX);
|
2013-08-29 05:34:58 +00:00
|
|
|
wm_filepath_default(path);
|
2009-02-18 13:29:54 +00:00
|
|
|
}
|
2010-07-19 15:39:12 +00:00
|
|
|
|
2012-12-18 12:14:14 +00:00
|
|
|
fileflags = G.fileflags & ~G_FILE_USERPREFS;
|
2009-10-20 13:58:53 +00:00
|
|
|
|
|
|
|
/* set compression flag */
|
2012-11-07 04:13:03 +00:00
|
|
|
BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "compress"),
|
|
|
|
G_FILE_COMPRESS);
|
|
|
|
BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "relative_remap"),
|
|
|
|
G_FILE_RELATIVE_REMAP);
|
|
|
|
BKE_BIT_TEST_SET(fileflags,
|
|
|
|
(RNA_struct_property_is_set(op->ptr, "copy") &&
|
|
|
|
RNA_boolean_get(op->ptr, "copy")),
|
|
|
|
G_FILE_SAVE_COPY);
|
|
|
|
|
2011-12-28 14:21:51 +00:00
|
|
|
#ifdef USE_BMESH_SAVE_AS_COMPAT
|
2012-11-07 04:13:03 +00:00
|
|
|
BKE_BIT_TEST_SET(fileflags,
|
|
|
|
(RNA_struct_find_property(op->ptr, "use_mesh_compat") &&
|
|
|
|
RNA_boolean_get(op->ptr, "use_mesh_compat")),
|
|
|
|
G_FILE_MESH_COMPAT);
|
2011-12-28 14:21:51 +00:00
|
|
|
#endif
|
2009-10-20 13:58:53 +00:00
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
if (wm_file_write(C, path, fileflags, op->reports) != 0)
|
2010-04-14 20:45:36 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL);
|
2009-01-21 19:28:28 +00:00
|
|
|
|
2010-04-14 20:27:45 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-01-21 19:28:28 +00:00
|
|
|
}
|
|
|
|
|
2010-09-17 09:27:31 +00:00
|
|
|
/* function used for WM_OT_save_mainfile too */
|
2013-06-18 15:30:51 +00:00
|
|
|
static bool blend_save_check(bContext *UNUSED(C), wmOperator *op)
|
2010-09-17 09:27:31 +00:00
|
|
|
{
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!BLO_has_bfile_extension(filepath)) {
|
2011-10-31 00:23:42 +00:00
|
|
|
/* some users would prefer BLI_replace_extension(),
|
2013-03-05 03:17:46 +00:00
|
|
|
* we keep getting nitpicking bug reports about this - campbell */
|
2011-10-31 00:23:42 +00:00
|
|
|
BLI_ensure_extension(filepath, FILE_MAX, ".blend");
|
2010-09-17 09:27:31 +00:00
|
|
|
RNA_string_set(op->ptr, "filepath", filepath);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-01-21 19:28:28 +00:00
|
|
|
static void WM_OT_save_as_mainfile(wmOperatorType *ot)
|
|
|
|
{
|
2013-10-09 19:29:50 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Save As Blender File";
|
|
|
|
ot->idname = "WM_OT_save_as_mainfile";
|
|
|
|
ot->description = "Save the current file in the desired location";
|
2009-01-21 19:28:28 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = wm_save_as_mainfile_invoke;
|
|
|
|
ot->exec = wm_save_as_mainfile_exec;
|
|
|
|
ot->check = blend_save_check;
|
2011-02-01 12:47:50 +00:00
|
|
|
/* ommit window poll so this can work in background mode */
|
|
|
|
|
2012-08-04 12:54:27 +00:00
|
|
|
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE,
|
|
|
|
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
|
2011-09-15 13:20:18 +00:00
|
|
|
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file");
|
2012-06-29 11:59:47 +00:00
|
|
|
RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative",
|
|
|
|
"Remap relative paths when saving in a different directory");
|
2013-10-09 19:29:50 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "copy", 0, "Save Copy",
|
2012-06-29 11:59:47 +00:00
|
|
|
"Save a copy of the actual working state but does not make saved file active");
|
2013-10-09 19:29:50 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2011-12-28 13:50:33 +00:00
|
|
|
#ifdef USE_BMESH_SAVE_AS_COMPAT
|
2012-06-29 11:59:47 +00:00
|
|
|
RNA_def_boolean(ot->srna, "use_mesh_compat", 0, "Legacy Mesh Format",
|
|
|
|
"Save using legacy mesh format (no ngons) - WARNING: only saves tris and quads, other ngons will "
|
|
|
|
"be lost (no implicit triangulation)");
|
2011-12-27 13:17:58 +00:00
|
|
|
#endif
|
2009-01-21 19:28:28 +00:00
|
|
|
}
|
|
|
|
|
2009-09-14 12:30:49 +00:00
|
|
|
/* *************** save file directly ******** */
|
2009-02-08 19:15:59 +00:00
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-02-08 19:15:59 +00:00
|
|
|
{
|
2009-02-13 13:04:48 +00:00
|
|
|
char name[FILE_MAX];
|
2011-12-12 18:06:36 +00:00
|
|
|
int ret;
|
2010-01-27 02:20:24 +00:00
|
|
|
|
2009-12-04 19:07:25 +00:00
|
|
|
/* cancel if no active window */
|
|
|
|
if (CTX_wm_window(C) == NULL)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
2009-07-23 21:35:11 +00:00
|
|
|
save_set_compress(op);
|
2011-02-05 15:05:17 +00:00
|
|
|
|
|
|
|
/* if not saved before, get the name of the most recently used .blend file */
|
2012-03-27 01:24:16 +00:00
|
|
|
if (G.main->name[0] == 0 && G.recent_files.first) {
|
2011-02-05 15:05:17 +00:00
|
|
|
struct RecentFile *recent = G.recent_files.first;
|
|
|
|
BLI_strncpy(name, recent->filepath, FILE_MAX);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BLI_strncpy(name, G.main->name, FILE_MAX);
|
|
|
|
|
2013-08-29 05:34:58 +00:00
|
|
|
wm_filepath_default(name);
|
2011-02-05 15:05:17 +00:00
|
|
|
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(op->ptr, "filepath", name);
|
2012-10-31 17:03:31 +00:00
|
|
|
|
2014-01-17 17:35:03 +11:00
|
|
|
/* if we're saving for the first time and prefer relative paths - any existing paths will be absolute,
|
2013-11-27 21:15:19 +11:00
|
|
|
* enable the option to remap paths to avoid confusion [#37240] */
|
|
|
|
if ((G.relbase_valid == false) && (U.flag & USER_RELPATHS)) {
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "relative_remap");
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-27 02:20:24 +00:00
|
|
|
if (G.save_over) {
|
2012-10-31 17:03:31 +00:00
|
|
|
if (BLI_exists(name)) {
|
2010-01-27 02:20:24 +00:00
|
|
|
uiPupMenuSaveOver(C, op, name);
|
2012-03-27 01:24:16 +00:00
|
|
|
ret = OPERATOR_RUNNING_MODAL;
|
2011-12-12 18:06:36 +00:00
|
|
|
}
|
2010-01-27 02:20:24 +00:00
|
|
|
else {
|
2012-03-27 01:24:16 +00:00
|
|
|
ret = wm_save_as_mainfile_exec(C, op);
|
2010-01-27 02:20:24 +00:00
|
|
|
}
|
2011-12-12 18:06:36 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-10-21 23:05:54 +00:00
|
|
|
WM_event_add_fileselect(C, op);
|
2012-03-27 01:24:16 +00:00
|
|
|
ret = OPERATOR_RUNNING_MODAL;
|
2010-01-27 02:20:24 +00:00
|
|
|
}
|
2009-10-21 23:05:54 +00:00
|
|
|
|
2011-12-12 18:06:36 +00:00
|
|
|
return ret;
|
2009-02-08 19:15:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_save_mainfile(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Save Blender File";
|
|
|
|
ot->idname = "WM_OT_save_mainfile";
|
|
|
|
ot->description = "Save the current Blender file";
|
2009-02-08 19:15:59 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = wm_save_mainfile_invoke;
|
|
|
|
ot->exec = wm_save_as_mainfile_exec;
|
|
|
|
ot->check = blend_save_check;
|
2011-06-10 09:44:27 +00:00
|
|
|
/* ommit window poll so this can work in background mode */
|
2009-02-08 19:15:59 +00:00
|
|
|
|
2012-08-04 12:54:27 +00:00
|
|
|
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE,
|
|
|
|
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
|
2011-09-15 13:20:18 +00:00
|
|
|
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file");
|
|
|
|
RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory");
|
2009-02-08 19:15:59 +00:00
|
|
|
}
|
|
|
|
|
2008-01-01 09:07:02 +00:00
|
|
|
static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Toggle Fullscreen";
|
|
|
|
ot->idname = "WM_OT_window_fullscreen_toggle";
|
|
|
|
ot->description = "Toggle the current window fullscreen";
|
2008-01-01 09:07:02 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = wm_window_fullscreen_toggle_exec;
|
|
|
|
ot->poll = WM_operator_winactive;
|
2008-01-01 09:07:02 +00:00
|
|
|
}
|
|
|
|
|
2013-07-28 17:06:31 +00:00
|
|
|
static int wm_exit_blender_exec(bContext *C, wmOperator *op)
|
2009-01-31 13:30:56 +00:00
|
|
|
{
|
|
|
|
WM_operator_free(op);
|
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
WM_exit(C);
|
2009-01-31 13:30:56 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2010-10-11 22:05:45 +00:00
|
|
|
static void WM_OT_quit_blender(wmOperatorType *ot)
|
2008-01-15 18:54:38 +00:00
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Quit Blender";
|
|
|
|
ot->idname = "WM_OT_quit_blender";
|
|
|
|
ot->description = "Quit Blender";
|
2008-01-15 18:54:38 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_operator_confirm;
|
2013-07-28 17:06:31 +00:00
|
|
|
ot->exec = wm_exit_blender_exec;
|
2008-01-15 18:54:38 +00:00
|
|
|
}
|
|
|
|
|
2010-10-18 20:41:52 +00:00
|
|
|
/* *********************** */
|
|
|
|
|
2011-05-09 08:01:48 +00:00
|
|
|
#if defined(WIN32)
|
|
|
|
|
2013-07-28 17:06:31 +00:00
|
|
|
static int wm_console_toggle_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
|
2010-10-18 20:41:52 +00:00
|
|
|
{
|
2011-05-02 08:07:24 +00:00
|
|
|
GHOST_toggleConsole(2);
|
2010-10-18 20:41:52 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2011-04-06 12:30:07 +00:00
|
|
|
static void WM_OT_console_toggle(wmOperatorType *ot)
|
2010-10-18 20:41:52 +00:00
|
|
|
{
|
2013-01-02 16:56:36 +00:00
|
|
|
/* XXX Have to mark these for xgettext, as under linux they do not exists... */
|
|
|
|
ot->name = CTX_N_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Toggle System Console");
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "WM_OT_console_toggle";
|
Fixed another bunch of i18n bugs (thx to Leon Cheung for spotting them), among which:
* Drag'n'drop translation in Outliner
* "Execute" button in file window
* "Labels" of spacing elements, in multi-column enums
* A glitch with nodes "Value to RGB", they where called "ColorRamp" in node_type_base() call. This is not definitive, though, as it appears that UI node names are determined by this call, while it should be by "defines" in rna_nodetrre_types.h, I guess... Anyway, not good to have such things in two different places!
Also moved default context name under BLF_translation.h, much better to have those all in one place, accessible from whole Blender code!
2012-04-14 15:06:41 +00:00
|
|
|
ot->description = N_("Toggle System Console");
|
2010-10-18 20:41:52 +00:00
|
|
|
|
2013-07-28 17:06:31 +00:00
|
|
|
ot->exec = wm_console_toggle_exec;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = WM_operator_winactive;
|
2010-10-18 20:41:52 +00:00
|
|
|
}
|
|
|
|
|
2011-05-09 08:01:48 +00:00
|
|
|
#endif
|
|
|
|
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* ************ default paint cursors, draw always around cursor *********** */
|
|
|
|
/*
|
2012-03-09 18:28:30 +00:00
|
|
|
* - returns handler to free
|
|
|
|
* - poll(bContext): returns 1 if draw should happen
|
|
|
|
* - draw(bContext): drawing callback for paint cursor
|
|
|
|
*/
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
2009-01-24 16:59:55 +00:00
|
|
|
void *WM_paint_cursor_activate(wmWindowManager *wm, int (*poll)(bContext *C),
|
2012-03-27 01:24:16 +00:00
|
|
|
wmPaintCursorDraw draw, void *customdata)
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmPaintCursor *pc = MEM_callocN(sizeof(wmPaintCursor), "paint cursor");
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
BLI_addtail(&wm->paintcursors, pc);
|
|
|
|
|
2009-01-24 16:59:55 +00:00
|
|
|
pc->customdata = customdata;
|
2012-03-27 01:24:16 +00:00
|
|
|
pc->poll = poll;
|
|
|
|
pc->draw = draw;
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
|
|
|
|
return pc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_paint_cursor_end(wmWindowManager *wm, void *handle)
|
|
|
|
{
|
|
|
|
wmPaintCursor *pc;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (pc = wm->paintcursors.first; pc; pc = pc->next) {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (pc == (wmPaintCursor *)handle) {
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
BLI_remlink(&wm->paintcursors, pc);
|
|
|
|
MEM_freeN(pc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
/* ************ window gesture operator-callback definitions ************** */
|
2008-01-19 17:54:05 +00:00
|
|
|
/*
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
* These are default callbacks for use in operators requiring gesture input
|
2008-01-19 17:54:05 +00:00
|
|
|
*/
|
|
|
|
|
2008-11-24 10:45:36 +00:00
|
|
|
/* **************** Border gesture *************** */
|
|
|
|
|
|
|
|
/* Border gesture has two types:
|
2012-03-09 18:28:30 +00:00
|
|
|
* 1) WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border
|
|
|
|
* 2) WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends
|
|
|
|
*
|
|
|
|
* It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
|
|
|
|
*/
|
2008-11-24 10:45:36 +00:00
|
|
|
|
2011-03-21 03:22:33 +00:00
|
|
|
static int border_apply_rect(wmOperator *op)
|
2008-01-19 17:54:05 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
|
|
|
rcti *rect = gesture->customdata;
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (rect->xmin == rect->xmax || rect->ymin == rect->ymax)
|
2009-01-31 10:00:08 +00:00
|
|
|
return 0;
|
2011-03-20 00:34:08 +00:00
|
|
|
|
|
|
|
|
2009-01-31 13:30:56 +00:00
|
|
|
/* operator arguments and storage. */
|
2012-10-24 05:06:40 +00:00
|
|
|
RNA_int_set(op->ptr, "xmin", min_ii(rect->xmin, rect->xmax));
|
|
|
|
RNA_int_set(op->ptr, "ymin", min_ii(rect->ymin, rect->ymax));
|
|
|
|
RNA_int_set(op->ptr, "xmax", max_ii(rect->xmin, rect->xmax));
|
|
|
|
RNA_int_set(op->ptr, "ymax", max_ii(rect->ymin, rect->ymax));
|
2011-03-20 00:34:08 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int border_apply(bContext *C, wmOperator *op, int gesture_mode)
|
|
|
|
{
|
2012-10-06 00:42:30 +00:00
|
|
|
int retval;
|
|
|
|
|
2011-03-21 03:22:33 +00:00
|
|
|
if (!border_apply_rect(op))
|
2011-03-20 00:34:08 +00:00
|
|
|
return 0;
|
2009-01-31 13:30:56 +00:00
|
|
|
|
2009-07-26 12:52:39 +00:00
|
|
|
/* XXX weak; border should be configured for this without reading event types */
|
2014-01-16 19:15:53 +11:00
|
|
|
if (RNA_struct_find_property(op->ptr, "gesture_mode")) {
|
2009-11-06 22:51:08 +00:00
|
|
|
RNA_int_set(op->ptr, "gesture_mode", gesture_mode);
|
2014-01-16 19:15:53 +11:00
|
|
|
}
|
2009-11-06 22:51:08 +00:00
|
|
|
|
2012-10-06 00:42:30 +00:00
|
|
|
retval = op->type->exec(C, op);
|
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
|
|
|
|
2009-01-31 13:30:56 +00:00
|
|
|
return 1;
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
static void wm_gesture_end(bContext *C, wmOperator *op)
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
|
|
|
|
op->customdata = NULL;
|
Lots of stuff; couldn't commit in parts because of refactor work.
* Changes in interface/ module
This commit brings back the way how buttons/menus work under control
of WM event system. The previous implementation extended usage of
handlers and operators in an interesting but confusing way. Better to
try it first according the design specs. :)
Most obviously:
- modal-handler operators are not stored anymore in regions/areas/windows.
such modal handlers own their operator, and should remove it themselves.
- removed code to move handlers from one queue to another.
(needs review with brecht!)
- WM fix: the API call to remove a modal handler got removed. This was a
dangerous thing anyway, and you should leave that to the event system.
Now, if a handler modal() call gets a cancel/finish return, it frees
itself in event system. WM_event_remove_modal_handler was a confusing
call anyway!
Todo:
- allow button-activate to refresh after using button
- re-enable arrow keys for menus
(do both after commit)
- review return values of operator callbacks in interface_ops.c
* Fixes in WM system
- Freeing areas/regions/windows, also on quit, now correctly closes
running modal handlers
- On starting a modal handler, the handler now stores previous area
and region context, so they send proper notifiers etc.
* Other fixes
- Area-split operator had bug, wrong minimal size checking. This
solves error when trying to split a very narrow area.
- removed DNA_USHORT_FIX from screen_types.h, gave warning
- operators didn't get ID name copied when activated, needed for
later re-use or saving.
2008-12-02 14:22:52 +00:00
|
|
|
|
2008-12-18 02:56:48 +00:00
|
|
|
ED_area_tag_redraw(CTX_wm_area(C));
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
|
2014-01-16 19:15:53 +11:00
|
|
|
if (RNA_struct_find_property(op->ptr, "cursor")) {
|
2013-09-06 22:34:29 +00:00
|
|
|
WM_cursor_modal_restore(CTX_wm_window(C));
|
2014-01-16 19:15:53 +11:00
|
|
|
}
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_border_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-01-19 17:54:05 +00:00
|
|
|
{
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ISTWEAK(event->type))
|
2012-03-27 01:24:16 +00:00
|
|
|
op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
|
2009-07-26 12:52:39 +00:00
|
|
|
else
|
2012-03-27 01:24:16 +00:00
|
|
|
op->customdata = WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
|
2008-01-19 17:54:05 +00:00
|
|
|
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
/* add modal handler */
|
2009-09-18 12:43:36 +00:00
|
|
|
WM_event_add_modal_handler(C, op);
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
|
2008-12-27 16:09:56 +00:00
|
|
|
wm_gesture_tag_redraw(C);
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2008-01-19 17:54:05 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-01-19 17:54:05 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
|
|
|
rcti *rect = gesture->customdata;
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
int sx, sy;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (event->type == MOUSEMOVE) {
|
2009-11-06 22:51:08 +00:00
|
|
|
wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->mode == 0) {
|
2012-03-24 02:51:46 +00:00
|
|
|
rect->xmin = rect->xmax = event->x - sx;
|
|
|
|
rect->ymin = rect->ymax = event->y - sy;
|
2009-11-06 22:51:08 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-24 02:51:46 +00:00
|
|
|
rect->xmax = event->x - sx;
|
|
|
|
rect->ymax = event->y - sy;
|
2009-11-06 22:51:08 +00:00
|
|
|
}
|
2011-03-21 03:22:33 +00:00
|
|
|
border_apply_rect(op);
|
2009-11-06 22:51:08 +00:00
|
|
|
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
2009-11-06 22:51:08 +00:00
|
|
|
switch (event->val) {
|
2012-03-27 01:24:16 +00:00
|
|
|
case GESTURE_MODAL_BEGIN:
|
|
|
|
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->mode == 0) {
|
|
|
|
gesture->mode = 1;
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GESTURE_MODAL_SELECT:
|
|
|
|
case GESTURE_MODAL_DESELECT:
|
|
|
|
case GESTURE_MODAL_IN:
|
|
|
|
case GESTURE_MODAL_OUT:
|
|
|
|
if (border_apply(C, op, event->val)) {
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
2009-01-02 14:11:18 +00:00
|
|
|
wm_gesture_end(C, op);
|
2012-03-27 01:24:16 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
break;
|
2009-11-06 22:51:08 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
case GESTURE_MODAL_CANCEL:
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-11-06 22:51:08 +00:00
|
|
|
}
|
|
|
|
|
2008-01-19 17:54:05 +00:00
|
|
|
}
|
2012-06-17 11:36:28 +00:00
|
|
|
// /* Allow view navigation??? */
|
2009-11-06 22:51:08 +00:00
|
|
|
// else {
|
|
|
|
// return OPERATOR_PASS_THROUGH;
|
|
|
|
// }
|
|
|
|
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2008-01-19 17:54:05 +00:00
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
void WM_border_select_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
}
|
|
|
|
|
2008-12-21 16:24:19 +00:00
|
|
|
/* **************** circle gesture *************** */
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
/* works now only for selection or modal paint stuff, calls exec while hold mouse, exit on release */
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2009-11-05 17:32:06 +00:00
|
|
|
#ifdef GESTURE_MEMORY
|
2012-06-17 11:36:28 +00:00
|
|
|
int circle_select_size = 25; /* XXX - need some operator memory thing! */
|
2009-11-05 17:32:06 +00:00
|
|
|
#endif
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-21 16:24:19 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
op->customdata = WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
|
2008-12-21 16:24:19 +00:00
|
|
|
|
|
|
|
/* add modal handler */
|
2009-09-18 12:43:36 +00:00
|
|
|
WM_event_add_modal_handler(C, op);
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2008-12-27 16:09:56 +00:00
|
|
|
wm_gesture_tag_redraw(C);
|
2008-12-21 16:24:19 +00:00
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2009-01-24 13:45:24 +00:00
|
|
|
static void gesture_circle_apply(bContext *C, wmOperator *op)
|
2008-12-21 16:24:19 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
|
|
|
rcti *rect = gesture->customdata;
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_NOP)
|
2010-03-22 09:30:00 +00:00
|
|
|
return;
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2008-12-21 16:24:19 +00:00
|
|
|
/* operator arguments and storage. */
|
|
|
|
RNA_int_set(op->ptr, "x", rect->xmin);
|
|
|
|
RNA_int_set(op->ptr, "y", rect->ymin);
|
|
|
|
RNA_int_set(op->ptr, "radius", rect->xmax);
|
|
|
|
|
2012-10-06 00:42:30 +00:00
|
|
|
if (op->type->exec) {
|
|
|
|
int retval;
|
|
|
|
retval = op->type->exec(C, op);
|
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
|
|
|
}
|
2009-11-05 17:32:06 +00:00
|
|
|
#ifdef GESTURE_MEMORY
|
2012-03-27 01:24:16 +00:00
|
|
|
circle_select_size = rect->xmax;
|
2009-11-05 17:32:06 +00:00
|
|
|
#endif
|
2008-12-21 16:24:19 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-21 16:24:19 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
|
|
|
rcti *rect = gesture->customdata;
|
2008-12-21 16:24:19 +00:00
|
|
|
int sx, sy;
|
2009-11-05 15:59:14 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (event->type == MOUSEMOVE) {
|
2009-11-05 17:32:06 +00:00
|
|
|
wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2012-03-24 02:51:46 +00:00
|
|
|
rect->xmin = event->x - sx;
|
|
|
|
rect->ymin = event->y - sy;
|
2009-11-05 17:32:06 +00:00
|
|
|
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (gesture->mode)
|
2009-11-05 17:32:06 +00:00
|
|
|
gesture_circle_apply(C, op);
|
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
2013-03-04 17:06:16 +00:00
|
|
|
float fac;
|
|
|
|
|
2009-11-05 17:32:06 +00:00
|
|
|
switch (event->val) {
|
2013-03-04 17:06:16 +00:00
|
|
|
case GESTURE_MODAL_CIRCLE_SIZE:
|
|
|
|
fac = 0.3f * (event->y - event->prevy);
|
|
|
|
if (fac > 0)
|
|
|
|
rect->xmax += ceil(fac);
|
|
|
|
else
|
|
|
|
rect->xmax += floor(fac);
|
|
|
|
if (rect->xmax < 1) rect->xmax = 1;
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
break;
|
2012-03-27 01:24:16 +00:00
|
|
|
case GESTURE_MODAL_CIRCLE_ADD:
|
|
|
|
rect->xmax += 2 + rect->xmax / 10;
|
2010-02-12 15:33:32 +00:00
|
|
|
wm_gesture_tag_redraw(C);
|
2012-03-27 01:24:16 +00:00
|
|
|
break;
|
|
|
|
case GESTURE_MODAL_CIRCLE_SUB:
|
|
|
|
rect->xmax -= 2 + rect->xmax / 10;
|
|
|
|
if (rect->xmax < 1) rect->xmax = 1;
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
break;
|
|
|
|
case GESTURE_MODAL_SELECT:
|
|
|
|
case GESTURE_MODAL_DESELECT:
|
|
|
|
case GESTURE_MODAL_NOP:
|
|
|
|
if (RNA_struct_find_property(op->ptr, "gesture_mode"))
|
|
|
|
RNA_int_set(op->ptr, "gesture_mode", event->val);
|
|
|
|
|
|
|
|
if (event->val != GESTURE_MODAL_NOP) {
|
|
|
|
/* apply first click */
|
|
|
|
gesture_circle_apply(C, op);
|
|
|
|
gesture->mode = 1;
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
}
|
|
|
|
break;
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
case GESTURE_MODAL_CANCEL:
|
|
|
|
case GESTURE_MODAL_CONFIRM:
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
return OPERATOR_FINISHED; /* use finish or we don't get an undo */
|
2009-11-05 17:32:06 +00:00
|
|
|
}
|
2008-12-21 16:24:19 +00:00
|
|
|
}
|
2013-03-18 12:16:19 +00:00
|
|
|
/* Allow view navigation??? */
|
|
|
|
/* note, this gives issues: 1) other modal ops run on top (border select), 2) middlemouse is used now 3) tablet/trackpad? */
|
2009-11-06 22:51:08 +00:00
|
|
|
// else {
|
|
|
|
// return OPERATOR_PASS_THROUGH;
|
|
|
|
// }
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2008-12-21 16:24:19 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
void WM_gesture_circle_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
}
|
|
|
|
|
2008-12-21 16:24:19 +00:00
|
|
|
#if 0
|
|
|
|
/* template to copy from */
|
|
|
|
void WM_OT_circle_gesture(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Circle Gesture";
|
|
|
|
ot->idname = "WM_OT_circle_gesture";
|
|
|
|
ot->description = "Enter rotate mode with a circular gesture";
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_gesture_circle_invoke;
|
|
|
|
ot->modal = WM_gesture_circle_modal;
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = WM_operator_winactive;
|
2008-12-21 16:24:19 +00:00
|
|
|
|
|
|
|
RNA_def_property(ot->srna, "x", PROP_INT, PROP_NONE);
|
|
|
|
RNA_def_property(ot->srna, "y", PROP_INT, PROP_NONE);
|
|
|
|
RNA_def_property(ot->srna, "radius", PROP_INT, PROP_NONE);
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-11-24 10:45:36 +00:00
|
|
|
/* **************** Tweak gesture *************** */
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static void tweak_gesture_modal(bContext *C, const wmEvent *event)
|
2008-11-24 10:45:36 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindow *window = CTX_wm_window(C);
|
|
|
|
wmGesture *gesture = window->tweak;
|
|
|
|
rcti *rect = gesture->customdata;
|
2008-11-24 10:45:36 +00:00
|
|
|
int sx, sy, val;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
switch (event->type) {
|
2008-11-24 10:45:36 +00:00
|
|
|
case MOUSEMOVE:
|
2010-07-02 11:26:12 +00:00
|
|
|
case INBETWEEN_MOUSEMOVE:
|
2008-11-24 10:45:36 +00:00
|
|
|
|
2008-12-18 02:56:48 +00:00
|
|
|
wm_subwindow_getorigin(window, gesture->swinid, &sx, &sy);
|
2008-11-24 10:45:36 +00:00
|
|
|
|
2012-03-24 02:51:46 +00:00
|
|
|
rect->xmax = event->x - sx;
|
|
|
|
rect->ymax = event->y - sy;
|
2008-11-24 10:45:36 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if ((val = wm_gesture_evaluate(gesture))) {
|
2010-12-03 12:30:59 +00:00
|
|
|
wmEvent tevent;
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
|
2013-07-29 08:29:04 +00:00
|
|
|
wm_event_init_from_window(window, &tevent);
|
2012-03-27 01:24:16 +00:00
|
|
|
if (gesture->event_type == LEFTMOUSE)
|
|
|
|
tevent.type = EVT_TWEAK_L;
|
|
|
|
else if (gesture->event_type == RIGHTMOUSE)
|
|
|
|
tevent.type = EVT_TWEAK_R;
|
2.5: work on bringing back SpaceTime options
- RMB select, also with SHIFT
- RMB tweak for translate
- SHIFT+D dupli
- BKEY border select/deselect
- AKEY (de)select all
- XKEY delete
- GKEY grab
Added some XXX comments for future todos, especially for when other
spaces come back with time markers.
Also added ED_util for putting in all to-be-cleaned cruft
Context conflict: input methods for Markers can conflict with other
spacetypes. It was solved in pre-2.5 with manually tweaking it all over,
but I would prefer one keymap for all marker stuff. Needs some thinking...
could be solved with a boundbox check for bottom part of 2d window.
Tweak issue: both tweak styles are possible:
- Hold mouse button, move, operator ends on mouse release
- Hold mouse button, move, operator ends on mouse click
Problem is that modally handled operators use fixed keymaps... like ESC,
SPACE, ENTER, or press/release mousebutton for 'assign'. There's a lot
to say for making this all consistant, or become part of 1 general keymap?
Should also be possibe to define 'tweak' defaults for Tablet different
than for mouse...
2008-11-29 15:10:31 +00:00
|
|
|
else
|
2012-03-27 01:24:16 +00:00
|
|
|
tevent.type = EVT_TWEAK_M;
|
|
|
|
tevent.val = val;
|
2008-11-24 10:45:36 +00:00
|
|
|
/* mouse coords! */
|
2010-12-03 12:30:59 +00:00
|
|
|
wm_event_add(window, &tevent);
|
2008-11-24 10:45:36 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
|
2008-11-24 10:45:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LEFTMOUSE:
|
|
|
|
case RIGHTMOUSE:
|
|
|
|
case MIDDLEMOUSE:
|
2012-03-27 01:24:16 +00:00
|
|
|
if (gesture->event_type == event->type) {
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
WM_gesture_end(C, gesture);
|
2009-09-24 10:35:04 +00:00
|
|
|
|
2009-02-02 16:30:03 +00:00
|
|
|
/* when tweak fails we should give the other keymap entries a chance */
|
2013-03-13 09:03:46 +00:00
|
|
|
|
|
|
|
/* XXX, assigning to readonly, BAD JUJU! */
|
|
|
|
((wmEvent *)event)->val = KM_RELEASE;
|
2008-11-24 10:45:36 +00:00
|
|
|
}
|
|
|
|
break;
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
default:
|
2013-06-27 15:07:27 +00:00
|
|
|
if (!ISTIMER(event->type) && event->type != EVENT_NONE) {
|
2009-11-11 15:29:22 +00:00
|
|
|
WM_gesture_end(C, gesture);
|
|
|
|
}
|
|
|
|
break;
|
2008-11-24 10:45:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
/* standard tweak, called after window handlers passed on event */
|
|
|
|
void wm_tweakevent_test(bContext *C, wmEvent *event, int action)
|
2008-11-24 10:45:36 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2008-11-24 10:45:36 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (win->tweak == NULL) {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (CTX_wm_region(C)) {
|
2012-03-27 01:24:16 +00:00
|
|
|
if (event->val == KM_PRESS) {
|
2014-01-16 19:15:53 +11:00
|
|
|
if (ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
|
2012-03-27 01:24:16 +00:00
|
|
|
win->tweak = WM_gesture_new(C, event, WM_GESTURE_TWEAK);
|
2014-01-16 19:15:53 +11:00
|
|
|
}
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
/* no tweaks if event was handled */
|
2012-03-24 06:24:53 +00:00
|
|
|
if ((action & WM_HANDLER_BREAK)) {
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
WM_gesture_end(C, win->tweak);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
tweak_gesture_modal(C, event);
|
|
|
|
}
|
2008-11-24 10:45:36 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* *********************** lasso gesture ****************** */
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-01-02 14:11:18 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LASSO);
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
/* add modal handler */
|
2009-09-18 12:43:36 +00:00
|
|
|
WM_event_add_modal_handler(C, op);
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
|
2014-01-16 19:15:53 +11:00
|
|
|
if (RNA_struct_find_property(op->ptr, "cursor")) {
|
2013-09-06 22:34:29 +00:00
|
|
|
WM_cursor_modal_set(CTX_wm_window(C), RNA_int_get(op->ptr, "cursor"));
|
2014-01-16 19:15:53 +11:00
|
|
|
}
|
2009-02-07 14:03:34 +00:00
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-02-07 14:03:34 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LINES);
|
2009-02-07 14:03:34 +00:00
|
|
|
|
|
|
|
/* add modal handler */
|
2009-09-18 12:43:36 +00:00
|
|
|
WM_event_add_modal_handler(C, op);
|
2009-02-07 14:03:34 +00:00
|
|
|
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
|
2014-01-16 19:15:53 +11:00
|
|
|
if (RNA_struct_find_property(op->ptr, "cursor")) {
|
2013-09-06 22:34:29 +00:00
|
|
|
WM_cursor_modal_set(CTX_wm_window(C), RNA_int_get(op->ptr, "cursor"));
|
2014-01-16 19:15:53 +11:00
|
|
|
}
|
2009-02-07 14:03:34 +00:00
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static void gesture_lasso_apply(bContext *C, wmOperator *op)
|
2009-01-02 14:11:18 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
2009-01-02 14:11:18 +00:00
|
|
|
PointerRNA itemptr;
|
|
|
|
float loc[2];
|
|
|
|
int i;
|
2012-03-27 01:24:16 +00:00
|
|
|
short *lasso = gesture->customdata;
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
/* operator storage as path. */
|
|
|
|
|
2012-03-12 14:39:37 +00:00
|
|
|
RNA_collection_clear(op->ptr, "path");
|
2012-03-27 01:24:16 +00:00
|
|
|
for (i = 0; i < gesture->points; i++, lasso += 2) {
|
|
|
|
loc[0] = lasso[0];
|
|
|
|
loc[1] = lasso[1];
|
2009-01-02 14:11:18 +00:00
|
|
|
RNA_collection_add(op->ptr, "path", &itemptr);
|
|
|
|
RNA_float_set_array(&itemptr, "loc", loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
|
2012-10-06 00:42:30 +00:00
|
|
|
if (op->type->exec) {
|
|
|
|
int retval = op->type->exec(C, op);
|
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
|
|
|
}
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-01-02 14:11:18 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
2009-01-02 14:11:18 +00:00
|
|
|
int sx, sy;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
switch (event->type) {
|
2009-01-02 14:11:18 +00:00
|
|
|
case MOUSEMOVE:
|
2010-07-02 11:26:12 +00:00
|
|
|
case INBETWEEN_MOUSEMOVE:
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
|
|
|
|
wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
|
2010-01-10 20:16:56 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (gesture->points == gesture->size) {
|
2010-01-10 20:16:56 +00:00
|
|
|
short *old_lasso = gesture->customdata;
|
2012-03-27 01:24:16 +00:00
|
|
|
gesture->customdata = MEM_callocN(2 * sizeof(short) * (gesture->size + WM_LASSO_MIN_POINTS), "lasso points");
|
|
|
|
memcpy(gesture->customdata, old_lasso, 2 * sizeof(short) * gesture->size);
|
2010-01-10 20:16:56 +00:00
|
|
|
gesture->size = gesture->size + WM_LASSO_MIN_POINTS;
|
|
|
|
MEM_freeN(old_lasso);
|
2011-11-07 04:36:37 +00:00
|
|
|
// printf("realloc\n");
|
2010-01-10 20:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2011-05-12 16:47:36 +00:00
|
|
|
int x, y;
|
2012-03-27 01:24:16 +00:00
|
|
|
short *lasso = gesture->customdata;
|
2010-10-01 08:12:37 +00:00
|
|
|
|
|
|
|
lasso += (2 * gesture->points - 2);
|
|
|
|
x = (event->x - sx - lasso[0]);
|
|
|
|
y = (event->y - sy - lasso[1]);
|
|
|
|
|
|
|
|
/* make a simple distance check to get a smoother lasso
|
2012-03-09 18:28:30 +00:00
|
|
|
* add only when at least 2 pixels between this and previous location */
|
2012-03-27 01:24:16 +00:00
|
|
|
if ((x * x + y * y) > 4) {
|
2010-10-01 08:12:37 +00:00
|
|
|
lasso += 2;
|
|
|
|
lasso[0] = event->x - sx;
|
|
|
|
lasso[1] = event->y - sy;
|
|
|
|
gesture->points++;
|
|
|
|
}
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LEFTMOUSE:
|
|
|
|
case MIDDLEMOUSE:
|
|
|
|
case RIGHTMOUSE:
|
2012-03-27 01:24:16 +00:00
|
|
|
if (event->val == KM_RELEASE) { /* key release */
|
2010-10-16 02:40:31 +00:00
|
|
|
gesture_lasso_apply(C, op);
|
2009-01-02 14:11:18 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ESCKEY:
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_lines_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-02-07 14:03:34 +00:00
|
|
|
{
|
|
|
|
return WM_gesture_lasso_modal(C, op, event);
|
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
void WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
void WM_gesture_lines_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
}
|
|
|
|
|
2012-05-14 12:41:56 +00:00
|
|
|
/**
|
|
|
|
* helper function, we may want to add options for conversion to view space
|
|
|
|
*
|
|
|
|
* caller must free.
|
|
|
|
*/
|
2012-10-05 15:44:11 +00:00
|
|
|
const int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *mcords_tot))[2]
|
2012-05-14 12:41:56 +00:00
|
|
|
{
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "path");
|
|
|
|
int (*mcords)[2] = NULL;
|
|
|
|
BLI_assert(prop != NULL);
|
|
|
|
|
|
|
|
if (prop) {
|
|
|
|
const int len = RNA_property_collection_length(op->ptr, prop);
|
|
|
|
|
|
|
|
if (len) {
|
|
|
|
int i = 0;
|
|
|
|
mcords = MEM_mallocN(sizeof(int) * 2 * len, __func__);
|
|
|
|
|
2013-08-24 10:05:29 +00:00
|
|
|
RNA_PROP_BEGIN (op->ptr, itemptr, prop)
|
2012-05-14 12:41:56 +00:00
|
|
|
{
|
|
|
|
float loc[2];
|
|
|
|
|
|
|
|
RNA_float_get_array(&itemptr, "loc", loc);
|
|
|
|
mcords[i][0] = (int)loc[0];
|
|
|
|
mcords[i][1] = (int)loc[1];
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
RNA_PROP_END;
|
|
|
|
}
|
|
|
|
*mcords_tot = len;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*mcords_tot = 0;
|
|
|
|
}
|
|
|
|
|
2012-10-05 15:44:11 +00:00
|
|
|
/* cast for 'const' */
|
|
|
|
return (const int (*)[2])mcords;
|
2012-05-14 12:41:56 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
#if 0
|
|
|
|
/* template to copy from */
|
|
|
|
|
|
|
|
static int gesture_lasso_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
2013-08-24 10:05:29 +00:00
|
|
|
RNA_BEGIN (op->ptr, itemptr, "path")
|
2012-04-30 16:22:40 +00:00
|
|
|
{
|
2009-01-02 14:11:18 +00:00
|
|
|
float loc[2];
|
|
|
|
|
|
|
|
RNA_float_get_array(&itemptr, "loc", loc);
|
|
|
|
printf("Location: %f %f\n", loc[0], loc[1]);
|
|
|
|
}
|
|
|
|
RNA_END;
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WM_OT_lasso_gesture(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Lasso Gesture";
|
|
|
|
ot->idname = "WM_OT_lasso_gesture";
|
|
|
|
ot->description = "Select objects within the lasso as you move the pointer";
|
2009-01-02 14:11:18 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_gesture_lasso_invoke;
|
|
|
|
ot->modal = WM_gesture_lasso_modal;
|
|
|
|
ot->exec = gesture_lasso_exec;
|
2009-01-02 14:11:18 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = WM_operator_winactive;
|
2009-01-02 14:11:18 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
|
2009-01-02 14:11:18 +00:00
|
|
|
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
|
|
|
|
}
|
|
|
|
#endif
|
2008-11-24 10:45:36 +00:00
|
|
|
|
2010-04-04 00:21:37 +00:00
|
|
|
/* *********************** straight line gesture ****************** */
|
|
|
|
|
|
|
|
static int straightline_apply(bContext *C, wmOperator *op)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
|
|
|
rcti *rect = gesture->customdata;
|
2010-04-04 00:21:37 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (rect->xmin == rect->xmax && rect->ymin == rect->ymax)
|
2010-04-04 00:21:37 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* operator arguments and storage. */
|
|
|
|
RNA_int_set(op->ptr, "xstart", rect->xmin);
|
|
|
|
RNA_int_set(op->ptr, "ystart", rect->ymin);
|
|
|
|
RNA_int_set(op->ptr, "xend", rect->xmax);
|
|
|
|
RNA_int_set(op->ptr, "yend", rect->ymax);
|
|
|
|
|
2012-10-06 00:42:30 +00:00
|
|
|
if (op->type->exec) {
|
|
|
|
int retval = op->type->exec(C, op);
|
|
|
|
OPERATOR_RETVAL_CHECK(retval);
|
|
|
|
}
|
2010-04-04 00:21:37 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2010-04-04 00:21:37 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
op->customdata = WM_gesture_new(C, event, WM_GESTURE_STRAIGHTLINE);
|
2010-04-04 00:21:37 +00:00
|
|
|
|
|
|
|
/* add modal handler */
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
|
2014-01-16 19:15:53 +11:00
|
|
|
if (RNA_struct_find_property(op->ptr, "cursor")) {
|
2013-09-06 22:34:29 +00:00
|
|
|
WM_cursor_modal_set(CTX_wm_window(C), RNA_int_get(op->ptr, "cursor"));
|
2014-01-16 19:15:53 +11:00
|
|
|
}
|
2010-04-04 00:21:37 +00:00
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2010-04-04 00:21:37 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmGesture *gesture = op->customdata;
|
|
|
|
rcti *rect = gesture->customdata;
|
2010-04-04 00:21:37 +00:00
|
|
|
int sx, sy;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (event->type == MOUSEMOVE) {
|
2010-04-04 00:21:37 +00:00
|
|
|
wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (gesture->mode == 0) {
|
2012-03-24 02:51:46 +00:00
|
|
|
rect->xmin = rect->xmax = event->x - sx;
|
|
|
|
rect->ymin = rect->ymax = event->y - sy;
|
2010-04-04 00:21:37 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-24 02:51:46 +00:00
|
|
|
rect->xmax = event->x - sx;
|
|
|
|
rect->ymax = event->y - sy;
|
2010-04-04 00:21:37 +00:00
|
|
|
straightline_apply(C, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
2010-04-04 00:21:37 +00:00
|
|
|
switch (event->val) {
|
|
|
|
case GESTURE_MODAL_BEGIN:
|
2012-03-27 01:24:16 +00:00
|
|
|
if (gesture->mode == 0) {
|
|
|
|
gesture->mode = 1;
|
2010-04-04 00:21:37 +00:00
|
|
|
wm_gesture_tag_redraw(C);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GESTURE_MODAL_SELECT:
|
2012-03-24 06:24:53 +00:00
|
|
|
if (straightline_apply(C, op)) {
|
2010-04-04 00:21:37 +00:00
|
|
|
wm_gesture_end(C, op);
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GESTURE_MODAL_CANCEL:
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
void WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
wm_gesture_end(C, op);
|
|
|
|
}
|
|
|
|
|
2010-04-04 00:21:37 +00:00
|
|
|
#if 0
|
|
|
|
/* template to copy from */
|
|
|
|
void WM_OT_straightline_gesture(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Straight Line Gesture";
|
|
|
|
ot->idname = "WM_OT_straightline_gesture";
|
|
|
|
ot->description = "Draw a straight line as you move the pointer";
|
2010-04-04 00:21:37 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_gesture_straightline_invoke;
|
|
|
|
ot->modal = WM_gesture_straightline_modal;
|
|
|
|
ot->exec = gesture_straightline_exec;
|
2010-04-04 00:21:37 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = WM_operator_winactive;
|
2010-04-04 00:21:37 +00:00
|
|
|
|
|
|
|
WM_operator_properties_gesture_straightline(ot, 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-01-24 16:59:55 +00:00
|
|
|
/* *********************** radial control ****************** */
|
|
|
|
|
2011-02-13 14:16:36 +00:00
|
|
|
static const int WM_RADIAL_CONTROL_DISPLAY_SIZE = 200;
|
2009-01-24 22:58:22 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
typedef struct {
|
|
|
|
PropertyType type;
|
|
|
|
PropertySubType subtype;
|
|
|
|
PointerRNA ptr, col_ptr, fill_col_ptr, rot_ptr, zoom_ptr, image_id_ptr;
|
|
|
|
PropertyRNA *prop, *col_prop, *fill_col_prop, *rot_prop, *zoom_prop;
|
|
|
|
StructRNA *image_id_srna;
|
|
|
|
float initial_value, current_value, min_value, max_value;
|
2009-01-24 16:59:55 +00:00
|
|
|
int initial_mouse[2];
|
2011-05-12 01:57:47 +00:00
|
|
|
unsigned int gltex;
|
|
|
|
ListBase orig_paintcursors;
|
2013-09-05 14:02:59 +00:00
|
|
|
bool use_secondary_tex;
|
2009-01-24 16:59:55 +00:00
|
|
|
void *cursor;
|
2011-05-12 01:57:47 +00:00
|
|
|
} RadialControl;
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *event)
|
2009-01-24 16:59:55 +00:00
|
|
|
{
|
2011-05-12 01:57:47 +00:00
|
|
|
float d[2] = {0, 0};
|
|
|
|
float zoom[2] = {1, 1};
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
rc->initial_mouse[0] = event->x;
|
|
|
|
rc->initial_mouse[1] = event->y;
|
|
|
|
|
|
|
|
switch (rc->subtype) {
|
2013-02-12 10:33:04 +00:00
|
|
|
case PROP_NONE:
|
2012-03-27 01:24:16 +00:00
|
|
|
case PROP_DISTANCE:
|
2013-12-12 20:07:16 +02:00
|
|
|
case PROP_PIXEL:
|
2012-03-27 01:24:16 +00:00
|
|
|
d[0] = rc->initial_value;
|
|
|
|
break;
|
|
|
|
case PROP_FACTOR:
|
|
|
|
d[0] = WM_RADIAL_CONTROL_DISPLAY_SIZE * (1 - rc->initial_value);
|
|
|
|
break;
|
|
|
|
case PROP_ANGLE:
|
|
|
|
d[0] = WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(rc->initial_value);
|
|
|
|
d[1] = WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(rc->initial_value);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
2009-01-24 22:58:22 +00:00
|
|
|
}
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->zoom_prop) {
|
2011-05-12 01:57:47 +00:00
|
|
|
RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
|
|
|
|
d[0] *= zoom[0];
|
|
|
|
d[1] *= zoom[1];
|
|
|
|
}
|
2009-01-24 22:58:22 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
rc->initial_mouse[0] -= d[0];
|
|
|
|
rc->initial_mouse[1] -= d[1];
|
2011-05-12 01:57:47 +00:00
|
|
|
}
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
static void radial_control_set_tex(RadialControl *rc)
|
|
|
|
{
|
|
|
|
ImBuf *ibuf;
|
2009-01-24 22:58:22 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
switch (RNA_type_to_ID_code(rc->image_id_ptr.type)) {
|
|
|
|
case ID_BR:
|
2013-09-05 14:02:59 +00:00
|
|
|
if ((ibuf = BKE_brush_gen_radial_control_imbuf(rc->image_id_ptr.data, rc->use_secondary_tex))) {
|
2012-03-27 01:24:16 +00:00
|
|
|
glGenTextures(1, &rc->gltex);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, rc->gltex);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, ibuf->x, ibuf->y, 0,
|
|
|
|
GL_ALPHA, GL_FLOAT, ibuf->rect_float);
|
|
|
|
MEM_freeN(ibuf->rect_float);
|
|
|
|
MEM_freeN(ibuf);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2010-07-14 14:11:03 +00:00
|
|
|
}
|
2011-05-12 01:57:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void radial_control_paint_tex(RadialControl *rc, float radius, float alpha)
|
|
|
|
{
|
|
|
|
float col[3] = {0, 0, 0};
|
|
|
|
float rot;
|
|
|
|
|
|
|
|
/* set fill color */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->fill_col_prop)
|
2011-05-12 01:57:47 +00:00
|
|
|
RNA_property_float_get_array(&rc->fill_col_ptr, rc->fill_col_prop, col);
|
|
|
|
glColor4f(col[0], col[1], col[2], alpha);
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->gltex) {
|
2011-05-12 01:57:47 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, rc->gltex);
|
2009-01-24 22:58:22 +00:00
|
|
|
|
|
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* set up rotation if available */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->rot_prop) {
|
2011-05-12 01:57:47 +00:00
|
|
|
rot = RNA_property_float_get(&rc->rot_ptr, rc->rot_prop);
|
|
|
|
glPushMatrix();
|
|
|
|
glRotatef(RAD2DEGF(rot), 0, 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw textured quad */
|
2009-01-24 22:58:22 +00:00
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glBegin(GL_QUADS);
|
2012-03-27 01:24:16 +00:00
|
|
|
glTexCoord2f(0, 0);
|
2011-05-12 01:57:47 +00:00
|
|
|
glVertex2f(-radius, -radius);
|
2012-03-27 01:24:16 +00:00
|
|
|
glTexCoord2f(1, 0);
|
2011-05-12 01:57:47 +00:00
|
|
|
glVertex2f(radius, -radius);
|
2012-03-27 01:24:16 +00:00
|
|
|
glTexCoord2f(1, 1);
|
2011-05-12 01:57:47 +00:00
|
|
|
glVertex2f(radius, radius);
|
2012-03-27 01:24:16 +00:00
|
|
|
glTexCoord2f(0, 1);
|
2011-05-12 01:57:47 +00:00
|
|
|
glVertex2f(-radius, radius);
|
2009-01-24 22:58:22 +00:00
|
|
|
glEnd();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
2011-05-12 01:57:47 +00:00
|
|
|
|
|
|
|
/* undo rotation */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->rot_prop)
|
2011-05-12 01:57:47 +00:00
|
|
|
glPopMatrix();
|
2009-01-24 22:58:22 +00:00
|
|
|
}
|
2011-05-12 01:57:47 +00:00
|
|
|
else {
|
|
|
|
/* flat color if no texture available */
|
|
|
|
glutil_draw_filled_arc(0, M_PI * 2, radius, 40);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void radial_control_paint_cursor(bContext *C, int x, int y, void *customdata)
|
|
|
|
{
|
|
|
|
RadialControl *rc = customdata;
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2012-03-27 01:24:16 +00:00
|
|
|
float r1 = 0.0f, r2 = 0.0f, tex_radius, alpha;
|
2011-05-12 01:57:47 +00:00
|
|
|
float zoom[2], col[3] = {1, 1, 1};
|
2009-01-24 22:58:22 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
switch (rc->subtype) {
|
2013-02-12 10:33:04 +00:00
|
|
|
case PROP_NONE:
|
2012-03-27 01:24:16 +00:00
|
|
|
case PROP_DISTANCE:
|
2013-12-12 20:07:16 +02:00
|
|
|
case PROP_PIXEL:
|
2012-03-27 01:24:16 +00:00
|
|
|
r1 = rc->current_value;
|
|
|
|
r2 = rc->initial_value;
|
|
|
|
tex_radius = r1;
|
|
|
|
alpha = 0.75;
|
|
|
|
break;
|
|
|
|
case PROP_FACTOR:
|
|
|
|
r1 = (1 - rc->current_value) * WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
|
|
|
r2 = tex_radius = WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
|
|
|
alpha = rc->current_value / 2.0f + 0.5f;
|
|
|
|
break;
|
|
|
|
case PROP_ANGLE:
|
|
|
|
r1 = r2 = tex_radius = WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
|
|
|
alpha = 0.75;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
tex_radius = WM_RADIAL_CONTROL_DISPLAY_SIZE; /* note, this is a dummy value */
|
|
|
|
alpha = 0.75;
|
|
|
|
break;
|
2011-05-12 01:57:47 +00:00
|
|
|
}
|
|
|
|
|
2013-02-17 14:53:29 +00:00
|
|
|
/* adjust for DPI, like BKE_brush_size_get */
|
|
|
|
r1 *= U.pixelsize;
|
|
|
|
r2 *= U.pixelsize;
|
|
|
|
tex_radius *= U.pixelsize;
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* Keep cursor in the original place */
|
|
|
|
x = rc->initial_mouse[0] - ar->winrct.xmin;
|
|
|
|
y = rc->initial_mouse[1] - ar->winrct.ymin;
|
|
|
|
glTranslatef((float)x, (float)y, 0.0f);
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
|
|
|
|
/* apply zoom if available */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->zoom_prop) {
|
2011-05-12 01:57:47 +00:00
|
|
|
RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
|
|
|
|
glScalef(zoom[0], zoom[1], 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw rotated texture */
|
|
|
|
radial_control_paint_tex(rc, tex_radius, alpha);
|
|
|
|
|
|
|
|
/* set line color */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->col_prop)
|
2011-05-12 01:57:47 +00:00
|
|
|
RNA_property_float_get_array(&rc->col_ptr, rc->col_prop, col);
|
|
|
|
glColor4f(col[0], col[1], col[2], 0.5);
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (rc->subtype == PROP_ANGLE) {
|
2011-05-12 01:57:47 +00:00
|
|
|
glPushMatrix();
|
|
|
|
/* draw original angle line */
|
|
|
|
glRotatef(RAD2DEGF(rc->initial_value), 0, 0, 1);
|
2011-04-10 09:37:04 +00:00
|
|
|
fdrawline(0.0f, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
|
2011-05-12 01:57:47 +00:00
|
|
|
/* draw new angle line */
|
|
|
|
glRotatef(RAD2DEGF(rc->current_value - rc->initial_value), 0, 0, 1);
|
2011-04-10 09:37:04 +00:00
|
|
|
fdrawline(0.0f, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
|
2011-05-12 01:57:47 +00:00
|
|
|
glPopMatrix();
|
2010-07-14 14:11:03 +00:00
|
|
|
}
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* draw circles on top */
|
2012-03-27 01:24:16 +00:00
|
|
|
glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r1, 40);
|
|
|
|
glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r2, 40);
|
2011-05-12 01:57:47 +00:00
|
|
|
|
2009-01-24 16:59:55 +00:00
|
|
|
glDisable(GL_BLEND);
|
2011-05-12 01:57:47 +00:00
|
|
|
glDisable(GL_LINE_SMOOTH);
|
2009-01-24 16:59:55 +00:00
|
|
|
}
|
|
|
|
|
2012-01-14 23:54:51 +00:00
|
|
|
typedef enum {
|
|
|
|
RC_PROP_ALLOW_MISSING = 1,
|
|
|
|
RC_PROP_REQUIRE_FLOAT = 2,
|
|
|
|
RC_PROP_REQUIRE_BOOL = 4,
|
|
|
|
} RCPropFlags;
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* attempt to retrieve the rna pointer/property from an rna path;
|
2012-03-09 18:28:30 +00:00
|
|
|
* returns 0 for failure, 1 for success, and also 1 if property is not
|
|
|
|
* set */
|
2011-05-12 01:57:47 +00:00
|
|
|
static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op,
|
2012-03-27 01:24:16 +00:00
|
|
|
const char *name, PointerRNA *r_ptr,
|
|
|
|
PropertyRNA **r_prop, int req_length, RCPropFlags flags)
|
2009-01-24 16:59:55 +00:00
|
|
|
{
|
2011-05-12 01:57:47 +00:00
|
|
|
PropertyRNA *unused_prop;
|
|
|
|
int len;
|
|
|
|
char *str;
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-01-14 23:54:51 +00:00
|
|
|
/* check flags */
|
2012-03-24 06:24:53 +00:00
|
|
|
if ((flags & RC_PROP_REQUIRE_BOOL) && (flags & RC_PROP_REQUIRE_FLOAT)) {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Property cannot be both boolean and float");
|
2012-01-14 23:54:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* get an rna string path from the operator's properties */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!(str = RNA_string_get_alloc(op->ptr, name, NULL, 0)))
|
2011-05-12 01:57:47 +00:00
|
|
|
return 1;
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (str[0] == '\0') {
|
|
|
|
if (r_prop) *r_prop = NULL;
|
2011-05-12 01:57:47 +00:00
|
|
|
MEM_freeN(str);
|
|
|
|
return 1;
|
|
|
|
}
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!r_prop)
|
2011-05-12 01:57:47 +00:00
|
|
|
r_prop = &unused_prop;
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* get rna from path */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!RNA_path_resolve(ctx_ptr, str, r_ptr, r_prop)) {
|
2011-05-12 01:57:47 +00:00
|
|
|
MEM_freeN(str);
|
2012-03-24 06:24:53 +00:00
|
|
|
if (flags & RC_PROP_ALLOW_MISSING)
|
2011-05-12 01:57:47 +00:00
|
|
|
return 1;
|
|
|
|
else {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name);
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-01-14 23:54:51 +00:00
|
|
|
/* check property type */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (flags & (RC_PROP_REQUIRE_BOOL | RC_PROP_REQUIRE_FLOAT)) {
|
2012-01-14 23:54:51 +00:00
|
|
|
PropertyType prop_type = RNA_property_type(*r_prop);
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (((flags & RC_PROP_REQUIRE_BOOL) && (prop_type != PROP_BOOLEAN)) ||
|
2012-05-20 19:49:27 +00:00
|
|
|
((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT))
|
|
|
|
{
|
2011-05-12 01:57:47 +00:00
|
|
|
MEM_freeN(str);
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' is not a float", name);
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
2009-01-24 22:58:22 +00:00
|
|
|
}
|
2011-05-12 01:57:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check property's array length */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (*r_prop && (len = RNA_property_array_length(r_ptr, *r_prop)) != req_length) {
|
2011-05-12 01:57:47 +00:00
|
|
|
MEM_freeN(str);
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' has length %d instead of %d",
|
2011-11-11 13:09:14 +00:00
|
|
|
name, len, req_length);
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
2009-01-24 16:59:55 +00:00
|
|
|
}
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* success */
|
|
|
|
MEM_freeN(str);
|
|
|
|
return 1;
|
|
|
|
}
|
2009-01-24 22:58:22 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* initialize the rna pointers and properties using rna paths */
|
|
|
|
static int radial_control_get_properties(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
RadialControl *rc = op->customdata;
|
2012-01-14 23:54:51 +00:00
|
|
|
PointerRNA ctx_ptr, use_secondary_ptr;
|
2013-03-19 10:54:52 +00:00
|
|
|
PropertyRNA *use_secondary_prop = NULL;
|
2012-01-14 23:54:51 +00:00
|
|
|
const char *data_path;
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-01-14 23:54:51 +00:00
|
|
|
/* check if we use primary or secondary path */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_path(&ctx_ptr, op, "use_secondary",
|
2012-03-27 01:24:16 +00:00
|
|
|
&use_secondary_ptr, &use_secondary_prop,
|
|
|
|
0, (RC_PROP_ALLOW_MISSING |
|
|
|
|
RC_PROP_REQUIRE_BOOL)))
|
|
|
|
{
|
2012-01-14 23:54:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (use_secondary_prop &&
|
2012-03-27 01:24:16 +00:00
|
|
|
RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop))
|
2012-04-28 06:31:57 +00:00
|
|
|
{
|
2012-01-14 23:54:51 +00:00
|
|
|
data_path = "data_path_secondary";
|
2012-04-28 06:31:57 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-01-14 23:54:51 +00:00
|
|
|
data_path = "data_path_primary";
|
2012-04-28 06:31:57 +00:00
|
|
|
}
|
2012-01-14 23:54:51 +00:00
|
|
|
}
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_path(&ctx_ptr, op, data_path, &rc->ptr, &rc->prop, 0, 0))
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* data path is required */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!rc->prop)
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_path(&ctx_ptr, op, "rotation_path", &rc->rot_ptr, &rc->rot_prop, 0, RC_PROP_REQUIRE_FLOAT))
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_path(&ctx_ptr, op, "color_path", &rc->col_ptr, &rc->col_prop, 3, RC_PROP_REQUIRE_FLOAT))
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_path(&ctx_ptr, op, "fill_color_path", &rc->fill_col_ptr, &rc->fill_col_prop, 3, RC_PROP_REQUIRE_FLOAT))
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* slightly ugly; allow this property to not resolve
|
2012-02-19 06:00:20 +00:00
|
|
|
* correctly. needed because 3d texture paint shares the same
|
|
|
|
* keymap as 2d image paint */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_path(&ctx_ptr, op, "zoom_path",
|
2012-03-27 01:24:16 +00:00
|
|
|
&rc->zoom_ptr, &rc->zoom_prop, 2,
|
|
|
|
RC_PROP_REQUIRE_FLOAT | RC_PROP_ALLOW_MISSING))
|
2012-04-28 06:31:57 +00:00
|
|
|
{
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
2012-04-28 06:31:57 +00:00
|
|
|
}
|
2011-05-12 01:57:47 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0))
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
2012-03-24 06:24:53 +00:00
|
|
|
else if (rc->image_id_ptr.data) {
|
2011-05-12 01:57:47 +00:00
|
|
|
/* extra check, pointer must be to an ID */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!RNA_struct_is_ID(rc->image_id_ptr.type)) {
|
2012-10-19 16:43:10 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Pointer from path image_id is not an ID");
|
2011-05-12 01:57:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2013-09-05 14:02:59 +00:00
|
|
|
rc->use_secondary_tex = RNA_boolean_get(op->ptr, "secondary_tex");
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
return 1;
|
2009-01-24 16:59:55 +00:00
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int radial_control_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-01-24 16:59:55 +00:00
|
|
|
{
|
2011-05-12 01:57:47 +00:00
|
|
|
wmWindowManager *wm;
|
|
|
|
RadialControl *rc;
|
|
|
|
int min_value_int, max_value_int, step_int;
|
|
|
|
float step_float, precision;
|
2010-11-03 06:31:53 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!(op->customdata = rc = MEM_callocN(sizeof(RadialControl), "RadialControl")))
|
2011-05-12 01:57:47 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!radial_control_get_properties(C, op)) {
|
2011-05-12 01:57:47 +00:00
|
|
|
MEM_freeN(rc);
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-24 22:58:22 +00:00
|
|
|
}
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* get type, initial, min, and max values of the property */
|
2012-03-27 01:24:16 +00:00
|
|
|
switch ((rc->type = RNA_property_type(rc->prop))) {
|
|
|
|
case PROP_INT:
|
|
|
|
rc->initial_value = RNA_property_int_get(&rc->ptr, rc->prop);
|
|
|
|
RNA_property_int_ui_range(&rc->ptr, rc->prop, &min_value_int,
|
|
|
|
&max_value_int, &step_int);
|
|
|
|
rc->min_value = min_value_int;
|
|
|
|
rc->max_value = max_value_int;
|
|
|
|
break;
|
|
|
|
case PROP_FLOAT:
|
|
|
|
rc->initial_value = RNA_property_float_get(&rc->ptr, rc->prop);
|
|
|
|
RNA_property_float_ui_range(&rc->ptr, rc->prop, &rc->min_value,
|
|
|
|
&rc->max_value, &step_float, &precision);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Property must be an integer or a float");
|
|
|
|
MEM_freeN(rc);
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-24 16:59:55 +00:00
|
|
|
}
|
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* get subtype of property */
|
|
|
|
rc->subtype = RNA_property_subtype(rc->prop);
|
2013-12-12 20:07:16 +02:00
|
|
|
if (!ELEM5(rc->subtype, PROP_NONE, PROP_DISTANCE, PROP_FACTOR, PROP_ANGLE, PROP_PIXEL)) {
|
2013-02-12 10:33:04 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Property must be a none, distance, a factor, or an angle");
|
2011-05-12 01:57:47 +00:00
|
|
|
MEM_freeN(rc);
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
rc->current_value = rc->initial_value;
|
|
|
|
radial_control_set_initial_mouse(rc, event);
|
|
|
|
radial_control_set_tex(rc);
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* temporarily disable other paint cursors */
|
|
|
|
wm = CTX_wm_manager(C);
|
|
|
|
rc->orig_paintcursors = wm->paintcursors;
|
|
|
|
wm->paintcursors.first = wm->paintcursors.last = NULL;
|
|
|
|
|
|
|
|
/* add radial control paint cursor */
|
|
|
|
rc->cursor = WM_paint_cursor_activate(wm, op->type->poll,
|
2012-03-27 01:24:16 +00:00
|
|
|
radial_control_paint_cursor, rc);
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2009-09-18 12:43:36 +00:00
|
|
|
WM_event_add_modal_handler(C, op);
|
2011-05-12 01:57:47 +00:00
|
|
|
|
2009-01-24 16:59:55 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
}
|
|
|
|
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
static void radial_control_set_value(RadialControl *rc, float val)
|
2009-01-25 21:02:52 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
switch (rc->type) {
|
|
|
|
case PROP_INT:
|
|
|
|
RNA_property_int_set(&rc->ptr, rc->prop, val);
|
|
|
|
break;
|
|
|
|
case PROP_FLOAT:
|
|
|
|
RNA_property_float_set(&rc->ptr, rc->prop, val);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2011-05-12 01:57:47 +00:00
|
|
|
}
|
2009-01-25 21:02:52 +00:00
|
|
|
}
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
static void radial_control_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
RadialControl *rc = op->customdata;
|
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
|
|
|
|
WM_paint_cursor_end(wm, rc->cursor);
|
|
|
|
|
|
|
|
/* restore original paint cursors */
|
|
|
|
wm->paintcursors = rc->orig_paintcursors;
|
|
|
|
|
|
|
|
/* not sure if this is a good notifier to use;
|
2012-03-09 18:28:30 +00:00
|
|
|
* intended purpose is to update the UI so that the
|
|
|
|
* new value is displayed in sliders/numfields */
|
2011-06-06 11:04:54 +00:00
|
|
|
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
|
|
|
|
|
|
|
glDeleteTextures(1, &rc->gltex);
|
|
|
|
|
|
|
|
MEM_freeN(rc);
|
|
|
|
}
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-01-24 16:59:55 +00:00
|
|
|
{
|
2011-05-12 01:57:47 +00:00
|
|
|
RadialControl *rc = op->customdata;
|
|
|
|
float new_value, dist, zoom[2];
|
|
|
|
float delta[2], snap, ret = OPERATOR_RUNNING_MODAL;
|
|
|
|
|
|
|
|
/* TODO: fix hardcoded events */
|
|
|
|
|
|
|
|
snap = event->ctrl;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
switch (event->type) {
|
|
|
|
case MOUSEMOVE:
|
|
|
|
delta[0] = rc->initial_mouse[0] - event->x;
|
|
|
|
delta[1] = rc->initial_mouse[1] - event->y;
|
2011-05-12 01:57:47 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
if (rc->zoom_prop) {
|
|
|
|
RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
|
|
|
|
delta[0] /= zoom[0];
|
|
|
|
delta[1] /= zoom[1];
|
|
|
|
}
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
dist = sqrt(delta[0] * delta[0] + delta[1] * delta[1]);
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
/* calculate new value and apply snapping */
|
|
|
|
switch (rc->subtype) {
|
2013-02-12 10:33:04 +00:00
|
|
|
case PROP_NONE:
|
2012-03-27 01:24:16 +00:00
|
|
|
case PROP_DISTANCE:
|
2013-12-12 20:07:16 +02:00
|
|
|
case PROP_PIXEL:
|
2012-03-27 01:24:16 +00:00
|
|
|
new_value = dist;
|
|
|
|
if (snap) new_value = ((int)new_value + 5) / 10 * 10;
|
|
|
|
break;
|
|
|
|
case PROP_FACTOR:
|
|
|
|
new_value = 1 - dist / WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
|
|
|
if (snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
|
|
|
|
break;
|
|
|
|
case PROP_ANGLE:
|
|
|
|
new_value = atan2(delta[1], delta[0]) + M_PI;
|
|
|
|
if (snap) new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
new_value = dist; /* dummy value, should this ever happen? - campbell */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clamp and update */
|
|
|
|
CLAMP(new_value, rc->min_value, rc->max_value);
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
radial_control_set_value(rc, new_value);
|
2012-03-27 01:24:16 +00:00
|
|
|
rc->current_value = new_value;
|
2011-05-12 01:57:47 +00:00
|
|
|
break;
|
2012-03-27 01:24:16 +00:00
|
|
|
|
|
|
|
case ESCKEY:
|
|
|
|
case RIGHTMOUSE:
|
|
|
|
/* canceled; restore original value */
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
radial_control_set_value(rc, rc->initial_value);
|
2012-03-27 01:24:16 +00:00
|
|
|
ret = OPERATOR_CANCELLED;
|
2011-05-12 01:57:47 +00:00
|
|
|
break;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
case LEFTMOUSE:
|
|
|
|
case PADENTER:
|
|
|
|
/* done; value already set */
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
RNA_property_update(C, &rc->ptr, rc->prop);
|
2012-03-27 01:24:16 +00:00
|
|
|
ret = OPERATOR_FINISHED;
|
|
|
|
break;
|
2011-05-12 01:57:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ret != OPERATOR_RUNNING_MODAL)
|
2011-06-06 11:04:54 +00:00
|
|
|
radial_control_cancel(C, op);
|
2011-05-12 01:57:47 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_radial_control(wmOperatorType *ot)
|
|
|
|
{
|
2013-11-25 05:13:05 +01:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Radial Control";
|
|
|
|
ot->idname = "WM_OT_radial_control";
|
2012-05-06 15:03:31 +00:00
|
|
|
ot->description = "Set some size property (like e.g. brush size) with mouse wheel";
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = radial_control_invoke;
|
|
|
|
ot->modal = radial_control_modal;
|
|
|
|
ot->cancel = radial_control_cancel;
|
2009-01-24 16:59:55 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
2010-08-20 09:41:16 +00:00
|
|
|
|
2011-05-12 01:57:47 +00:00
|
|
|
/* all paths relative to the context */
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "data_path_primary", NULL, 0, "Primary Data Path", "Primary path of property to be set by the radial control");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "data_path_secondary", NULL, 0, "Secondary Data Path", "Secondary path of property to be set by the radial control");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "use_secondary", NULL, 0, "Use Secondary", "Path of property to select between the primary and secondary data paths");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "rotation_path", NULL, 0, "Rotation Path", "Path of property used to rotate the texture display");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "color_path", NULL, 0, "Color Path", "Path of property used to set the color of the control");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "fill_color_path", NULL, 0, "Fill Color Path", "Path of property used to set the fill color of the control");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "zoom_path", NULL, 0, "Zoom Path", "Path of property used to set the zoom level for the control");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
2014-01-16 21:43:22 +11:00
|
|
|
prop = RNA_def_string(ot->srna, "image_id", NULL, 0, "Image ID", "Path of ID that is used to generate an image for the control");
|
2013-11-25 05:13:05 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
|
|
|
prop = RNA_def_boolean(ot->srna, "secondary_tex", 0, "Secondary Texture", "Tweak brush secondary/mask texture");
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
2009-01-24 16:59:55 +00:00
|
|
|
}
|
|
|
|
|
2009-05-19 12:54:54 +00:00
|
|
|
/* ************************** timer for testing ***************** */
|
|
|
|
|
|
|
|
/* uses no type defines, fully local testing function anyway... ;) */
|
|
|
|
|
2010-06-14 10:33:26 +00:00
|
|
|
static void redraw_timer_window_swap(bContext *C)
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2010-06-14 10:33:26 +00:00
|
|
|
ScrArea *sa;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (sa = CTX_wm_screen(C)->areabase.first; sa; sa = sa->next)
|
2010-06-14 10:33:26 +00:00
|
|
|
ED_area_tag_redraw(sa);
|
|
|
|
wm_draw_update(C);
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
CTX_wm_window_set(C, win); /* XXX context manipulation warning! */
|
2010-06-14 10:33:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static EnumPropertyItem redraw_timer_type_items[] = {
|
2011-10-20 20:38:26 +00:00
|
|
|
{0, "DRAW", 0, "Draw Region", "Draw Region"},
|
|
|
|
{1, "DRAW_SWAP", 0, "Draw Region + Swap", "Draw Region and Swap"},
|
|
|
|
{2, "DRAW_WIN", 0, "Draw Window", "Draw Window"},
|
|
|
|
{3, "DRAW_WIN_SWAP", 0, "Draw Window + Swap", "Draw Window and Swap"},
|
|
|
|
{4, "ANIM_STEP", 0, "Anim Step", "Animation Steps"},
|
|
|
|
{5, "ANIM_PLAY", 0, "Anim Play", "Animation Playback"},
|
|
|
|
{6, "UNDO", 0, "Undo/Redo", "Undo/Redo"},
|
2012-03-27 01:24:16 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
};
|
2010-06-14 10:33:26 +00:00
|
|
|
|
2009-09-22 09:12:39 +00:00
|
|
|
static int redraw_timer_exec(bContext *C, wmOperator *op)
|
2009-05-19 12:54:54 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
double stime = PIL_check_seconds_timer();
|
2011-03-22 13:30:20 +00:00
|
|
|
int type = RNA_enum_get(op->ptr, "type");
|
2009-09-22 09:12:39 +00:00
|
|
|
int iter = RNA_int_get(op->ptr, "iterations");
|
|
|
|
int a;
|
|
|
|
float time;
|
2012-03-27 01:24:16 +00:00
|
|
|
const char *infostr = "";
|
2009-05-19 12:54:54 +00:00
|
|
|
|
|
|
|
WM_cursor_wait(1);
|
2009-09-22 09:12:39 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (a = 0; a < iter; a++) {
|
|
|
|
if (type == 0) {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ar)
|
2010-11-04 15:59:09 +00:00
|
|
|
ED_region_do_draw(C, ar);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (type == 1) {
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2009-05-19 12:54:54 +00:00
|
|
|
|
|
|
|
ED_region_tag_redraw(ar);
|
|
|
|
wm_draw_update(C);
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
CTX_wm_window_set(C, win); /* XXX context manipulation warning! */
|
2009-05-19 12:54:54 +00:00
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (type == 2) {
|
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2009-05-19 12:54:54 +00:00
|
|
|
ScrArea *sa;
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
ScrArea *sa_back = CTX_wm_area(C);
|
|
|
|
ARegion *ar_back = CTX_wm_region(C);
|
2009-09-22 09:12:39 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (sa = CTX_wm_screen(C)->areabase.first; sa; sa = sa->next) {
|
2009-09-22 09:12:39 +00:00
|
|
|
ARegion *ar_iter;
|
|
|
|
CTX_wm_area_set(C, sa);
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) {
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ar_iter->swinid) {
|
2009-12-14 20:37:05 +00:00
|
|
|
CTX_wm_region_set(C, ar_iter);
|
|
|
|
ED_region_do_draw(C, ar_iter);
|
|
|
|
}
|
2009-09-22 09:12:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
CTX_wm_window_set(C, win); /* XXX context manipulation warning! */
|
2009-09-22 09:12:39 +00:00
|
|
|
|
|
|
|
CTX_wm_area_set(C, sa_back);
|
|
|
|
CTX_wm_region_set(C, ar_back);
|
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (type == 3) {
|
2010-06-14 10:33:26 +00:00
|
|
|
redraw_timer_window_swap(C);
|
2009-05-19 12:54:54 +00:00
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (type == 4) {
|
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2009-05-19 15:37:50 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (a & 1) scene->r.cfra--;
|
2009-05-19 15:37:50 +00:00
|
|
|
else scene->r.cfra++;
|
2013-12-26 17:24:42 +06:00
|
|
|
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
|
2009-05-19 15:37:50 +00:00
|
|
|
}
|
2012-03-27 01:24:16 +00:00
|
|
|
else if (type == 5) {
|
2010-06-14 10:33:26 +00:00
|
|
|
|
|
|
|
/* play anim, return on same frame as started with */
|
2012-03-27 01:24:16 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
int tot = (scene->r.efra - scene->r.sfra) + 1;
|
2010-06-14 10:33:26 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
while (tot--) {
|
2010-06-14 10:33:26 +00:00
|
|
|
/* todo, ability to escape! */
|
|
|
|
scene->r.cfra++;
|
2012-03-24 06:24:53 +00:00
|
|
|
if (scene->r.cfra > scene->r.efra)
|
2012-03-27 01:24:16 +00:00
|
|
|
scene->r.cfra = scene->r.sfra;
|
2010-06-14 10:33:26 +00:00
|
|
|
|
2013-12-26 17:24:42 +06:00
|
|
|
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
|
2010-06-14 10:33:26 +00:00
|
|
|
redraw_timer_window_swap(C);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { /* 6 */
|
2009-05-19 12:54:54 +00:00
|
|
|
ED_undo_pop(C);
|
|
|
|
ED_undo_redo(C);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
time = (float)((PIL_check_seconds_timer() - stime) * 1000);
|
2010-06-14 10:33:26 +00:00
|
|
|
|
|
|
|
RNA_enum_description(redraw_timer_type_items, type, &infostr);
|
|
|
|
|
2009-05-19 12:54:54 +00:00
|
|
|
WM_cursor_wait(0);
|
2010-06-14 10:33:26 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
BKE_reportf(op->reports, RPT_WARNING, "%d x %s: %.2f ms, average: %.4f", iter, infostr, time, time / iter);
|
2009-05-19 12:54:54 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-09-22 09:12:39 +00:00
|
|
|
static void WM_OT_redraw_timer(wmOperatorType *ot)
|
2009-05-19 12:54:54 +00:00
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Redraw Timer";
|
|
|
|
ot->idname = "WM_OT_redraw_timer";
|
|
|
|
ot->description = "Simple redraw timer to test the speed of updating the interface";
|
2010-06-14 10:33:26 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_menu_invoke;
|
|
|
|
ot->exec = redraw_timer_exec;
|
|
|
|
ot->poll = WM_operator_winactive;
|
2010-06-14 10:33:26 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->prop = RNA_def_enum(ot->srna, "type", redraw_timer_type_items, 0, "Type", "");
|
2012-03-27 01:24:16 +00:00
|
|
|
RNA_def_int(ot->srna, "iterations", 10, 1, INT_MAX, "Iterations", "Number of times to redraw", 1, 1000);
|
2009-05-19 12:54:54 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-10-27 10:29:51 +00:00
|
|
|
/* ************************** memory statistics for testing ***************** */
|
2009-05-19 12:54:54 +00:00
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
static int memory_statistics_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
|
2009-10-27 10:29:51 +00:00
|
|
|
{
|
|
|
|
MEM_printmemlist_stats();
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_memory_statistics(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Memory Statistics";
|
|
|
|
ot->idname = "WM_OT_memory_statistics";
|
|
|
|
ot->description = "Print memory statistics to the console";
|
2009-10-27 10:29:51 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = memory_statistics_exec;
|
2009-10-27 10:29:51 +00:00
|
|
|
}
|
2009-05-19 12:54:54 +00:00
|
|
|
|
2011-11-04 13:17:35 +00:00
|
|
|
/* ************************** memory statistics for testing ***************** */
|
|
|
|
|
|
|
|
static int dependency_relations_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
Object *ob = CTX_data_active_object(C);
|
2011-11-04 13:17:35 +00:00
|
|
|
|
|
|
|
DAG_print_dependencies(bmain, scene, ob);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_dependency_relations(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Dependency Relations";
|
|
|
|
ot->idname = "WM_OT_dependency_relations";
|
|
|
|
ot->description = "Print dependency graph relations to the console";
|
2011-11-04 13:17:35 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = dependency_relations_exec;
|
2011-11-04 13:17:35 +00:00
|
|
|
}
|
|
|
|
|
2.5: gesture code in WM
- Simplified and cleaned previous border code
It was a bit too complex, too many data manipulations
Original idea was to have WM API calls to manage border, circle, lines,
lasso, etc. This now means that WM provides callbacks for custom operators,
so it's very easy to make them. Check bottom of screen_edit.c for an
example.
Currently two borders were coded; with and without cross hair.
Press Bkey in any area-region to test it (note: time window has wrong matrix!)
Some specs to note:
- gestures are in region space, and draw 'over'. That latter still needs some
work when we do real composites.
- only the active region is redrawn.
- on todo is the generic gesture engine for 'tweak' or like how currently grab
gestures in Blender work. These will be configurable per area-region, and WM
then will send the proper "Gesture Event" with properties (N, S, E, W, etc)
to which you then can assign operators. Such events will be generated with low
priority, so other handlers who swallowed mouse events have preference.
2008-11-19 13:16:05 +00:00
|
|
|
/* ******************************************************* */
|
2011-07-28 13:44:36 +00:00
|
|
|
|
|
|
|
static int wm_ndof_sensitivity_exec(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
{
|
2012-06-17 11:36:28 +00:00
|
|
|
const float min = 0.25f, max = 4.0f; /* TODO: get these from RNA property */
|
2011-07-29 21:07:51 +00:00
|
|
|
float change;
|
|
|
|
float sensitivity = U.ndof_sensitivity;
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "fast"))
|
2012-06-17 11:36:28 +00:00
|
|
|
change = 0.5f; /* 50% change */
|
2011-07-29 21:07:51 +00:00
|
|
|
else
|
2012-06-17 11:36:28 +00:00
|
|
|
change = 0.1f; /* 10% */
|
2011-07-28 13:44:36 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "decrease")) {
|
2011-07-29 21:07:51 +00:00
|
|
|
sensitivity -= sensitivity * change;
|
|
|
|
if (sensitivity < min)
|
|
|
|
sensitivity = min;
|
2011-08-02 09:18:21 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-07-29 21:07:51 +00:00
|
|
|
sensitivity += sensitivity * change;
|
|
|
|
if (sensitivity > max)
|
|
|
|
sensitivity = max;
|
2011-08-02 09:18:21 +00:00
|
|
|
}
|
2011-07-29 21:07:51 +00:00
|
|
|
|
2011-08-02 09:18:21 +00:00
|
|
|
if (sensitivity != U.ndof_sensitivity) {
|
2011-07-29 21:07:51 +00:00
|
|
|
U.ndof_sensitivity = sensitivity;
|
2011-08-02 09:18:21 +00:00
|
|
|
}
|
2011-07-28 13:44:36 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WM_OT_ndof_sensitivity_change(wmOperatorType *ot)
|
|
|
|
{
|
2013-01-27 07:23:58 +00:00
|
|
|
ot->name = "Change NDOF Sensitivity";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "WM_OT_ndof_sensitivity_change";
|
|
|
|
ot->description = "Change NDOF sensitivity";
|
2011-07-28 13:44:36 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = wm_ndof_sensitivity_exec;
|
2011-07-28 13:44:36 +00:00
|
|
|
|
|
|
|
RNA_def_boolean(ot->srna, "decrease", 1, "Decrease NDOF sensitivity", "If true then action decreases NDOF sensitivity instead of increasing");
|
2011-07-29 21:07:51 +00:00
|
|
|
RNA_def_boolean(ot->srna, "fast", 0, "Fast NDOF sensitivity change", "If true then sensitivity changes 50%, otherwise 10%");
|
2011-07-28 13:44:36 +00:00
|
|
|
}
|
2011-07-29 21:07:51 +00:00
|
|
|
|
2011-08-11 06:06:17 +00:00
|
|
|
|
|
|
|
static void operatortype_ghash_free_cb(wmOperatorType *ot)
|
|
|
|
{
|
2012-03-21 06:33:31 +00:00
|
|
|
if (ot->last_properties) {
|
|
|
|
IDP_FreeProperty(ot->last_properties);
|
|
|
|
MEM_freeN(ot->last_properties);
|
|
|
|
}
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ot->macro.first)
|
2011-08-11 06:06:17 +00:00
|
|
|
wm_operatortype_free_macro(ot);
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (ot->ext.srna) /* python operator, allocs own string */
|
2011-08-11 06:06:17 +00:00
|
|
|
MEM_freeN((void *)ot->idname);
|
|
|
|
|
|
|
|
MEM_freeN(ot);
|
|
|
|
}
|
|
|
|
|
2011-07-28 13:44:36 +00:00
|
|
|
/* ******************************************************* */
|
2007-12-24 18:27:28 +00:00
|
|
|
/* called on initialize WM_exit() */
|
|
|
|
void wm_operatortype_free(void)
|
|
|
|
{
|
2011-08-11 06:06:17 +00:00
|
|
|
BLI_ghash_free(global_ops_hash, NULL, (GHashValFreeFP)operatortype_ghash_free_cb);
|
2012-03-27 01:24:16 +00:00
|
|
|
global_ops_hash = NULL;
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* called on initialize WM_init() */
|
|
|
|
void wm_operatortype_init(void)
|
|
|
|
{
|
2013-08-24 17:33:47 +00:00
|
|
|
/* reserve size is set based on blender default setup */
|
|
|
|
global_ops_hash = BLI_ghash_str_new_ex("wm_operatortype_init gh", 2048);
|
2011-08-11 06:06:17 +00:00
|
|
|
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
WM_operatortype_append(WM_OT_window_duplicate);
|
2013-03-28 02:29:10 +00:00
|
|
|
WM_operatortype_append(WM_OT_read_history);
|
2009-02-07 10:00:46 +00:00
|
|
|
WM_operatortype_append(WM_OT_read_homefile);
|
2010-10-02 13:45:26 +00:00
|
|
|
WM_operatortype_append(WM_OT_read_factory_settings);
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
WM_operatortype_append(WM_OT_save_homefile);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
WM_operatortype_append(WM_OT_save_userpref);
|
2013-06-18 18:11:52 +00:00
|
|
|
WM_operatortype_append(WM_OT_userpref_autoexec_path_add);
|
|
|
|
WM_operatortype_append(WM_OT_userpref_autoexec_path_remove);
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
|
2010-10-11 22:05:45 +00:00
|
|
|
WM_operatortype_append(WM_OT_quit_blender);
|
2009-01-06 14:42:54 +00:00
|
|
|
WM_operatortype_append(WM_OT_open_mainfile);
|
2009-09-12 19:54:39 +00:00
|
|
|
WM_operatortype_append(WM_OT_link_append);
|
2009-07-23 21:35:11 +00:00
|
|
|
WM_operatortype_append(WM_OT_recover_last_session);
|
2009-10-20 13:58:53 +00:00
|
|
|
WM_operatortype_append(WM_OT_recover_auto_save);
|
2009-01-21 19:28:28 +00:00
|
|
|
WM_operatortype_append(WM_OT_save_as_mainfile);
|
2009-02-08 19:15:59 +00:00
|
|
|
WM_operatortype_append(WM_OT_save_mainfile);
|
2009-09-22 09:12:39 +00:00
|
|
|
WM_operatortype_append(WM_OT_redraw_timer);
|
2009-10-27 10:29:51 +00:00
|
|
|
WM_operatortype_append(WM_OT_memory_statistics);
|
2011-11-04 13:17:35 +00:00
|
|
|
WM_operatortype_append(WM_OT_dependency_relations);
|
2009-05-22 15:02:32 +00:00
|
|
|
WM_operatortype_append(WM_OT_debug_menu);
|
2012-11-12 21:44:48 +00:00
|
|
|
WM_operatortype_append(WM_OT_operator_defaults);
|
2009-11-23 13:58:55 +00:00
|
|
|
WM_operatortype_append(WM_OT_splash);
|
2009-06-03 18:31:37 +00:00
|
|
|
WM_operatortype_append(WM_OT_search_menu);
|
2009-10-06 13:04:31 +00:00
|
|
|
WM_operatortype_append(WM_OT_call_menu);
|
2011-05-12 01:57:47 +00:00
|
|
|
WM_operatortype_append(WM_OT_radial_control);
|
2011-07-28 13:44:36 +00:00
|
|
|
WM_operatortype_append(WM_OT_ndof_sensitivity_change);
|
2010-11-11 20:32:28 +00:00
|
|
|
#if defined(WIN32)
|
2011-04-06 12:30:07 +00:00
|
|
|
WM_operatortype_append(WM_OT_console_toggle);
|
2010-10-18 20:41:52 +00:00
|
|
|
#endif
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
2010-04-02 03:52:44 +00:00
|
|
|
/* circleselect-like modal operators */
|
2009-11-05 17:32:06 +00:00
|
|
|
static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
{
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-27 01:24:16 +00:00
|
|
|
{GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
|
|
|
{GESTURE_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
|
|
|
{GESTURE_MODAL_CIRCLE_ADD, "ADD", 0, "Add", ""},
|
|
|
|
{GESTURE_MODAL_CIRCLE_SUB, "SUBTRACT", 0, "Subtract", ""},
|
2013-03-04 17:06:16 +00:00
|
|
|
{GESTURE_MODAL_CIRCLE_SIZE, "SIZE", 0, "Size", ""},
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
|
|
|
|
{GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""},
|
|
|
|
{GESTURE_MODAL_NOP, "NOP", 0, "No Operation", ""},
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2012-06-12 22:05:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
};
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2013-04-29 17:59:44 +00:00
|
|
|
/* WARNING - name is incorrect, use for non-3d views */
|
2012-03-27 01:24:16 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Gesture Circle");
|
2009-11-05 17:32:06 +00:00
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "View3D Gesture Circle", modal_items);
|
2009-11-05 17:32:06 +00:00
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
|
|
|
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
|
|
|
|
|
|
|
WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CONFIRM);
|
2009-11-06 12:43:20 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, 0, 0, GESTURE_MODAL_CONFIRM);
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2009-11-06 12:43:20 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_SELECT);
|
2009-11-05 17:32:06 +00:00
|
|
|
|
2013-06-19 15:20:50 +00:00
|
|
|
/* left mouse shift for deselect too */
|
2009-11-06 12:43:20 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_DESELECT);
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_NOP);
|
2013-06-19 15:20:50 +00:00
|
|
|
|
2011-10-17 06:39:13 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_DESELECT); // default 2.4x
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); // default 2.4x
|
2009-11-06 12:43:20 +00:00
|
|
|
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP);
|
2009-11-06 12:43:20 +00:00
|
|
|
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_SUB);
|
|
|
|
WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_SUB);
|
|
|
|
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_ADD);
|
|
|
|
WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_ADD);
|
2013-03-04 17:06:16 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, GESTURE_MODAL_CIRCLE_SIZE);
|
2009-11-05 17:32:06 +00:00
|
|
|
|
|
|
|
/* assign map to operators */
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle");
|
|
|
|
WM_modalkeymap_assign(keymap, "UV_OT_circle_select");
|
2011-11-07 12:55:18 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle");
|
2012-06-04 16:42:58 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "MASK_OT_select_circle");
|
2013-11-06 19:21:42 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "NODE_OT_select_circle");
|
2009-11-05 17:32:06 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-04-04 00:21:37 +00:00
|
|
|
/* straight line modal operators */
|
|
|
|
static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
{
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-27 01:24:16 +00:00
|
|
|
{GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
|
|
|
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
|
|
|
|
{GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""},
|
2012-06-12 22:05:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
};
|
2010-04-04 00:21:37 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Straight Line");
|
2010-04-04 00:21:37 +00:00
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2010-04-04 00:21:37 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "Gesture Straight Line", modal_items);
|
2010-04-04 00:21:37 +00:00
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
|
|
|
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
|
|
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_SELECT);
|
|
|
|
|
|
|
|
/* assign map to operators */
|
|
|
|
WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line");
|
2012-12-22 08:19:27 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "PAINT_OT_weight_gradient");
|
2013-08-29 18:45:04 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "MESH_OT_bisect");
|
2010-04-04 00:21:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-02 03:52:44 +00:00
|
|
|
/* borderselect-like modal operators */
|
2009-11-06 22:51:08 +00:00
|
|
|
static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
{
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-27 01:24:16 +00:00
|
|
|
{GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
|
|
|
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
|
|
|
|
{GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""},
|
|
|
|
{GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""},
|
2012-06-12 22:05:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
};
|
2009-11-06 22:51:08 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Border");
|
2009-11-06 22:51:08 +00:00
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2009-11-06 22:51:08 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "Gesture Border", modal_items);
|
2009-11-06 22:51:08 +00:00
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
2013-06-19 15:20:50 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
/* Note: cancel only on press otherwise you cannot map this to RMB-gesture */
|
2011-07-18 14:41:59 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
|
|
|
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
|
2009-11-06 22:51:08 +00:00
|
|
|
|
2013-06-19 15:20:50 +00:00
|
|
|
/* allow shift leftclick for deselect too */
|
2010-04-04 00:21:37 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN);
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_DESELECT);
|
2013-06-19 15:20:50 +00:00
|
|
|
|
|
|
|
/* any unhandled leftclick release handles select */
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
|
|
|
|
|
2010-04-04 00:21:37 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_DESELECT);
|
2013-06-19 15:20:50 +00:00
|
|
|
|
2009-11-06 22:51:08 +00:00
|
|
|
/* assign map to operators */
|
2009-11-28 14:37:21 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "ACTION_OT_select_border");
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "ANIM_OT_channels_select_border");
|
2009-11-17 10:12:35 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "ANIM_OT_previewrange_set");
|
2010-11-11 13:36:57 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "INFO_OT_select_border");
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "FILE_OT_select_border");
|
|
|
|
WM_modalkeymap_assign(keymap, "GRAPH_OT_select_border");
|
2009-11-19 10:48:59 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "MARKER_OT_select_border");
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "NLA_OT_select_border");
|
|
|
|
WM_modalkeymap_assign(keymap, "NODE_OT_select_border");
|
2013-03-07 17:47:30 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "NODE_OT_viewer_border");
|
2012-03-14 06:32:43 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "PAINT_OT_hide_show");
|
2012-01-18 21:12:51 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "OUTLINER_OT_select_border");
|
2009-11-19 10:48:59 +00:00
|
|
|
// WM_modalkeymap_assign(keymap, "SCREEN_OT_border_select"); // template
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "SEQUENCER_OT_select_border");
|
2010-07-08 10:03:29 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "SEQUENCER_OT_view_ghost_border");
|
2009-11-19 10:48:59 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "UV_OT_select_border");
|
2011-11-07 12:55:18 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "CLIP_OT_select_border");
|
2012-03-04 19:34:01 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_border");
|
2012-06-04 16:42:58 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "MASK_OT_select_border");
|
2009-11-28 02:53:11 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
|
2009-11-19 10:48:59 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border");
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border");
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_border");
|
2012-10-20 20:20:02 +00:00
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom_border"); /* XXX TODO: zoom border should perhaps map rightmouse to zoom out instead of in+cancel */
|
2009-11-06 22:51:08 +00:00
|
|
|
}
|
|
|
|
|
2010-04-02 03:52:44 +00:00
|
|
|
/* zoom to border modal operators */
|
|
|
|
static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
{
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-27 01:24:16 +00:00
|
|
|
{GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
|
|
|
{GESTURE_MODAL_IN, "IN", 0, "In", ""},
|
|
|
|
{GESTURE_MODAL_OUT, "OUT", 0, "Out", ""},
|
|
|
|
{GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""},
|
2012-06-12 22:05:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
};
|
2010-04-02 03:52:44 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Zoom Border");
|
2010-04-02 03:52:44 +00:00
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2010-04-02 03:52:44 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "Gesture Zoom Border", modal_items);
|
2010-04-02 03:52:44 +00:00
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
|
|
|
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL);
|
|
|
|
|
2010-04-04 00:21:37 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
|
2010-04-02 03:52:44 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_IN);
|
|
|
|
|
2010-04-04 00:21:37 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
|
2010-04-02 03:52:44 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_OUT);
|
|
|
|
|
|
|
|
/* assign map to operators */
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom_border");
|
|
|
|
}
|
|
|
|
|
2008-11-19 16:28:11 +00:00
|
|
|
/* default keymap for windows and screens, only call once per WM */
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
void wm_window_keymap(wmKeyConfig *keyconf)
|
2008-11-19 16:28:11 +00:00
|
|
|
{
|
2012-03-24 02:51:46 +00:00
|
|
|
wmKeyMap *keymap = WM_keymap_find(keyconf, "Window", 0, 0);
|
2009-12-24 09:36:15 +00:00
|
|
|
wmKeyMapItem *kmi;
|
2008-12-08 15:02:57 +00:00
|
|
|
|
2008-11-19 16:28:11 +00:00
|
|
|
/* note, this doesn't replace existing keymap items */
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
|
2013-12-22 14:11:10 +11:00
|
|
|
#ifdef __APPLE__
|
2009-09-09 19:43:05 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0);
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_keymap_add_menu(keymap, "INFO_MT_file_open_recent", OKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
|
2009-09-09 19:43:05 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_OSKEY, 0);
|
|
|
|
WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_OSKEY, 0);
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
|
2010-10-11 22:05:45 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_quit_blender", QKEY, KM_PRESS, KM_OSKEY, 0);
|
2013-12-22 14:11:10 +11:00
|
|
|
#endif
|
2009-09-09 15:45:12 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_CTRL, 0);
|
|
|
|
WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_keymap_add_menu(keymap, "INFO_MT_file_open_recent", OKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
|
2009-09-09 15:45:12 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0);
|
2009-10-19 17:10:16 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_open_mainfile", F1KEY, KM_PRESS, 0, 0);
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
|
2012-03-24 02:51:46 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_link_append", F1KEY, KM_PRESS, KM_SHIFT, 0);
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_boolean_set(kmi->ptr, "link", FALSE);
|
2010-04-06 01:16:39 +00:00
|
|
|
RNA_boolean_set(kmi->ptr, "instance_groups", FALSE);
|
2009-11-03 11:00:10 +00:00
|
|
|
|
2009-09-09 15:45:12 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0);
|
2009-10-19 17:10:16 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_save_mainfile", WKEY, KM_PRESS, KM_CTRL, 0);
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
|
2009-10-19 17:10:16 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", F2KEY, KM_PRESS, 0, 0);
|
2012-03-27 01:24:16 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
|
2012-01-16 09:51:04 +00:00
|
|
|
RNA_boolean_set(kmi->ptr, "copy", TRUE);
|
2009-09-09 19:43:05 +00:00
|
|
|
|
2009-10-13 17:50:14 +00:00
|
|
|
WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_ALT, 0);
|
2010-10-11 22:05:45 +00:00
|
|
|
WM_keymap_add_item(keymap, "WM_OT_quit_blender", QKEY, KM_PRESS, KM_CTRL, 0);
|
2009-01-28 18:26:47 +00:00
|
|
|
|
2009-05-22 15:02:32 +00:00
|
|
|
/* debug/testing */
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_keymap_verify_item(keymap, "WM_OT_redraw_timer", TKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
|
|
|
|
WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2011-07-23 21:55:52 +00:00
|
|
|
/* menus that can be accessed anywhere in blender */
|
|
|
|
WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0);
|
2011-08-05 14:53:13 +00:00
|
|
|
WM_keymap_add_menu(keymap, "USERPREF_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0);
|
2009-10-13 17:50:14 +00:00
|
|
|
|
|
|
|
/* Space switching */
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "LOGIC_EDITOR");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F3KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "NODE_EDITOR");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F4KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was data browser */
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "CONSOLE");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F5KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "VIEW_3D");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F6KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "GRAPH_EDITOR");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F7KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "PROPERTIES");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F8KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "SEQUENCE_EDITOR");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F9KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "OUTLINER");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F10KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "IMAGE_EDITOR");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F11KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "TEXT_EDITOR");
|
2009-10-13 17:50:14 +00:00
|
|
|
|
2009-12-24 09:36:15 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F12KEY, KM_PRESS, KM_SHIFT, 0);
|
2010-06-14 03:52:10 +00:00
|
|
|
RNA_string_set(kmi->ptr, "data_path", "area.type");
|
2009-12-24 09:36:15 +00:00
|
|
|
RNA_string_set(kmi->ptr, "value", "DOPESHEET_EDITOR");
|
2011-07-28 13:44:36 +00:00
|
|
|
|
|
|
|
/* ndof speed */
|
2012-03-24 02:51:46 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_PLUS, KM_PRESS, 0, 0);
|
2011-07-28 13:44:36 +00:00
|
|
|
RNA_boolean_set(kmi->ptr, "decrease", FALSE);
|
|
|
|
RNA_boolean_set(kmi->ptr, "fast", FALSE);
|
|
|
|
|
2012-03-24 02:51:46 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_MINUS, KM_PRESS, 0, 0);
|
2011-07-28 13:44:36 +00:00
|
|
|
RNA_boolean_set(kmi->ptr, "decrease", TRUE);
|
|
|
|
RNA_boolean_set(kmi->ptr, "fast", FALSE);
|
|
|
|
|
2012-03-24 02:51:46 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_PLUS, KM_PRESS, KM_SHIFT, 0);
|
2011-07-28 13:44:36 +00:00
|
|
|
RNA_boolean_set(kmi->ptr, "decrease", FALSE);
|
|
|
|
RNA_boolean_set(kmi->ptr, "fast", TRUE);
|
|
|
|
|
2012-03-24 02:51:46 +00:00
|
|
|
kmi = WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_MINUS, KM_PRESS, KM_SHIFT, 0);
|
2011-07-28 13:44:36 +00:00
|
|
|
RNA_boolean_set(kmi->ptr, "decrease", TRUE);
|
|
|
|
RNA_boolean_set(kmi->ptr, "fast", TRUE);
|
2009-11-05 17:32:06 +00:00
|
|
|
|
|
|
|
gesture_circle_modal_keymap(keyconf);
|
2009-11-06 22:51:08 +00:00
|
|
|
gesture_border_modal_keymap(keyconf);
|
2010-04-02 03:52:44 +00:00
|
|
|
gesture_zoom_border_modal_keymap(keyconf);
|
2010-04-04 00:21:37 +00:00
|
|
|
gesture_straightline_modal_keymap(keyconf);
|
2.5 Branch
==========
* Changed wmOperatorType, removing init/exit callbacks and adding cancel
callback, removed default storage in favor of properties. Defined return
values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
handlers. Now it frees based on return values from callbacks, and just
keeps a wmOperator on the heap. Also it now registers after the operator
is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
otherwise, gives more readable code in my opinion. Added OP_verify_*
functions to quickly check if the property is available and set if it's
not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
which takes a function pointer instead of a list, avoids macro's and
duplicating code.
* Fix a crash where the handler would still be used while it was freed by
the operator.
* Spacetypes now have operatortypes() and keymap() callbacks to abstract
them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
leaving that context, instead of leaving the pointers there.
* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
give link errors.
* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
the frame.
2008-06-11 10:10:31 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 10:25:57 +00:00
|
|
|
/* Generic itemf's for operators that take library args */
|
2014-01-04 18:08:43 +11:00
|
|
|
static EnumPropertyItem *rna_id_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), bool *r_free, ID *id, bool local)
|
2009-11-04 10:25:57 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
EnumPropertyItem item_tmp = {0}, *item = NULL;
|
|
|
|
int totitem = 0;
|
|
|
|
int i = 0;
|
2009-11-04 10:25:57 +00:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
for (; id; id = id->next) {
|
2014-01-04 18:08:43 +11:00
|
|
|
if (local == false || id->lib == NULL) {
|
2012-03-27 01:24:16 +00:00
|
|
|
item_tmp.identifier = item_tmp.name = id->name + 2;
|
|
|
|
item_tmp.value = i++;
|
2010-05-05 15:41:38 +00:00
|
|
|
RNA_enum_item_add(&item, &totitem, &item_tmp);
|
|
|
|
}
|
2009-11-04 10:25:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
RNA_enum_item_end(&item, &totitem);
|
2014-01-04 18:08:43 +11:00
|
|
|
*r_free = true;
|
2009-11-04 10:25:57 +00:00
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
2010-02-23 19:32:32 +00:00
|
|
|
/* can add more as needed */
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_action_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2010-02-23 19:32:32 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, FALSE);
|
2010-05-05 15:41:38 +00:00
|
|
|
}
|
2012-04-23 07:32:13 +00:00
|
|
|
#if 0 /* UNUSED */
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_action_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2010-05-05 15:41:38 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, TRUE);
|
2010-02-23 19:32:32 +00:00
|
|
|
}
|
2012-04-23 07:32:13 +00:00
|
|
|
#endif
|
2010-05-05 15:41:38 +00:00
|
|
|
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_group_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2009-11-04 10:25:57 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, FALSE);
|
2010-05-05 15:41:38 +00:00
|
|
|
}
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_group_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2010-05-05 15:41:38 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, TRUE);
|
2009-11-04 10:25:57 +00:00
|
|
|
}
|
2010-05-05 15:41:38 +00:00
|
|
|
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_image_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2010-03-05 18:19:32 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, FALSE);
|
2010-05-05 15:41:38 +00:00
|
|
|
}
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_image_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2010-05-05 15:41:38 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, TRUE);
|
2010-03-05 18:19:32 +00:00
|
|
|
}
|
2010-05-05 15:41:38 +00:00
|
|
|
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_scene_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2009-11-04 10:25:57 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, FALSE);
|
2010-05-05 15:41:38 +00:00
|
|
|
}
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_scene_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2010-05-05 15:41:38 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, TRUE);
|
2009-11-04 10:25:57 +00:00
|
|
|
}
|
2012-03-21 18:02:29 +00:00
|
|
|
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_movieclip_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2012-03-21 18:02:29 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, FALSE);
|
2012-03-21 18:02:29 +00:00
|
|
|
}
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_movieclip_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2012-03-21 18:02:29 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, TRUE);
|
2012-03-21 18:02:29 +00:00
|
|
|
}
|
2012-06-07 18:24:36 +00:00
|
|
|
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_mask_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2012-06-07 18:24:36 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, FALSE);
|
2012-06-07 18:24:36 +00:00
|
|
|
}
|
2014-01-04 18:08:43 +11:00
|
|
|
EnumPropertyItem *RNA_mask_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
2012-06-07 18:24:36 +00:00
|
|
|
{
|
2014-01-04 18:08:43 +11:00
|
|
|
return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, TRUE);
|
2012-06-07 18:24:36 +00:00
|
|
|
}
|
|
|
|
|