[NUI] Adjust directory (#903)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / XamlBinding / Setter.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Reflection;
5 using System.Runtime.CompilerServices;
6 using System.Xml;
7 using Tizen.NUI.Binding.Internals;
8 using Tizen.NUI.Xaml;
9
10 namespace Tizen.NUI.Binding
11 {
12     /// <since_tizen> 6 </since_tizen>
13     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
14     [EditorBrowsable(EditorBrowsableState.Never)]
15     [ContentProperty("Value")]
16     [ProvideCompiled("Tizen.NUI.Core.XamlC.SetterValueProvider")]
17     public sealed class Setter : IValueProvider
18     {
19         readonly ConditionalWeakTable<BindableObject, object> _originalValues = new ConditionalWeakTable<BindableObject, object>();
20
21         /// <since_tizen> 6 </since_tizen>
22         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
23         [EditorBrowsable(EditorBrowsableState.Never)]
24         public BindableProperty Property { get; set; }
25
26         /// <since_tizen> 6 </since_tizen>
27         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
28         [EditorBrowsable(EditorBrowsableState.Never)]
29         public object Value { get; set; }
30
31         object IValueProvider.ProvideValue(IServiceProvider serviceProvider)
32         {
33             if (Property == null)
34             {
35                 var lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
36                 IXmlLineInfo lineInfo = lineInfoProvider != null ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
37                 throw new XamlParseException("Property not set", lineInfo);
38             }
39             var valueconverter = serviceProvider.GetService(typeof(IValueConverterProvider)) as IValueConverterProvider;
40
41             Func<MemberInfo> minforetriever =
42                 () =>
43                 (MemberInfo)Property.DeclaringType.GetRuntimeProperty(Property.PropertyName) ?? (MemberInfo)Property.DeclaringType.GetRuntimeMethod("Get" + Property.PropertyName, new[] { typeof(BindableObject) });
44
45             object value = valueconverter?.Convert(Value, Property.ReturnType, minforetriever, serviceProvider);
46             Value = value;
47             return this;
48         }
49
50         internal void Apply(BindableObject target, bool fromStyle = false)
51         {
52             if (target == null)
53                 throw new ArgumentNullException("target");
54             if (Property == null)
55                 return;
56
57             object originalValue = target.GetValue(Property);
58             if (!Equals(originalValue, Property.DefaultValue))
59             {
60                 _originalValues.Remove(target);
61                 _originalValues.Add(target, originalValue);
62             }
63
64             var dynamicResource = Value as DynamicResource;
65             var binding = Value as BindingBase;
66             if (binding != null)
67                 target.SetBinding(Property, binding.Clone(), fromStyle);
68             else if (dynamicResource != null)
69                 target.SetDynamicResource(Property, dynamicResource.Key, fromStyle);
70             else
71             {
72                 if (Value is IList<VisualStateGroup> visualStateGroupCollection)
73                     target.SetValue(Property, visualStateGroupCollection.Clone(), fromStyle);
74                 else
75                     target.SetValue(Property, Value, fromStyle);
76             }
77         }
78
79         internal void UnApply(BindableObject target, bool fromStyle = false)
80         {
81             if (target == null)
82                 throw new ArgumentNullException(nameof(target));
83             if (Property == null)
84                 return;
85
86             object actual = target.GetValue(Property);
87             if (!Equals(actual, Value) && !(Value is Tizen.NUI.Binding.Binding) && !(Value is DynamicResource))
88             {
89                 //Do not reset default value if the value has been changed
90                 _originalValues.Remove(target);
91                 return;
92             }
93
94             object defaultValue;
95             if (_originalValues.TryGetValue(target, out defaultValue))
96             {
97                 //reset default value, unapply bindings and dynamicResource
98                 target.SetValue(Property, defaultValue, fromStyle);
99                 _originalValues.Remove(target);
100             }
101             else
102                 target.ClearValue(Property);
103         }
104     }
105 }