Merge with trunk/2.5 at r25563
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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
30 #include "DNA_object_types.h"
31
32 #include "BKE_context.h"
33 #include "BKE_utildefines.h"
34
35 #include "RNA_access.h"
36
37 #include "UI_interface.h"
38 #include "UI_resources.h"
39
40 #include "WM_api.h"
41 #include "WM_types.h"
42
43 /*************************** RNA Utilities ******************************/
44
45 uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2)
46 {
47         uiBut *but=NULL;
48         const char *propname= RNA_property_identifier(prop);
49         char prop_item[sizeof(((IDProperty *)NULL)->name)+4]; /* size of the ID prop name + room for [""] */
50         int arraylen= RNA_property_array_length(ptr, prop);
51
52         /* support for custom props */
53         if(RNA_property_is_idprop(prop)) {
54                 sprintf(prop_item, "[\"%s\"]", propname);
55                 propname= prop_item;
56         }
57
58         switch(RNA_property_type(prop)) {
59                 case PROP_BOOLEAN: {
60                         int value, length;
61
62                         if(arraylen && index == -1)
63                                 return NULL;
64
65                         length= RNA_property_array_length(ptr, prop);
66
67                         if(length)
68                                 value= RNA_property_boolean_get_index(ptr, prop, index);
69                         else
70                                 value= RNA_property_boolean_get(ptr, prop);
71                         
72                         if(icon && name && strcmp(name, "") == 0)
73                                 but= uiDefIconButR(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
74                         else if(icon)
75                                 but= uiDefIconTextButR(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
76                         else
77                                 but= uiDefButR(block, OPTION, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
78                         break;
79                 }
80                 case PROP_INT:
81                 case PROP_FLOAT:
82                         if(arraylen && index == -1) {
83                                 if(ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA))
84                                         but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
85                         }
86                         else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR)
87                                 but= uiDefButR(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
88                         else
89                                 but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
90                         break;
91                 case PROP_ENUM:
92                         if(icon && name && strcmp(name, "") == 0)
93                                 but= uiDefIconButR(block, MENU, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
94                         else if(icon)
95                                 but= uiDefIconTextButR(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
96                         else
97                                 but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
98                         break;
99                 case PROP_STRING:
100                         if(icon && name && strcmp(name, "") == 0)
101                                 but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
102                         else if(icon)
103                                 but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
104                         else
105                                 but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
106                         break;
107                 case PROP_POINTER: {
108                         PointerRNA pptr;
109                         int icon;
110
111                         pptr= RNA_property_pointer_get(ptr, prop);
112                         if(!pptr.type)
113                                 pptr.type= RNA_property_pointer_type(ptr, prop);
114                         icon= RNA_struct_ui_icon(pptr.type);
115                         if(icon == ICON_DOT)
116                                 icon= 0;
117
118                         but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
119                         break;
120                 }
121                 case PROP_COLLECTION: {
122                         char text[256];
123                         sprintf(text, "%d items", RNA_property_collection_length(ptr, prop));
124                         but= uiDefBut(block, LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
125                         uiButSetFlag(but, UI_BUT_DISABLED);
126                         break;
127                 }
128                 default:
129                         but= NULL;
130                         break;
131         }
132
133         return but;
134 }
135
136 void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr, int columns)
137 {
138         uiLayout *split, *col;
139         int flag;
140         char *name;
141
142         RNA_STRUCT_BEGIN(ptr, prop) {
143                 flag= RNA_property_flag(prop);
144                 if(flag & PROP_HIDDEN)
145                         continue;
146
147                 name= (char*)RNA_property_ui_name(prop);
148
149                 if(columns == 1) {
150                         col= uiLayoutColumn(layout, 1);
151                         uiItemL(col, name, 0);
152                 }
153                 else if(columns == 2) {
154                         split = uiLayoutSplit(layout, 0.5f, 0);
155
156                         uiItemL(uiLayoutColumn(split, 0), name, 0);
157                         col= uiLayoutColumn(split, 0);
158                 }
159                 else
160                         col= NULL;
161
162                 uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0);
163         }
164         RNA_STRUCT_END;
165 }
166
167 /***************************** ID Utilities *******************************/
168
169 int uiIconFromID(ID *id)
170 {
171         Object *ob;
172         PointerRNA ptr;
173         short idcode;
174
175         if(id==NULL)
176                 return 0;
177         
178         idcode= GS(id->name);
179
180         /* exception for objects */
181         if(idcode == ID_OB) {
182                 ob= (Object*)id;
183
184                 if(ob->type == OB_EMPTY)
185                         return ICON_EMPTY_DATA;
186                 else
187                         return uiIconFromID(ob->data);
188         }
189
190         /* otherwise get it through RNA, creating the pointer
191            will set the right type, also with subclassing */
192         RNA_id_pointer_create(id, &ptr);
193
194         return (ptr.type)? RNA_struct_ui_icon(ptr.type): 0;
195 }