Merge branch 'master' into blender2.8
[blender.git] / source / blender / makesrna / intern / rna_wm_manipulator_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_manipulator_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_manipulator_library.h"
48
49 static void rna_manipulator_draw_preset_box(
50         wmManipulator *mpr, float matrix[16], int select_id)
51 {
52         ED_manipulator_draw_preset_box(mpr, (float (*)[4])matrix, select_id);
53 }
54
55 static void rna_manipulator_draw_preset_arrow(
56         wmManipulator *mpr, float matrix[16], int axis, int select_id)
57 {
58         ED_manipulator_draw_preset_arrow(mpr, (float (*)[4])matrix, axis, select_id);
59 }
60
61 static void rna_manipulator_draw_preset_circle(
62         wmManipulator *mpr, float matrix[16], int axis, int select_id)
63 {
64         ED_manipulator_draw_preset_circle(mpr, (float (*)[4])matrix, axis, select_id);
65 }
66
67 static void rna_manipulator_draw_preset_facemap(
68         wmManipulator *mpr, struct bContext *C, struct Object *ob, int facemap, int select_id)
69 {
70         struct Scene *scene = CTX_data_scene(C);
71         ED_manipulator_draw_preset_facemap(C, mpr, scene, ob, facemap, select_id);
72 }
73
74 static void rna_manipulator_target_set_prop(
75         wmManipulator *mpr, ReportList *reports, const char *target_propname,
76         PointerRNA *ptr, const char *propname, int index)
77 {
78         const wmManipulatorPropertyType *mpr_prop_type =
79                 WM_manipulatortype_target_property_find(mpr->type, target_propname);
80         if (mpr_prop_type == NULL) {
81                 BKE_reportf(reports, RPT_ERROR, "Manipulator target property '%s.%s' not found",
82                             mpr->type->idname, target_propname);
83                 return;
84         }
85
86         PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
87         if (prop == NULL) {
88                 BKE_reportf(reports, RPT_ERROR, "Property '%s.%s' not found",
89                             RNA_struct_identifier(ptr->type), target_propname);
90                 return;
91         }
92
93         if (mpr_prop_type->data_type != RNA_property_type(prop)) {
94                 const int manipulator_type_index = RNA_enum_from_value(rna_enum_property_type_items, mpr_prop_type->data_type);
95                 const int prop_type_index = RNA_enum_from_value(rna_enum_property_type_items, RNA_property_type(prop));
96                 BLI_assert((manipulator_type_index != -1) && (prop_type_index == -1));
97
98                 BKE_reportf(reports, RPT_ERROR, "Manipulator target '%s.%s' expects '%s', '%s.%s' is '%s'",
99                             mpr->type->idname, target_propname,
100                             rna_enum_property_type_items[manipulator_type_index].identifier,
101                             RNA_struct_identifier(ptr->type), propname,
102                             rna_enum_property_type_items[prop_type_index].identifier);
103                 return;
104         }
105
106         if (RNA_property_array_check(prop)) {
107                 if (index == -1) {
108                         const int prop_array_length = RNA_property_array_length(ptr, prop);
109                         if (mpr_prop_type->array_length != prop_array_length) {
110                                 BKE_reportf(reports, RPT_ERROR,
111                                             "Manipulator target property '%s.%s' expects an array of length %d, found %d",
112                                             mpr->type->idname, target_propname,
113                                             mpr_prop_type->array_length,
114                                             prop_array_length);
115                                 return;
116                         }
117                 }
118         }
119         else {
120                 if (mpr_prop_type->array_length != 1) {
121                         BKE_reportf(reports, RPT_ERROR,
122                                     "Manipulator target property '%s.%s' expects an array of length %d",
123                                     mpr->type->idname, target_propname,
124                                     mpr_prop_type->array_length);
125                         return;
126                 }
127         }
128
129         if (index >= mpr_prop_type->array_length) {
130                 BKE_reportf(reports, RPT_ERROR, "Manipulator target property '%s.%s', index %d must be below %d",
131                             mpr->type->idname, target_propname, index, mpr_prop_type->array_length);
132                 return;
133         }
134
135         WM_manipulator_target_property_def_rna_ptr(mpr, mpr_prop_type, ptr, prop, index);
136 }
137
138 static PointerRNA rna_manipulator_target_set_operator(
139         wmManipulator *mpr, ReportList *reports, const char *opname)
140 {
141         wmOperatorType *ot;
142
143         ot = WM_operatortype_find(opname, 0); /* print error next */
144         if (!ot || !ot->srna) {
145                 BKE_reportf(reports, RPT_ERROR, "%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
146                 return PointerRNA_NULL;
147         }
148
149         /* For the return value to be usable, we need 'PointerRNA.data' to be set. */
150         IDProperty *properties;
151         {
152                 IDPropertyTemplate val = {0};
153                 properties = IDP_New(IDP_GROUP, &val, "wmManipulatorProperties");
154         }
155
156         WM_manipulator_set_operator(mpr, ot, properties);
157
158         return mpr->op_data.ptr;
159 }
160
161 #else
162
163 void RNA_api_manipulator(StructRNA *srna)
164 {
165         /* Utility draw functions, since we don't expose new OpenGL drawing wrappers via Python yet.
166          * exactly how these should be exposed isn't totally clear.
167          * However it's probably good to have some high level API's for this anyway.
168          * Just note that this could be re-worked once tests are done.
169          */
170
171         FunctionRNA *func;
172         PropertyRNA *parm;
173
174         /* -------------------------------------------------------------------- */
175         /* Primitive Shapes */
176
177         /* draw_preset_box */
178         func = RNA_def_function(srna, "draw_preset_box", "rna_manipulator_draw_preset_box");
179         RNA_def_function_ui_description(func, "Draw a box");
180         parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
181         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
182         RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
183         RNA_def_property_ui_text(parm, "", "The matrix to transform");
184         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
185
186         /* draw_preset_box */
187         func = RNA_def_function(srna, "draw_preset_arrow", "rna_manipulator_draw_preset_arrow");
188         RNA_def_function_ui_description(func, "Draw a box");
189         parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
190         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
191         RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
192         RNA_def_property_ui_text(parm, "", "The matrix to transform");
193         RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
194         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
195
196         func = RNA_def_function(srna, "draw_preset_circle", "rna_manipulator_draw_preset_circle");
197         RNA_def_function_ui_description(func, "Draw a box");
198         parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
199         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
200         RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
201         RNA_def_property_ui_text(parm, "", "The matrix to transform");
202         RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
203         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
204
205         /* -------------------------------------------------------------------- */
206         /* Other Shapes */
207
208         /* draw_preset_facemap */
209         func = RNA_def_function(srna, "draw_preset_facemap", "rna_manipulator_draw_preset_facemap");
210         RNA_def_function_ui_description(func, "Draw the face-map of a mesh object");
211         RNA_def_function_flag(func, FUNC_USE_CONTEXT);
212         parm = RNA_def_pointer(func, "object", "Object", "", "Object");
213         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
214         RNA_def_int(func, "facemap", 0, 0, INT_MAX, "Face map index", "", 0, INT_MAX);
215         RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
216
217
218         /* -------------------------------------------------------------------- */
219         /* Property API */
220
221         /* note, 'target_set_handler' is defined in 'bpy_rna_manipulator.c' */
222         func = RNA_def_function(srna, "target_set_prop", "rna_manipulator_target_set_prop");
223         RNA_def_function_flag(func, FUNC_USE_REPORTS);
224         RNA_def_function_ui_description(func, "");
225         parm = RNA_def_string(func, "target", NULL, 0, "", "Target property");
226         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
227         /* similar to UILayout.prop */
228         parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
229         RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
230         parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data");
231         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
232         RNA_def_int(func, "index", -1, -1, INT_MAX, "", "", -1, INT_MAX); /* RNA_NO_INDEX == -1 */
233
234         func = RNA_def_function(srna, "target_set_operator", "rna_manipulator_target_set_operator");
235         RNA_def_function_flag(func, FUNC_USE_REPORTS);
236         RNA_def_function_ui_description(
237                 func,"Operator to run when activating the manipulator "
238                 "(overrides property targets)");
239         parm = RNA_def_string(func, "operator", NULL, 0, "", "Target operator");
240         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
241         /* similar to UILayout.operator */
242         parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "Operator properties to fill in");
243         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
244         RNA_def_function_return(func, parm);
245
246 }
247
248
249 void RNA_api_manipulatorgroup(StructRNA *UNUSED(srna))
250 {
251         /* nothing yet */
252 }
253
254 #endif