]> git.saurik.com Git - wxWidgets.git/blob - src/univ/radiobut.cpp
don't crash trying to draw buttons with invalid bitmaps (the real fix would be to...
[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 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
45
46 // ----------------------------------------------------------------------------
47 // wxRadioButton
48 // ----------------------------------------------------------------------------
49
50 bool wxRadioButton::Create(wxWindow *parent,
51 wxWindowID id,
52 const wxString &label,
53 const wxPoint &pos,
54 const wxSize &size,
55 long style,
56 const wxValidator& validator,
57 const wxString &name)
58 {
59 if ( !wxCheckBox::Create(parent, id, label, pos, size, style,
60 validator, name) )
61 {
62 return false;
63 }
64
65 return true;
66 }
67
68 // ----------------------------------------------------------------------------
69 // radio button methods
70 // ----------------------------------------------------------------------------
71
72 void wxRadioButton::OnCheck()
73 {
74 // clear all others radio buttons in our group: for this we need to
75 // find the radio button which is the first in the group, i.e. the one
76 // with wxRB_GROUP style
77 const wxWindowList& siblings = GetParent()->GetChildren();
78 wxWindowList::compatibility_iterator nodeStart = siblings.Find(this);
79 while ( nodeStart )
80 {
81 // stop if we found a radio button with wxRB_GROUP style or it we
82 // are at the first control
83 if ( !nodeStart->GetPrevious() ||
84 (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) )
85 break;
86
87 nodeStart = nodeStart->GetPrevious();
88 }
89
90 // now clear all radio buttons from the starting one until the next
91 // one with wxRB_GROUP style
92 while ( nodeStart )
93 {
94 wxWindow *win = nodeStart->GetData();
95 if ( win != this )
96 {
97 wxRadioButton *btn = wxDynamicCast(win, wxRadioButton);
98 if ( btn )
99 {
100 btn->ClearValue();
101 }
102 }
103
104 nodeStart = nodeStart->GetNext();
105 if ( !nodeStart ||
106 (nodeStart->GetData()->GetWindowStyle() & wxRB_GROUP) )
107 {
108 // we reached the next group
109 break;
110 }
111 }
112 }
113
114 void wxRadioButton::ChangeValue(bool value)
115 {
116 if ( value == IsChecked() )
117 return;
118
119 if ( !IsChecked() )
120 {
121 wxCheckBox::ChangeValue(value);
122 }
123 else // attempt to clear a radio button - this can't be done
124 {
125 // but still refresh as our PRESSED flag changed
126 Refresh();
127 }
128 }
129
130 void wxRadioButton::ClearValue()
131 {
132 if ( IsChecked() )
133 {
134 SetValue(false);
135 }
136 }
137
138 void wxRadioButton::SendEvent()
139 {
140 wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, GetId());
141 InitCommandEvent(event);
142 event.SetInt(IsChecked());
143 Command(event);
144 }
145
146 // ----------------------------------------------------------------------------
147 // overridden wxCheckBox methods
148 // ----------------------------------------------------------------------------
149
150 wxSize wxRadioButton::GetBitmapSize() const
151 {
152 wxBitmap bmp = GetBitmap(State_Normal, Status_Checked);
153 return bmp.Ok() ? wxSize(bmp.GetWidth(), bmp.GetHeight())
154 : GetRenderer()->GetRadioBitmapSize();
155 }
156
157 void wxRadioButton::DoDraw(wxControlRenderer *renderer)
158 {
159 wxDC& dc = renderer->GetDC();
160 dc.SetFont(GetFont());
161 dc.SetTextForeground(GetForegroundColour());
162
163 int flags = GetStateFlags();
164 Status status = GetStatus();
165 if ( status == Status_Checked )
166 flags |= wxCONTROL_CHECKED;
167
168 renderer->GetRenderer()->
169 DrawRadioButton(dc,
170 GetLabel(),
171 GetBitmap(GetState(flags), status),
172 renderer->GetRect(),
173 flags,
174 GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT
175 : wxALIGN_LEFT,
176 GetAccelIndex());
177 }
178
179 #endif // wxUSE_RADIOBTN