]> git.saurik.com Git - wxWidgets.git/blob - src/msw/tglbtn.cpp
Add wxItemContainer::DetachClientObject() and use it in wxRearrangeList.
[wxWidgets.git] / src / msw / tglbtn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/tglbtn.cpp
3 // Purpose: Definition of the wxToggleButton class, which implements a
4 // toggle button under wxMSW.
5 // Author: John Norris, minor changes by Axel Schlueter
6 // and William Gallafent.
7 // Modified by:
8 // Created: 08.02.01
9 // RCS-ID: $Id$
10 // Copyright: (c) 2000 Johnny C. Norris II
11 // Licence: wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
13
14 // ============================================================================
15 // declarations
16 // ============================================================================
17
18 // ----------------------------------------------------------------------------
19 // headers
20 // ----------------------------------------------------------------------------
21
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #if wxUSE_TOGGLEBTN
29
30 #include "wx/tglbtn.h"
31
32 #ifndef WX_PRECOMP
33 #include "wx/button.h"
34 #include "wx/brush.h"
35 #include "wx/dcscreen.h"
36 #include "wx/settings.h"
37
38 #include "wx/log.h"
39 #endif // WX_PRECOMP
40
41 #include "wx/renderer.h"
42 #include "wx/dcclient.h"
43
44 #include "wx/msw/private.h"
45 #include "wx/msw/private/button.h"
46
47 // ----------------------------------------------------------------------------
48 // macros
49 // ----------------------------------------------------------------------------
50
51 wxDEFINE_EVENT( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEvent );
52
53 // ============================================================================
54 // implementation
55 // ============================================================================
56
57 //-----------------------------------------------------------------------------
58 // wxBitmapToggleButton
59 //-----------------------------------------------------------------------------
60
61 IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxControl)
62
63 BEGIN_EVENT_TABLE(wxBitmapToggleButton,wxToggleButtonBase)
64 EVT_PAINT(wxBitmapToggleButton::OnPaint)
65 EVT_MOUSE_EVENTS(wxBitmapToggleButton::OnMouse)
66 EVT_CHAR(wxBitmapToggleButton::OnChar)
67 EVT_SIZE(wxBitmapToggleButton::OnSize)
68 END_EVENT_TABLE()
69
70 void wxBitmapToggleButton::Init()
71 {
72 m_depressed = false;
73 m_oldValue = false;
74 m_capturing = false;
75 }
76
77 bool wxBitmapToggleButton::Create( wxWindow *parent, wxWindowID id,
78 const wxBitmap& label,const wxPoint& pos, const wxSize& size, long style,
79 const wxValidator& validator, const wxString& name )
80 {
81 Init();
82
83 if (!wxToggleButtonBase::Create( parent, id, pos, size, style, validator, name ))
84 return false;
85
86 m_bitmap = label;
87
88 if (size.x == -1 || size.y == -1)
89 {
90 wxSize new_size = GetBestSize();
91 if (size.x != -1)
92 new_size.x = size.x;
93 if (size.y != -1)
94 new_size.y = size.y;
95 SetSize( new_size );
96 }
97
98 return true;
99 }
100
101 void wxBitmapToggleButton::SetValue(bool state)
102 {
103 if (m_capturing) return;
104
105 if (state == m_depressed) return;
106
107 m_depressed = state;
108 Refresh();
109 }
110
111 bool wxBitmapToggleButton::GetValue() const
112 {
113 return m_depressed;
114 }
115
116 void wxBitmapToggleButton::SetLabel(const wxBitmap& label)
117 {
118 m_bitmap = label;
119 m_disabledBitmap = wxBitmap();
120
121 Refresh();
122 }
123
124 bool wxBitmapToggleButton::Enable(bool enable)
125 {
126 if (m_capturing) return false;
127
128 if (!wxToggleButtonBase::Enable( enable ))
129 return false;
130
131 Refresh();
132
133 return true;
134 }
135
136 void wxBitmapToggleButton::OnPaint(wxPaintEvent &WXUNUSED(event))
137 {
138 wxSize size = GetSize();
139
140 wxBitmap bitmap = m_bitmap;
141
142 wxPaintDC dc(this);
143 wxRendererNative &renderer = wxRendererNative::Get();
144 int flags = 0;
145 if (m_depressed)
146 flags |= wxCONTROL_PRESSED;
147 wxRect rect(0,0,size.x,size.y);
148 renderer.DrawPushButton( this, dc, rect, flags );
149
150 if (bitmap.IsOk())
151 {
152 if (!IsEnabled())
153 {
154 if (!m_disabledBitmap.IsOk())
155 {
156 wxImage image = m_bitmap.ConvertToImage();
157 m_disabledBitmap = wxBitmap( image.ConvertToGreyscale() );
158 }
159
160 bitmap = m_disabledBitmap;
161 }
162
163 wxSize bsize = bitmap.GetSize();
164 int offset = 0;
165 if (m_depressed) offset = 1;
166 dc.DrawBitmap( bitmap, (size.x-bsize.x) / 2 + offset, (size.y-bsize.y) / 2 + offset, true );
167 }
168
169 }
170
171 void wxBitmapToggleButton::OnMouse(wxMouseEvent &event)
172 {
173 if (!IsEnabled())
174 return;
175
176 wxSize size = GetSize();
177 bool mouse_in = ((event.GetX() > 0) && (event.GetX() < size.x) &&
178 (event.GetY() > 0) && (event.GetY() < size.y));
179
180 if (m_capturing)
181 {
182 bool old_depressed = m_depressed;
183 if (mouse_in)
184 m_depressed = !m_oldValue;
185 else
186 m_depressed = m_oldValue;
187
188 if (event.LeftUp())
189 {
190 ReleaseMouse();
191 m_capturing = false;
192 if (mouse_in)
193 {
194 wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId);
195 event.SetInt(GetValue());
196 event.SetEventObject(this);
197 ProcessCommand(event);
198 }
199 }
200
201 if (old_depressed != m_depressed)
202 Refresh();
203 }
204 else
205 {
206 if (event.LeftDown())
207 {
208 m_capturing = true;
209 m_oldValue = m_depressed;
210 m_depressed = !m_oldValue;
211 CaptureMouse();
212 Refresh();
213 }
214 }
215 }
216
217 void wxBitmapToggleButton::OnChar(wxKeyEvent &event)
218 {
219 if (event.GetKeyCode() == WXK_SPACE)
220 {
221 m_depressed = !m_depressed;
222 Refresh();
223
224 wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId);
225 event.SetInt(GetValue());
226 event.SetEventObject(this);
227 ProcessCommand(event);
228 }
229 }
230
231 void wxBitmapToggleButton::OnSize(wxSizeEvent &WXUNUSED(event))
232 {
233 Refresh();
234 }
235
236 wxSize wxBitmapToggleButton::DoGetBestSize() const
237 {
238 if (!m_bitmap.IsOk())
239 return wxSize(16,16);
240
241 wxSize ret = m_bitmap.GetSize();
242 ret.x += 8;
243 ret.y += 8;
244 return ret;
245 }
246
247
248 // ----------------------------------------------------------------------------
249 // wxToggleButton
250 // ----------------------------------------------------------------------------
251
252 IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
253
254 // Single check box item
255 bool wxToggleButton::Create(wxWindow *parent,
256 wxWindowID id,
257 const wxString& label,
258 const wxPoint& pos,
259 const wxSize& size, long style,
260 const wxValidator& validator,
261 const wxString& name)
262 {
263 if ( !CreateControl(parent, id, pos, size, style, validator, name) )
264 return false;
265
266 // if the label contains several lines we must explicitly tell the button
267 // about it or it wouldn't draw it correctly ("\n"s would just appear as
268 // black boxes)
269 //
270 // NB: we do it here and not in MSWGetStyle() because we need the label
271 // value and the label is not set yet when MSWGetStyle() is called
272 WXDWORD exstyle;
273 WXDWORD msStyle = MSWGetStyle(style, &exstyle);
274 msStyle |= wxMSWButton::GetMultilineStyle(label);
275
276 return MSWCreateControl(wxT("BUTTON"), msStyle, pos, size, label, exstyle);
277 }
278
279 WXDWORD wxToggleButton::MSWGetStyle(long style, WXDWORD *exstyle) const
280 {
281 WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
282
283 msStyle |= BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP;
284
285 if ( style & wxBU_LEFT )
286 msStyle |= BS_LEFT;
287 if ( style & wxBU_RIGHT )
288 msStyle |= BS_RIGHT;
289 if ( style & wxBU_TOP )
290 msStyle |= BS_TOP;
291 if ( style & wxBU_BOTTOM )
292 msStyle |= BS_BOTTOM;
293
294 return msStyle;
295 }
296
297 wxSize wxToggleButton::DoGetBestSize() const
298 {
299 return wxMSWButton::ComputeBestSize(const_cast<wxToggleButton *>(this));
300 }
301
302 void wxToggleButton::SetLabel(const wxString& label)
303 {
304 wxMSWButton::UpdateMultilineStyle(GetHwnd(), label);
305
306 wxToggleButtonBase::SetLabel(label);
307 }
308
309 void wxToggleButton::SetValue(bool val)
310 {
311 ::SendMessage(GetHwnd(), BM_SETCHECK, val, 0);
312 }
313
314 bool wxToggleButton::GetValue() const
315 {
316 return ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) == BST_CHECKED;
317 }
318
319 void wxToggleButton::Command(wxCommandEvent& event)
320 {
321 SetValue(event.GetInt() != 0);
322 ProcessCommand(event);
323 }
324
325 bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
326 {
327 wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId);
328 event.SetInt(GetValue());
329 event.SetEventObject(this);
330 ProcessCommand(event);
331 return true;
332 }
333
334 #endif // wxUSE_TOGGLEBTN