[NUI] Fix to invoke SelectedChanged when IsSelected is changed by setter
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / SelectButton.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 using System;
18 using Tizen.NUI.BaseComponents;
19 using System.ComponentModel;
20
21 namespace Tizen.NUI.Components
22 {
23     /// <summary>
24     /// SelectButton is base class of CheckBox and RadioButton.
25     /// It can be used as selector and add into group for single-choice or multiple-choice .
26     /// User can handle Navigation by adding/inserting/deleting NavigationItem.
27     /// </summary>
28     /// <since_tizen> 6 </since_tizen>
29     /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
30     [EditorBrowsable(EditorBrowsableState.Never)]
31     public class SelectButton : Button
32     {
33         private SelectGroup itemGroup = null;
34
35         /// <summary>
36         /// Item group which is used to manager all SelectButton in it.
37         /// </summary>
38         /// <since_tizen> 6 </since_tizen>
39         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
40         [EditorBrowsable(EditorBrowsableState.Never)]
41         protected SelectGroup ItemGroup { get => itemGroup; set => itemGroup = value; }
42
43         static SelectButton() { }
44
45         /// <summary>
46         /// Creates a new instance of a SelectButton.
47         /// </summary>
48         /// <since_tizen> 6 </since_tizen>
49         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
50         [EditorBrowsable(EditorBrowsableState.Never)]
51         public SelectButton() : base()
52         {
53         }
54
55         /// <summary>
56         /// Creates a new instance of a SelectButton with style.
57         /// </summary>
58         /// <param name="style">Create SelectButton by special style defined in UX.</param>
59         /// <since_tizen> 6 </since_tizen>
60         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public SelectButton(string style) : base(style)
63         {
64         }
65
66         /// <summary>
67         /// Creates a new instance of a SelectButton with style.
68         /// </summary>
69         /// <param name="buttonStyle">Create SelectButton by style customized by user.</param>
70         /// <since_tizen> 6 </since_tizen>
71         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
72         [EditorBrowsable(EditorBrowsableState.Never)]
73         public SelectButton(ButtonStyle buttonStyle) : base(buttonStyle)
74         {
75         }
76
77         /// <summary>
78         /// An event for the item selected signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
79         /// </summary>
80         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
81         [EditorBrowsable(EditorBrowsableState.Never)]
82         public event EventHandler<SelectedChangedEventArgs> SelectedChanged;
83
84         /// <summary>
85         /// Index of selection in selection group. If selection is not in the group, return -1;
86         /// </summary>
87         /// <since_tizen> 6 </since_tizen>
88         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
89         [EditorBrowsable(EditorBrowsableState.Never)]
90         public int Index
91         {
92             get
93             {
94                 if (ItemGroup != null)
95                 {
96                     return ItemGroup.GetIndex(this);
97                 }
98
99                 return -1;
100             }
101         }
102
103         /// <inheritdoc/>
104         [EditorBrowsable(EditorBrowsableState.Never)]
105         public override void OnInitialize()
106         {
107             base.OnInitialize();
108             IsSelectable = true;
109         }
110
111         /// <summary>
112         /// Dispose SelectButton and all children on it.
113         /// </summary>
114         /// <param name="type">Dispose type.</param>
115         /// <since_tizen> 6 </since_tizen>
116         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
117         [EditorBrowsable(EditorBrowsableState.Never)]
118         protected override void Dispose(DisposeTypes type)
119         {
120             if (disposed)
121             {
122                 return;
123             }
124
125             if (type == DisposeTypes.Explicit)
126             {
127                 RemoveFromGroup();
128             }
129
130             base.Dispose(type);
131         }
132
133         /// <summary>
134         /// Called after a key event is received by the view that has had its focus set.
135         /// </summary>
136         /// <param name="key">The key event.</param>
137         /// <returns>True if the key event should be consumed.</returns>
138         /// <since_tizen> 6 </since_tizen>
139         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
140         [EditorBrowsable(EditorBrowsableState.Never)]
141         public override bool OnKey(Key key)
142         {
143             if ((IsEnabled == false) || (key == null))
144             {
145                 return false;
146             }
147
148             return base.OnKey(key);
149         }
150
151         /// <summary>
152         /// Called after a touch event is received by the owning view.<br />
153         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
154         /// </summary>
155         /// <param name="touch">The touch event.</param>
156         /// <returns>True if the event should be consumed.</returns>
157         /// <since_tizen> 6 </since_tizen>
158         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
159         [EditorBrowsable(EditorBrowsableState.Never)]
160         public override bool OnTouch(Touch touch)
161         {
162             return base.OnTouch(touch);
163         }
164
165         /// <inheritdoc/>
166         [EditorBrowsable(EditorBrowsableState.Never)]
167         protected override bool HandleControlStateOnTouch(Touch touch)
168         {
169             if ((IsEnabled == false) || (touch == null))
170             {
171                 return false;
172             }
173
174             return base.HandleControlStateOnTouch(touch);
175         }
176
177         /// <summary>
178         /// Overrides this method if want to handle behavior after pressing return key by user.
179         /// </summary>
180         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
181         [EditorBrowsable(EditorBrowsableState.Never)]
182         protected virtual void OnSelectedChanged()
183         {
184         }
185
186         /// <inheritdoc/>
187         [EditorBrowsable(EditorBrowsableState.Never)]
188         protected override void OnControlStateChanged(ControlStateChangedEventArgs info)
189         {
190             if (info.PreviousState.Contains(ControlState.Selected) != info.CurrentState.Contains(ControlState.Selected))
191             {
192                 if (Accessibility.Accessibility.IsEnabled && IsHighlighted)
193                 {
194                     EmitAccessibilityStateChangedEvent(AccessibilityState.Checked, info.CurrentState.Contains(ControlState.Selected));
195                 }
196
197                 OnSelectedChanged();
198
199                 if (SelectedChanged != null)
200                 {
201                     SelectedChangedEventArgs eventArgs = new SelectedChangedEventArgs();
202                     eventArgs.IsSelected = IsSelected;
203                     SelectedChanged(this, eventArgs);
204                 }
205             }
206         }
207
208         internal void RemoveFromGroup() => itemGroup?.RemoveSelection(this);
209
210         internal void ResetItemGroup() => itemGroup = null;
211     }
212 }