2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2007-12-24 18:27:28 +00:00
|
|
|
* 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
|
2018-06-01 18:19:39 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2007-12-24 18:27:28 +00:00
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup wm
|
2014-01-19 23:14:24 +11:00
|
|
|
*
|
2021-03-12 00:46:41 +11:00
|
|
|
* Internal functions for managing UI registerable types (operator, UI and menu types).
|
2014-01-19 23:14:24 +11:00
|
|
|
*
|
2020-10-14 15:04:49 -05:00
|
|
|
* Also Blender's main event loop (WM_main).
|
2011-02-25 14:04:21 +00:00
|
|
|
*/
|
|
|
|
|
|
2020-11-06 13:04:44 +01:00
|
|
|
/* Allow using deprecated functionality for .blend file I/O. */
|
|
|
|
|
#define DNA_DEPRECATED_ALLOW
|
|
|
|
|
|
2010-08-13 06:30:04 +00:00
|
|
|
#include <stddef.h>
|
2020-03-19 09:33:03 +01:00
|
|
|
#include <string.h>
|
2009-10-08 19:06:32 +00:00
|
|
|
|
2013-05-28 19:35:26 +00:00
|
|
|
#include "BLI_sys_types.h"
|
2010-08-31 11:31:21 +00:00
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "DNA_windowmanager_types.h"
|
|
|
|
|
|
2011-08-11 06:06:17 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "BLI_blenlib.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2020-03-09 11:17:37 +01:00
|
|
|
#include "BLT_translation.h"
|
|
|
|
|
|
2008-12-18 02:56:48 +00:00
|
|
|
#include "BKE_context.h"
|
2018-11-07 18:00:24 +01:00
|
|
|
#include "BKE_global.h"
|
2008-12-29 13:38:08 +00:00
|
|
|
#include "BKE_idprop.h"
|
2020-03-09 11:17:37 +01:00
|
|
|
#include "BKE_idtype.h"
|
2020-02-10 12:58:59 +01:00
|
|
|
#include "BKE_lib_id.h"
|
2020-05-18 18:51:06 +02:00
|
|
|
#include "BKE_lib_query.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
#include "BKE_main.h"
|
2008-12-29 13:38:08 +00:00
|
|
|
#include "BKE_report.h"
|
2020-05-18 18:51:06 +02:00
|
|
|
#include "BKE_screen.h"
|
2017-11-09 05:37:09 +01:00
|
|
|
#include "BKE_workspace.h"
|
2007-12-24 18:27:28 +00:00
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
2017-11-13 19:43:34 +11:00
|
|
|
#include "WM_message.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "WM_types.h"
|
2008-10-03 18:03:30 +00:00
|
|
|
#include "wm.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "wm_draw.h"
|
|
|
|
|
#include "wm_event_system.h"
|
|
|
|
|
#include "wm_window.h"
|
2020-04-04 02:17:49 +02:00
|
|
|
#ifdef WITH_XR_OPENXR
|
|
|
|
|
# include "wm_xr.h"
|
|
|
|
|
#endif
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2018-03-19 14:17:59 +01:00
|
|
|
#include "BKE_undo_system.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "ED_screen.h"
|
2008-01-07 18:03:41 +00:00
|
|
|
|
2010-10-31 04:11:39 +00:00
|
|
|
#ifdef WITH_PYTHON
|
2010-09-12 12:09:31 +00:00
|
|
|
# include "BPY_extern.h"
|
2020-08-17 17:46:06 +10:00
|
|
|
# include "BPY_extern_run.h"
|
2010-09-12 12:09:31 +00:00
|
|
|
#endif
|
2009-01-01 20:44:40 +00:00
|
|
|
|
2020-11-06 13:04:44 +01:00
|
|
|
#include "BLO_read_write.h"
|
|
|
|
|
|
2007-12-24 18:27:28 +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
|
|
|
|
2020-03-09 11:17:37 +01:00
|
|
|
static void window_manager_free_data(ID *id)
|
|
|
|
|
{
|
|
|
|
|
wm_close_and_free(NULL, (wmWindowManager *)id);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-18 18:51:06 +02:00
|
|
|
static void window_manager_foreach_id(ID *id, LibraryForeachIDData *data)
|
|
|
|
|
{
|
|
|
|
|
wmWindowManager *wm = (wmWindowManager *)id;
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
|
|
|
|
BKE_LIB_FOREACHID_PROCESS(data, win->scene, IDWALK_CB_USER_ONE);
|
|
|
|
|
|
|
|
|
|
/* This pointer can be NULL during old files reading, better be safe than sorry. */
|
|
|
|
|
if (win->workspace_hook != NULL) {
|
|
|
|
|
ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
|
|
|
|
|
BKE_LIB_FOREACHID_PROCESS_ID(data, workspace, IDWALK_CB_NOP);
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Allow callback to set a different workspace. */
|
2020-05-18 18:51:06 +02:00
|
|
|
BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
|
|
|
|
|
}
|
|
|
|
|
if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
|
|
|
|
|
BKE_screen_foreach_id_screen_area(data, area);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-06 13:04:44 +01:00
|
|
|
static void write_wm_xr_data(BlendWriter *writer, wmXrData *xr_data)
|
|
|
|
|
{
|
|
|
|
|
BKE_screen_view3d_shading_blend_write(writer, &xr_data->session_settings.shading);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void window_manager_blend_write(BlendWriter *writer, ID *id, const void *id_address)
|
|
|
|
|
{
|
|
|
|
|
wmWindowManager *wm = (wmWindowManager *)id;
|
|
|
|
|
|
|
|
|
|
BLO_write_id_struct(writer, wmWindowManager, id_address, &wm->id);
|
|
|
|
|
BKE_id_blend_write(writer, &wm->id);
|
|
|
|
|
write_wm_xr_data(writer, &wm->xr);
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
|
|
|
|
/* update deprecated screen member (for so loading in 2.7x uses the correct screen) */
|
|
|
|
|
win->screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
|
|
|
|
|
|
|
|
|
BLO_write_struct(writer, wmWindow, win);
|
|
|
|
|
BLO_write_struct(writer, WorkSpaceInstanceHook, win->workspace_hook);
|
|
|
|
|
BLO_write_struct(writer, Stereo3dFormat, win->stereo3d_format);
|
|
|
|
|
|
|
|
|
|
BKE_screen_area_map_blend_write(writer, &win->global_areas);
|
|
|
|
|
|
|
|
|
|
/* data is written, clear deprecated data again */
|
|
|
|
|
win->screen = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void direct_link_wm_xr_data(BlendDataReader *reader, wmXrData *xr_data)
|
|
|
|
|
{
|
|
|
|
|
BKE_screen_view3d_shading_blend_read_data(reader, &xr_data->session_settings.shading);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void window_manager_blend_read_data(BlendDataReader *reader, ID *id)
|
|
|
|
|
{
|
|
|
|
|
wmWindowManager *wm = (wmWindowManager *)id;
|
|
|
|
|
|
|
|
|
|
id_us_ensure_real(&wm->id);
|
|
|
|
|
BLO_read_list(reader, &wm->windows);
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
|
|
|
|
BLO_read_data_address(reader, &win->parent);
|
|
|
|
|
|
|
|
|
|
WorkSpaceInstanceHook *hook = win->workspace_hook;
|
|
|
|
|
BLO_read_data_address(reader, &win->workspace_hook);
|
|
|
|
|
|
|
|
|
|
/* This will be NULL for any pre-2.80 blend file. */
|
|
|
|
|
if (win->workspace_hook != NULL) {
|
|
|
|
|
/* We need to restore a pointer to this later when reading workspaces,
|
|
|
|
|
* so store in global oldnew-map.
|
|
|
|
|
* Note that this is only needed for versioning of older .blend files now.. */
|
|
|
|
|
BLO_read_data_globmap_add(reader, hook, win->workspace_hook);
|
|
|
|
|
/* Cleanup pointers to data outside of this data-block scope. */
|
|
|
|
|
win->workspace_hook->act_layout = NULL;
|
|
|
|
|
win->workspace_hook->temp_workspace_store = NULL;
|
|
|
|
|
win->workspace_hook->temp_layout_store = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BKE_screen_area_map_blend_read_data(reader, &win->global_areas);
|
|
|
|
|
|
|
|
|
|
win->ghostwin = NULL;
|
|
|
|
|
win->gpuctx = NULL;
|
|
|
|
|
win->eventstate = NULL;
|
|
|
|
|
win->cursor_keymap_status = NULL;
|
|
|
|
|
win->tweak = NULL;
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
win->ime_data = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-03-05 14:54:29 +11:00
|
|
|
BLI_listbase_clear(&win->event_queue);
|
2020-11-06 13:04:44 +01:00
|
|
|
BLI_listbase_clear(&win->handlers);
|
|
|
|
|
BLI_listbase_clear(&win->modalhandlers);
|
|
|
|
|
BLI_listbase_clear(&win->gesture);
|
|
|
|
|
|
|
|
|
|
win->active = 0;
|
|
|
|
|
|
|
|
|
|
win->cursor = 0;
|
|
|
|
|
win->lastcursor = 0;
|
|
|
|
|
win->modalcursor = 0;
|
|
|
|
|
win->grabcursor = 0;
|
|
|
|
|
win->addmousemove = true;
|
2021-03-05 17:09:01 +11:00
|
|
|
win->event_queue_check_click = 0;
|
|
|
|
|
win->event_queue_check_drag = 0;
|
2021-04-16 23:46:21 +10:00
|
|
|
win->event_queue_check_drag_handled = 0;
|
2020-11-06 13:04:44 +01:00
|
|
|
BLO_read_data_address(reader, &win->stereo3d_format);
|
|
|
|
|
|
|
|
|
|
/* Multi-view always fallback to anaglyph at file opening
|
|
|
|
|
* otherwise quad-buffer saved files can break Blender. */
|
|
|
|
|
if (win->stereo3d_format) {
|
|
|
|
|
win->stereo3d_format->display_mode = S3D_DISPLAY_ANAGLYPH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
direct_link_wm_xr_data(reader, &wm->xr);
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&wm->timers);
|
|
|
|
|
BLI_listbase_clear(&wm->operators);
|
|
|
|
|
BLI_listbase_clear(&wm->paintcursors);
|
2021-03-05 14:54:29 +11:00
|
|
|
BLI_listbase_clear(&wm->notifier_queue);
|
2020-11-06 13:04:44 +01:00
|
|
|
BKE_reports_init(&wm->reports, RPT_STORE);
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&wm->keyconfigs);
|
|
|
|
|
wm->defaultconf = NULL;
|
|
|
|
|
wm->addonconf = NULL;
|
|
|
|
|
wm->userconf = NULL;
|
|
|
|
|
wm->undo_stack = NULL;
|
|
|
|
|
|
|
|
|
|
wm->message_bus = NULL;
|
|
|
|
|
|
|
|
|
|
wm->xr.runtime = NULL;
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&wm->jobs);
|
|
|
|
|
BLI_listbase_clear(&wm->drags);
|
|
|
|
|
|
|
|
|
|
wm->windrawable = NULL;
|
|
|
|
|
wm->winactive = NULL;
|
|
|
|
|
wm->initialized = 0;
|
|
|
|
|
wm->op_undo_depth = 0;
|
|
|
|
|
wm->is_interface_locked = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_wm_xr_data(BlendLibReader *reader, ID *parent_id, wmXrData *xr_data)
|
|
|
|
|
{
|
|
|
|
|
BLO_read_id_address(reader, parent_id->lib, &xr_data->session_settings.base_pose_object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lib_link_workspace_instance_hook(BlendLibReader *reader,
|
|
|
|
|
WorkSpaceInstanceHook *hook,
|
|
|
|
|
ID *id)
|
|
|
|
|
{
|
|
|
|
|
WorkSpace *workspace = BKE_workspace_active_get(hook);
|
|
|
|
|
BLO_read_id_address(reader, id->lib, &workspace);
|
|
|
|
|
BKE_workspace_active_set(hook, workspace);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void window_manager_blend_read_lib(BlendLibReader *reader, ID *id)
|
|
|
|
|
{
|
|
|
|
|
wmWindowManager *wm = (wmWindowManager *)id;
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
|
|
|
|
if (win->workspace_hook) { /* NULL for old files */
|
|
|
|
|
lib_link_workspace_instance_hook(reader, win->workspace_hook, &wm->id);
|
|
|
|
|
}
|
|
|
|
|
BLO_read_id_address(reader, wm->id.lib, &win->scene);
|
|
|
|
|
/* deprecated, but needed for versioning (will be NULL'ed then) */
|
|
|
|
|
BLO_read_id_address(reader, NULL, &win->screen);
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
|
|
|
|
|
BKE_screen_area_blend_read_lib(reader, &wm->id, area);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lib_link_wm_xr_data(reader, &wm->id, &wm->xr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-09 11:17:37 +01:00
|
|
|
IDTypeInfo IDType_ID_WM = {
|
|
|
|
|
.id_code = ID_WM,
|
|
|
|
|
.id_filter = 0,
|
|
|
|
|
.main_listbase_index = INDEX_ID_WM,
|
|
|
|
|
.struct_size = sizeof(wmWindowManager),
|
|
|
|
|
.name = "WindowManager",
|
|
|
|
|
.name_plural = "window_managers",
|
|
|
|
|
.translation_context = BLT_I18NCONTEXT_ID_WINDOWMANAGER,
|
2020-10-07 12:35:58 +02:00
|
|
|
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING | IDTYPE_FLAGS_NO_MAKELOCAL |
|
|
|
|
|
IDTYPE_FLAGS_NO_ANIMDATA,
|
2020-03-09 11:17:37 +01:00
|
|
|
|
|
|
|
|
.init_data = NULL,
|
|
|
|
|
.copy_data = NULL,
|
|
|
|
|
.free_data = window_manager_free_data,
|
|
|
|
|
.make_local = NULL,
|
2020-05-18 18:51:06 +02:00
|
|
|
.foreach_id = window_manager_foreach_id,
|
2020-08-28 13:05:48 +02:00
|
|
|
.foreach_cache = NULL,
|
2021-02-25 10:17:31 +01:00
|
|
|
.owner_get = NULL,
|
2020-08-28 13:05:48 +02:00
|
|
|
|
2020-11-06 13:04:44 +01:00
|
|
|
.blend_write = window_manager_blend_write,
|
|
|
|
|
.blend_read_data = window_manager_blend_read_data,
|
|
|
|
|
.blend_read_lib = window_manager_blend_read_lib,
|
2020-08-28 13:05:48 +02:00
|
|
|
.blend_read_expand = NULL,
|
2020-11-03 11:39:36 +01:00
|
|
|
|
|
|
|
|
.blend_read_undo_preserve = NULL,
|
2021-01-22 14:52:50 +01:00
|
|
|
|
|
|
|
|
.lib_override_apply_post = NULL,
|
2020-03-09 11:17:37 +01:00
|
|
|
};
|
|
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
#define MAX_OP_REGISTERED 32
|
2007-12-24 18:27:28 +00:00
|
|
|
|
2008-12-24 14:52:17 +00:00
|
|
|
void WM_operator_free(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
|
|
|
{
|
2010-03-23 21:37:02 +00:00
|
|
|
|
2010-10-31 04:11:39 +00:00
|
|
|
#ifdef WITH_PYTHON
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->py_instance) {
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Do this first in case there are any __del__ functions or similar that use properties. */
|
2012-10-26 10:54:02 +00:00
|
|
|
BPY_DECREF_RNA_INVALIDATE(op->py_instance);
|
2010-02-27 14:44:46 +00:00
|
|
|
}
|
2010-03-23 21:37:02 +00:00
|
|
|
#endif
|
2010-02-27 14:44:46 +00:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->ptr) {
|
2012-03-27 01:24:16 +00:00
|
|
|
op->properties = op->ptr->data;
|
2009-01-01 20:44:40 +00:00
|
|
|
MEM_freeN(op->ptr);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->properties) {
|
2008-11-21 19:14:38 +00:00
|
|
|
IDP_FreeProperty(op->properties);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->reports && (op->reports->flag & RPT_FREE)) {
|
2008-12-29 13:38:08 +00:00
|
|
|
BKE_reports_clear(op->reports);
|
|
|
|
|
MEM_freeN(op->reports);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
if (op->macro.first) {
|
2009-09-14 05:00:03 +00:00
|
|
|
wmOperator *opm, *opmnext;
|
2012-03-27 01:24:16 +00:00
|
|
|
for (opm = op->macro.first; opm; opm = opmnext) {
|
2009-09-14 05:00:03 +00:00
|
|
|
opmnext = 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
|
|
|
WM_operator_free(opm);
|
2009-09-14 05:00:03 +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
|
|
|
}
|
2019-04-17 06:17:24 +02: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
|
|
|
MEM_freeN(op);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-15 05:16:07 +11:00
|
|
|
void WM_operator_free_all_after(wmWindowManager *wm, struct wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
op = op->next;
|
|
|
|
|
while (op != NULL) {
|
|
|
|
|
wmOperator *op_next = op->next;
|
|
|
|
|
BLI_remlink(&wm->operators, op);
|
|
|
|
|
WM_operator_free(op);
|
|
|
|
|
op = op_next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-30 03:44:03 +00:00
|
|
|
/**
|
|
|
|
|
* Use with extreme care!,
|
2020-07-01 13:12:24 +10:00
|
|
|
* properties, custom-data etc - must be compatible.
|
2013-04-30 03:44:03 +00:00
|
|
|
*
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param op: Operator to assign the type to.
|
2020-07-01 13:12:24 +10:00
|
|
|
* \param ot: Operator type to assign.
|
2013-04-30 03:44:03 +00:00
|
|
|
*/
|
|
|
|
|
void WM_operator_type_set(wmOperator *op, wmOperatorType *ot)
|
|
|
|
|
{
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Not supported for Python. */
|
2013-04-30 03:44:03 +00:00
|
|
|
BLI_assert(op->py_instance == NULL);
|
|
|
|
|
|
|
|
|
|
op->type = ot;
|
|
|
|
|
op->ptr->type = ot->srna;
|
2013-12-13 00:28:35 +11:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Ensure compatible properties. */
|
2013-12-13 00:28:35 +11:00
|
|
|
if (op->properties) {
|
|
|
|
|
PointerRNA ptr;
|
|
|
|
|
WM_operator_properties_create_ptr(&ptr, ot);
|
|
|
|
|
|
|
|
|
|
WM_operator_properties_default(&ptr, false);
|
|
|
|
|
|
|
|
|
|
if (ptr.data) {
|
|
|
|
|
IDP_SyncGroupTypes(op->properties, ptr.data, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_operator_properties_free(&ptr);
|
|
|
|
|
}
|
2013-04-30 03:44:03 +00:00
|
|
|
}
|
|
|
|
|
|
2010-06-03 07:27:55 +00:00
|
|
|
static void wm_reports_free(wmWindowManager *wm)
|
|
|
|
|
{
|
|
|
|
|
BKE_reports_clear(&wm->reports);
|
|
|
|
|
WM_event_remove_timer(wm, NULL, wm->reports.reporttimer);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* All operations get registered in the windowmanager here. */
|
|
|
|
|
/* Called on event handling by event_system.c. */
|
2009-07-16 00:50:27 +00:00
|
|
|
void wm_operator_register(bContext *C, wmOperator *op)
|
2007-12-24 18:27:28 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2017-03-15 02:37:33 +11:00
|
|
|
int tot = 0;
|
2019-04-17 06:17:24 +02: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
|
|
|
BLI_addtail(&wm->operators, op);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Only count registered operators. */
|
2017-03-15 02:37:33 +11:00
|
|
|
while (op) {
|
|
|
|
|
wmOperator *op_prev = op->prev;
|
|
|
|
|
if (op->type->flag & OPTYPE_REGISTER) {
|
|
|
|
|
tot += 1;
|
|
|
|
|
}
|
|
|
|
|
if (tot > MAX_OP_REGISTERED) {
|
|
|
|
|
BLI_remlink(&wm->operators, op);
|
|
|
|
|
WM_operator_free(op);
|
|
|
|
|
}
|
|
|
|
|
op = op_prev;
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* So the console is redrawn. */
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
|
|
|
|
|
WM_event_add_notifier(C, NC_WM | ND_HISTORY, NULL);
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
2011-05-18 10:56:26 +00:00
|
|
|
void WM_operator_stack_clear(wmWindowManager *wm)
|
2009-06-26 15:48:09 +00:00
|
|
|
{
|
|
|
|
|
wmOperator *op;
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2013-08-26 23:37:08 +00:00
|
|
|
while ((op = BLI_pophead(&wm->operators))) {
|
2009-06-26 15:48:09 +00:00
|
|
|
WM_operator_free(op);
|
|
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
WM_main_add_notifier(NC_WM | ND_HISTORY, NULL);
|
2009-06-26 15:48:09 +00:00
|
|
|
}
|
|
|
|
|
|
2013-01-22 06:16:49 +00:00
|
|
|
/**
|
|
|
|
|
* This function is needed in the case when an addon id disabled
|
|
|
|
|
* while a modal operator it defined is running.
|
|
|
|
|
*/
|
|
|
|
|
void WM_operator_handlers_clear(wmWindowManager *wm, wmOperatorType *ot)
|
|
|
|
|
{
|
2020-10-17 16:36:02 -05:00
|
|
|
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
2013-01-22 06:16:49 +00:00
|
|
|
ListBase *lb[2] = {&win->handlers, &win->modalhandlers};
|
2019-02-19 15:18:56 +11:00
|
|
|
for (int i = 0; i < ARRAY_SIZE(lb); i++) {
|
2019-02-20 09:19:07 +11:00
|
|
|
LISTBASE_FOREACH (wmEventHandler *, handler_base, lb[i]) {
|
2019-02-19 15:18:56 +11:00
|
|
|
if (handler_base->type == WM_HANDLER_TYPE_OP) {
|
|
|
|
|
wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
|
|
|
|
|
if (handler->op && handler->op->type == ot) {
|
|
|
|
|
/* don't run op->cancel because it needs the context,
|
|
|
|
|
* assume whoever unregisters the operator will cleanup */
|
2019-02-20 09:43:29 +11:00
|
|
|
handler->head.flag |= WM_HANDLER_DO_FREE;
|
2019-02-19 15:18:56 +11:00
|
|
|
WM_operator_free(handler->op);
|
|
|
|
|
handler->op = NULL;
|
|
|
|
|
}
|
2013-01-22 06:16:49 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
|
2009-10-08 19:06:32 +00:00
|
|
|
/* ****************************************** */
|
|
|
|
|
|
2018-11-13 19:02:12 +01:00
|
|
|
void WM_keyconfig_reload(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
if (CTX_py_init_get(C) && !G.background) {
|
2019-04-15 08:40:15 +02:00
|
|
|
#ifdef WITH_PYTHON
|
2020-08-17 18:16:54 +10:00
|
|
|
BPY_run_string_eval(C, (const char *[]){"bpy", NULL}, "bpy.utils.keyconfig_init()");
|
2019-04-15 08:40:15 +02:00
|
|
|
#endif
|
2018-11-13 19:02:12 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WM_keyconfig_init(bContext *C)
|
2009-07-18 19:40:26 +00:00
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Create standard key configs. */
|
2018-11-19 13:07:57 +11:00
|
|
|
if (wm->defaultconf == NULL) {
|
|
|
|
|
/* Keep lowercase to match the preset filename. */
|
2018-11-19 13:16:18 +11:00
|
|
|
wm->defaultconf = WM_keyconfig_new(wm, WM_KEYCONFIG_STR_DEFAULT, false);
|
2018-11-19 13:07:57 +11:00
|
|
|
}
|
|
|
|
|
if (wm->addonconf == NULL) {
|
2018-11-19 13:16:18 +11:00
|
|
|
wm->addonconf = WM_keyconfig_new(wm, WM_KEYCONFIG_STR_DEFAULT " addon", false);
|
2018-11-19 13:07:57 +11:00
|
|
|
}
|
|
|
|
|
if (wm->userconf == NULL) {
|
2018-11-19 13:16:18 +11:00
|
|
|
wm->userconf = WM_keyconfig_new(wm, WM_KEYCONFIG_STR_DEFAULT " user", false);
|
2018-11-19 13:07:57 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Initialize only after python init is done, for keymaps that use python operators. */
|
2020-08-01 13:02:21 +10:00
|
|
|
if (CTX_py_init_get(C) && (wm->initialized & WM_KEYCONFIG_IS_INIT) == 0) {
|
2011-09-29 13:52:58 +00:00
|
|
|
/* create default key config, only initialize once,
|
2012-03-09 18:28:30 +00:00
|
|
|
* it's persistent across sessions */
|
2012-03-24 06:24:53 +00:00
|
|
|
if (!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) {
|
2011-09-29 13:52:58 +00:00
|
|
|
wm_window_keymap(wm->defaultconf);
|
|
|
|
|
ED_spacetypes_keymap(wm->defaultconf);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-13 19:02:12 +01:00
|
|
|
WM_keyconfig_reload(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-09-29 13:52:58 +00:00
|
|
|
wm->defaultconf->flag |= KEYCONF_INIT_DEFAULT;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-03-14 18:00:15 +11:00
|
|
|
/* Harmless, but no need to update in background mode. */
|
|
|
|
|
if (!G.background) {
|
|
|
|
|
WM_keyconfig_update_tag(NULL, NULL);
|
|
|
|
|
}
|
KEYMAP REFACTORING
Diff Keymaps
User edited keymaps now no longer override the builtin keymaps entirely, but
rather save only the difference and reapply those changes. This means they can
stay better in sync when the builtin keymaps change. The diff/patch algorithm
is not perfect, but better for the common case where only a few items are changed
rather than entire keymaps The main weakness is that if a builtin keymap item
changes, user modification of that item may need to be redone in some cases.
Keymap Editor
The most noticeable change here is that there is no longer an "Edit" button for
keymaps, all are editable immediately, but a "Restore" buttons shows for keymaps
and items that have been edited. Shortcuts for addons can also be edited in the
keymap editor.
Addons
Addons now should only modify the new addon keyconfiguration, the keymap items
there will be added to the builtin ones for handling events, and not get lost
when starting new files. Example code of register/unregister:
km = wm.keyconfigs.addon.keymaps.new("3D View", space_type="VIEW_3D")
km.keymap_items.new('my.operator', 'ESC', 'PRESS')
km = wm.keyconfigs.addon.keymaps["3D View"]
km.keymap_items.remove(km.keymap_items["my.operator"])
Compatibility
The changes made are not forward compatible, i.e. if you save user preferences
with newer versions, older versions will not have key configuration changes that
were made.
2011-08-05 20:45:26 +00:00
|
|
|
WM_keyconfig_update(wm);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-01 13:02:21 +10:00
|
|
|
wm->initialized |= WM_KEYCONFIG_IS_INIT;
|
2009-07-18 19:40:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-11 04:08:09 +00:00
|
|
|
void WM_check(bContext *C)
|
2007-12-24 18:27:28 +00:00
|
|
|
{
|
2018-06-06 15:50:24 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* WM context. */
|
2012-03-27 01:24:16 +00:00
|
|
|
if (wm == NULL) {
|
2020-02-19 15:06:14 +11:00
|
|
|
wm = bmain->wm.first;
|
2008-12-18 02:56:48 +00:00
|
|
|
CTX_wm_manager_set(C, wm);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-08 06:07:10 +11:00
|
|
|
if (wm == NULL || BLI_listbase_is_empty(&wm->windows)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-01-28 16:44:24 +11:00
|
|
|
/* Run before loading the keyconfig. */
|
|
|
|
|
if (wm->message_bus == NULL) {
|
|
|
|
|
wm->message_bus = WM_msgbus_create();
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-11 04:08:09 +00:00
|
|
|
if (!G.background) {
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Case: fileread. */
|
2020-08-01 13:02:21 +10:00
|
|
|
if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
|
2018-11-13 19:02:12 +01:00
|
|
|
WM_keyconfig_init(C);
|
2009-12-08 17:23:48 +00:00
|
|
|
WM_autosave_init(wm);
|
2009-11-11 04:08:09 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Case: no open windows at all, for old file reads. */
|
2015-10-07 00:27:27 +11:00
|
|
|
wm_window_ghostwindows_ensure(wm);
|
2010-10-27 16:05:31 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Case: fileread. */
|
|
|
|
|
/* Note: this runs in background mode to set the screen context cb. */
|
2020-08-01 13:02:21 +10:00
|
|
|
if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
|
|
|
|
|
ED_screens_init(bmain, wm);
|
|
|
|
|
wm->initialized |= WM_WINDOW_IS_INIT;
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-30 04:16:24 +00:00
|
|
|
void wm_clear_default_size(bContext *C)
|
|
|
|
|
{
|
2012-03-27 01:24:16 +00:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* WM context. */
|
2012-03-27 01:24:16 +00:00
|
|
|
if (wm == NULL) {
|
|
|
|
|
wm = CTX_data_main(C)->wm.first;
|
2009-05-30 04:16:24 +00:00
|
|
|
CTX_wm_manager_set(C, wm);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-08 06:07:10 +11:00
|
|
|
if (wm == NULL || BLI_listbase_is_empty(&wm->windows)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-17 16:36:02 -05:00
|
|
|
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
2009-05-30 07:26:45 +00:00
|
|
|
win->sizex = 0;
|
|
|
|
|
win->sizey = 0;
|
|
|
|
|
win->posx = 0;
|
|
|
|
|
win->posy = 0;
|
|
|
|
|
}
|
2009-05-30 04:16:24 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* On startup, it adds all data, for matching. */
|
2017-11-09 04:57:14 +01:00
|
|
|
void wm_add_default(Main *bmain, bContext *C)
|
2007-12-24 18:27:28 +00:00
|
|
|
{
|
2017-11-09 04:57:14 +01:00
|
|
|
wmWindowManager *wm = BKE_libblock_alloc(bmain, ID_WM, "WinMan", 0);
|
2007-12-24 18:27:28 +00:00
|
|
|
wmWindow *win;
|
2012-03-27 01:24:16 +00:00
|
|
|
bScreen *screen = CTX_wm_screen(C); /* XXX from file read hrmf */
|
2017-11-09 05:37:09 +01:00
|
|
|
WorkSpace *workspace;
|
|
|
|
|
WorkSpaceLayout *layout = BKE_workspace_layout_find_global(bmain, screen, &workspace);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2008-12-18 02:56:48 +00:00
|
|
|
CTX_wm_manager_set(C, wm);
|
2020-05-20 17:02:36 +02:00
|
|
|
win = wm_window_new(bmain, wm, NULL, false);
|
2017-11-09 05:37:09 +01:00
|
|
|
win->scene = CTX_data_scene(C);
|
2018-07-04 13:00:46 +02:00
|
|
|
STRNCPY(win->view_layer_name, CTX_data_view_layer(C)->name);
|
2018-07-03 15:34:26 +02:00
|
|
|
BKE_workspace_active_set(win->workspace_hook, workspace);
|
2020-09-30 14:49:42 +02:00
|
|
|
BKE_workspace_active_layout_set(win->workspace_hook, win->winid, workspace, layout);
|
2012-03-27 01:24:16 +00:00
|
|
|
screen->winid = win->winid;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-27 01:24:16 +00:00
|
|
|
wm->winactive = win;
|
|
|
|
|
wm->file_saved = 1;
|
2017-11-09 04:57:14 +01:00
|
|
|
wm_window_make_drawable(wm, win);
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Context is allowed to be NULL, do not free wm itself (lib_id.c). */
|
2007-12-24 18:27:28 +00:00
|
|
|
void wm_close_and_free(bContext *C, wmWindowManager *wm)
|
|
|
|
|
{
|
2019-04-13 09:15:15 +02:00
|
|
|
if (wm->autosavetimer) {
|
2021-03-15 14:06:38 +11:00
|
|
|
wm_autosave_timer_end(wm);
|
2019-04-13 09:15:15 +02:00
|
|
|
}
|
2009-10-20 13:58:53 +00:00
|
|
|
|
VR: Initial Virtual Reality support - Milestone 1, Scene Inspection
NOTE: While most of the milestone 1 goals are there, a few smaller features and
improvements are still to be done.
Big picture of this milestone: Initial, OpenXR-based virtual reality support
for users and foundation for advanced use cases.
Maniphest Task: https://developer.blender.org/T71347
The tasks contains more information about this milestone.
To be clear: This is not a feature rich VR implementation, it's focused on the
initial scene inspection use case. We intentionally focused on that, further
features like controller support are part of the next milestone.
- How to use?
Instructions on how to use this are here:
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/How_to_Test
These will be updated and moved to a more official place (likely the manual) soon.
Currently Windows Mixed Reality and Oculus devices are usable. Valve/HTC
headsets don't support the OpenXR standard yet and hence, do not work with this
implementation.
---------------
This is the C-side implementation of the features added for initial VR
support as per milestone 1. A "VR Scene Inspection" Add-on will be
committed separately, to expose the VR functionality in the UI. It also
adds some further features for milestone 1, namely a landmarking system
(stored view locations in the VR space)
Main additions/features:
* Support for rendering viewports to an HMD, with good performance.
* Option to sync the VR view perspective with a fully interactive,
regular 3D View (VR-Mirror).
* Option to disable positional tracking. Keeps the current position (calculated
based on the VR eye center pose) when enabled while a VR session is running.
* Some regular viewport settings for the VR view
* RNA/Python-API to query and set VR session state information.
* WM-XR: Layer tying Ghost-XR to the Blender specific APIs/data
* wmSurface API: drawable, non-window container (manages Ghost-OpenGL and GPU
context)
* DNA/RNA for management of VR session settings
* `--debug-xr` and `--debug-xr-time` commandline options
* Utility batch & config file for using the Oculus runtime on Windows.
* Most VR data is runtime only. The exception is user settings which are saved
to files (`XrSessionSettings`).
* VR support can be disabled through the `WITH_XR_OPENXR` compiler flag.
For architecture and code documentation, see
https://wiki.blender.org/wiki/Source/Interface/XR.
---------------
A few thank you's:
* A huge shoutout to Ray Molenkamp for his help during the project - it would
have not been that successful without him!
* Sebastian Koenig and Simeon Conzendorf for testing and feedback!
* The reviewers, especially Brecht Van Lommel!
* Dalai Felinto for pushing and managing me to get this done ;)
* The OpenXR working group for providing an open standard. I think we're the
first bigger application to adopt OpenXR. Congratulations to them and
ourselves :)
This project started as a Google Summer of Code 2019 project - "Core Support of
Virtual Reality Headsets through OpenXR" (see
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/).
Some further information, including ideas for further improvements can be found
in the final GSoC report:
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/Final_Report
Differential Revisions: D6193, D7098
Reviewed by: Brecht Van Lommel, Jeroen Bakker
2020-03-17 20:20:55 +01:00
|
|
|
#ifdef WITH_XR_OPENXR
|
|
|
|
|
/* May send notifier, so do before freeing notifier queue. */
|
|
|
|
|
wm_xr_exit(wm);
|
|
|
|
|
#endif
|
|
|
|
|
|
2020-10-17 16:36:02 -05:00
|
|
|
wmWindow *win;
|
2013-08-26 23:37:08 +00:00
|
|
|
while ((win = BLI_pophead(&wm->windows))) {
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Prevent draw clear to use screen. */
|
2018-07-03 15:34:26 +02:00
|
|
|
BKE_workspace_active_set(win->workspace_hook, NULL);
|
2009-10-20 13:58:53 +00:00
|
|
|
wm_window_free(C, wm, win);
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2020-10-17 16:36:02 -05:00
|
|
|
wmOperator *op;
|
2013-08-26 23:37:08 +00:00
|
|
|
while ((op = BLI_pophead(&wm->operators))) {
|
2008-12-24 14:52:17 +00:00
|
|
|
WM_operator_free(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
|
|
|
}
|
|
|
|
|
|
2020-10-17 16:36:02 -05:00
|
|
|
wmKeyConfig *keyconf;
|
2013-08-26 23:37:08 +00:00
|
|
|
while ((keyconf = BLI_pophead(&wm->keyconfigs))) {
|
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
|
|
|
WM_keyconfig_free(keyconf);
|
2008-12-08 15:02:57 +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
|
|
|
|
2021-03-05 14:54:29 +11:00
|
|
|
BLI_freelistN(&wm->notifier_queue);
|
2017-11-13 19:43:34 +11:00
|
|
|
|
|
|
|
|
if (wm->message_bus != NULL) {
|
|
|
|
|
WM_msgbus_destroy(wm->message_bus);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 11:57:29 -03:00
|
|
|
#ifdef WITH_PYTHON
|
|
|
|
|
BPY_callback_wm_free(wm);
|
|
|
|
|
#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
|
|
|
BLI_freelistN(&wm->paintcursors);
|
2014-07-21 12:02:05 +02:00
|
|
|
|
|
|
|
|
WM_drag_free_list(&wm->drags);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2010-06-03 07:27:55 +00:00
|
|
|
wm_reports_free(wm);
|
2018-03-19 14:17:59 +01:00
|
|
|
|
|
|
|
|
if (wm->undo_stack) {
|
|
|
|
|
BKE_undosys_stack_destroy(wm->undo_stack);
|
|
|
|
|
wm->undo_stack = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-13 09:15:15 +02:00
|
|
|
if (C && CTX_wm_manager(C) == wm) {
|
|
|
|
|
CTX_wm_manager_set(C, NULL);
|
|
|
|
|
}
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void wm_close_and_free_all(bContext *C, ListBase *wmlist)
|
|
|
|
|
{
|
|
|
|
|
wmWindowManager *wm;
|
2012-03-27 01:24:16 +00:00
|
|
|
while ((wm = wmlist->first)) {
|
2007-12-24 18:27:28 +00:00
|
|
|
wm_close_and_free(C, wm);
|
|
|
|
|
BLI_remlink(wmlist, wm);
|
2017-06-14 11:16:34 +02:00
|
|
|
BKE_libblock_free_data(&wm->id, true);
|
2007-12-24 18:27:28 +00:00
|
|
|
MEM_freeN(wm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WM_main(bContext *C)
|
|
|
|
|
{
|
2017-08-25 20:26:52 +10:00
|
|
|
/* Single refresh before handling events.
|
|
|
|
|
* This ensures we don't run operators before the depsgraph has been evaluated. */
|
|
|
|
|
wm_event_do_refresh_wm_and_depsgraph(C);
|
|
|
|
|
|
2012-03-24 06:24:53 +00:00
|
|
|
while (1) {
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Get events from ghost, handle window events, add to window queues. */
|
2018-06-07 16:43:52 +02:00
|
|
|
wm_window_process_events(C);
|
|
|
|
|
|
2020-10-14 15:04:49 -05:00
|
|
|
/* Per window, all events to the window, screen, area and region handlers. */
|
2007-12-24 18:27:28 +00:00
|
|
|
wm_event_do_handlers(C);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2021-03-11 13:01:27 +01:00
|
|
|
/* Events have left notes about changes, we handle and cache it. */
|
2008-01-07 18:03:41 +00:00
|
|
|
wm_event_do_notifiers(C);
|
2018-06-07 16:43:52 +02:00
|
|
|
|
2021-03-11 13:01:27 +01:00
|
|
|
/* Execute cached changes draw. */
|
2008-01-07 18:03:41 +00:00
|
|
|
wm_draw_update(C);
|
2007-12-24 18:27:28 +00:00
|
|
|
}
|
|
|
|
|
}
|