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> : BindableObject
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)]
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)]
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)]
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)]
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)]
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
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
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
154 /// PressedSelected State.
156 [EditorBrowsable(EditorBrowsableState.Never)]
157 public T PressedSelected
166 /// <since_tizen> 6 </since_tizen>
167 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
168 [EditorBrowsable(EditorBrowsableState.Never)]
175 /// Get value by State.
177 /// <since_tizen> 6 </since_tizen>
178 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
179 [EditorBrowsable(EditorBrowsableState.Never)]
180 public T GetValue(ControlStates state)
188 case ControlStates.Normal:
189 return Normal != null? Normal : Other;
190 case ControlStates.Focused:
191 return Focused != null? Focused : Other;
192 case ControlStates.Pressed:
193 return Pressed != null? Pressed : Other;
194 case ControlStates.Disabled:
195 return Disabled != null? Disabled : Other;
196 case ControlStates.Selected:
197 return Selected != null? Selected : Other;
198 case ControlStates.DisabledFocused:
199 return DisabledFocused != null? DisabledFocused : (Disabled != null ? Disabled : Other);
200 case ControlStates.DisabledSelected:
201 return DisabledSelected != null ? DisabledSelected : (Disabled != null ? Disabled : Other);
202 case ControlStates.SelectedFocused:
203 return SelectedFocused != null ? SelectedFocused : (Selected != null ? Selected : Other);
204 case ControlStates.PressedSelected:
205 return PressedSelected != null ? PressedSelected : (Selected != null ? Selected : Other);
213 /// <since_tizen> 6 </since_tizen>
214 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
215 [EditorBrowsable(EditorBrowsableState.Never)]
216 public void Clone(Selector<T> selector)
219 Normal = selector.Normal;
220 Focused = selector.Focused;
221 Pressed = selector.Pressed;
222 Disabled = selector.Disabled;
223 Selected = selector.Selected;
224 DisabledSelected = selector.DisabledSelected;
225 DisabledFocused = selector.DisabledFocused;
226 SelectedFocused = selector.SelectedFocused;
227 PressedSelected = selector.PressedSelected;
228 Other = selector.Other;
231 internal void Clone<U>(Selector<U> other) where U : T, Tizen.NUI.Internal.ICloneable
233 // TODO Apply constraint to the Selector (not to Clone method)
235 All = (T)(other.All)?.Clone();
236 Normal = (T)(other.Normal)?.Clone();
237 Focused = (T)(other.Focused)?.Clone();
238 Pressed = (T)(other.Pressed)?.Clone();
239 Disabled = (T)(other.Disabled)?.Clone();
240 Selected = (T)(other.Selected)?.Clone();
241 DisabledSelected = (T)(other.DisabledSelected)?.Clone();
242 DisabledFocused = (T)(other.DisabledFocused)?.Clone();
243 SelectedFocused = (T)(other.SelectedFocused)?.Clone();
244 PressedSelected = (T)(other.PressedSelected)?.Clone();
245 Other = (T)(other.Other)?.Clone();
249 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
250 [EditorBrowsable(EditorBrowsableState.Never)]
251 public class TriggerableSelector<T> : Selector<T>
253 public TriggerableSelector(View view, BindableProperty bindableProperty)
256 targetBindableProperty = bindableProperty;
257 view.ControlStateChangeEvent += OnViewControlState;
263 /// <since_tizen> 6 </since_tizen>
264 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
265 [EditorBrowsable(EditorBrowsableState.Never)]
266 public new void Clone(Selector<T> selector)
268 base.Clone(selector);
270 if (null != targetView && null != GetValue(targetView.ControlState))
272 targetView.SetValue(targetBindableProperty, GetValue(targetView.ControlState));
276 private void OnViewControlState(View obj, ControlStates state)
278 if (null != obj && null != GetValue(state))
280 obj.SetValue(targetBindableProperty, GetValue(state));
284 private View targetView;
285 private BindableProperty targetBindableProperty;
289 /// A class that helps binding a non-selector property in View to selector property in ViewStyle.
291 internal class ViewSelector<T>
293 protected Selector<T> selector;
295 protected View.ControlStateChangesDelegate controlStateChanged;
297 internal ViewSelector(View view, View.ControlStateChangesDelegate controlStateChanged)
299 if (view == null || controlStateChanged == null)
301 throw new global::System.ArgumentNullException();
304 this.controlStateChanged = controlStateChanged;
305 this.selector = null;
308 internal T GetValue()
310 return selector == null ? default(T) : selector.GetValue(view.ControlState);
313 internal void Set(object value)
315 bool hadMultiValue = HasMultiValue();
316 var type = value?.GetType();
318 if (type == typeof(T))
320 CopyValueToSelector((T)value);
322 else if (type == typeof(Selector<T>))
324 CopySelectorToSelector((Selector<T>)value);
326 else if (type == Nullable.GetUnderlyingType(typeof(T)))
328 CopyValueToSelector((T)value);
335 if (hadMultiValue != HasMultiValue())
337 if (hadMultiValue) view.ControlStateChangeEvent -= controlStateChanged;
338 else view.ControlStateChangeEvent += controlStateChanged;
342 protected virtual void CopyValueToSelector(T value)
344 selector = new Selector<T>();
345 selector.All = value;
348 protected virtual void CopySelectorToSelector(Selector<T> value)
350 selector = new Selector<T>();
351 selector.Clone(value);
354 internal void Clear()
358 view.ControlStateChangeEvent -= controlStateChanged;
363 internal bool IsEmpty()
365 return selector == null;
368 protected bool HasMultiValue()
370 return (selector != null && selector.All == null);
375 /// ViewSelector class for ICloneable type
377 internal class CloneableViewSelector<T> : ViewSelector<T> where T : Tizen.NUI.Internal.ICloneable
379 internal CloneableViewSelector(View view, View.ControlStateChangesDelegate controlStateChanged) : base(view, controlStateChanged)
383 protected override void CopyValueToSelector(T value)
385 selector = new Selector<T>();
386 selector.All = (T)((T)value).Clone();
389 protected override void CopySelectorToSelector(Selector<T> value)
391 selector = new Selector<T>();
392 selector.Clone<T>((Selector<T>)value);
396 internal static class SelectorHelper
399 /// For the object type of T or Selector T, convert it to Selector T and return the cloned one.
400 /// Otherwise, return null. <br/>
402 static internal Selector<T> CopyCloneable<T>(object value) where T : class, Tizen.NUI.Internal.ICloneable
404 var type = value?.GetType();
406 if (type == typeof(Selector<T>))
408 var result = new Selector<T>();
409 result.Clone<T>((Selector<T>)value);
413 if (type == typeof(T))
415 return new Selector<T>((T)((T)value).Clone());
422 /// For the value type of T or Selector T, convert it to Selector T and return the cloned one.
423 /// Otherwise, return null. <br/>
425 static internal Selector<T> CopyValue<T>(object value)
427 var type = value?.GetType();
429 if (type == typeof(Selector<T>))
431 var result = new Selector<T>();
432 result.Clone((Selector<T>)value);
436 if (type == typeof(T))
438 return new Selector<T>((T)value);