Skip to content
Snippets Groups Projects
Commit 188277f9 authored by Hans Goudey's avatar Hans Goudey Committed by Philipp Oeser
Browse files

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
parent 45482ac5
No related branches found
Tags
No related merge requests found
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "BLI_math.h" #include "BLI_math.h"
#include "BLI_math_bits.h" #include "BLI_math_bits.h"
#include "BLI_rand.h" #include "BLI_rand.h"
#include "BLI_string.h"
#include "BLI_utildefines_stack.h" #include "BLI_utildefines_stack.h"
#include "BKE_context.h" #include "BKE_context.h"
...@@ -55,6 +56,8 @@ ...@@ -55,6 +56,8 @@
#include "ED_transform.h" #include "ED_transform.h"
#include "ED_view3d.h" #include "ED_view3d.h"
#include "BLT_translation.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
...@@ -1389,6 +1392,36 @@ static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *e ...@@ -1389,6 +1392,36 @@ static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *e
return edbm_select_mode_exec(C, op); 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) void MESH_OT_select_mode(wmOperatorType *ot)
{ {
PropertyRNA *prop; PropertyRNA *prop;
...@@ -1409,6 +1442,7 @@ void MESH_OT_select_mode(wmOperatorType *ot) ...@@ -1409,6 +1442,7 @@ void MESH_OT_select_mode(wmOperatorType *ot)
ot->invoke = edbm_select_mode_invoke; ot->invoke = edbm_select_mode_invoke;
ot->exec = edbm_select_mode_exec; ot->exec = edbm_select_mode_exec;
ot->poll = ED_operator_editmesh; ot->poll = ED_operator_editmesh;
ot->get_description = edbm_select_mode_get_description;
/* flags */ /* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
......
...@@ -52,8 +52,6 @@ ...@@ -52,8 +52,6 @@
#include "view3d_intern.h" #include "view3d_intern.h"
static void do_view3d_header_buttons(bContext *C, void *arg, int event);
#define B_SEL_VERT 110 #define B_SEL_VERT 110
#define B_SEL_EDGE 111 #define B_SEL_EDGE 111
#define B_SEL_FACE 112 #define B_SEL_FACE 112
...@@ -98,101 +96,45 @@ void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot) ...@@ -98,101 +96,45 @@ void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
/** \name UI Templates /** \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) void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
{ {
Object *obedit = CTX_data_edit_object(C); Object *obedit = CTX_data_edit_object(C);
uiBlock *block = uiLayoutGetBlock(layout); if (!obedit || obedit->type != OB_MESH) {
return;
UI_block_func_handle_set(block, do_view3d_header_buttons, NULL); }
if (obedit && (obedit->type == OB_MESH)) {
BMEditMesh *em = BKE_editmesh_from_object(obedit); BMEditMesh *em = BKE_editmesh_from_object(obedit);
uiLayout *row; uiLayout *row = uiLayoutRow(layout, true);
uiBut *but;
PointerRNA op_ptr;
row = uiLayoutRow(layout, true); wmOperatorType *ot = WM_operatortype_find("MESH_OT_select_mode", true);
block = uiLayoutGetBlock(row); uiItemFullO_ptr(row,
but = uiDefIconButBitS( ot,
block, "",
UI_BTYPE_TOGGLE,
SCE_SELECT_VERTEX,
B_SEL_VERT,
ICON_VERTEXSEL, ICON_VERTEXSEL,
0, NULL,
0, WM_OP_INVOKE_DEFAULT,
UI_UNIT_X, (em->selectmode & SCE_SELECT_VERTEX) ? UI_ITEM_O_DEPRESS : 0,
UI_UNIT_Y, &op_ptr);
&em->selectmode, RNA_enum_set(&op_ptr, "type", SCE_SELECT_VERTEX);
1.0, uiItemFullO_ptr(row,
0.0, ot,
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, ICON_EDGESEL,
0, NULL,
0, WM_OP_INVOKE_DEFAULT,
ceilf(UI_UNIT_X - U.pixelsize), (em->selectmode & SCE_SELECT_EDGE) ? UI_ITEM_O_DEPRESS : 0,
UI_UNIT_Y, &op_ptr);
&em->selectmode, RNA_enum_set(&op_ptr, "type", SCE_SELECT_EDGE);
1.0, uiItemFullO_ptr(row,
0.0, ot,
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, ICON_FACESEL,
0, NULL,
0, WM_OP_INVOKE_DEFAULT,
ceilf(UI_UNIT_X - U.pixelsize), (em->selectmode & SCE_SELECT_FACE) ? UI_ITEM_O_DEPRESS : 0,
UI_UNIT_Y, &op_ptr);
&em->selectmode, RNA_enum_set(&op_ptr, "type", SCE_SELECT_FACE);
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);
}
} }
static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C) static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment