Blender V4.5
MOD_ui_common.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_listbase.h"
10#include "BLI_string.h"
11
12#include "MEM_guardedalloc.h"
13
14#include "BKE_context.hh"
15#include "BKE_library.hh"
16#include "BKE_modifier.hh"
17#include "BKE_screen.hh"
18
19#include "DNA_object_types.h"
20#include "DNA_particle_types.h"
21#include "DNA_screen_types.h"
22
23#include "ED_object.hh"
24
25#include "BLT_translation.hh"
26
27#include "UI_interface.hh"
28#include "UI_resources.hh"
29
30#include "RNA_access.hh"
31#include "RNA_prototypes.hh"
32
33#include "WM_api.hh"
34#include "WM_types.hh"
35
36#include "MOD_ui_common.hh" /* Self include */
37
39
44static bool modifier_ui_poll(const bContext *C, PanelType * /*pt*/)
45{
47 return ob != nullptr;
48}
49
50/* -------------------------------------------------------------------- */
53
57static void modifier_reorder(bContext *C, Panel *panel, int new_index)
58{
59 PointerRNA *md_ptr = UI_panel_custom_data_get(panel);
60 ModifierData *md = (ModifierData *)md_ptr->data;
61
62 PointerRNA props_ptr;
63 wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_modifier_move_to_index", false);
65 RNA_string_set(&props_ptr, "modifier", md->name);
66 RNA_int_set(&props_ptr, "index", new_index);
67 WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, nullptr);
69}
70
71static short get_modifier_expand_flag(const bContext * /*C*/, Panel *panel)
72{
73 PointerRNA *md_ptr = UI_panel_custom_data_get(panel);
74 ModifierData *md = (ModifierData *)md_ptr->data;
75 return md->ui_expand_flag;
76}
77
78static void set_modifier_expand_flag(const bContext * /*C*/, Panel *panel, short expand_flag)
79{
80 PointerRNA *md_ptr = UI_panel_custom_data_get(panel);
81 ModifierData *md = (ModifierData *)md_ptr->data;
82 md->ui_expand_flag = expand_flag;
83}
84
86
87/* -------------------------------------------------------------------- */
90
92{
93 ModifierData *md = static_cast<ModifierData *>(ptr->data);
94 if (md->error) {
95 uiLayout *row = &layout->row(false);
96 row->label(RPT_(md->error), ICON_ERROR);
97 }
98}
99
106#define ERROR_LIBDATA_MESSAGE N_("External library data")
108{
111 BLI_assert(RNA_struct_is_a(ptr->type, &RNA_Modifier));
112
113 if (r_ob_ptr != nullptr) {
114 *r_ob_ptr = RNA_pointer_create_discrete(ptr->owner_id, &RNA_Object, ptr->owner_id);
115 }
116
117 uiBlock *block = uiLayoutGetBlock(panel->layout);
119
120 UI_panel_context_pointer_set(panel, "modifier", ptr);
121
122 return ptr;
123}
124
127 PointerRNA *ob_ptr,
128 const StringRefNull vgroup_prop,
129 const std::optional<StringRefNull> invert_vgroup_prop,
130 const std::optional<StringRefNull> text)
131{
132 bool has_vertex_group = RNA_string_length(ptr, vgroup_prop.c_str()) != 0;
133
134 uiLayout *row = &layout->row(true);
135 uiItemPointerR(row, ptr, vgroup_prop, ob_ptr, "vertex_groups", text, ICON_GROUP_VERTEX);
136 if (invert_vgroup_prop) {
137 uiLayout *sub = &row->row(true);
138 uiLayoutSetActive(sub, has_vertex_group);
139 uiLayoutSetPropDecorate(sub, false);
140 sub->prop(ptr, *invert_vgroup_prop, UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
141 }
142}
143
145{
146 uiLayout *layout = panel->layout;
147
149
150 layout->prop(ptr, "use_custom_curve", UI_ITEM_NONE, std::nullopt, ICON_NONE);
151}
152
154{
155 uiLayout *layout = panel->layout;
156
158
159 uiTemplateCurveMapping(layout, ptr, "curve", 0, false, false, false, false);
160}
161
167{
168 /* Physic Tab */
169 if (ELEM(md->type,
177 {
178 return 1;
179 }
180 /* Particle Tab */
182 return 2;
183 }
184
185 return 0;
186}
187
189{
190 /* fluid particle modifier can't be deleted here */
192 short particle_type = ((ParticleSystemModifierData *)md)->psys->part->type;
193 if (ELEM(particle_type,
204 {
205 return false;
206 }
207 }
208 return true;
209}
210
211static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
212{
213 PointerRNA op_ptr;
214 ModifierData *md = (ModifierData *)md_v;
215
217 PointerRNA ptr = RNA_pointer_create_discrete(&ob->id, &RNA_Modifier, md);
218 uiLayoutSetContextPointer(layout, "modifier", &ptr);
220
221 uiLayoutSetUnitsX(layout, 4.0f);
222
223 /* Apply. */
224 if (ob->type == OB_GREASE_PENCIL) {
225 layout->op("OBJECT_OT_modifier_apply",
226 CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply (Active Keyframe)"),
227 ICON_CHECKMARK);
228
229 op_ptr = layout->op("OBJECT_OT_modifier_apply",
230 IFACE_("Apply (All Keyframes)"),
231 ICON_KEYFRAME,
234 RNA_boolean_set(&op_ptr, "all_keyframes", true);
235 }
236 else {
237 layout->op("OBJECT_OT_modifier_apply",
239 ICON_CHECKMARK);
240 }
241
242 /* Apply as shapekey. */
244 PointerRNA op_ptr = layout->op(
245 "OBJECT_OT_modifier_apply_as_shapekey",
246 CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply as Shape Key"),
247 ICON_SHAPEKEY_DATA);
248 RNA_boolean_set(&op_ptr, "keep_modifier", false);
249
250 op_ptr = layout->op("OBJECT_OT_modifier_apply_as_shapekey",
251 CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save as Shape Key"),
252 ICON_NONE);
253 RNA_boolean_set(&op_ptr, "keep_modifier", true);
254 layout->separator();
255 }
256
257 /* Duplicate. */
258 if (!ELEM(md->type,
264 {
265 layout->op("OBJECT_OT_modifier_copy",
267 ICON_DUPLICATE);
268 }
269
270 layout->op("OBJECT_OT_modifier_copy_to_selected",
271 CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy to Selected"),
272 0);
273
274 layout->separator();
275
276 /* Move to first. */
277 op_ptr = layout->op("OBJECT_OT_modifier_move_to_index",
278 IFACE_("Move to First"),
279 ICON_TRIA_UP,
282 RNA_int_set(&op_ptr, "index", 0);
283
284 /* Move to last. */
285 op_ptr = layout->op("OBJECT_OT_modifier_move_to_index",
286 IFACE_("Move to Last"),
287 ICON_TRIA_DOWN,
290 RNA_int_set(&op_ptr, "index", BLI_listbase_count(&ob->modifiers) - 1);
291
292 layout->separator();
293
294 layout->prop(&ptr, "use_pin_to_last", UI_ITEM_NONE, std::nullopt, ICON_NONE);
295
296 if (md->type == eModifierType_Nodes) {
297 layout->separator();
298 op_ptr = layout->op("OBJECT_OT_geometry_nodes_move_to_nodes",
299 std::nullopt,
300 ICON_NONE,
303 layout->prop(&ptr, "show_group_selector", UI_ITEM_NONE, std::nullopt, ICON_NONE);
304 }
305}
306
307static void modifier_panel_header(const bContext *C, Panel *panel)
308{
309 uiLayout *row, *sub, *name_row;
310 uiLayout *layout = panel->layout;
311
312 /* Don't use #modifier_panel_get_property_pointers, we don't want to lock the header. */
314 ModifierData *md = (ModifierData *)ptr->data;
315 Object *ob = (Object *)ptr->owner_id;
316
317 UI_panel_context_pointer_set(panel, "modifier", ptr);
318
320 Scene *scene = CTX_data_scene(C);
321 int index = BLI_findindex(&ob->modifiers, md);
322
323 /* Modifier Icon. */
324 sub = &layout->row(true);
326 if (mti->is_disabled && mti->is_disabled(scene, md, false)) {
327 uiLayoutSetRedAlert(sub, true);
328 }
329 PointerRNA op_ptr = sub->op("OBJECT_OT_modifier_set_active", "", RNA_struct_ui_icon(ptr->type));
330 RNA_string_set(&op_ptr, "modifier", md->name);
331
332 row = &layout->row(true);
333
334 /* Modifier Name.
335 * Count how many buttons are added to the header to check if there is enough space. */
336 int buttons_number = 0;
337 name_row = &row->row(true);
338
339 /* Display mode switching buttons. */
340 if (ob->type == OB_MESH) {
341 int last_cage_index;
342 int cage_index = BKE_modifiers_get_cage_index(scene, ob, &last_cage_index, false);
343 if (BKE_modifier_supports_cage(scene, md) && (index <= last_cage_index)) {
344 sub = &row->row(true);
345 if (index < cage_index || !BKE_modifier_couldbe_cage(scene, md)) {
346 uiLayoutSetActive(sub, false);
347 }
348 sub->prop(ptr, "show_on_cage", UI_ITEM_NONE, "", ICON_NONE);
349 buttons_number++;
350 }
351 } /* Tessellation point for curve-typed objects. */
352 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
353 /* Smooth modifier can work with tessellated curves only (works on mesh edges explicitly). */
354 if (md->type == eModifierType_Smooth) {
355 /* Add button (appearing to be OFF) and add tip why this can't be changed. */
356 sub = &row->row(true);
357 uiBlock *block = uiLayoutGetBlock(sub);
358 static int apply_on_spline_always_off_hack = 0;
359 uiBut *but = uiDefIconButBitI(block,
362 0,
363 ICON_SURFACE_DATA,
364 0,
365 0,
366 UI_UNIT_X - 2,
367 UI_UNIT_Y,
368 &apply_on_spline_always_off_hack,
369 0.0,
370 0.0,
371 RPT_("Apply on Spline"));
372 UI_but_disable(but,
373 "This modifier can only deform filled curve/surface, not the control points");
374 buttons_number++;
375 }
376 /* Some modifiers can work with pre-tessellated curves only. */
378 {
379 /* Add button (appearing to be ON) and add tip why this can't be changed. */
380 sub = &row->row(true);
381 uiBlock *block = uiLayoutGetBlock(sub);
382 static int apply_on_spline_always_on_hack = eModifierMode_ApplyOnSpline;
383 uiBut *but = uiDefIconButBitI(block,
386 0,
387 ICON_SURFACE_DATA,
388 0,
389 0,
390 UI_UNIT_X - 2,
391 UI_UNIT_Y,
392 &apply_on_spline_always_on_hack,
393 0.0,
394 0.0,
395 RPT_("Apply on Spline"));
396 UI_but_disable(but,
397 "This modifier can only deform control points, not the filled curve/surface");
398 buttons_number++;
399 }
400 else if (mti->type != ModifierTypeType::Constructive) {
401 /* Constructive modifiers tessellates curve before applying. */
402 row->prop(ptr, "use_apply_on_spline", UI_ITEM_NONE, "", ICON_NONE);
403 buttons_number++;
404 }
405 }
406 /* Collision and Surface are always enabled, hide buttons. */
409 sub = &row->row(true);
411 sub->prop(ptr, "show_in_editmode", UI_ITEM_NONE, "", ICON_NONE);
412 buttons_number++;
413 }
414 row->prop(ptr, "show_viewport", UI_ITEM_NONE, "", ICON_NONE);
415 row->prop(ptr, "show_render", UI_ITEM_NONE, "", ICON_NONE);
416 buttons_number += 2;
417 }
418
419 /* Extra operators menu. */
420 row->menu_fn("", ICON_DOWNARROW_HLT, modifier_ops_extra_draw, md);
421
422 /* Delete button. */
424 sub = &row->row(false);
426 sub->op("OBJECT_OT_modifier_remove", "", ICON_X);
427 buttons_number++;
428 }
429
430 /* Switch context buttons. */
431 if (modifier_is_simulation(md) == 1) {
432 PointerRNA op_ptr = row->op("WM_OT_properties_context_change", "", ICON_PROPERTIES);
433 if (!RNA_pointer_is_null(&op_ptr)) {
434 RNA_string_set(&op_ptr, "context", "PHYSICS");
435 }
436 buttons_number++;
437 }
438 else if (modifier_is_simulation(md) == 2) {
439 PointerRNA op_ptr = row->op("WM_OT_properties_context_change", "", ICON_PROPERTIES);
440 if (!RNA_pointer_is_null(&op_ptr)) {
441 RNA_string_set(&op_ptr, "context", "PARTICLES");
442 }
443 buttons_number++;
444 }
445
446 bool display_name = (panel->sizex / UI_UNIT_X - buttons_number > 5) || (panel->sizex == 0);
447 if (display_name) {
448 name_row->prop(ptr, "name", UI_ITEM_NONE, "", ICON_NONE);
449 }
450 else {
452 }
453
454 /* Extra padding for delete button. */
455 layout->separator();
456}
457
459
460/* -------------------------------------------------------------------- */
463
465{
466 PanelType *panel_type = MEM_callocN<PanelType>(__func__);
467
468 BKE_modifier_type_panel_id(type, panel_type->idname);
469 STRNCPY(panel_type->label, "");
470 STRNCPY(panel_type->context, "modifier");
472 STRNCPY(panel_type->active_property, "is_active");
473 STRNCPY(panel_type->pin_to_last_property, "use_pin_to_last");
474
476 panel_type->draw = draw;
477 panel_type->poll = modifier_ui_poll;
478
479 /* Give the panel the special flag that says it was built here and corresponds to a
480 * modifier rather than a #PanelType. */
482 panel_type->reorder = modifier_reorder;
485
486 BLI_addtail(&region_type->paneltypes, panel_type);
487
488 return panel_type;
489}
490
492 const char *name,
493 const char *label,
494 PanelDrawFn draw_header,
495 PanelDrawFn draw,
496 PanelType *parent)
497{
498 PanelType *panel_type = MEM_callocN<PanelType>(__func__);
499
500 BLI_assert(parent != nullptr);
501 SNPRINTF(panel_type->idname, "%s_%s", parent->idname, name);
502 STRNCPY(panel_type->label, label);
503 STRNCPY(panel_type->context, "modifier");
505 STRNCPY(panel_type->active_property, "is_active");
506
507 panel_type->draw_header = draw_header;
508 panel_type->draw = draw;
509 panel_type->poll = modifier_ui_poll;
510 panel_type->flag = PANEL_TYPE_DEFAULT_CLOSED;
511
512 STRNCPY(panel_type->parent_id, parent->idname);
513 panel_type->parent = parent;
514 BLI_addtail(&parent->children, BLI_genericNodeN(panel_type));
515 BLI_addtail(&region_type->paneltypes, panel_type);
516
517 return panel_type;
518}
519
Scene * CTX_data_scene(const bContext *C)
bool BKE_modifier_is_non_geometrical(ModifierData *md)
int BKE_modifiers_get_cage_index(const Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
@ eModifierTypeFlag_SupportsEditmode
bool BKE_modifier_supports_cage(Scene *scene, ModifierData *md)
bool BKE_modifier_is_same_topology(ModifierData *md)
void BKE_modifier_type_panel_id(ModifierType type, char *r_idname)
bool BKE_modifier_couldbe_cage(Scene *scene, ModifierData *md)
@ PANEL_TYPE_INSTANCED
@ PANEL_TYPE_DEFAULT_CLOSED
@ PANEL_TYPE_HEADER_EXPAND
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:922
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define ELEM(...)
#define RPT_(msgid)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
@ eModifierMode_ApplyOnSpline
@ eModifierMode_Realtime
@ eModifierType_ParticleSystem
@ eModifierType_MeshDeform
@ eModifierType_Fluidsim
@ eModifierType_Surface
@ eModifierType_Cloth
@ eModifierType_Fluid
@ eModifierType_Hook
@ eModifierType_Nodes
@ eModifierType_Collision
@ eModifierType_Smooth
@ eModifierType_DynamicPaint
@ eModifierType_Softbody
Object is a sort of wrapper for general info.
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_CURVES_LEGACY
@ PART_FLUID_FLIP
@ PART_FLUID_BUBBLE
@ PART_FLUID_SPRAYBUBBLE
@ PART_FLUID_TRACER
@ PART_FLUID
@ PART_FLUID_FOAM
@ PART_FLUID_SPRAYFOAMBUBBLE
@ PART_FLUID_SPRAYFOAM
@ PART_FLUID_SPRAY
@ PART_FLUID_FOAMBUBBLE
Read Guarded memory(de)allocation.
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const StringRefNull vgroup_prop, const std::optional< StringRefNull > invert_vgroup_prop, const std::optional< StringRefNull > text)
static void modifier_reorder(bContext *C, Panel *panel, int new_index)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
static void modifier_panel_header(const bContext *C, Panel *panel)
static int modifier_is_simulation(const ModifierData *md)
void modifier_grease_pencil_curve_header_draw(const bContext *, Panel *panel)
static bool modifier_ui_poll(const bContext *C, PanelType *)
void modifier_grease_pencil_curve_panel_draw(const bContext *, Panel *panel)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
static bool modifier_can_delete(ModifierData *md)
static void set_modifier_expand_flag(const bContext *, Panel *panel, short expand_flag)
static short get_modifier_expand_flag(const bContext *, Panel *panel)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_error_message_draw(uiLayout *layout, PointerRNA *ptr)
static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
#define C
Definition RandGen.cpp:29
void UI_but_disable(uiBut *but, const char *disabled_hint)
#define UI_UNIT_Y
#define UI_UNIT_X
@ UI_BTYPE_TOGGLE
PointerRNA * UI_panel_custom_data_get(const Panel *panel)
void UI_panel_context_pointer_set(Panel *panel, const char *name, PointerRNA *ptr)
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
uiBut * uiDefIconButBitI(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, int *poin, float min, float max, std::optional< blender::StringRef > tip)
void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, blender::StringRefNull propname, int type, bool levels, bool brush, bool neg_slope, bool tone)
void uiLayoutSetContextPointer(uiLayout *layout, blender::StringRef name, PointerRNA *ptr)
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiItemPointerR(uiLayout *layout, PointerRNA *ptr, blender::StringRefNull propname, PointerRNA *searchptr, blender::StringRefNull searchpropname, std::optional< blender::StringRefNull > name, int icon)
void uiLayoutSetRedAlert(uiLayout *layout, bool redalert)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_LAYOUT_ALIGN_RIGHT
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
#define UI_ITEM_NONE
void uiLayoutSetUnitsX(uiLayout *layout, float unit)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiLayoutSetEmboss(uiLayout *layout, blender::ui::EmbossType emboss)
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:238
constexpr const char * c_str() const
void(*)(const bContext *, Panel *) PanelDrawFn
#define ID_IS_EDITABLE(_id)
#define ERROR_LIBDATA_MESSAGE
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
Object * context_active_object(const bContext *C)
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
int RNA_struct_ui_icon(const StructRNA *type)
int RNA_string_length(PointerRNA *ptr, const char *name)
bool RNA_pointer_is_null(const PointerRNA *ptr)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
ListBase paneltypes
bool(* is_disabled)(const Scene *scene, ModifierData *md, bool use_render_params)
ModifierTypeFlag flags
ModifierTypeType type
ListBase modifiers
void(* reorder)(bContext *C, Panel *pa, int new_index)
void(* set_list_data_expand_flag)(const bContext *C, Panel *pa, short expand_flag)
void(* draw)(const bContext *C, Panel *panel)
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, PanelType *pt)
char pin_to_last_property[BKE_ST_MAXNAME]
char context[BKE_ST_MAXNAME]
char translation_context[BKE_ST_MAXNAME]
char active_property[BKE_ST_MAXNAME]
ListBase children
char label[BKE_ST_MAXNAME]
short(* get_list_data_expand_flag)(const bContext *C, Panel *pa)
char parent_id[BKE_ST_MAXNAME]
PanelType * parent
void(* draw_header)(const bContext *C, Panel *panel)
struct uiLayout * layout
void * data
Definition RNA_types.hh:53
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
void label(blender::StringRef name, int icon)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
void menu_fn(blender::StringRefNull name, int icon, uiMenuCreateFunc func, void *arg)
uiLayout & row(bool align)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
wmOperatorStatus WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
PointerRNA * ptr
Definition wm_files.cc:4227
wmOperatorType * ot
Definition wm_files.cc:4226
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_operator_properties_free(PointerRNA *ptr)