]> git.saurik.com Git - wxWidgets.git/blob - src/univ/radiobut.cpp
fix crash in wxWindowGTK::GTKHandleUnrealize(), closes #14752
[wxWidgets.git] / src / univ / radiobut.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/radiobut.cpp
3 // Purpose: wxRadioButton implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 10.09.00
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_RADIOBTN
27
28 #include "wx/radiobut.h"
29
30 #ifndef WX_PRECOMP
31 #include "wx/dcclient.h"
32 #include "wx/validate.h"
33 #endif
34
35 #include "wx/univ/theme.h"
36 #include "wx/univ/renderer.h"
37 #include "wx/univ/inphand.h"
38 #include "wx/univ/colschem.h"
39
40 // ============================================================================
41 // implementation
42 // ============================================================================
43
44 // ----------------------------------------------------------------------------
45 // wxRadioButton
46 // ----------------------------------------------------------------------------
47
48 bool wxRadioButton::Create(wxWindow *parent,
49 wxWindowID id,
50 const wxString &label,
51 const wxPoint &pos,
52 const wxSize &size,
53 long style,
54 const wxValidator& validator,
55 const wxString &name)
56 {
57 if ( !wxCheckBox::Create(parent, id, label, pos, size, style,
58 validator, name) )
59 {
60 return false;
61 }
62
63 return true;
64 }
65
66 // ----------------------------------------------------------------------------
67 // radio button methods
68 // ----------------------------------------------------------------------------
69
70 void wxRadioButton::OnCheck()
71 {
72 // clear all others radio buttons in our group: for this we need to
73 // find the radio button which is the first in the group, i.e. the one
74 // with wxRB_GROUP style
75 const wxWindowList& siblings = GetParent()->GetChildren();
76 wxWindowList::compatibility_iterator nodeStart = siblings.Find(this);
77 while ( nodeStart )
78 {
79 // stop if we found a radio button with wxRB_GROUP style or it we
80 // are at the first control
81 if ( !nodeStart->GetPrevious() ||
82 (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) )
83 break;
84
85 nodeStart = nodeStart->GetPrevious();
86 }
87
88 // now clear all radio buttons from the starting one until the next
89 // one with wxRB_GROUP style
90 while ( nodeStart )
91 {
92 wxWindow *win = nodeStart->GetData();
93 if ( win != this )
94 {
95 wxRadioButton *btn = wxDynamicCast(win, wxRadioButton);
96 if ( btn )
97 {
98 btn->ClearValue();
99 }
100 }
101
102 nodeStart = nodeStart->GetNext();
103 if ( !nodeStart ||
104 (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) )
105 {
106 // we reached the next group
107 break;
108 }
109 }
110 }
111
112 void wxRadioButton::ChangeValue(bool value)
113 {
114 if ( value == IsChecked() )
115 return;
116
117 if ( !IsChecked() )
118 {
119 wxCheckBox::ChangeValue(value);
120 }
121 else // attempt to clear a radio button - this can't be done
122 {
123 // but still refresh as our PRESSED flag changed
124 Refresh();
125 }
126 }
127
128 void wxRadioButton::ClearValue()
129 {
130 if ( IsChecked() )
131 {
132 SetValue(false);
133 }
134 }
135
136 void wxRadioButton::SendEvent()
137 {
138 wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, GetId());
139 InitCommandEvent(event);
140 event.SetInt(IsChecked());
141 Command(event);
142 }
143
144 // ----------------------------------------------------------------------------
145 // overridden wxCheckBox methods
146 // ----------------------------------------------------------------------------
147
148 wxSize wxRadioButton::GetBitmapSize() const
149 {
150 wxBitmap bmp = GetBitmap(State_Normal, Status_Checked);
151 return bmp.IsOk() ? wxSize(bmp.GetWidth(), bmp.GetHeight())
152 : GetRenderer()->GetRadioBitmapSize();
153 }
154
155 void wxRadioButton::DoDraw(wxControlRenderer *renderer)
156 {
157 wxDC& dc = renderer->GetDC();
158 dc.SetFont(GetFont());
159 dc.SetTextForeground(GetForegroundColour());
160
161 int flags = GetStateFlags();
162 Status status = GetStatus();
163 if ( status == Status_Checked )
164 flags |= wxCONTROL_CHECKED;
165
166 renderer->GetRenderer()->
167 DrawRadioButton(dc,
168 GetLabel(),
169 GetBitmap(GetState(flags), status),
170 renderer->GetRect(),
171 flags,
172 GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT
173 : wxALIGN_LEFT,
174 GetAccelIndex());
175 }
176
177 #endif // wxUSE_RADIOBTN