]> git.saurik.com Git - wxWidgets.git/blob - src/generic/buttonbar.cpp
wxButtonToolBar only useful on Mac right now
[wxWidgets.git] / src / generic / buttonbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/buttonbar.cpp
3 // Purpose: wxButtonToolBar implementation
4 // Author: Julian Smart, after Robert Roebling, Vadim Zeitlin, SciTech
5 // Modified by:
6 // Created: 2006-04-13
7 // Id: $Id$
8 // Copyright: (c) Julian Smart, Robert Roebling, Vadim Zeitlin,
9 // SciTech Software, Inc.
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 // ============================================================================
14 // declarations
15 // ============================================================================
16
17 // ----------------------------------------------------------------------------
18 // headers
19 // ----------------------------------------------------------------------------
20
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 // Currently, only for Mac as a toolbar replacement.
29 #if defined(__WXMAC__) && wxUSE_TOOLBAR && wxUSE_BMPBUTTON
30
31 #ifndef WX_PRECOMP
32 #include "wx/utils.h"
33 #include "wx/app.h"
34 #endif
35
36 #include "wx/generic/buttonbar.h"
37 #include "wx/frame.h"
38 #include "wx/image.h"
39 #include "wx/log.h"
40
41 // ----------------------------------------------------------------------------
42 // wxButtonToolBarTool: our implementation of wxToolBarToolBase
43 // ----------------------------------------------------------------------------
44
45 class WXDLLEXPORT wxButtonToolBarTool : public wxToolBarToolBase
46 {
47 public:
48 wxButtonToolBarTool(wxButtonToolBar *tbar,
49 int id,
50 const wxString& label,
51 const wxBitmap& bmpNormal,
52 const wxBitmap& bmpDisabled,
53 wxItemKind kind,
54 wxObject *clientData,
55 const wxString& shortHelp,
56 const wxString& longHelp)
57 : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
58 clientData, shortHelp, longHelp)
59 {
60 m_x = m_y = wxDefaultCoord;
61 m_width =
62 m_height = 0;
63
64 m_button = NULL;
65 }
66
67 wxButtonToolBarTool(wxButtonToolBar *tbar, wxControl *control)
68 : wxToolBarToolBase(tbar, control)
69 {
70 m_x = m_y = wxDefaultCoord;
71 m_width =
72 m_height = 0;
73 m_button = NULL;
74 }
75
76 wxBitmapButton* GetButton() const { return m_button; }
77 void SetButton(wxBitmapButton* button) { m_button = button; }
78
79 public:
80 // the tool position (for controls)
81 wxCoord m_x;
82 wxCoord m_y;
83 wxCoord m_width;
84 wxCoord m_height;
85
86 private:
87 // the control representing the button
88 wxBitmapButton* m_button;
89 };
90
91 // ============================================================================
92 // wxButtonToolBar implementation
93 // ============================================================================
94
95 IMPLEMENT_DYNAMIC_CLASS(wxButtonToolBar, wxControl)
96
97 BEGIN_EVENT_TABLE(wxButtonToolBar, wxControl)
98 EVT_BUTTON(wxID_ANY, wxButtonToolBar::OnCommand)
99 END_EVENT_TABLE()
100
101 // ----------------------------------------------------------------------------
102 // wxButtonToolBar creation
103 // ----------------------------------------------------------------------------
104
105 void wxButtonToolBar::Init()
106 {
107 // no tools yet
108 m_needsLayout = false;
109
110 // unknown widths for the tools and separators
111 m_widthSeparator = wxDefaultCoord;
112
113 m_maxWidth =
114 m_maxHeight = 0;
115 }
116
117 bool wxButtonToolBar::Create(wxWindow *parent,
118 wxWindowID id,
119 const wxPoint& pos,
120 const wxSize& size,
121 long style,
122 const wxString& name)
123 {
124 if ( !wxToolBarBase::Create(parent, id, pos, size, style,
125 wxDefaultValidator, name) )
126 {
127 return false;
128 }
129
130 return true;
131 }
132
133 wxButtonToolBar::~wxButtonToolBar()
134 {
135 }
136
137 // ----------------------------------------------------------------------------
138 // wxButtonToolBar tool-related methods
139 // ----------------------------------------------------------------------------
140
141 wxToolBarToolBase *wxButtonToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
142 {
143 // check the "other" direction first: it must be inside the toolbar or we
144 // don't risk finding anything
145 if ( IsVertical() )
146 {
147 if ( x < 0 || x > m_maxWidth )
148 return NULL;
149
150 // we always use x, even for a vertical toolbar, this makes the code
151 // below simpler
152 x = y;
153 }
154 else // horizontal
155 {
156 if ( y < 0 || y > m_maxHeight )
157 return NULL;
158 }
159
160 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
161 node;
162 node = node->GetNext() )
163 {
164 wxButtonToolBarTool *tool = (wxButtonToolBarTool*) node->GetData();
165 wxRect rectTool = GetToolRect(tool);
166
167 wxCoord startTool, endTool;
168 GetRectLimits(rectTool, &startTool, &endTool);
169
170 if ( x >= startTool && x <= endTool )
171 {
172 // don't return the separators from here, they don't accept any
173 // input anyhow
174 return tool->IsSeparator() ? NULL : tool;
175 }
176 }
177
178 return NULL;
179 }
180
181 void wxButtonToolBar::GetRectLimits(const wxRect& rect,
182 wxCoord *start,
183 wxCoord *end) const
184 {
185 wxCHECK_RET( start && end, _T("NULL pointer in GetRectLimits") );
186
187 if ( IsVertical() )
188 {
189 *start = rect.GetTop();
190 *end = rect.GetBottom();
191 }
192 else // horizontal
193 {
194 *start = rect.GetLeft();
195 *end = rect.GetRight();
196 }
197 }
198
199
200 void wxButtonToolBar::SetToolShortHelp(int id, const wxString& help)
201 {
202 wxToolBarToolBase *tool = FindById(id);
203
204 wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") );
205
206 // TODO: set tooltip/short help
207 tool->SetShortHelp(help);
208 }
209
210 bool wxButtonToolBar::DoInsertTool(size_t WXUNUSED(pos),
211 wxToolBarToolBase * WXUNUSED(tool))
212 {
213 return true;
214 }
215
216 bool wxButtonToolBar::DoDeleteTool(size_t WXUNUSED(pos),
217 wxToolBarToolBase * WXUNUSED(tool))
218 {
219 // TODO
220 return true;
221 }
222
223 void wxButtonToolBar::DoEnableTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(enable))
224 {
225 // TODO
226 }
227
228 void wxButtonToolBar::DoToggleTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
229 {
230 // TODO
231 }
232
233 void wxButtonToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
234 {
235 // TODO
236 }
237
238 wxToolBarToolBase *wxButtonToolBar::CreateTool(int id,
239 const wxString& label,
240 const wxBitmap& bmpNormal,
241 const wxBitmap& bmpDisabled,
242 wxItemKind kind,
243 wxObject *clientData,
244 const wxString& shortHelp,
245 const wxString& longHelp)
246 {
247 return new wxButtonToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
248 clientData, shortHelp, longHelp);
249 }
250
251 wxToolBarToolBase *wxButtonToolBar::CreateTool(wxControl *control)
252 {
253 return new wxButtonToolBarTool(this, control);
254 }
255
256 // ----------------------------------------------------------------------------
257 // wxButtonToolBar geometry
258 // ----------------------------------------------------------------------------
259
260 wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
261 {
262 const wxButtonToolBarTool *tool = (wxButtonToolBarTool *)toolBase;
263
264 wxRect rect;
265
266 wxCHECK_MSG( tool, rect, _T("GetToolRect: NULL tool") );
267
268 // ensure that we always have the valid tool position
269 if ( m_needsLayout )
270 {
271 wxConstCast(this, wxButtonToolBar)->DoLayout();
272 }
273
274 rect.x = tool->m_x - m_xMargin;
275 rect.y = tool->m_y - m_yMargin;
276
277 if ( IsVertical() )
278 {
279 if (tool->IsButton())
280 {
281 rect.width = m_defaultWidth;
282 rect.height = m_defaultHeight;
283 if (tool->GetButton())
284 rect.SetSize(tool->GetButton()->GetSize());
285 }
286 else if (tool->IsSeparator())
287 {
288 rect.width = m_defaultWidth;
289 rect.height = m_widthSeparator;
290 }
291 else // control
292 {
293 rect.width = tool->m_width;
294 rect.height = tool->m_height;
295 }
296 }
297 else // horizontal
298 {
299 if (tool->IsButton())
300 {
301 rect.width = m_defaultWidth;
302 rect.height = m_defaultHeight;
303 if (tool->GetButton())
304 rect.SetSize(tool->GetButton()->GetSize());
305 }
306 else if (tool->IsSeparator())
307 {
308 rect.width = m_widthSeparator;
309 rect.height = m_defaultHeight;
310 }
311 else // control
312 {
313 rect.width = tool->m_width;
314 rect.height = tool->m_height;
315 }
316 }
317
318 rect.width += 2*m_xMargin;
319 rect.height += 2*m_yMargin;
320
321 return rect;
322 }
323
324 bool wxButtonToolBar::Realize()
325 {
326 if ( !wxToolBarBase::Realize() )
327 return false;
328
329 m_needsLayout = true;
330 DoLayout();
331
332 SetBestSize(wxSize(m_maxWidth, m_maxHeight));
333
334 return true;
335 }
336
337 void wxButtonToolBar::DoLayout()
338 {
339 m_needsLayout = false;
340
341 wxCoord x = m_xMargin,
342 y = m_yMargin;
343
344 int maxHeight = 0;
345
346 const wxCoord widthTool = IsVertical() ? m_defaultHeight : m_defaultWidth;
347 wxCoord margin = IsVertical() ? m_xMargin : m_yMargin;
348 wxCoord *pCur = IsVertical() ? &y : &x;
349
350 // calculate the positions of all elements
351 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
352 node;
353 node = node->GetNext() )
354 {
355 wxButtonToolBarTool *tool = (wxButtonToolBarTool *) node->GetData();
356
357 tool->m_x = x;
358 tool->m_y = y;
359
360 if (tool->IsButton())
361 {
362 if (!tool->GetButton())
363 {
364 wxBitmapButton* bmpButton = new wxBitmapButton(this, tool->GetId(), tool->GetNormalBitmap(), wxPoint(tool->m_x, tool->m_y), wxDefaultSize,
365 wxBU_AUTODRAW);
366
367 tool->SetButton(bmpButton);
368 }
369 else
370 {
371 tool->GetButton()->Move(wxPoint(tool->m_x, tool->m_y));
372 }
373
374 int w = widthTool;
375 if (tool->GetButton())
376 {
377 wxSize sz = tool->GetButton()->GetSize();
378 w = sz.x;
379
380 maxHeight = wxMax(maxHeight, sz.y);
381 }
382
383 *pCur += (w + GetToolPacking());
384 }
385 else if (tool->IsSeparator())
386 {
387 *pCur += m_widthSeparator;
388 }
389 else if (!IsVertical()) // horizontal control
390 {
391 wxControl *control = tool->GetControl();
392 wxSize size = control->GetSize();
393 tool->m_y += (m_defaultHeight - size.y)/2;
394 tool->m_width = size.x;
395 tool->m_height = size.y;
396
397 *pCur += tool->m_width;
398
399 maxHeight = wxMax(maxHeight, size.y);
400 }
401 *pCur += margin;
402 }
403
404 // calculate the total toolbar size
405 m_maxWidth = x + 2*m_xMargin;
406 m_maxHeight = maxHeight + 2*m_yMargin;
407 }
408
409 wxSize wxButtonToolBar::DoGetBestClientSize() const
410 {
411 return wxSize(m_maxWidth, m_maxHeight);
412 }
413
414 // receives button commands
415 void wxButtonToolBar::OnCommand(wxCommandEvent& event)
416 {
417 wxButtonToolBarTool* tool = (wxButtonToolBarTool*) FindById(event.GetId());
418 if (!tool)
419 {
420 event.Skip();
421 return;
422 }
423
424 // TODO: handle toggle items
425 OnLeftClick(event.GetId(), false);
426 }
427
428 #endif // wxUSE_TOOLBAR && wxUSE_BMPBUTTON
429