2 * Copyright(c) 2019 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.ComponentModel;
19 using Tizen.NUI.Binding;
20 using Tizen.NUI.Components;
22 namespace Tizen.NUI.BaseComponents
25 /// Selector class, which is related by Control State, it is base class for other Selector.
27 /// <since_tizen> 6 </since_tizen>
28 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
29 [EditorBrowsable(EditorBrowsableState.Never)]
30 public class Selector<T> : StateValueCollection<T>
32 /// <since_tizen> 6 </since_tizen>
33 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
34 public static implicit operator Selector<T>(T value)
36 Selector<T> selector = new Selector<T>();
41 /// Default Contructor
42 [EditorBrowsable(EditorBrowsableState.Never)]
48 [EditorBrowsable(EditorBrowsableState.Never)]
49 public Selector(T value) : this()
57 /// <since_tizen> 6 </since_tizen>
58 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
59 [EditorBrowsable(EditorBrowsableState.Never)]
68 /// <since_tizen> 6 </since_tizen>
69 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
70 [EditorBrowsable(EditorBrowsableState.Never)]
73 get => Find(x => x.State == ControlState.Normal).Value;
74 set => Add(ControlState.Normal, value);
79 /// <since_tizen> 6 </since_tizen>
80 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
81 [EditorBrowsable(EditorBrowsableState.Never)]
84 get => Find(x => x.State == ControlState.Pressed).Value;
85 set => Add(ControlState.Pressed, value);
90 /// <since_tizen> 6 </since_tizen>
91 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
92 [EditorBrowsable(EditorBrowsableState.Never)]
95 get => Find(x => x.State == ControlState.Focused).Value;
96 set => Add(ControlState.Focused, value);
101 /// <since_tizen> 6 </since_tizen>
102 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
103 [EditorBrowsable(EditorBrowsableState.Never)]
106 get => Find(x => x.State == ControlState.Selected).Value;
107 set => Add(ControlState.Selected, value);
112 /// <since_tizen> 6 </since_tizen>
113 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
114 [EditorBrowsable(EditorBrowsableState.Never)]
117 get => Find(x => x.State == ControlState.Disabled).Value;
118 set => Add(ControlState.Disabled, value);
121 /// DisabledFocused State.
123 /// <since_tizen> 6 </since_tizen>
124 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
125 [EditorBrowsable(EditorBrowsableState.Never)]
126 public T DisabledFocused
128 get => Find(x => x.State == ControlState.DisabledFocused).Value;
129 set => Add(ControlState.DisabledFocused, value);
132 /// SelectedFocused State.
134 /// <since_tizen> 6 </since_tizen>
135 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
136 public T SelectedFocused
138 get => Find(x => x.State == ControlState.SelectedFocused).Value;
139 set => Add(ControlState.SelectedFocused, value);
142 /// DisabledSelected State.
144 /// <since_tizen> 6 </since_tizen>
145 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
146 [EditorBrowsable(EditorBrowsableState.Never)]
147 public T DisabledSelected
149 get => Find(x => x.State == ControlState.DisabledSelected).Value;
150 set => Add(ControlState.DisabledSelected, value);
156 /// <since_tizen> 6 </since_tizen>
157 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
158 [EditorBrowsable(EditorBrowsableState.Never)]
161 get => Find(x => x.State == ControlState.Other).Value;
162 set => Add(ControlState.Other, value);
165 /// Get value by State.
167 /// <since_tizen> 6 </since_tizen>
168 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
169 [EditorBrowsable(EditorBrowsableState.Never)]
170 public T GetValue(ControlState state)
177 StateValuePair<T> value = Find(x => x.State == state);
178 if (value.Value != null)
183 if (state.IsCombined)
185 value = Find(x => state.Contains(x.State));
186 if (value.Value != null)
198 /// <since_tizen> 6 </since_tizen>
199 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
200 [EditorBrowsable(EditorBrowsableState.Never)]
201 public void Clone(Selector<T> selector)
204 Normal = selector.Normal;
205 Focused = selector.Focused;
206 Pressed = selector.Pressed;
207 Disabled = selector.Disabled;
208 Selected = selector.Selected;
209 DisabledSelected = selector.DisabledSelected;
210 DisabledFocused = selector.DisabledFocused;
211 SelectedFocused = selector.SelectedFocused;
212 Other = selector.Other;
215 internal void Clone<U>(Selector<U> other) where U : T, Tizen.NUI.Internal.ICloneable
217 // TODO Apply constraint to the Selector (not to Clone method)
219 All = (T)(other.All)?.Clone();
220 Normal = (T)(other.Normal)?.Clone();
221 Focused = (T)(other.Focused)?.Clone();
222 Pressed = (T)(other.Pressed)?.Clone();
223 Disabled = (T)(other.Disabled)?.Clone();
224 Selected = (T)(other.Selected)?.Clone();
225 DisabledSelected = (T)(other.DisabledSelected)?.Clone();
226 DisabledFocused = (T)(other.DisabledFocused)?.Clone();
227 SelectedFocused = (T)(other.SelectedFocused)?.Clone();
228 Other = (T)(other.Other)?.Clone();
231 internal bool HasMultiValue()
237 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
238 [EditorBrowsable(EditorBrowsableState.Never)]
239 public class TriggerableSelector<T> : Selector<T>
241 public TriggerableSelector(View view, BindableProperty bindableProperty)
244 targetBindableProperty = bindableProperty;
245 view.ControlStateChangeEventInternal += OnViewControlState;
251 /// <since_tizen> 6 </since_tizen>
252 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
253 [EditorBrowsable(EditorBrowsableState.Never)]
254 public new void Clone(Selector<T> selector)
256 base.Clone(selector);
258 if (null != targetView && null != GetValue(targetView.ControlState))
260 targetView.SetValue(targetBindableProperty, GetValue(targetView.ControlState));
264 private void OnViewControlState(object obj, View.ControlStateChangedEventArgs controlStateChangedInfo)
266 View view = obj as View;
267 if (null != view && null != GetValue(controlStateChangedInfo.CurrentState))
269 view.SetValue(targetBindableProperty, GetValue(controlStateChangedInfo.CurrentState));
273 private View targetView;
274 private BindableProperty targetBindableProperty;
278 /// A class that helps binding a non-selector property in View to selector property in ViewStyle.
280 internal class ViewSelector<T>
282 protected Selector<T> selector;
284 protected EventHandler<View.ControlStateChangedEventArgs> controlStateChanged;
286 internal ViewSelector(View view, EventHandler<View.ControlStateChangedEventArgs> controlStateChanged)
288 if (view == null || controlStateChanged == null)
290 throw new global::System.ArgumentNullException();
293 this.controlStateChanged = controlStateChanged;
294 this.selector = null;
297 internal T GetValue()
299 return selector == null ? default(T) : selector.GetValue(view.ControlState);
302 internal void Set(object value)
304 bool hadMultiValue = HasMultiValue();
305 var type = value?.GetType();
307 if (type == typeof(T))
309 CopyValueToSelector((T)value);
311 else if (type == typeof(Selector<T>))
313 CopySelectorToSelector((Selector<T>)value);
315 else if (type == Nullable.GetUnderlyingType(typeof(T)))
317 CopyValueToSelector((T)value);
324 if (hadMultiValue != HasMultiValue())
326 if (hadMultiValue) view.ControlStateChangeEventInternal -= controlStateChanged;
327 else view.ControlStateChangeEventInternal += controlStateChanged;
331 protected virtual void CopyValueToSelector(T value)
333 selector = new Selector<T>();
334 selector.All = value;
337 protected virtual void CopySelectorToSelector(Selector<T> value)
339 selector = new Selector<T>();
340 selector.Clone(value);
343 internal void Clear()
347 view.ControlStateChangeEventInternal -= controlStateChanged;
352 internal bool IsEmpty()
354 return selector == null;
357 protected bool HasMultiValue()
359 return (selector != null && selector.All == null);
364 /// ViewSelector class for ICloneable type
366 internal class CloneableViewSelector<T> : ViewSelector<T> where T : Tizen.NUI.Internal.ICloneable
368 internal CloneableViewSelector(View view, EventHandler<View.ControlStateChangedEventArgs> controlStateChanged) : base(view, controlStateChanged)
372 protected override void CopyValueToSelector(T value)
374 selector = new Selector<T>();
375 selector.All = (T)((T)value).Clone();
378 protected override void CopySelectorToSelector(Selector<T> value)
380 selector = new Selector<T>();
381 selector.Clone<T>((Selector<T>)value);
385 internal static class SelectorHelper
388 /// For the object type of T or Selector T, convert it to Selector T and return the cloned one.
389 /// Otherwise, return null. <br/>
391 static internal Selector<T> CopyCloneable<T>(object value) where T : class, Tizen.NUI.Internal.ICloneable
395 var type = value.GetType();
397 if (type == typeof(Selector<T>))
399 var result = new Selector<T>();
400 result.Clone<T>((Selector<T>)value);
404 if (type == typeof(T))
406 return new Selector<T>((T)((T)value).Clone());
414 /// For the value type of T or Selector T, convert it to Selector T and return the cloned one.
415 /// Otherwise, return null. <br/>
417 static internal Selector<T> CopyValue<T>(object value)
421 var type = value.GetType();
423 if (type == typeof(Selector<T>))
425 var result = new Selector<T>();
426 result.Clone((Selector<T>)value);
430 if (type == typeof(T))
432 return new Selector<T>((T)value);