add the 2.1-bootstrap dir to MONO_PATH when running smcs
[moon.git] / src / resources.cpp
blob4598c0a9ceb98714a9590c084182e6dfe98b7036
1 /*
2 * resources.cpp
4 * Copyright 2007 Novell, Inc. (http://www.novell.com)
6 * See the LICENSE file included with the distribution for details.
7 *
8 */
10 #include <config.h>
11 #include <stdlib.h>
13 #include "runtime.h"
14 #include "resources.h"
15 #include "namescope.h"
16 #include "error.h"
18 static void
19 free_value (Value *value)
21 delete value;
24 ResourceDictionary::ResourceDictionary ()
26 SetObjectType (Type::RESOURCE_DICTIONARY);
27 hash = g_hash_table_new_full (g_str_hash,
28 g_str_equal,
29 (GDestroyNotify)g_free,
30 (GDestroyNotify)free_value);
31 from_resource_dictionary_api = false;
34 ResourceDictionary::~ResourceDictionary ()
36 g_hash_table_destroy (hash);
39 bool
40 ResourceDictionary::CanAdd (Value *value)
42 return true;
45 bool
46 ResourceDictionary::Add (const char* key, Value *value)
48 MoonError err;
49 return AddWithError (key, value, &err);
52 bool
53 ResourceDictionary::AddWithError (const char* key, Value *value, MoonError *error)
55 if (!key) {
56 MoonError::FillIn (error, MoonError::ARGUMENT_NULL, "key was null");
57 return false;
60 if (ContainsKey (key)) {
61 MoonError::FillIn (error, MoonError::ARGUMENT, "An item with the same key has already been added");
62 return false;
65 Value *v = new Value (*value);
67 from_resource_dictionary_api = true;
68 bool result = Collection::AddWithError (v, error) != -1;
69 from_resource_dictionary_api = false;
70 if (result)
71 g_hash_table_insert (hash, g_strdup (key), v);
72 return result;
75 bool
76 ResourceDictionary::Clear ()
78 #if GLIB_CHECK_VERSION(2,12,0)
79 if (glib_check_version (2,12,0))
80 g_hash_table_remove_all (hash);
81 else
82 #endif
83 g_hash_table_foreach_remove (hash, (GHRFunc) gtk_true, NULL);
85 from_resource_dictionary_api = true;
86 bool rv = Collection::Clear ();
87 from_resource_dictionary_api = false;
89 return rv;
92 bool
93 ResourceDictionary::ContainsKey (const char *key)
95 if (!key)
96 return false;
98 gpointer orig_value;
99 gpointer orig_key;
101 return g_hash_table_lookup_extended (hash, key,
102 &orig_key, &orig_value);
105 bool
106 ResourceDictionary::Remove (const char *key)
108 if (!key)
109 return false;
111 /* check if the item exists first */
112 Value* orig_value;
113 gpointer orig_key;
115 if (!g_hash_table_lookup_extended (hash, key,
116 &orig_key, (gpointer*)&orig_value))
117 return false;
119 from_resource_dictionary_api = true;
120 Collection::Remove (orig_value);
121 from_resource_dictionary_api = false;
123 g_hash_table_remove (hash, key);
125 return true;
128 bool
129 ResourceDictionary::Set (const char *key, Value *value)
131 Value *v = new Value (*value);
133 /* check if the item exists first */
134 Value* orig_value;
135 gpointer orig_key;
137 if (g_hash_table_lookup_extended (hash, key,
138 &orig_key, (gpointer*)&orig_value)) {
139 return false;
142 from_resource_dictionary_api = true;
143 Collection::Remove (orig_value);
144 Collection::Add (v);
145 from_resource_dictionary_api = false;
147 g_hash_table_replace (hash, g_strdup (key), v);
149 return true; // XXX
152 Value*
153 ResourceDictionary::Get (const char *key, bool *exists)
155 Value *v = NULL;
156 gpointer orig_key;
158 *exists = g_hash_table_lookup_extended (hash, key,
159 &orig_key, (gpointer*)&v);
161 return v;
164 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
165 bool
166 ResourceDictionary::AddedToCollection (Value *value, MoonError *error)
168 if (value->Is(Type::DEPENDENCY_OBJECT)) {
169 DependencyObject *obj = value->AsDependencyObject ();
170 DependencyObject *parent = obj ? obj->GetParent () : NULL;
171 // Call SetSurface() /before/ setting the logical parent
172 // because Storyboard::SetSurface() needs to be able to
173 // distinguish between the two cases.
175 if (parent) {
176 MoonError::FillIn (error, MoonError::INVALID_OPERATION, "Element is already a child of another element.");
177 return false;
180 obj->SetSurface (GetSurface ());
181 obj->SetParent (this, error);
182 if (error->number)
183 return false;
185 obj->AddPropertyChangeListener (this);
187 if (!from_resource_dictionary_api) {
188 const char *key = obj->GetName();
190 if (!key) {
191 MoonError::FillIn (error, MoonError::ARGUMENT_NULL, "key was null");
192 return false;
195 if (ContainsKey (key)) {
196 MoonError::FillIn (error, MoonError::ARGUMENT, "An item with the same key has already been added");
197 return false;
202 bool rv = Collection::AddedToCollection (value, error);
204 if (rv && !from_resource_dictionary_api && value->Is(Type::DEPENDENCY_OBJECT)) {
205 DependencyObject *obj = value->AsDependencyObject ();
206 const char *key = obj->GetName();
208 g_hash_table_insert (hash, g_strdup (key), new Value (obj));
211 return rv;
214 static gboolean
215 remove_from_hash_by_value (gpointer key,
216 gpointer value,
217 gpointer user_data)
219 Value *v = (Value*)value;
221 return (v->Is (Type::DEPENDENCY_OBJECT) && v->AsDependencyObject() == user_data);
224 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
225 void
226 ResourceDictionary::RemovedFromCollection (Value *value)
228 if (value->Is (Type::DEPENDENCY_OBJECT)) {
229 DependencyObject *obj = value->AsDependencyObject ();
231 obj->RemovePropertyChangeListener (this);
232 obj->SetParent (NULL, NULL);
233 obj->SetSurface (NULL);
235 Collection::RemovedFromCollection (value);
237 if (!from_resource_dictionary_api)
238 g_hash_table_foreach_remove (hash, remove_from_hash_by_value, value->AsDependencyObject ());
242 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
243 void
244 ResourceDictionary::SetSurface (Surface *surface)
246 if (GetSurface() == surface)
247 return;
249 Value *value;
251 for (guint i = 0; i < array->len; i++) {
252 value = (Value *) array->pdata[i];
253 if (value->Is (Type::DEPENDENCY_OBJECT)) {
254 DependencyObject *obj = value->AsDependencyObject ();
255 obj->SetSurface (surface);
259 Collection::SetSurface (surface);
262 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
263 void
264 ResourceDictionary::UnregisterAllNamesRootedAt (NameScope *from_ns)
266 Value *value;
268 for (guint i = 0; i < array->len; i++) {
269 value = (Value *) array->pdata[i];
270 if (value->Is (Type::DEPENDENCY_OBJECT)) {
271 DependencyObject *obj = value->AsDependencyObject ();
272 obj->UnregisterAllNamesRootedAt (from_ns);
276 Collection::UnregisterAllNamesRootedAt (from_ns);
279 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
280 void
281 ResourceDictionary::RegisterAllNamesRootedAt (NameScope *to_ns, MoonError *error)
283 Value *value;
285 for (guint i = 0; i < array->len; i++) {
286 if (error->number)
287 break;
289 value = (Value *) array->pdata[i];
290 if (value->Is (Type::DEPENDENCY_OBJECT)) {
291 DependencyObject *obj = value->AsDependencyObject ();
292 obj->RegisterAllNamesRootedAt (to_ns, error);
296 Collection::RegisterAllNamesRootedAt (to_ns, error);