Merge remote-tracking branch 'origin/master' into tizen
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / XamlBinding / ResourcesExtensions.cs
1 /*
2  * Copyright(c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System;
19 using System.Collections.Generic;
20
21 namespace Tizen.NUI.Binding
22 {
23     internal static class ResourcesExtensions
24     {
25         public static IEnumerable<KeyValuePair<string, object>> GetMergedResources(this IElement element)
26         {
27             Dictionary<string, object> resources = null;
28             while (element != null)
29             {
30                 var ve = element as IResourcesProvider;
31                 if (ve != null && ve.IsResourcesCreated)
32                 {
33                     resources = resources ?? new Dictionary<string, object>();
34                     if (null == resources)
35                     {
36                         return null;
37                     }
38
39                     if (ve.XamlResources != null)
40                     {
41                         foreach (KeyValuePair<string, object> res in ve.XamlResources.MergedResources)
42                         {
43                             // If a MergedDictionary value is overridden for a DynamicResource, 
44                             // it comes out later in the enumeration of MergedResources
45                             // TryGetValue ensures we pull the up-to-date value for the key
46                             if (!resources.ContainsKey(res.Key) && ve.XamlResources.TryGetValue(res.Key, out object value))
47                                 resources.Add(res.Key, value);
48                         }
49                     }
50                 }
51
52                 var app = element as Application;
53                 if (app != null && app.SystemResources != null)
54                 {
55                     resources = resources ?? new Dictionary<string, object>(8);
56                     if (null == resources)
57                     {
58                         return null;
59                     }
60
61                     foreach (KeyValuePair<string, object> res in app.SystemResources)
62                         if (!resources.ContainsKey(res.Key))
63                             resources.Add(res.Key, res.Value);
64                 }
65                 element = element.Parent;
66             }
67             return resources;
68         }
69
70         public static bool TryGetResource(this IElement element, string key, out object value)
71         {
72             while (element != null)
73             {
74                 var ve = element as IResourcesProvider;
75                 if (ve != null && ve.IsResourcesCreated && ve.XamlResources != null && ve.XamlResources.TryGetValue(key, out value))
76                 {
77                     return true;
78                 }
79                 var app = element as Application;
80                 if (app != null && app.SystemResources != null && app.SystemResources.TryGetValue(key, out value))
81                 {
82                     return true;
83                 }
84                 element = element.Parent;
85             }
86
87             //Fallback for the XF previewer
88             if (Application.Current != null && ((IResourcesProvider)Application.Current).IsResourcesCreated && Application.Current.XamlResources.TryGetValue(key, out value))
89                 return true;
90
91             value = null;
92             return false;
93         }
94     }
95 }