diff options
author | Julian Eisel <julian@blender.org> | 2020-03-26 23:03:42 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-03-26 23:18:45 +0300 |
commit | c94b6209861ca7cc3985b53474feed7d94c0221a (patch) | |
tree | 752054f0dca1338cda5cf8ad4f6d18573fcca3b9 /source/blender/windowmanager/intern/wm_operators.c | |
parent | 357ed79cb93f9d655501a828c6cddd68282de62d (diff) | |
parent | afb1a64ccb81b7ed792f64151986f40f53af8da5 (diff) |
Merge branch 'master' into wm-drag-drop-rewrite
Diffstat (limited to 'source/blender/windowmanager/intern/wm_operators.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 325 |
1 files changed, 240 insertions, 85 deletions
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5837e8e952c..853da714f76 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -24,13 +24,13 @@ * as well as some generic operators and shared operator properties. */ -#include <float.h> -#include <string.h> -#include <ctype.h> -#include <stdio.h> -#include <stddef.h> #include <assert.h> +#include <ctype.h> #include <errno.h> +#include <float.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> #ifdef WIN32 # include "GHOST_C-api.h" @@ -43,8 +43,8 @@ #include "DNA_ID.h" #include "DNA_brush_types.h" #include "DNA_object_types.h" -#include "DNA_screen_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" @@ -65,8 +65,8 @@ #include "BKE_icons.h" #include "BKE_idprop.h" #include "BKE_image.h" -#include "BKE_library.h" -#include "BKE_library_query.h" +#include "BKE_lib_id.h" +#include "BKE_lib_query.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_report.h" @@ -74,7 +74,7 @@ #include "BKE_screen.h" /* BKE_ST_MAXNAME */ #include "BKE_unit.h" -#include "BKE_idcode.h" +#include "BKE_idtype.h" #include "BLF_api.h" @@ -457,7 +457,7 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr } case ID_MA: { # define ID_CAST_OBMATACT(id_pt) \ - (give_current_material(((Object *)id_pt), ((Object *)id_pt)->actcol)) + (BKE_object_material_get(((Object *)id_pt), ((Object *)id_pt)->actcol)) CTX_TEST_PTR_ID_CAST( C, "object", "object.active_material", ID_CAST_OBMATACT, ptr->owner_id); break; @@ -1000,7 +1000,7 @@ struct EnumSearchMenu { }; /** Generic enum search invoke popup. */ -static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg) +static uiBlock *wm_enum_search_menu(bContext *C, ARegion *region, void *arg) { struct EnumSearchMenu *search_menu = arg; wmWindow *win = CTX_wm_window(C); @@ -1015,7 +1015,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg) uiBlock *block; uiBut *but; - block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + block = UI_block_begin(C, region, "_popup", UI_EMBOSS); UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); @@ -1256,7 +1256,7 @@ ID *WM_operator_drop_load_path(struct bContext *C, wmOperator *op, const short i BKE_reportf(op->reports, RPT_ERROR, "Cannot read %s '%s': %s", - BKE_idcode_to_name(idcode), + BKE_idtype_idcode_to_name(idcode), path, errno ? strerror(errno) : TIP_("unsupported format")); return NULL; @@ -1278,7 +1278,8 @@ ID *WM_operator_drop_load_path(struct bContext *C, wmOperator *op, const short i RNA_string_get(op->ptr, "name", name); id = BKE_libblock_find_name(bmain, idcode, name); if (!id) { - BKE_reportf(op->reports, RPT_ERROR, "%s '%s' not found", BKE_idcode_to_name(idcode), name); + BKE_reportf( + op->reports, RPT_ERROR, "%s '%s' not found", BKE_idtype_idcode_to_name(idcode), name); return NULL; } id_us_plus(id); @@ -1314,15 +1315,15 @@ static void wm_block_redo_cancel_cb(bContext *C, void *arg_op) } } -static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) +static uiBlock *wm_block_create_redo(bContext *C, ARegion *region, void *arg_op) { wmOperator *op = arg_op; uiBlock *block; uiLayout *layout; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get_dpi(); int width = 15 * UI_UNIT_X; - block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + block = UI_block_begin(C, region, __func__, UI_EMBOSS); UI_block_flag_disable(block, UI_BLOCK_LOOP); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_REGULAR); @@ -1395,15 +1396,15 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2) } /* Dialogs are popups that require user verification (click OK) before exec */ -static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData) +static uiBlock *wm_block_dialog_create(bContext *C, ARegion *region, void *userData) { wmOpPopUp *data = userData; wmOperator *op = data->op; uiBlock *block; uiLayout *layout; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get_dpi(); - block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + block = UI_block_begin(C, region, __func__, UI_EMBOSS); UI_block_flag_disable(block, UI_BLOCK_LOOP); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_REGULAR); @@ -1439,20 +1440,20 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData) UI_block_bounds_set_popup( block, 6 * U.dpi_fac, (const int[2]){data->width / -2, data->height / 2}); - UI_block_active_only_flagged_buttons(C, ar, block); + UI_block_active_only_flagged_buttons(C, region, block); return block; } -static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData) +static uiBlock *wm_operator_ui_create(bContext *C, ARegion *region, void *userData) { wmOpPopUp *data = userData; wmOperator *op = data->op; uiBlock *block; uiLayout *layout; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get_dpi(); - block = UI_block_begin(C, ar, __func__, UI_EMBOSS); + block = UI_block_begin(C, region, __func__, UI_EMBOSS); UI_block_flag_disable(block, UI_BLOCK_LOOP); UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_REGULAR); @@ -1467,8 +1468,6 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData) UI_block_bounds_set_popup(block, 6 * U.dpi_fac, NULL); - UI_block_active_only_flagged_buttons(C, ar, block); - return block; } @@ -1502,12 +1501,13 @@ static void wm_operator_ui_popup_ok(struct bContext *C, void *arg, int retval) MEM_freeN(data); } -int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height) +int WM_operator_ui_popup(bContext *C, wmOperator *op, int width) { wmOpPopUp *data = MEM_callocN(sizeof(wmOpPopUp), "WM_operator_ui_popup"); data->op = op; data->width = width * U.dpi_fac; - data->height = height * U.dpi_fac; + /* Actual used height depends on the content. */ + data->height = 0; data->free_op = true; /* if this runs and gets registered we may want not to free it */ UI_popup_block_ex(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data, op); return OPERATOR_RUNNING_MODAL; @@ -1543,7 +1543,7 @@ static int wm_operator_props_popup_ex(bContext *C, /* 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 */ if (!do_redo || !(U.uiflag & USER_GLOBALUNDO)) { - return WM_operator_props_dialog_popup(C, op, 300, 20); + return WM_operator_props_dialog_popup(C, op, 300); } UI_popup_block_ex(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op, op); @@ -1579,13 +1579,14 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *UNUSED(e return wm_operator_props_popup_ex(C, op, false, true); } -int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height) +int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width) { wmOpPopUp *data = MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup"); data->op = op; data->width = width * U.dpi_fac; - data->height = height * U.dpi_fac; + /* Actual height depends on the content. */ + data->height = 0; data->free_op = true; /* if this runs and gets registered we may want not to free it */ /* op is not executed until popup OK but is clicked */ @@ -1636,7 +1637,7 @@ static int wm_debug_menu_exec(bContext *C, wmOperator *op) static int wm_debug_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { RNA_int_set(op->ptr, "debug_value", G.debug_value); - return WM_operator_props_dialog_popup(C, op, 180, 20); + return WM_operator_props_dialog_popup(C, op, 180); } static void WM_OT_debug_menu(wmOperatorType *ot) @@ -1674,7 +1675,7 @@ static int wm_operator_defaults_exec(bContext *C, wmOperator *op) /* 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->name = "Restore Operator Defaults"; ot->idname = "WM_OT_operator_defaults"; ot->description = "Set the active operator to its default values"; @@ -1686,21 +1687,26 @@ static void WM_OT_operator_defaults(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Operator Search Menu +/** \name Operator/Menu Search Operator * \{ */ struct SearchPopupInit_Data { + enum { + SEARCH_TYPE_OPERATOR = 0, + SEARCH_TYPE_MENU = 1, + } search_type; + int size[2]; }; -static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *userdata) +static uiBlock *wm_block_search_menu(bContext *C, ARegion *region, void *userdata) { const struct SearchPopupInit_Data *init_data = userdata; static char search[256] = ""; uiBlock *block; uiBut *but; - block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + block = UI_block_begin(C, region, "_popup", UI_EMBOSS); UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); @@ -1716,7 +1722,17 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *userdata) 0, 0, ""); - UI_but_func_operator_search(but); + + if (init_data->search_type == SEARCH_TYPE_OPERATOR) { + UI_but_func_operator_search(but); + } + else if (init_data->search_type == SEARCH_TYPE_MENU) { + UI_but_func_menu_search(but); + } + else { + BLI_assert(0); + } + UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT); /* fake button, it holds space for search items */ @@ -1746,10 +1762,10 @@ static int wm_search_menu_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -static int wm_search_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *event) { /* Exception for launching via spacebar */ - if (event->type == SPACEKEY) { + if (event->type == EVT_SPACEKEY) { bool ok = true; ScrArea *sa = CTX_wm_area(C); if (sa) { @@ -1774,9 +1790,20 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv } } + PropertyRNA *prop = op->type->prop; + int search_type; + if (RNA_property_is_set(op->ptr, prop)) { + search_type = RNA_property_enum_get(op->ptr, prop); + } + else { + search_type = U.experimental.use_menu_search ? SEARCH_TYPE_MENU : SEARCH_TYPE_OPERATOR; + } + static struct SearchPopupInit_Data data; - data.size[0] = UI_searchbox_size_x() * 2; - data.size[1] = UI_searchbox_size_y(); + data = (struct SearchPopupInit_Data){ + .search_type = search_type, + .size = {UI_searchbox_size_x() * 2, UI_searchbox_size_y()}, + }; UI_popup_block_invoke(C, wm_block_search_menu, &data, NULL); @@ -1792,6 +1819,15 @@ static void WM_OT_search_menu(wmOperatorType *ot) ot->invoke = wm_search_menu_invoke; ot->exec = wm_search_menu_exec; ot->poll = WM_operator_winactive; + + static const EnumPropertyItem search_type_items[] = { + {SEARCH_TYPE_OPERATOR, "OPERATOR", 0, "Operator", "Search all operators"}, + {SEARCH_TYPE_MENU, "MENU", 0, "Menu", "Search active menu items"}, + {0, NULL, 0, NULL, NULL}, + }; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", search_type_items, SEARCH_TYPE_OPERATOR, "Type", ""); } static int wm_call_menu_exec(bContext *C, wmOperator *op) @@ -2308,7 +2344,7 @@ static void radial_control_paint_curve(uint pos, Brush *br, float radius, int li static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void *customdata) { RadialControl *rc = customdata; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); const uiFontStyle *fstyle = &style->widget; const int fontid = fstyle->uifont_id; short fstyle_points = fstyle->points; @@ -2815,7 +2851,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even else { handled = false; switch (event->type) { - case ESCKEY: + case EVT_ESCKEY: case RIGHTMOUSE: /* canceled; restore original value */ radial_control_set_value(rc, rc->initial_value); @@ -2823,8 +2859,8 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even break; case LEFTMOUSE: - case PADENTER: - case RETKEY: + case EVT_PADENTER: + case EVT_RETKEY: /* done; value already set */ RNA_property_update(C, &rc->ptr, rc->prop); ret = OPERATOR_FINISHED; @@ -2930,8 +2966,8 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even } break; - case LEFTSHIFTKEY: - case RIGHTSHIFTKEY: { + case EVT_LEFTSHIFTKEY: + case EVT_RIGHTSHIFTKEY: { if (event->val == KM_PRESS) { rc->slow_mouse[0] = event->x; rc->slow_mouse[1] = event->y; @@ -3141,19 +3177,19 @@ static void redraw_timer_step(bContext *C, struct Depsgraph *depsgraph, wmWindow *win, ScrArea *sa, - ARegion *ar, + ARegion *region, const int type, const int cfra) { if (type == eRTDrawRegion) { - if (ar) { - wm_draw_region_test(C, sa, ar); + if (region) { + wm_draw_region_test(C, sa, region); } } else if (type == eRTDrawRegionSwap) { CTX_wm_menu_set(C, NULL); - ED_region_tag_redraw(ar); + ED_region_tag_redraw(region); wm_draw_update(C); CTX_wm_window_set(C, win); /* XXX context manipulation warning! */ @@ -3179,7 +3215,7 @@ static void redraw_timer_step(bContext *C, CTX_wm_window_set(C, win); /* XXX context manipulation warning! */ CTX_wm_area_set(C, sa); - CTX_wm_region_set(C, ar); + CTX_wm_region_set(C, region); } else if (type == eRTDrawWindowSwap) { redraw_timer_window_swap(C); @@ -3215,7 +3251,7 @@ static int redraw_timer_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); - ARegion *ar = CTX_wm_region(C); + ARegion *region = CTX_wm_region(C); wmWindowManager *wm = CTX_wm_manager(C); double time_start, time_delta; const int type = RNA_enum_get(op->ptr, "type"); @@ -3236,7 +3272,7 @@ static int redraw_timer_exec(bContext *C, wmOperator *op) wm_window_make_drawable(wm, win); for (a = 0; a < iter; a++) { - redraw_timer_step(C, bmain, scene, depsgraph, win, sa, ar, type, cfra); + redraw_timer_step(C, bmain, scene, depsgraph, win, sa, region, type, cfra); iter_steps += 1; if (time_limit != 0.0) { @@ -3336,17 +3372,16 @@ static void previews_id_ensure(bContext *C, Scene *scene, ID *id) } } -static int previews_id_ensure_callback(void *userdata, - ID *UNUSED(self_id), - ID **idptr, - int cb_flag) +static int previews_id_ensure_callback(LibraryIDLinkCallbackData *cb_data) { - if (cb_flag & IDWALK_CB_PRIVATE) { + const int cb_flag = cb_data->cb_flag; + + if (cb_flag & IDWALK_CB_EMBEDDED) { return IDWALK_RET_NOP; } - PreviewsIDEnsureData *data = userdata; - ID *id = *idptr; + PreviewsIDEnsureData *data = cb_data->user_data; + ID *id = *cb_data->id_pointer; if (id && (id->tag & LIB_TAG_DOIT)) { BLI_assert(ELEM(GS(id->name), ID_MA, ID_TE, ID_IM, ID_WO, ID_LA)); @@ -3413,38 +3448,78 @@ static void WM_OT_previews_ensure(wmOperatorType *ot) /** \name Data-Block Preview Clear Operator * \{ */ +typedef enum PreviewFilterID { + PREVIEW_FILTER_ALL, + PREVIEW_FILTER_GEOMETRY, + PREVIEW_FILTER_SHADING, + PREVIEW_FILTER_SCENE, + PREVIEW_FILTER_COLLECTION, + PREVIEW_FILTER_OBJECT, + PREVIEW_FILTER_MATERIAL, + PREVIEW_FILTER_LIGHT, + PREVIEW_FILTER_WORLD, + PREVIEW_FILTER_TEXTURE, + PREVIEW_FILTER_IMAGE, +} PreviewFilterID; + /* Only types supporting previews currently. */ static const EnumPropertyItem preview_id_type_items[] = { - {FILTER_ID_SCE | FILTER_ID_GR | FILTER_ID_OB | FILTER_ID_MA | FILTER_ID_LA | FILTER_ID_WO | - FILTER_ID_TE | FILTER_ID_IM, - "ALL", - 0, - "All Types", - ""}, - {FILTER_ID_SCE | FILTER_ID_GR | FILTER_ID_OB, + {PREVIEW_FILTER_ALL, "ALL", 0, "All Types", ""}, + {PREVIEW_FILTER_GEOMETRY, "GEOMETRY", 0, "All Geometry Types", "Clear previews for scenes, collections and objects"}, - {FILTER_ID_MA | FILTER_ID_LA | FILTER_ID_WO | FILTER_ID_TE | FILTER_ID_IM, + {PREVIEW_FILTER_SHADING, "SHADING", 0, "All Shading Types", - "Clear previews for materiasl, lights, worlds, textures and images"}, - {FILTER_ID_SCE, "SCENE", 0, "Scenes", ""}, - {FILTER_ID_GR, "GROUP", 0, "Groups", ""}, - {FILTER_ID_OB, "OBJECT", 0, "Objects", ""}, - {FILTER_ID_MA, "MATERIAL", 0, "Materials", ""}, - {FILTER_ID_LA, "LIGHT", 0, "Lights", ""}, - {FILTER_ID_WO, "WORLD", 0, "Worlds", ""}, - {FILTER_ID_TE, "TEXTURE", 0, "Textures", ""}, - {FILTER_ID_IM, "IMAGE", 0, "Images", ""}, + "Clear previews for materials, lights, worlds, textures and images"}, + {PREVIEW_FILTER_SCENE, "SCENE", 0, "Scenes", ""}, + {PREVIEW_FILTER_COLLECTION, "COLLECTION", 0, "Collections", ""}, + {PREVIEW_FILTER_OBJECT, "OBJECT", 0, "Objects", ""}, + {PREVIEW_FILTER_MATERIAL, "MATERIAL", 0, "Materials", ""}, + {PREVIEW_FILTER_LIGHT, "LIGHT", 0, "Lights", ""}, + {PREVIEW_FILTER_WORLD, "WORLD", 0, "Worlds", ""}, + {PREVIEW_FILTER_TEXTURE, "TEXTURE", 0, "Textures", ""}, + {PREVIEW_FILTER_IMAGE, "IMAGE", 0, "Images", ""}, #if 0 /* XXX TODO */ - {FILTER_ID_BR, "BRUSH", 0, "Brushes", ""}, + {PREVIEW_FILTER_BRUSH, "BRUSH", 0, "Brushes", ""}, #endif {0, NULL, 0, NULL, NULL}, }; +static uint preview_filter_to_idfilter(enum PreviewFilterID filter) +{ + switch (filter) { + case PREVIEW_FILTER_ALL: + return FILTER_ID_SCE | FILTER_ID_GR | FILTER_ID_OB | FILTER_ID_MA | FILTER_ID_LA | + FILTER_ID_WO | FILTER_ID_TE | FILTER_ID_IM; + case PREVIEW_FILTER_GEOMETRY: + return FILTER_ID_SCE | FILTER_ID_GR | FILTER_ID_OB; + case PREVIEW_FILTER_SHADING: + return FILTER_ID_MA | FILTER_ID_LA | FILTER_ID_WO | FILTER_ID_TE | FILTER_ID_IM; + case PREVIEW_FILTER_SCENE: + return FILTER_ID_SCE; + case PREVIEW_FILTER_COLLECTION: + return FILTER_ID_GR; + case PREVIEW_FILTER_OBJECT: + return FILTER_ID_OB; + case PREVIEW_FILTER_MATERIAL: + return FILTER_ID_MA; + case PREVIEW_FILTER_LIGHT: + return FILTER_ID_LA; + case PREVIEW_FILTER_WORLD: + return FILTER_ID_WO; + case PREVIEW_FILTER_TEXTURE: + return FILTER_ID_TE; + case PREVIEW_FILTER_IMAGE: + return FILTER_ID_IM; + } + + return 0; +} + static int previews_clear_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -3460,7 +3535,7 @@ static int previews_clear_exec(bContext *C, wmOperator *op) }; int i; - const int id_filters = RNA_enum_get(op->ptr, "id_type"); + const int id_filters = preview_filter_to_idfilter(RNA_enum_get(op->ptr, "id_type")); for (i = 0; lb[i]; i++) { ID *id = lb[i]->first; @@ -3472,12 +3547,12 @@ static int previews_clear_exec(bContext *C, wmOperator *op) printf("%s: %d, %d, %d -> %d\n", id->name, GS(id->name), - BKE_idcode_to_idfilter(GS(id->name)), + BKE_idtype_idcode_to_idfilter(GS(id->name)), id_filters, - BKE_idcode_to_idfilter(GS(id->name)) & id_filters); + BKE_idtype_idcode_to_idfilter(GS(id->name)) & id_filters); #endif - if (!id || !(BKE_idcode_to_idfilter(GS(id->name)) & id_filters)) { + if (!(BKE_idtype_idcode_to_idfilter(GS(id->name)) & id_filters)) { continue; } @@ -3504,8 +3579,7 @@ static void WM_OT_previews_clear(wmOperatorType *ot) ot->prop = RNA_def_enum_flag(ot->srna, "id_type", preview_id_type_items, - FILTER_ID_SCE | FILTER_ID_OB | FILTER_ID_GR | FILTER_ID_MA | - FILTER_ID_LA | FILTER_ID_WO | FILTER_ID_TE | FILTER_ID_IM, + PREVIEW_FILTER_ALL, "Data-Block Type", "Which data-block previews to clear"); } @@ -3607,6 +3681,84 @@ static void WM_OT_stereo3d_set(wmOperatorType *ot) /** \} */ +#ifdef WITH_XR_OPENXR + +static void wm_xr_session_update_screen(Main *bmain, const wmXrData *xr_data) +{ + const bool session_exists = WM_xr_session_exists(xr_data); + + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + for (ScrArea *area = screen->areabase.first; area; area = area->next) { + for (SpaceLink *slink = area->spacedata.first; slink; slink = slink->next) { + if (slink->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)slink; + + if (v3d->flag & V3D_XR_SESSION_MIRROR) { + ED_view3d_xr_mirror_update(area, v3d, session_exists); + } + + if (session_exists) { + wmWindowManager *wm = bmain->wm.first; + const Scene *scene = WM_windows_scene_get_from_screen(wm, screen); + + ED_view3d_xr_shading_update(wm, v3d, scene); + } + /* Ensure no 3D View is tagged as session root. */ + else { + v3d->runtime.flag &= ~V3D_RUNTIME_XR_SESSION_ROOT; + } + } + } + } + } +} + +static void wm_xr_session_update_screen_on_exit_cb(const wmXrData *xr_data) +{ + /* Just use G_MAIN here, storing main isn't reliable enough on file read or exit. */ + wm_xr_session_update_screen(G_MAIN, xr_data); +} + +static int wm_xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + wmWindowManager *wm = CTX_wm_manager(C); + View3D *v3d = CTX_wm_view3d(C); + + /* Lazy-create xr context - tries to dynlink to the runtime, reading active_runtime.json. */ + if (wm_xr_init(wm) == false) { + return OPERATOR_CANCELLED; + } + + v3d->runtime.flag |= V3D_RUNTIME_XR_SESSION_ROOT; + wm_xr_session_toggle(wm, wm_xr_session_update_screen_on_exit_cb); + wm_xr_session_update_screen(bmain, &wm->xr); + + WM_event_add_notifier(C, NC_WM | ND_XR_DATA_CHANGED, NULL); + + return OPERATOR_FINISHED; +} + +static void WM_OT_xr_session_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Toggle VR Session"; + ot->idname = "WM_OT_xr_session_toggle"; + ot->description = + "Open a view for use with virtual reality headsets, or close it if already " + "opened"; + + /* callbacks */ + ot->exec = wm_xr_session_toggle_exec; + ot->poll = ED_operator_view3d_active; + + /* XXX INTERNAL just to hide it from the search menu by default, an Add-on will expose it in the + * UI instead. Not meant as a permanent solution. */ + ot->flag = OPTYPE_INTERNAL; +} + +#endif /* WITH_XR_OPENXR */ + /* -------------------------------------------------------------------- */ /** \name Operator Registration & Keymaps * \{ */ @@ -3648,6 +3800,9 @@ void wm_operatortypes_register(void) WM_operatortype_append(WM_OT_call_panel); WM_operatortype_append(WM_OT_radial_control); WM_operatortype_append(WM_OT_stereo3d_set); +#ifdef WITH_XR_OPENXR + WM_operatortype_append(WM_OT_xr_session_toggle); +#endif #if defined(WIN32) WM_operatortype_append(WM_OT_console_toggle); #endif |