1
2
3
4
5
6 using System;
7
8 namespace System.Windows
9 {
10 public nothrow ControlCreateParams& RadioButtonControlCreateParams(ControlCreateParams& controlCreateParams, ButtonStyle buttonStyle)
11 {
12 return controlCreateParams.SetWindowClassName("BUTTON").
13 SetWindowStyle(cast<WindowStyle>(DefaultChildWindowStyle() | WindowStyle.WS_TABSTOP | buttonStyle));
14 }
15
16 public nothrow ControlCreateParams& RadioButtonControlCreateParams(ControlCreateParams& controlCreateParams)
17 {
18 return RadioButtonControlCreateParams(controlCreateParams, cast<ButtonStyle>(ButtonStyle.BS_RADIOBUTTON | ButtonStyle.BS_NOTIFY));
19 }
20
21 public class RadioButtonCreateParams
22 {
23 public nothrow RadioButtonCreateParams(ControlCreateParams& controlCreateParams_) :
24 controlCreateParams(controlCreateParams_), autoSize(true)
25 {
26 }
27 public nothrow RadioButtonCreateParams& Defaults()
28 {
29 return *this;
30 }
31 public nothrow RadioButtonCreateParams& SetAutoSize(bool autoSize_)
32 {
33 autoSize = autoSize_;
34 return *this;
35 }
36 public ControlCreateParams& controlCreateParams;
37 public bool autoSize;
38 }
39
40 public class RadioButton : ButtonBase
41 {
42 private enum Flags : sbyte
43 {
44 none = 0, checked = 1 << 0, autoSize = 1 << 1, autoSized = 1 << 2
45 }
46
47 public RadioButton(const Color& backgroundColor, const string& text, const Point& location, const Size& size, Dock dock, Anchors anchors,
48 bool autoSize) : base("BUTTON", DefaultWindowClassStyle(),
49 cast<WindowStyle>(DefaultChildWindowStyle() | WindowStyle.WS_TABSTOP | ButtonStyle.BS_RADIOBUTTON | ButtonStyle.BS_NOTIFY),
50 DefaultExtendedWindowStyle(), backgroundColor, text, location, size, dock, anchors), flags(Flags.none)
51 {
52 if (autoSize)
53 {
54 SetAutoSizeFlag();
55 }
56 else
57 {
58 ResetAutoSizeFlag();
59 }
60 }
61 public RadioButton(const string& text, const Point& location, const Size& size, Dock dock, Anchors anchors, bool autoSize) :
62 this(DefaultControlBackgroundColor(), text, location, size, dock, anchors, autoSize)
63 {
64 }
65 public RadioButton(RadioButtonCreateParams& createParams) : base(createParams.controlCreateParams), flags(Flags.none)
66 {
67 if (createParams.autoSize)
68 {
69 SetAutoSizeFlag();
70 }
71 else
72 {
73 ResetAutoSizeFlag();
74 }
75 }
76 public bool Checked()
77 {
78 return GetCheckedFlag();
79 }
80 public void SetChecked(bool checked)
81 {
82 if (checked)
83 {
84 Control* parent = ParentControl();
85 if (parent != null)
86 {
87 if (parent is GroupBox*)
88 {
89 GroupBox* groupBox = cast<GroupBox*>(parent);
90 if (groupBox->CheckedRadioButton() != this)
91 {
92 groupBox->SetCheckedRadioButton(this);
93 }
94 }
95 }
96 SetCheckedFlag();
97 if (Handle() != null)
98 {
99 WinSendMessage(Handle(), BM_SETCHECK, BST_CHECKED, 0);
100 }
101 SetFocus();
102 }
103 else
104 {
105 Control* parent = ParentControl();
106 if (parent != null)
107 {
108 if (parent is GroupBox*)
109 {
110 GroupBox* groupBox = cast<GroupBox*>(parent);
111 if (groupBox->CheckedRadioButton() == this)
112 {
113 groupBox->ResetCheckedRadioButton();
114 }
115 }
116 }
117 ResetCheckedFlag();
118 if (Handle() != null)
119 {
120 WinSendMessage(Handle(), BM_SETCHECK, BST_UNCHECKED, 0);
121 }
122 }
123 }
124 protected override void OnCreated()
125 {
126 base->OnCreated();
127 Graphics graphics = Graphics.FromWindowHandle(Handle());
128 const FontHandle& fontHandle = GetFontHandle(graphics);
129 if (!fontHandle.IsNull())
130 {
131 SendSetFontMessage(fontHandle);
132 }
133 if (GetCheckedFlag())
134 {
135 SetChecked(true);
136 }
137 else
138 {
139 SetChecked(false);
140 }
141 if (GetAutoSizeFlag())
142 {
143 DoAutoSize();
144 }
145 }
146 protected override void OnClick()
147 {
148 base->OnClick();
149 SetChecked(true);
150 }
151 protected override void OnTextChanged()
152 {
153 base->OnTextChanged();
154 if (GetAutoSizeFlag())
155 {
156 ResetAutoSized();
157 DoAutoSize();
158 }
159 }
160 protected virtual void OnCheckedChanged()
161 {
162 checkedChangedEvent.Fire();
163 }
164 public nothrow Event<CheckedChangedEventHandler>& CheckedChangedEvent() const
165 {
166 return checkedChangedEvent;
167 }
168 private void RetrieveCheckedState()
169 {
170 long result = WinSendMessage(Handle(), BM_GETCHECK, 0u, 0);
171 if (result == BST_CHECKED)
172 {
173 SetCheckedFlag();
174 }
175 else
176 {
177 ResetCheckedFlag();
178 }
179 }
180 private void DoAutoSize()
181 {
182 if (AutoSized()) return;
183 if (Handle() == null) return;
184 Graphics graphics = Graphics.FromWindowHandle(Handle());
185 const Font& font = GetFont();
186 StringFormat stringFormat;
187 RectF r = graphics.MeasureStringChecked(Text(), font, PointF(0, 0), stringFormat);
188 Size buttonSize = GetButtonSize();
189 Size borderSize = GetBorderSize();
190 r.size.w = r.size.w + buttonSize.w + borderSize.w;
191 r.size.h = Max(r.size.h, buttonSize.h + borderSize.h);
192 SetSize(Size(cast<int>(r.size.w), cast<int>(r.size.h)));
193 SetAutoSized();
194 }
195 private nothrow Size GetButtonSize()
196 {
197 int x = GetSystemMetrics(SystemMetricsId.SM_CXMENUCHECK);
198 int y = GetSystemMetrics(SystemMetricsId.SM_CYMENUCHECK);
199 return Size(x, y);
200 }
201 private nothrow Size GetBorderSize()
202 {
203 int x = GetSystemMetrics(SystemMetricsId.SM_CXBORDER);
204 int y = GetSystemMetrics(SystemMetricsId.SM_CYBORDER);
205 return Size(x, y);
206 }
207 private inline nothrow bool GetCheckedFlag() const
208 {
209 return (flags & Flags.checked) != Flags.none;
210 }
211 private void SetCheckedFlag()
212 {
213 if (!GetCheckedFlag())
214 {
215 flags = cast<Flags>(flags | Flags.checked);
216 OnCheckedChanged();
217 }
218 }
219 private void ResetCheckedFlag()
220 {
221 if (GetCheckedFlag())
222 {
223 flags = cast<Flags>(flags & ~Flags.checked);
224 OnCheckedChanged();
225 }
226 }
227 private inline nothrow bool GetAutoSizeFlag() const
228 {
229 return (flags & Flags.autoSize) != Flags.none;
230 }
231 private inline nothrow void SetAutoSizeFlag()
232 {
233 flags = cast<Flags>(flags | Flags.autoSize);
234 }
235 private inline nothrow void ResetAutoSizeFlag()
236 {
237 flags = cast<Flags>(flags & ~Flags.autoSize);
238 }
239 private inline nothrow bool AutoSized() const
240 {
241 return (flags & Flags.autoSized) != Flags.none;
242 }
243 private inline nothrow void SetAutoSized()
244 {
245 flags = cast<Flags>(flags | Flags.autoSized);
246 }
247 private inline nothrow void ResetAutoSized()
248 {
249 flags = cast<Flags>(flags & ~Flags.autoSized);
250 }
251 private Flags flags;
252 private Event<CheckedChangedEventHandler> checkedChangedEvent;
253 }
254 }