[NUI] Adjust directory (#903)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / XamlBinding / Interactivity / XamlPropertyCondition.cs
1 using System;
2 using System.ComponentModel;
3 using System.Reflection;
4 using Tizen.NUI.Xaml;
5
6 namespace Tizen.NUI.Binding
7 {
8     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
9     [EditorBrowsable(EditorBrowsableState.Never)]
10     [ProvideCompiled("Tizen.NUI.Core.XamlC.PassthroughValueProvider")]
11     [AcceptEmptyServiceProvider]
12     public sealed class XamlPropertyCondition : Condition, IValueProvider
13     {
14         readonly BindableProperty _stateProperty;
15
16         BindableProperty _property;
17         object _triggerValue;
18
19         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
20         [EditorBrowsable(EditorBrowsableState.Never)]
21         public XamlPropertyCondition()
22         {
23             _stateProperty = BindableProperty.CreateAttached("State", typeof(bool), typeof(XamlPropertyCondition), false, propertyChanged: OnStatePropertyChanged);
24         }
25
26         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
27         [EditorBrowsable(EditorBrowsableState.Never)]
28         public BindableProperty Property
29         {
30             get { return _property; }
31             set
32             {
33                 if (_property == value)
34                     return;
35                 if (IsSealed)
36                     throw new InvalidOperationException("Can not change Property once the Trigger has been applied.");
37                 _property = value;
38
39                 //convert the value
40                 if (_property != null && s_valueConverter != null)
41                 {
42                     Func<MemberInfo> minforetriever = () => _property.DeclaringType.GetRuntimeProperty(_property.PropertyName);
43                     Value = s_valueConverter.Convert(Value, _property.ReturnType, minforetriever, null);
44                 }
45             }
46         }
47
48         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
49         [EditorBrowsable(EditorBrowsableState.Never)]
50         public object Value
51         {
52             get { return _triggerValue; }
53             set
54             {
55                 if (_triggerValue == value)
56                     return;
57                 if (IsSealed)
58                     throw new InvalidOperationException("Can not change Value once the Trigger has been applied.");
59
60                 //convert the value
61                 if (_property != null && s_valueConverter != null)
62                 {
63                     Func<MemberInfo> minforetriever = () => _property.DeclaringType.GetRuntimeProperty(_property.PropertyName);
64                     _triggerValue = s_valueConverter.Convert(value, _property.ReturnType, minforetriever, null);
65                 }
66                 else
67                 {
68                     _triggerValue = value;
69                 }
70                 
71             }
72         }
73
74         object IValueProvider.ProvideValue(IServiceProvider serviceProvider)
75         {
76             //This is no longer required
77             return this;
78         }
79
80         internal override bool GetState(BindableObject bindable)
81         {
82             return (bool)bindable.GetValue(_stateProperty);
83         }
84
85         static IValueConverterProvider s_valueConverter = DependencyService.Get<IValueConverterProvider>();
86
87         internal override void SetUp(BindableObject bindable)
88         {
89             object newvalue = bindable.GetValue(Property);
90             bool newState = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value));
91             bindable.SetValue(_stateProperty, newState);
92             bindable.PropertyChanged += OnAttachedObjectPropertyChanged;
93         }
94
95         internal override void TearDown(BindableObject bindable)
96         {
97             bindable.ClearValue(_stateProperty);
98             bindable.PropertyChanged -= OnAttachedObjectPropertyChanged;
99         }
100
101         void OnAttachedObjectPropertyChanged(object sender, PropertyChangedEventArgs e)
102         {
103             var bindable = (BindableObject)sender;
104             var oldState = (bool)bindable.GetValue(_stateProperty);
105
106             if (Property == null)
107                 return;
108             if (e.PropertyName != Property.PropertyName)
109                 return;
110             object newvalue = bindable.GetValue(Property);
111             bool newstate = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value));
112             if (oldState != newstate)
113                 bindable.SetValue(_stateProperty, newstate);
114         }
115
116         void OnStatePropertyChanged(BindableObject bindable, object oldValue, object newValue)
117         {
118             if ((bool)oldValue == (bool)newValue)
119                 return;
120
121             ConditionChanged?.Invoke(bindable, (bool)oldValue, (bool)newValue);
122         }
123     }
124 }