[NUI] Change GetDefaultWindow() to static func (#900)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / XamlBinding / Interactivity / TriggerBase.cs
1 using System;
2 using System.Reflection;
3 using System.Collections;
4 using System.Collections.Generic;
5
6 namespace Tizen.NUI.Binding
7 {
8     internal abstract class TriggerBase : BindableObject, IAttachedObject
9     {
10         bool _isSealed;
11
12         internal TriggerBase(Type targetType)
13         {
14             if (targetType == null)
15                 throw new ArgumentNullException("targetType");
16             TargetType = targetType;
17
18             EnterActions = new SealedList<TriggerAction>();
19             ExitActions = new SealedList<TriggerAction>();
20         }
21
22         internal TriggerBase(Condition condition, Type targetType) : this(targetType)
23         {
24             Setters = new SealedList<Setter>();
25             Condition = condition;
26             Condition.ConditionChanged = OnConditionChanged;
27         }
28
29         public IList<TriggerAction> EnterActions { get; }
30
31         public IList<TriggerAction> ExitActions { get; }
32
33         public bool IsSealed
34         {
35             get { return _isSealed; }
36             private set
37             {
38                 if (_isSealed == value)
39                     return;
40                 if (!value)
41                     throw new InvalidOperationException("What is sealed can not be unsealed.");
42                 _isSealed = value;
43                 OnSeal();
44             }
45         }
46
47         public Type TargetType { get; }
48
49         internal Condition Condition { get; }
50
51         //Setters and Condition are used by Trigger, DataTrigger and MultiTrigger
52         internal IList<Setter> Setters { get; }
53
54         void IAttachedObject.AttachTo(BindableObject bindable)
55         {
56             IsSealed = true;
57
58             if (bindable == null)
59                 throw new ArgumentNullException("bindable");
60             if (!TargetType.IsInstanceOfType(bindable))
61                 throw new InvalidOperationException("bindable not an instance of AssociatedType");
62             OnAttachedTo(bindable);
63         }
64
65         void IAttachedObject.DetachFrom(BindableObject bindable)
66         {
67             if (bindable == null)
68                 throw new ArgumentNullException("bindable");
69             OnDetachingFrom(bindable);
70         }
71
72         internal virtual void OnAttachedTo(BindableObject bindable)
73         {
74             if (Condition != null)
75                 Condition.SetUp(bindable);
76         }
77
78         internal virtual void OnDetachingFrom(BindableObject bindable)
79         {
80             if (Condition != null)
81                 Condition.TearDown(bindable);
82         }
83
84         internal virtual void OnSeal()
85         {
86             ((SealedList<TriggerAction>)EnterActions).IsReadOnly = true;
87             ((SealedList<TriggerAction>)ExitActions).IsReadOnly = true;
88             if (Setters != null)
89                 ((SealedList<Setter>)Setters).IsReadOnly = true;
90             if (Condition != null)
91                 Condition.IsSealed = true;
92         }
93
94         void OnConditionChanged(BindableObject bindable, bool oldValue, bool newValue)
95         {
96             if (newValue)
97             {
98                 foreach (TriggerAction action in EnterActions)
99                     action.DoInvoke(bindable);
100                 foreach (Setter setter in Setters)
101                     setter.Apply(bindable);
102             }
103             else
104             {
105                 foreach (Setter setter in Setters)
106                     setter.UnApply(bindable);
107                 foreach (TriggerAction action in ExitActions)
108                     action.DoInvoke(bindable);
109             }
110         }
111
112         internal class SealedList<T> : IList<T>
113         {
114             readonly IList<T> _actual;
115
116             bool _isReadOnly;
117
118             public SealedList()
119             {
120                 _actual = new List<T>();
121             }
122
123             public void Add(T item)
124             {
125                 if (IsReadOnly)
126                     throw new InvalidOperationException("This list is ReadOnly");
127                 _actual.Add(item);
128             }
129
130             public void Clear()
131             {
132                 if (IsReadOnly)
133                     throw new InvalidOperationException("This list is ReadOnly");
134                 _actual.Clear();
135             }
136
137             public bool Contains(T item)
138             {
139                 return _actual.Contains(item);
140             }
141
142             public void CopyTo(T[] array, int arrayIndex)
143             {
144                 _actual.CopyTo(array, arrayIndex);
145             }
146
147             public int Count
148             {
149                 get { return _actual.Count; }
150             }
151
152             public bool IsReadOnly
153             {
154                 get { return _isReadOnly; }
155                 set
156                 {
157                     if (_isReadOnly == value)
158                         return;
159                     if (!value)
160                         throw new InvalidOperationException("Can't change this back to non readonly");
161                     _isReadOnly = value;
162                 }
163             }
164
165             public bool Remove(T item)
166             {
167                 if (IsReadOnly)
168                     throw new InvalidOperationException("This list is ReadOnly");
169                 return _actual.Remove(item);
170             }
171
172             IEnumerator IEnumerable.GetEnumerator()
173             {
174                 return ((IEnumerable)_actual).GetEnumerator();
175             }
176
177             public IEnumerator<T> GetEnumerator()
178             {
179                 return _actual.GetEnumerator();
180             }
181
182             public int IndexOf(T item)
183             {
184                 return _actual.IndexOf(item);
185             }
186
187             public void Insert(int index, T item)
188             {
189                 if (IsReadOnly)
190                     throw new InvalidOperationException("This list is ReadOnly");
191                 _actual.Insert(index, item);
192             }
193
194             public T this[int index]
195             {
196                 get { return _actual[index]; }
197                 set
198                 {
199                     if (IsReadOnly)
200                         throw new InvalidOperationException("This list is ReadOnly");
201                     _actual[index] = value;
202                 }
203             }
204
205             public void RemoveAt(int index)
206             {
207                 if (IsReadOnly)
208                     throw new InvalidOperationException("This list is ReadOnly");
209                 _actual.RemoveAt(index);
210             }
211         }
212     }
213 }