f55bdd152792ade7dd052ee7fdcf74185eabffdb
[blender.git] / source / blender / blenkernel / intern / property.c
1
2 /*  property.c   june 2000
3  * 
4  *  ton roosendaal
5  * $Id$
6  *
7  * ***** BEGIN GPL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include "MEM_guardedalloc.h"
42
43 #include "DNA_property_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_listBase.h"
46
47
48 #include "BLI_blenlib.h"
49 #include "BKE_bad_level_calls.h"
50 #include "BKE_property.h"
51
52 void free_property(bProperty *prop)
53 {
54         
55         if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin);
56         MEM_freeN(prop);
57         
58 }
59
60 void free_properties(ListBase *lb)
61 {
62         bProperty *prop;
63         
64         while( (prop= lb->first) ) {
65                 BLI_remlink(lb, prop);
66                 free_property(prop);
67         }
68 }
69
70 bProperty *copy_property(bProperty *prop)
71 {
72         bProperty *propn;
73         
74         propn= MEM_dupallocN(prop);
75         if(prop->poin && prop->poin != &prop->data) {
76                 propn->poin= MEM_dupallocN(prop->poin);
77         }
78         else propn->poin= &propn->data;
79         
80         return propn;
81 }
82
83 void copy_properties(ListBase *lbn, ListBase *lbo)
84 {
85         bProperty *prop, *propn;
86         
87         lbn->first= lbn->last= 0;
88         prop= lbo->first;
89         while(prop) {
90                 propn= copy_property(prop);
91                 BLI_addtail(lbn, propn);
92                 prop= prop->next;
93         }
94         
95         
96 }
97
98 void init_property(bProperty *prop)
99 {
100         /* also use when property changes type */
101         
102         if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin);
103         prop->poin= 0;
104         
105         prop->otype= prop->type;
106         prop->data= 0;
107         
108         switch(prop->type) {
109         case PROP_BOOL:
110                 prop->poin= &prop->data;
111                 break;
112         case PROP_INT:
113                 prop->poin= &prop->data;
114                 break;
115         case PROP_FLOAT:
116                 prop->poin= &prop->data;
117                 break;
118         case PROP_STRING:
119                 prop->poin= MEM_callocN(MAX_PROPSTRING, "property string");
120                 break;
121         case PROP_TIME:
122                 prop->poin= &prop->data;
123                 break;
124         }
125 }
126
127
128 bProperty *new_property(int type)
129 {
130         bProperty *prop;
131
132         prop= MEM_callocN(sizeof(bProperty), "property");
133         prop->type= type;
134
135         init_property(prop);
136         
137         strcpy(prop->name, "prop");
138
139         return prop;
140 }
141
142 bProperty *get_property(Object *ob, char *name)
143 {
144         bProperty *prop;
145         
146         prop= ob->prop.first;
147         while(prop) {
148                 if( strcmp(prop->name, name)==0 ) return prop;
149                 prop= prop->next;
150         }
151         return NULL;
152 }
153
154 /* negative: prop is smaller
155  * positive: prop is larger
156  */
157 int compare_property(bProperty *prop, char *str)
158 {
159 //      extern int Gdfra;               /* sector.c */
160         float fvalue, ftest;
161         
162         switch(prop->type) {
163         case PROP_BOOL:
164                 if(BLI_strcasecmp(str, "true")==0) {
165                         if(prop->data==1) return 0;
166                         else return 1;
167                 }
168                 else if(BLI_strcasecmp(str, "false")==0) {
169                         if(prop->data==0) return 0;
170                         else return 1;
171                 }
172                 /* no break, do prop_int too! */
173                 
174         case PROP_INT:
175                 return prop->data - atoi(str);
176
177         case PROP_FLOAT:
178         case PROP_TIME:
179                 // WARNING: untested for PROP_TIME
180                 // function isn't used currently
181                 fvalue= *((float *)&prop->data);
182                 ftest= (float)atof(str);
183                 if( fvalue > ftest) return 1;
184                 else if( fvalue < ftest) return -1;
185                 return 0;
186
187         case PROP_STRING:
188                 return strcmp(prop->poin, str);
189         }
190         
191         return 0;
192 }
193
194 void set_property(bProperty *prop, char *str)
195 {
196 //      extern int Gdfra;               /* sector.c */
197
198         switch(prop->type) {
199         case PROP_BOOL:
200                 if(BLI_strcasecmp(str, "true")==0) prop->data= 1;
201                 else if(BLI_strcasecmp(str, "false")==0) prop->data= 0;
202                 else prop->data= (atoi(str)!=0);
203                 break;
204         case PROP_INT:
205                 prop->data= atoi(str);
206                 break;
207         case PROP_FLOAT:
208         case PROP_TIME:
209                 *((float *)&prop->data)= (float)atof(str);
210                 break;
211         case PROP_STRING:
212                 strcpy(prop->poin, str);
213                 break;
214         }
215         
216 }
217
218 void add_property(bProperty *prop, char *str)
219 {
220 //      extern int Gdfra;               /* sector.c */
221
222         switch(prop->type) {
223         case PROP_BOOL:
224         case PROP_INT:
225                 prop->data+= atoi(str);
226                 break;
227         case PROP_FLOAT:
228         case PROP_TIME:
229                 *((float *)&prop->data)+= (float)atof(str);
230                 break;
231         case PROP_STRING:
232                 /* strcpy(prop->poin, str); */
233                 break;
234         }
235 }
236
237 /* reads value of property, sets it in chars in str */
238 void set_property_valstr(bProperty *prop, char *str)
239 {
240 //      extern int Gdfra;               /* sector.c */
241
242         if(str == NULL) return;
243
244         switch(prop->type) {
245         case PROP_BOOL:
246         case PROP_INT:
247                 sprintf(str, "%d", prop->data);
248                 break;
249         case PROP_FLOAT:
250         case PROP_TIME:
251                 sprintf(str, "%f", *((float *)&prop->data));
252                 break;
253         case PROP_STRING:
254                 BLI_strncpy(str, prop->poin, MAX_PROPSTRING);
255                 break;
256         }
257 }
258
259 void cp_property(bProperty *prop1, bProperty *prop2)
260 {
261         char str[128];
262
263         set_property_valstr(prop2, str);
264
265         set_property(prop1, str);
266 }