Centralized operator UI drawing into a new function uiLayoutOperatorButs(),
[blender.git] / source / blender / editors / interface / interface_utils.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  * The Original Code is Copyright (C) 2009 Blender Foundation.
19  * All rights reserved.
20  * 
21  * Contributor(s): Blender Foundation
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <assert.h>
30
31 #include "DNA_object_types.h"
32
33 #include "BKE_context.h"
34 #include "BKE_utildefines.h"
35
36 #include "RNA_access.h"
37
38 #include "UI_interface.h"
39 #include "UI_resources.h"
40
41
42 /*************************** RNA Utilities ******************************/
43
44 uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2)
45 {
46         uiBut *but=NULL;
47         const char *propname= RNA_property_identifier(prop);
48         char prop_item[sizeof(((IDProperty *)NULL)->name)+4]; /* size of the ID prop name + room for [""] */
49         int arraylen= RNA_property_array_length(ptr, prop);
50
51         /* support for custom props */
52         if(RNA_property_is_idprop(prop)) {
53                 sprintf(prop_item, "[\"%s\"]", propname);
54                 propname= prop_item;
55         }
56
57         switch(RNA_property_type(prop)) {
58                 case PROP_BOOLEAN: {
59                         int value, length;
60
61                         if(arraylen && index == -1)
62                                 return NULL;
63
64                         length= RNA_property_array_length(ptr, prop);
65
66                         if(length)
67                                 value= RNA_property_boolean_get_index(ptr, prop, index);
68                         else
69                                 value= RNA_property_boolean_get(ptr, prop);
70                         
71                         if(icon && name && strcmp(name, "") == 0)
72                                 but= uiDefIconButR(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
73                         else if(icon)
74                                 but= uiDefIconTextButR(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
75                         else
76                                 but= uiDefButR(block, OPTION, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
77                         break;
78                 }
79                 case PROP_INT:
80                 case PROP_FLOAT:
81                         if(arraylen && index == -1) {
82                                 if(ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA))
83                                         but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
84                         }
85                         else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR)
86                                 but= uiDefButR(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
87                         else
88                                 but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
89                         break;
90                 case PROP_ENUM:
91                         if(icon && name && strcmp(name, "") == 0)
92                                 but= uiDefIconButR(block, MENU, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
93                         else if(icon)
94                                 but= uiDefIconTextButR(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
95                         else
96                                 but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
97                         break;
98                 case PROP_STRING:
99                         if(icon && name && strcmp(name, "") == 0)
100                                 but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
101                         else if(icon)
102                                 but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
103                         else
104                                 but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
105                         break;
106                 case PROP_POINTER: {
107                         PointerRNA pptr;
108                         int icon;
109
110                         pptr= RNA_property_pointer_get(ptr, prop);
111                         if(!pptr.type)
112                                 pptr.type= RNA_property_pointer_type(ptr, prop);
113                         icon= RNA_struct_ui_icon(pptr.type);
114                         if(icon == ICON_DOT)
115                                 icon= 0;
116
117                         but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
118                         break;
119                 }
120                 case PROP_COLLECTION: {
121                         char text[256];
122                         sprintf(text, "%d items", RNA_property_collection_length(ptr, prop));
123                         but= uiDefBut(block, LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
124                         uiButSetFlag(but, UI_BUT_DISABLED);
125                         break;
126                 }
127                 default:
128                         but= NULL;
129                         break;
130         }
131
132         return but;
133 }
134
135 int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(PropertyRNA *), const char label_align)
136 {
137         uiLayout *split, *col;
138         int flag;
139         const char *name;
140         int tot= 0;
141
142         assert(ELEM3(label_align, '\0', 'H', 'V'));
143
144         RNA_STRUCT_BEGIN(ptr, prop) {
145                 flag= RNA_property_flag(prop);
146                 if(flag & PROP_HIDDEN || (check_prop && check_prop(prop)==FALSE))
147                         continue;
148
149                 if(label_align != '\0') {
150                         name= RNA_property_ui_name(prop);
151
152                         if(label_align=='V') {
153                                 col= uiLayoutColumn(layout, 1);
154                                 uiItemL(col, name, 0);
155                         }
156                         else if(label_align=='H') {
157                                 split = uiLayoutSplit(layout, 0.5f, 0);
158
159                                 uiItemL(uiLayoutColumn(split, 0), name, 0);
160                                 col= uiLayoutColumn(split, 0);
161                         }
162                         else {
163                                 col= NULL;
164                         }
165
166                         name= ""; /* name is shown above, empty name for button below */
167                 }
168                 else {
169                         col= layout;
170                         name= NULL; /* no smart label alignment, show default name with button */
171                 }
172
173                 uiItemFullR(col, ptr, prop, -1, 0, 0, name, 0);
174                 tot++;
175         }
176         RNA_STRUCT_END;
177
178         return tot;
179 }
180
181 /***************************** ID Utilities *******************************/
182
183 int uiIconFromID(ID *id)
184 {
185         Object *ob;
186         PointerRNA ptr;
187         short idcode;
188
189         if(id==NULL)
190                 return 0;
191         
192         idcode= GS(id->name);
193
194         /* exception for objects */
195         if(idcode == ID_OB) {
196                 ob= (Object*)id;
197
198                 if(ob->type == OB_EMPTY)
199                         return ICON_EMPTY_DATA;
200                 else
201                         return uiIconFromID(ob->data);
202         }
203
204         /* otherwise get it through RNA, creating the pointer
205            will set the right type, also with subclassing */
206         RNA_id_pointer_create(id, &ptr);
207
208         return (ptr.type)? RNA_struct_ui_icon(ptr.type): 0;
209 }