Fix T94334: Area close operator crash in 3D view menu
This fixes the crash by removing the `do_view3d_header_buttons` handler. The code can work at a higher level here, using the operator for setting the select mode, which makes this patch a cleanup as well. The operator now has a description callback to add the custom description used for the behavior in its invoke method. Differential Revision: https://developer.blender.org/D13660
This commit is contained in:
parent
af426c8508
commit
b73d3b80fd
Notes:
blender-bot
2023-02-13 16:42:22 +01:00
Referenced by commit 28656293c6
, Cleanup: Clang tidy, use braces
Referenced by issue #96241, 3.1: Potential candidates for corrective releases
Referenced by issue #94334, Close Area crashes Blender (3.0.0 and 3.0.1)
|
@ -32,6 +32,7 @@
|
|||
#include "BLI_math.h"
|
||||
#include "BLI_math_bits.h"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines_stack.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
@ -55,6 +56,8 @@
|
|||
#include "ED_transform.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
@ -1389,6 +1392,36 @@ static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *e
|
|||
return edbm_select_mode_exec(C, op);
|
||||
}
|
||||
|
||||
static char *edbm_select_mode_get_description(struct bContext *UNUSED(C),
|
||||
struct wmOperatorType *UNUSED(op),
|
||||
struct PointerRNA *values)
|
||||
{
|
||||
const int type = RNA_enum_get(values, "type");
|
||||
|
||||
/* Because the special behavior for shift and ctrl click depend on user input, they may be
|
||||
* incorrect if the operator is used from a script or from a special button. So only return the
|
||||
* specialized descriptions if only the "type" is set, which conveys that the operator is meant
|
||||
* to be used with the logic in the `invoke` method. */
|
||||
if (RNA_struct_property_is_set(values, "type") &&
|
||||
!RNA_struct_property_is_set(values, "use_extend") &&
|
||||
!RNA_struct_property_is_set(values, "use_expand") &&
|
||||
!RNA_struct_property_is_set(values, "action"))
|
||||
switch (type) {
|
||||
case SCE_SELECT_VERTEX:
|
||||
return BLI_strdup(
|
||||
N_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
|
||||
case SCE_SELECT_EDGE:
|
||||
return BLI_strdup(
|
||||
N_("Edge select - Shift-Click for multiple modes, "
|
||||
"Ctrl-Click expands/contracts selection depending on the current mode"));
|
||||
case SCE_SELECT_FACE:
|
||||
return BLI_strdup(
|
||||
N_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MESH_OT_select_mode(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
@ -1409,6 +1442,7 @@ void MESH_OT_select_mode(wmOperatorType *ot)
|
|||
ot->invoke = edbm_select_mode_invoke;
|
||||
ot->exec = edbm_select_mode_exec;
|
||||
ot->poll = ED_operator_editmesh;
|
||||
ot->get_description = edbm_select_mode_get_description;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
|
||||
#include "view3d_intern.h"
|
||||
|
||||
static void do_view3d_header_buttons(bContext *C, void *arg, int event);
|
||||
|
||||
#define B_SEL_VERT 110
|
||||
#define B_SEL_EDGE 111
|
||||
#define B_SEL_FACE 112
|
||||
|
@ -98,101 +96,45 @@ void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
|
|||
/** \name UI Templates
|
||||
* \{ */
|
||||
|
||||
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
|
||||
|
||||
/* watch it: if area->win does not exist, check that when calling direct drawing routines */
|
||||
|
||||
switch (event) {
|
||||
case B_SEL_VERT:
|
||||
if (EDBM_selectmode_toggle_multi(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Vertex");
|
||||
}
|
||||
break;
|
||||
case B_SEL_EDGE:
|
||||
if (EDBM_selectmode_toggle_multi(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Edge");
|
||||
}
|
||||
break;
|
||||
case B_SEL_FACE:
|
||||
if (EDBM_selectmode_toggle_multi(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Face");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
uiBlock *block = uiLayoutGetBlock(layout);
|
||||
|
||||
UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
|
||||
|
||||
if (obedit && (obedit->type == OB_MESH)) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
uiLayout *row;
|
||||
uiBut *but;
|
||||
|
||||
row = uiLayoutRow(layout, true);
|
||||
block = uiLayoutGetBlock(row);
|
||||
but = uiDefIconButBitS(
|
||||
block,
|
||||
UI_BTYPE_TOGGLE,
|
||||
SCE_SELECT_VERTEX,
|
||||
B_SEL_VERT,
|
||||
ICON_VERTEXSEL,
|
||||
0,
|
||||
0,
|
||||
UI_UNIT_X,
|
||||
UI_UNIT_Y,
|
||||
&em->selectmode,
|
||||
1.0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
|
||||
UI_but_flag_disable(but, UI_BUT_UNDO);
|
||||
but = uiDefIconButBitS(
|
||||
block,
|
||||
UI_BTYPE_TOGGLE,
|
||||
SCE_SELECT_EDGE,
|
||||
B_SEL_EDGE,
|
||||
ICON_EDGESEL,
|
||||
0,
|
||||
0,
|
||||
ceilf(UI_UNIT_X - U.pixelsize),
|
||||
UI_UNIT_Y,
|
||||
&em->selectmode,
|
||||
1.0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
TIP_("Edge select - Shift-Click for multiple modes, "
|
||||
"Ctrl-Click expands/contracts selection depending on the current mode"));
|
||||
UI_but_flag_disable(but, UI_BUT_UNDO);
|
||||
but = uiDefIconButBitS(
|
||||
block,
|
||||
UI_BTYPE_TOGGLE,
|
||||
SCE_SELECT_FACE,
|
||||
B_SEL_FACE,
|
||||
ICON_FACESEL,
|
||||
0,
|
||||
0,
|
||||
ceilf(UI_UNIT_X - U.pixelsize),
|
||||
UI_UNIT_Y,
|
||||
&em->selectmode,
|
||||
1.0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
|
||||
UI_but_flag_disable(but, UI_BUT_UNDO);
|
||||
if (!obedit || obedit->type != OB_MESH) {
|
||||
return;
|
||||
}
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
uiLayout *row = uiLayoutRow(layout, true);
|
||||
|
||||
PointerRNA op_ptr;
|
||||
wmOperatorType *ot = WM_operatortype_find("MESH_OT_select_mode", true);
|
||||
uiItemFullO_ptr(row,
|
||||
ot,
|
||||
"",
|
||||
ICON_VERTEXSEL,
|
||||
NULL,
|
||||
WM_OP_INVOKE_DEFAULT,
|
||||
(em->selectmode & SCE_SELECT_VERTEX) ? UI_ITEM_O_DEPRESS : 0,
|
||||
&op_ptr);
|
||||
RNA_enum_set(&op_ptr, "type", SCE_SELECT_VERTEX);
|
||||
uiItemFullO_ptr(row,
|
||||
ot,
|
||||
"",
|
||||
ICON_EDGESEL,
|
||||
NULL,
|
||||
WM_OP_INVOKE_DEFAULT,
|
||||
(em->selectmode & SCE_SELECT_EDGE) ? UI_ITEM_O_DEPRESS : 0,
|
||||
&op_ptr);
|
||||
RNA_enum_set(&op_ptr, "type", SCE_SELECT_EDGE);
|
||||
uiItemFullO_ptr(row,
|
||||
ot,
|
||||
"",
|
||||
ICON_FACESEL,
|
||||
NULL,
|
||||
WM_OP_INVOKE_DEFAULT,
|
||||
(em->selectmode & SCE_SELECT_FACE) ? UI_ITEM_O_DEPRESS : 0,
|
||||
&op_ptr);
|
||||
RNA_enum_set(&op_ptr, "type", SCE_SELECT_FACE);
|
||||
}
|
||||
|
||||
static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
|
||||
|
|
Loading…
Reference in New Issue