Cleanup: RNA boolean names (use prefix conventions)
[blender.git] / source / blender / makesrna / intern / rna_wm_gizmo_api.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file \ingroup RNA
18  */
19
20
21 #include <stdlib.h>
22 #include <stdio.h>
23
24 #include "BLI_utildefines.h"
25
26 #include "BKE_report.h"
27
28 #include "RNA_define.h"
29 #include "RNA_enum_types.h"
30
31 #include "DNA_windowmanager_types.h"
32
33 #include "WM_api.h"
34
35 #include "rna_internal.h"  /* own include */
36
37 #ifdef RNA_RUNTIME
38
39 #include "UI_interface.h"
40 #include "BKE_context.h"
41
42 #include "ED_gizmo_library.h"
43
44 static void rna_gizmo_draw_preset_box(
45         wmGizmo *gz, float matrix[16], int select_id)
46 {
47         ED_gizmo_draw_preset_box(gz, (float (*)[4])matrix, select_id);
48 }
49
50 static void rna_gizmo_draw_preset_arrow(
51         wmGizmo *gz, float matrix[16], int axis, int select_id)
52 {
53         ED_gizmo_draw_preset_arrow(gz, (float (*)[4])matrix, axis, select_id);
54 }
55
56 static void rna_gizmo_draw_preset_circle(
57         wmGizmo *gz, float matrix[16], int axis, int select_id)
58 {
59         ED_gizmo_draw_preset_circle(gz, (float (*)[4])matrix, axis, select_id);
60 }
61
62 static void rna_gizmo_draw_preset_facemap(
63         wmGizmo *gz, struct bContext *C, struct Object *ob, int facemap, int select_id)
64 {
65         ED_gizmo_draw_preset_facemap(C, gz, ob, facemap, select_id);
66 }
67
68 /* -------------------------------------------------------------------- */
69 /** \name Gizmo Property Define
70  * \{ */
71
72 static void rna_gizmo_target_set_prop(
73         wmGizmo *gz, ReportList *reports, const char *target_propname,
74         PointerRNA *ptr, const char *propname, int index)
75 {
76         const wmGizmoPropertyType *gz_prop_type =
77                 WM_gizmotype_target_property_find(gz->type, target_propname);
78         if (gz_prop_type == NULL) {
79                 BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s' not found",
80                             gz->type->idname, target_propname);
81                 return;
82         }
83
84         PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
85         if (prop == NULL) {
86                 BKE_reportf(reports, RPT_ERROR, "Property '%s.%s' not found",
87                             RNA_struct_identifier(ptr->type), target_propname);
88                 return;
89         }
90
91         if (gz_prop_type->data_type != RNA_property_type(prop)) {
92                 const int gizmo_type_index = RNA_enum_from_value(rna_enum_property_type_items, gz_prop_type->data_type);
93                 const int prop_type_index = RNA_enum_from_value(rna_enum_property_type_items, RNA_property_type(prop));
94                 BLI_assert((gizmo_type_index != -1) && (prop_type_index == -1));
95
96                 BKE_reportf(reports, RPT_ERROR, "Gizmo target '%s.%s' expects '%s', '%s.%s' is '%s'",
97                             gz->type->idname, target_propname,
98                             rna_enum_property_type_items[gizmo_type_index].identifier,
99                             RNA_struct_identifier(ptr->type), propname,
100                             rna_enum_property_type_items[prop_type_index].identifier);
101                 return;
102         }
103
104         if (RNA_property_array_check(prop)) {
105                 if (index == -1) {
106                         const int prop_array_length = RNA_property_array_length(ptr, prop);
107                         if (gz_prop_type->array_length != prop_array_length) {
108                                 BKE_reportf(reports, RPT_ERROR,
109                                             "Gizmo target property '%s.%s' expects an array of length %d, found %d",
110                                             gz->type->idname, 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, RPT_ERROR,
120                                     "Gizmo target property '%s.%s' expects an array of length %d",
121                                     gz->type->idname, target_propname,
122                                     gz_prop_type->array_length);
123                         return;
124                 }
125         }
126
127         if (index >= gz_prop_type->array_length) {
128                 BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s', index %d must be below %d",
129                             gz->type->idname, target_propname, index, gz_prop_type->array_length);
130                 return;
131         }
132
133         WM_gizmo_target_property_def_rna_ptr(gz, gz_prop_type, ptr, prop, index);
134 }
135
136 static PointerRNA rna_gizmo_target_set_operator(
137         wmGizmo *gz, ReportList *reports, const char *opname, int part_index)
138 {
139         wmOperatorType *ot;
140
141         ot = WM_operatortype_find(opname, 0); /* print error next */
142         if (!ot || !ot->srna) {
143                 BKE_reportf(reports, RPT_ERROR, "%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
144                 return PointerRNA_NULL;
145         }
146
147         /* For the return value to be usable, we need 'PointerRNA.data' to be set. */
148         IDProperty *properties;
149         {
150                 IDPropertyTemplate val = {0};
151                 properties = IDP_New(IDP_GROUP, &val, "wmGizmoProperties");
152         }
153
154         return *WM_gizmo_operator_set(gz, part_index, ot, properties);
155 }
156
157 /** \} */
158
159 /* -------------------------------------------------------------------- */
160 /** \name Gizmo Property Access
161  * \{ */
162
163 static bool rna_gizmo_target_is_valid(
164         wmGizmo *gz, ReportList *reports, const char *target_propname)
165 {
166         wmGizmoProperty *gz_prop =
167                 WM_gizmo_target_property_find(gz, target_propname);
168         if (gz_prop == NULL) {
169                 BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s' not found",
170                             gz->type->idname, target_propname);
171                 return false;
172         }
173         return WM_gizmo_target_property_is_valid(gz_prop);
174 }
175
176 /** \} */
177
178 #else
179
180 void RNA_api_gizmo(StructRNA *srna)
181 {
182         /* Utility draw functions, since we don't expose new OpenGL drawing wrappers via Python yet.
183          * exactly how these should be exposed isn't totally clear.
184          * However it's probably good to have some high level API's for this anyway.
185          * Just note that this could be re-worked once tests are done.
186          */
187
188         FunctionRNA *func;
189         PropertyRNA *parm;
190
191         /* -------------------------------------------------------------------- */
192         /* Primitive Shapes */
193
194         /* draw_preset_box */
195         func = RNA_def_function(srna, "draw_preset_box", "rna_gizmo_draw_preset_box");
196         RNA_def_function_ui_description(func, "Draw a box");
197         parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
198         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
199         RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
200         RNA_def_property_ui_text(parm, "", "The matrix to transform");
201         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
202
203         /* draw_preset_box */
204         func = RNA_def_function(srna, "draw_preset_arrow", "rna_gizmo_draw_preset_arrow");
205         RNA_def_function_ui_description(func, "Draw a box");
206         parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
207         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
208         RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
209         RNA_def_property_ui_text(parm, "", "The matrix to transform");
210         RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
211         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
212
213         func = RNA_def_function(srna, "draw_preset_circle", "rna_gizmo_draw_preset_circle");
214         RNA_def_function_ui_description(func, "Draw a box");
215         parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
216         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
217         RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
218         RNA_def_property_ui_text(parm, "", "The matrix to transform");
219         RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
220         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
221
222         /* -------------------------------------------------------------------- */
223         /* Other Shapes */
224
225         /* draw_preset_facemap */
226         func = RNA_def_function(srna, "draw_preset_facemap", "rna_gizmo_draw_preset_facemap");
227         RNA_def_function_ui_description(func, "Draw the face-map of a mesh object");
228         RNA_def_function_flag(func, FUNC_USE_CONTEXT);
229         parm = RNA_def_pointer(func, "object", "Object", "", "Object");
230         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
231         parm = RNA_def_int(func, "face_map", 0, 0, INT_MAX, "Face map index", "", 0, INT_MAX);
232         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
233         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
234
235
236         /* -------------------------------------------------------------------- */
237         /* Property API */
238
239         /* Define Properties */
240         /* note, 'target_set_handler' is defined in 'bpy_rna_gizmo.c' */
241         func = RNA_def_function(srna, "target_set_prop", "rna_gizmo_target_set_prop");
242         RNA_def_function_flag(func, FUNC_USE_REPORTS);
243         RNA_def_function_ui_description(func, "");
244         parm = RNA_def_string(func, "target", NULL, 0, "", "Target property");
245         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
246         /* similar to UILayout.prop */
247         parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
248         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
249         parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data");
250         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
251         RNA_def_int(func, "index", -1, -1, INT_MAX, "", "", -1, INT_MAX); /* RNA_NO_INDEX == -1 */
252
253         func = RNA_def_function(srna, "target_set_operator", "rna_gizmo_target_set_operator");
254         RNA_def_function_flag(func, FUNC_USE_REPORTS);
255         RNA_def_function_ui_description(
256                 func, "Operator to run when activating the gizmo "
257                 "(overrides property targets)");
258         parm = RNA_def_string(func, "operator", NULL, 0, "", "Target operator");
259         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
260         RNA_def_int(func, "index", 0, 0, 255, "Part index", "", 0, 255);
261
262         /* similar to UILayout.operator */
263         parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "Operator properties to fill in");
264         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
265         RNA_def_function_return(func, parm);
266
267         /* Access Properties */
268         /* note, 'target_get', 'target_set' is defined in 'bpy_rna_gizmo.c' */
269         func = RNA_def_function(srna, "target_is_valid", "rna_gizmo_target_is_valid");
270         RNA_def_function_flag(func, FUNC_USE_REPORTS);
271         parm = RNA_def_string(func, "property", NULL, 0, "", "Property identifier");
272         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
273         RNA_def_function_ui_description(func, "");
274         parm = RNA_def_boolean(func, "result", 0, "", "");
275         RNA_def_function_return(func, parm);
276
277 }
278
279
280 void RNA_api_gizmogroup(StructRNA *UNUSED(srna))
281 {
282         /* nothing yet */
283 }
284
285 #endif