UI
[blender-staging.git] / source / blender / editors / interface / interface_templates.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Blender Foundation 2009.
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <stdlib.h>
26
27 #include "MEM_guardedalloc.h"
28
29 #include "BLI_string.h"
30
31 #include "BKE_context.h"
32 #include "BKE_library.h"
33 #include "BKE_utildefines.h"
34
35 #include "ED_screen.h"
36
37 #include "RNA_access.h"
38
39 #include "WM_api.h"
40 #include "WM_types.h"
41
42 #include "UI_interface.h"
43 #include "UI_resources.h"
44
45 void ui_template_fix_linking()
46 {
47 }
48
49 /********************** Header Template *************************/
50
51 void uiTemplateHeader(uiLayout *layout, bContext *C)
52 {
53         uiBlock *block;
54         
55         block= uiLayoutFreeBlock(layout);
56         ED_area_header_standardbuttons(C, block, 0);
57 }
58
59 /******************* Header ID Template ************************/
60
61 typedef struct TemplateHeaderID {
62         PointerRNA ptr;
63         PropertyRNA *prop;
64
65         int flag;
66         short browse;
67
68         char newop[256];
69         char openop[256];
70         char unlinkop[256];
71 } TemplateHeaderID;
72
73 static void template_header_id_cb(bContext *C, void *arg_litem, void *arg_event)
74 {
75         TemplateHeaderID *template= (TemplateHeaderID*)arg_litem;
76         PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
77         ID *idtest, *id= idptr.data;
78         ListBase *lb= wich_libbase(CTX_data_main(C), ID_TXT);
79         int nr, event= GET_INT_FROM_POINTER(arg_event);
80         
81         if(event == UI_ID_BROWSE && template->browse == 32767)
82                 event= UI_ID_ADD_NEW;
83         else if(event == UI_ID_BROWSE && template->browse == 32766)
84                 event= UI_ID_OPEN;
85
86         switch(event) {
87                 case UI_ID_BROWSE: {
88                         if(template->browse== -2) {
89                                 /* XXX implement or find a replacement
90                                  * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &template->browse, do_global_buttons); */
91                                 return;
92                         }
93                         if(template->browse < 0)
94                                 return;
95
96                         for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) {
97                                 if(nr==template->browse) {
98                                         if(id == idtest)
99                                                 return;
100
101                                         id= idtest;
102                                         RNA_id_pointer_create(id, &idptr);
103                                         RNA_property_pointer_set(&template->ptr, template->prop, idptr);
104                                         RNA_property_update(C, &template->ptr, template->prop);
105                                         /* XXX */
106
107                                         break;
108                                 }
109                         }
110                         break;
111                 }
112 #if 0
113                 case UI_ID_DELETE:
114                         id= NULL;
115                         break;
116                 case UI_ID_FAKE_USER:
117                         if(id) {
118                                 if(id->flag & LIB_FAKEUSER) id->us++;
119                                 else id->us--;
120                         }
121                         else return;
122                         break;
123 #endif
124                 case UI_ID_PIN:
125                         break;
126                 case UI_ID_ADD_NEW:
127                         WM_operator_name_call(C, template->newop, WM_OP_INVOKE_REGION_WIN, NULL);
128                         break;
129                 case UI_ID_OPEN:
130                         WM_operator_name_call(C, template->openop, WM_OP_INVOKE_REGION_WIN, NULL);
131                         break;
132 #if 0
133                 case UI_ID_ALONE:
134                         if(!id || id->us < 1)
135                                 return;
136                         break;
137                 case UI_ID_LOCAL:
138                         if(!id || id->us < 1)
139                                 return;
140                         break;
141                 case UI_ID_AUTO_NAME:
142                         break;
143 #endif
144         }
145 }
146
147 static void template_header_ID(bContext *C, uiBlock *block, TemplateHeaderID *template)
148 {
149         uiBut *but;
150         TemplateHeaderID *duptemplate;
151         PointerRNA idptr;
152         ListBase *lb;
153         int x= 0, y= 0;
154
155         idptr= RNA_property_pointer_get(&template->ptr, template->prop);
156         lb= wich_libbase(CTX_data_main(C), ID_TXT);
157
158         uiBlockBeginAlign(block);
159         if(template->flag & UI_ID_BROWSE) {
160                 char *extrastr, *str;
161                 
162                 if((template->flag & UI_ID_ADD_NEW) && (template->flag && UI_ID_OPEN))
163                         extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
164                 else if(template->flag & UI_ID_ADD_NEW)
165                         extrastr= "ADD NEW %x 32767";
166                 else if(template->flag & UI_ID_OPEN)
167                         extrastr= "OPEN NEW %x 32766";
168                 else
169                         extrastr= NULL;
170
171                 duptemplate= MEM_dupallocN(template);
172                 IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse);
173
174                 but= uiDefButS(block, MENU, 0, str, x, y, UI_UNIT_X, UI_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new");
175                 uiButSetNFunc(but, template_header_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE));
176                 x+= UI_UNIT_X;
177         
178                 MEM_freeN(str);
179         }
180
181         /* text button with name */
182         if(idptr.data) {
183                 char name[64];
184
185                 text_idbutton(idptr.data, name);
186                 but= uiDefButR(block, TEX, 0, name, x, y, UI_UNIT_X*6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL);
187                 uiButSetNFunc(but, template_header_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
188                 x += UI_UNIT_X*6;
189
190                 /* delete button */
191                 if(template->flag & UI_ID_DELETE) {
192                         but= uiDefIconButO(block, BUT, template->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, x, y, UI_UNIT_X, UI_UNIT_Y, NULL);
193                         x += UI_UNIT_X;
194                 }
195         }
196         uiBlockEndAlign(block);
197 }
198
199 void uiTemplateHeaderID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
200 {
201         TemplateHeaderID *template;
202         uiBlock *block;
203         PropertyRNA *prop;
204
205         if(!ptr->data)
206                 return;
207
208         prop= RNA_struct_find_property(ptr, propname);
209
210         if(!prop) {
211                 printf("uiTemplateHeaderID: property not found: %s\n", propname);
212                 return;
213         }
214
215         template= MEM_callocN(sizeof(TemplateHeaderID), "TemplateHeaderID");
216         template->ptr= *ptr;
217         template->prop= prop;
218         template->flag= UI_ID_BROWSE|UI_ID_RENAME;
219
220         if(newop) {
221                 template->flag |= UI_ID_ADD_NEW;
222                 BLI_strncpy(template->newop, newop, sizeof(template->newop));
223         }
224         if(openop) {
225                 template->flag |= UI_ID_OPEN;
226                 BLI_strncpy(template->openop, openop, sizeof(template->openop));
227         }
228         if(unlinkop) {
229                 template->flag |= UI_ID_DELETE;
230                 BLI_strncpy(template->unlinkop, unlinkop, sizeof(template->unlinkop));
231         }
232
233         block= uiLayoutFreeBlock(layout);
234         template_header_ID(C, block, template);
235
236         MEM_freeN(template);
237 }
238