DeepStyleWalker::DeepStyleWalker (Style **styles, Types *types) { // Create a list of all Setters in the style sorted by their DP. // Use the hashtable to ensure that we only take the first setter // declared for each DP (i.e. if the BasedOn style and main style // have setters for the same DP, we ignore the BasedOn one // NOTE: This can be pre-computed and cached as once a style is // sealed it can never be changed. this->offset = 0; this->types = types || !styles[0] ? types : styles[0]->GetDeployment ()->GetTypes (); this->setter_list = g_ptr_array_new (); if (!styles) return; GHashTable *styles_seen = g_hash_table_new (g_direct_hash, g_direct_equal); GHashTable *dps = g_hash_table_new (g_direct_hash, g_direct_equal); for (int i = 0; styles[i]; i ++) { Style *style = styles[i]; while (style != NULL) { if (g_hash_table_lookup (styles_seen, style)) continue; SetterBaseCollection *setters = style->GetSetters (); int count = setters ? setters->GetCount () : 0; for (int i = count-1; i >= 0; i--) { Value *v = setters->GetValueAt (i); if (Value::IsNull (v) || !types->IsSubclassOf (v->GetKind (), Type::SETTER)) continue; Setter *setter = v->AsSetter (); Value* dpVal = setter->GetValue (Setter::PropertyProperty); if (Value::IsNull (dpVal)) continue; DependencyProperty *prop = dpVal->AsDependencyProperty (); if (!g_hash_table_lookup_extended (dps, prop, NULL, NULL)) { g_hash_table_insert (dps, prop, setter); g_ptr_array_add (setter_list, setter); } } g_hash_table_insert (styles_seen, style, style); style = style->GetBasedOn (); } } g_hash_table_destroy (dps); g_hash_table_destroy (styles_seen); g_ptr_array_sort (setter_list, SetterComparer); }