Blender V5.0
rna_wm_gizmo_api.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 <cstdlib>
10
11#include "RNA_define.hh"
12#include "RNA_enum_types.hh"
13
14#include "WM_api.hh"
15
16#include "rna_internal.hh" /* own include */
17
18#ifdef RNA_RUNTIME
19
20# include "BLT_translation.hh"
21
22# include "BKE_context.hh"
23# include "BKE_idprop.hh"
24# include "BKE_report.hh"
25
26# include "UI_interface.hh"
27
28# include "ED_gizmo_library.hh"
29
30static void rna_gizmo_draw_preset_box(wmGizmo *gz, const float matrix[16], int select_id)
31{
32 ED_gizmo_draw_preset_box(gz, (const float (*)[4])matrix, select_id);
33}
34
35static void rna_gizmo_draw_preset_arrow(wmGizmo *gz,
36 const float matrix[16],
37 int axis,
38 int select_id)
39{
40 ED_gizmo_draw_preset_arrow(gz, (const float (*)[4])matrix, axis, select_id);
41}
42
43static void rna_gizmo_draw_preset_circle(wmGizmo *gz,
44 const float matrix[16],
45 int axis,
46 int select_id)
47{
48 ED_gizmo_draw_preset_circle(gz, (const float (*)[4])matrix, axis, select_id);
49}
50
51/* -------------------------------------------------------------------- */
54
55static void rna_gizmo_target_set_prop(wmGizmo *gz,
56 ReportList *reports,
57 const char *target_propname,
59 const char *propname,
60 int index)
61{
63 target_propname);
64 if (gz_prop_type == nullptr) {
65 BKE_reportf(reports,
67 "Gizmo target property '%s.%s' not found",
68 gz->type->idname,
69 target_propname);
70 return;
71 }
72
73 PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
74 if (prop == nullptr) {
75 BKE_reportf(reports,
77 "Property '%s.%s' not found",
79 propname);
80 return;
81 }
82
83 if (gz_prop_type->data_type != RNA_property_type(prop)) {
84 const int gizmo_type_index = RNA_enum_from_value(rna_enum_property_type_items,
85 gz_prop_type->data_type);
86 const int prop_type_index = RNA_enum_from_value(rna_enum_property_type_items,
87 RNA_property_type(prop));
88 BLI_assert((gizmo_type_index != -1) && (prop_type_index == -1));
89
90 BKE_reportf(reports,
92 "Gizmo target '%s.%s' expects '%s', '%s.%s' is '%s'",
93 gz->type->idname,
94 target_propname,
95 rna_enum_property_type_items[gizmo_type_index].identifier,
97 propname,
98 rna_enum_property_type_items[prop_type_index].identifier);
99 return;
100 }
101
102 if (RNA_property_array_check(prop)) {
103 if (index == -1) {
104 const int prop_array_length = RNA_property_array_length(ptr, prop);
105 if (gz_prop_type->array_length != prop_array_length) {
106 BKE_reportf(reports,
107 RPT_ERROR,
108 "Gizmo target property '%s.%s' expects an array of length %d, found %d",
109 gz->type->idname,
110 target_propname,
111 gz_prop_type->array_length,
112 prop_array_length);
113 return;
114 }
115 }
116 }
117 else {
118 if (gz_prop_type->array_length != 1) {
119 BKE_reportf(reports,
120 RPT_ERROR,
121 "Gizmo target property '%s.%s' expects an array of length %d",
122 gz->type->idname,
123 target_propname,
124 gz_prop_type->array_length);
125 return;
126 }
127 }
128
129 if (index >= gz_prop_type->array_length) {
130 BKE_reportf(reports,
131 RPT_ERROR,
132 "Gizmo target property '%s.%s', index %d must be below %d",
133 gz->type->idname,
134 target_propname,
135 index,
136 gz_prop_type->array_length);
137 return;
138 }
139
140 WM_gizmo_target_property_def_rna_ptr(gz, gz_prop_type, ptr, prop, index);
141}
142
143static PointerRNA rna_gizmo_target_set_operator(wmGizmo *gz,
144 ReportList *reports,
145 const char *opname,
146 int part_index)
147{
149
150 ot = WM_operatortype_find(opname, false); /* print error next */
151 if (!ot || !ot->srna) {
152 BKE_reportf(reports,
153 RPT_ERROR,
154 "%s '%s'",
155 ot ? RPT_("Operator missing srna") : RPT_("Unknown operator"),
156 opname);
157 return PointerRNA_NULL;
158 }
159
160 /* For the return value to be usable, we need 'PointerRNA.data' to be set. */
161 IDProperty *properties = blender::bke::idprop::create_group("wmGizmoProperties").release();
162
163 return *WM_gizmo_operator_set(gz, part_index, ot, properties);
164}
165
167
168/* -------------------------------------------------------------------- */
171
172static bool rna_gizmo_target_is_valid(wmGizmo *gz,
173 ReportList *reports,
174 const char *target_propname)
175{
176 wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, target_propname);
177 if (gz_prop == nullptr) {
178 BKE_reportf(reports,
179 RPT_ERROR,
180 "Gizmo target property '%s.%s' not found",
181 gz->type->idname,
182 target_propname);
183 return false;
184 }
185 return WM_gizmo_target_property_is_valid(gz_prop);
186}
187
189
190#else
191
193{
194 /* Utility draw functions, since we don't expose new OpenGL drawing wrappers via Python yet.
195 * exactly how these should be exposed isn't totally clear.
196 * However it's probably good to have some high level API's for this anyway.
197 * Just note that this could be re-worked once tests are done.
198 */
199
200 FunctionRNA *func;
201 PropertyRNA *parm;
202
203 /* -------------------------------------------------------------------- */
204 /* Primitive Shapes */
205
206 /* draw_preset_box */
207 func = RNA_def_function(srna, "draw_preset_box", "rna_gizmo_draw_preset_box");
208 RNA_def_function_ui_description(func, "Draw a box");
209 parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
212 RNA_def_property_ui_text(parm, "", "The matrix to transform");
213 RNA_def_int(func,
214 "select_id",
215 -1,
216 -1,
217 INT_MAX,
218 "ID to use when gizmo is selectable. Use -1 when not selecting.",
219 "",
220 -1,
221 INT_MAX);
222
223 /* draw_preset_box */
224 func = RNA_def_function(srna, "draw_preset_arrow", "rna_gizmo_draw_preset_arrow");
225 RNA_def_function_ui_description(func, "Draw a box");
226 parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
229 RNA_def_property_ui_text(parm, "", "The matrix to transform");
230 RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
231 RNA_def_int(func,
232 "select_id",
233 -1,
234 -1,
235 INT_MAX,
236 "ID to use when gizmo is selectable. Use -1 when not selecting.",
237 "",
238 -1,
239 INT_MAX);
240
241 func = RNA_def_function(srna, "draw_preset_circle", "rna_gizmo_draw_preset_circle");
242 RNA_def_function_ui_description(func, "Draw a box");
243 parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
246 RNA_def_property_ui_text(parm, "", "The matrix to transform");
247 RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
248 RNA_def_int(func,
249 "select_id",
250 -1,
251 -1,
252 INT_MAX,
253 "ID to use when gizmo is selectable. Use -1 when not selecting.",
254 "",
255 -1,
256 INT_MAX);
257
258 /* -------------------------------------------------------------------- */
259 /* Other Shapes */
260
261 /* -------------------------------------------------------------------- */
262 /* Property API */
263
264 /* Define Properties */
265 /* NOTE: 'target_set_handler' is defined in `bpy_rna_gizmo.cc`. */
266 func = RNA_def_function(srna, "target_set_prop", "rna_gizmo_target_set_prop");
269 parm = RNA_def_string(func, "target", nullptr, 0, "", "Target property");
271 /* similar to UILayout.prop */
272 parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
274 parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in data");
276 RNA_def_int(func, "index", -1, -1, INT_MAX, "", "", -1, INT_MAX); /* RNA_NO_INDEX == -1 */
277
278 func = RNA_def_function(srna, "target_set_operator", "rna_gizmo_target_set_operator");
281 "Operator to run when activating the gizmo "
282 "(overrides property targets)");
283 parm = RNA_def_string(func, "operator", nullptr, 0, "", "Target operator");
285 RNA_def_int(func, "index", 0, 0, 255, "Part index", "", 0, 255);
286
287 /* similar to UILayout.operator */
288 parm = RNA_def_pointer(
289 func, "properties", "OperatorProperties", "", "Operator properties to fill in");
291 RNA_def_function_return(func, parm);
292
293 /* Access Properties */
294 /* NOTE: 'target_get', 'target_set' is defined in `bpy_rna_gizmo.cc`. */
295 func = RNA_def_function(srna, "target_is_valid", "rna_gizmo_target_is_valid");
297 parm = RNA_def_string(func, "property", nullptr, 0, "", "Property identifier");
300 parm = RNA_def_boolean(func, "result", false, "", "");
301 RNA_def_function_return(func, parm);
302}
303
305{
306 /* nothing yet */
307}
308
309#endif
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
#define BLI_assert(a)
Definition BLI_assert.h:46
#define RPT_(msgid)
@ PARM_RNAPTR
Definition RNA_types.hh:547
@ PARM_REQUIRED
Definition RNA_types.hh:545
@ FUNC_USE_REPORTS
Definition RNA_types.hh:914
@ PROP_FLOAT
Definition RNA_types.hh:164
PropertyFlag
Definition RNA_types.hh:300
@ PROP_NEVER_NULL
Definition RNA_types.hh:377
@ PROP_MATRIX
Definition RNA_types.hh:265
void ED_gizmo_draw_preset_box(const wmGizmo *gz, const float mat[4][4], int select_id)
void ED_gizmo_draw_preset_circle(const wmGizmo *gz, const float mat[4][4], int axis, int select_id)
void ED_gizmo_draw_preset_arrow(const wmGizmo *gz, const float mat[4][4], int axis, int select_id)
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRef prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
bool RNA_property_array_check(PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PropertyType RNA_property_type(PropertyRNA *prop)
const PointerRNA PointerRNA_NULL
const char * RNA_struct_identifier(const StructRNA *type)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
const int rna_matrix_dimsize_4x4[]
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_function_flag(FunctionRNA *func, int flag)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
const EnumPropertyItem rna_enum_object_axis_items[]
const EnumPropertyItem rna_enum_property_type_items[]
Definition rna_rna.cc:43
void RNA_api_gizmo(StructRNA *srna)
void RNA_api_gizmogroup(StructRNA *)
const char * idname
const wmGizmoType * type
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237
PointerRNA * WM_gizmo_operator_set(wmGizmo *gz, int part_index, wmOperatorType *ot, IDProperty *properties)
Definition wm_gizmo.cc:203
const wmGizmoPropertyType * WM_gizmotype_target_property_find(const wmGizmoType *gzt, const char *idname)
bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *gz_prop)
wmGizmoProperty * WM_gizmo_target_property_find(wmGizmo *gz, const char *idname)
void WM_gizmo_target_property_def_rna_ptr(wmGizmo *gz, const wmGizmoPropertyType *gz_prop_type, PointerRNA *ptr, PropertyRNA *prop, int index)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)