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