1 //------------------------------------------------------------------------------
2 // emRadioButton.cpp
3 //
4 // Copyright (C) 2005-2011,2014-2016 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20
21 #include <emCore/emRadioButton.h>
22
23
emRadioButton(ParentArg parent,const emString & name,const emString & caption,const emString & description,const emImage & icon)24 emRadioButton::emRadioButton(
25 ParentArg parent, const emString & name, const emString & caption,
26 const emString & description, const emImage & icon
27 )
28 : emCheckButton(parent,name,caption,description,icon)
29 {
30 Mechanism * mechanism;
31
32 SetShownRadioed(true);
33 Mech=NULL;
34 MechIndex=-1;
35 if (GetParent()) {
36 mechanism=dynamic_cast<emRadioButton::Mechanism*>(GetParent());
37 if (mechanism) mechanism->Add(this);
38 }
39 }
40
41
~emRadioButton()42 emRadioButton::~emRadioButton()
43 {
44 if (Mech) Mech->Remove(this);
45 }
46
47
Mechanism()48 emRadioButton::Mechanism::Mechanism()
49 {
50 Array.SetTuningLevel(4);
51 CheckIndex=-1;
52 }
53
54
~Mechanism()55 emRadioButton::Mechanism::~Mechanism()
56 {
57 RemoveAll();
58 }
59
60
Add(emRadioButton * radioButton)61 void emRadioButton::Mechanism::Add(emRadioButton * radioButton)
62 {
63 if (radioButton->Mech) radioButton->Mech->Remove(radioButton);
64 radioButton->Mech=this;
65 radioButton->MechIndex=Array.GetCount();
66 Array.Add(radioButton);
67 if (radioButton->IsChecked()) {
68 if (CheckIndex>=0) {
69 radioButton->SetChecked(false);
70 }
71 else {
72 CheckIndex=Array.GetCount()-1;
73 CheckSignal.Signal(radioButton->GetScheduler());
74 CheckChanged();
75 }
76 }
77 }
78
79
AddAll(emPanel * parent)80 void emRadioButton::Mechanism::AddAll(emPanel * parent)
81 {
82 emRadioButton * rb;
83 emPanel * p;
84
85 for (p=parent->GetFirstChild(); p; p=p->GetNext()) {
86 rb=dynamic_cast<emRadioButton*>(p);
87 if (rb) Add(rb);
88 }
89 }
90
91
Remove(emRadioButton * radioButton)92 void emRadioButton::Mechanism::Remove(emRadioButton * radioButton)
93 {
94 RemoveByIndex(GetIndexOf(radioButton));
95 }
96
97
RemoveByIndex(int index)98 void emRadioButton::Mechanism::RemoveByIndex(int index)
99 {
100 emScheduler * scheduler;
101 emRadioButton * rb;
102 int i;
103
104 if (index>=0 && index<Array.GetCount()) {
105 rb=Array[index];
106 rb->Mech=NULL;
107 rb->MechIndex=-1;
108 scheduler=&rb->GetScheduler();
109 Array.Remove(index);
110 for (i=Array.GetCount()-1; i>=index; i--) Array[i]->MechIndex=i;
111 if (CheckIndex>=index) {
112 if (CheckIndex==index) CheckIndex=-1;
113 else CheckIndex--;
114 CheckSignal.Signal(*scheduler);
115 CheckChanged();
116 }
117 }
118 }
119
120
RemoveAll()121 void emRadioButton::Mechanism::RemoveAll()
122 {
123 emScheduler * scheduler;
124 emRadioButton * rb;
125 int i;
126
127 i=Array.GetCount()-1;
128 if (i>=0) {
129 scheduler=&Array[0]->GetScheduler();
130 do {
131 rb=Array[i];
132 rb->Mech=NULL;
133 rb->MechIndex=-1;
134 i--;
135 } while (i>=0);
136 Array.Clear();
137 if (CheckIndex>=0) {
138 CheckIndex=-1;
139 CheckSignal.Signal(*scheduler);
140 CheckChanged();
141 }
142 }
143 }
144
145
SetChecked(emRadioButton * radioButton)146 void emRadioButton::Mechanism::SetChecked(emRadioButton * radioButton)
147 {
148 SetCheckIndex(GetIndexOf(radioButton));
149 }
150
151
SetCheckIndex(int index)152 void emRadioButton::Mechanism::SetCheckIndex(int index)
153 {
154 emScheduler * scheduler;
155 int old;
156
157 if (index<-1 || index>=Array.GetCount()) index=-1;
158 if (CheckIndex!=index) {
159 // Remember, this could be called recursively!
160 scheduler=&Array[0]->GetScheduler();
161 if (CheckIndex>=0 && Array[CheckIndex]->IsChecked()) {
162 old=CheckIndex;
163 CheckIndex=-1;
164 Array[old]->SetChecked(false);
165 if (CheckIndex!=-1) return;
166 }
167 CheckIndex=index;
168 if (CheckIndex>=0 && !Array[CheckIndex]->IsChecked()) {
169 Array[CheckIndex]->SetChecked(true);
170 if (CheckIndex!=index) return;
171 }
172 CheckSignal.Signal(*scheduler);
173 CheckChanged();
174 }
175 }
176
177
GetButton(int index) const178 emRadioButton * emRadioButton::Mechanism::GetButton(int index) const
179 {
180 if (index>=0 && index<Array.GetCount()) {
181 return Array[index];
182 }
183 return NULL;
184 }
185
186
187
CheckChanged()188 void emRadioButton::Mechanism::CheckChanged()
189 {
190 }
191
192
LinearGroup(ParentArg parent,const emString & name,const emString & caption,const emString & description,const emImage & icon)193 emRadioButton::LinearGroup::LinearGroup(
194 ParentArg parent, const emString & name, const emString & caption,
195 const emString & description, const emImage & icon
196 )
197 : emLinearGroup(parent,name,caption,description,icon)
198 {
199 }
200
201
~LinearGroup()202 emRadioButton::LinearGroup::~LinearGroup()
203 {
204 }
205
206
RasterGroup(ParentArg parent,const emString & name,const emString & caption,const emString & description,const emImage & icon)207 emRadioButton::RasterGroup::RasterGroup(
208 ParentArg parent, const emString & name, const emString & caption,
209 const emString & description, const emImage & icon
210 )
211 : emRasterGroup(parent,name,caption,description,icon)
212 {
213 }
214
215
~RasterGroup()216 emRadioButton::RasterGroup::~RasterGroup()
217 {
218 }
219
220
Group(ParentArg parent,const emString & name,const emString & caption,const emString & description,const emImage & icon)221 emRadioButton::Group::Group(
222 ParentArg parent, const emString & name, const emString & caption,
223 const emString & description, const emImage & icon
224 )
225 : emGroup(parent,name,caption,description,icon,0)
226 {
227 }
228
229
~Group()230 emRadioButton::Group::~Group()
231 {
232 }
233
234
Clicked()235 void emRadioButton::Clicked()
236 {
237 if (Mech) Mech->SetChecked(this);
238 }
239
240
CheckChanged()241 void emRadioButton::CheckChanged()
242 {
243 if (Mech) {
244 if (IsChecked()) Mech->SetChecked(this);
245 else if (Mech->GetChecked()==this) Mech->SetChecked(NULL);
246 }
247 }
248
249
GetHowTo() const250 emString emRadioButton::GetHowTo() const
251 {
252 emString h;
253
254 h=emCheckButton::GetHowTo();
255 h+=HowToRadioButton;
256 return h;
257 }
258
259
260 const char * emRadioButton::HowToRadioButton=
261 "\n"
262 "\n"
263 "RADIO BUTTON\n"
264 "\n"
265 "This is a radio button. It is a check button with changed behavior: In a set of\n"
266 "radio buttons, only one button can have checked state. When triggering a radio\n"
267 "button, that button is checked and all the other radio buttons of the set are\n"
268 "unchecked. There is no way to uncheck a radio button directly.\n"
269 ;
270