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