]> git.saurik.com Git - wxWidgets.git/blame - src/common/tbarbase.cpp
take const reference (thanks to Alberto Barbati)
[wxWidgets.git] / src / common / tbarbase.cpp
CommitLineData
10b959e3 1/////////////////////////////////////////////////////////////////////////////
8a0681f9
VZ
2// Name: common/tbarbase.cpp
3// Purpose: wxToolBarBase implementation
10b959e3 4// Author: Julian Smart
8a0681f9 5// Modified by: VZ at 11.12.99 (wxScrollableToolBar splitted off)
10b959e3
JS
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
1c383dba 9// Licence: wxWindows license
10b959e3
JS
10/////////////////////////////////////////////////////////////////////////////
11
8a0681f9
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
10b959e3 20#ifdef __GNUG__
8a0681f9 21 #pragma implementation "tbarbase.h"
10b959e3
JS
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
8a0681f9 28 #pragma hdrstop
10b959e3
JS
29#endif
30
1e6feb95
VZ
31#if wxUSE_TOOLBAR
32
10b959e3 33#ifndef WX_PRECOMP
10b959e3
JS
34#endif
35
e702ff0f
JS
36#include "wx/frame.h"
37
10b959e3 38// For ::UpdateWindow
2049ba38 39#ifdef __WXMSW__
10b959e3
JS
40#include <windows.h>
41#endif
42
10b959e3
JS
43#include "wx/tbarbase.h"
44
8a0681f9
VZ
45// ----------------------------------------------------------------------------
46// wxWindows macros
47// ----------------------------------------------------------------------------
48
12ed316d
JS
49IMPLEMENT_CLASS(wxToolBarBase, wxControl)
50
1e6feb95
VZ
51BEGIN_EVENT_TABLE(wxToolBarBase, wxControl)
52 EVT_IDLE(wxToolBarBase::OnIdle)
53END_EVENT_TABLE()
54
8a0681f9 55#include "wx/listimpl.cpp"
1c383dba 56
8a0681f9 57WX_DEFINE_LIST(wxToolBarToolsList);
10b959e3 58
8a0681f9
VZ
59// ============================================================================
60// implementation
61// ============================================================================
10b959e3 62
8a0681f9
VZ
63// ----------------------------------------------------------------------------
64// wxToolBarToolBase
65// ----------------------------------------------------------------------------
10b959e3 66
8a0681f9 67bool wxToolBarToolBase::Enable(bool enable)
10b959e3 68{
8a0681f9
VZ
69 if ( m_enabled == enable )
70 return FALSE;
10b959e3 71
8a0681f9 72 m_enabled = enable;
10b959e3 73
8a0681f9 74 return TRUE;
10b959e3
JS
75}
76
8a0681f9 77bool wxToolBarToolBase::Toggle(bool toggle)
10b959e3 78{
8a0681f9
VZ
79 wxASSERT_MSG( m_isToggle, _T("can't toggle this tool") );
80
81 if ( m_toggled == toggle )
82 return FALSE;
10b959e3 83
8a0681f9
VZ
84 m_toggled = toggle;
85
86 return TRUE;
10b959e3
JS
87}
88
8a0681f9 89bool wxToolBarToolBase::SetToggle(bool toggle)
10b959e3 90{
8a0681f9
VZ
91 if ( m_isToggle == toggle )
92 return FALSE;
10b959e3 93
8a0681f9 94 m_isToggle = toggle;
10b959e3
JS
95
96 return TRUE;
97}
98
8a0681f9 99bool wxToolBarToolBase::SetShortHelp(const wxString& help)
10b959e3 100{
8a0681f9
VZ
101 if ( m_shortHelpString == help )
102 return FALSE;
10b959e3 103
8a0681f9
VZ
104 m_shortHelpString = help;
105
106 return TRUE;
10b959e3
JS
107}
108
8a0681f9 109bool wxToolBarToolBase::SetLongHelp(const wxString& help)
10b959e3 110{
8a0681f9
VZ
111 if ( m_longHelpString == help )
112 return FALSE;
10b959e3 113
8a0681f9
VZ
114 m_longHelpString = help;
115
116 return TRUE;
10b959e3
JS
117}
118
8a0681f9 119wxToolBarToolBase::~wxToolBarToolBase()
10b959e3 120{
8a0681f9 121}
10b959e3 122
8a0681f9
VZ
123// ----------------------------------------------------------------------------
124// wxToolBarBase adding/deleting items
125// ----------------------------------------------------------------------------
ac91b9d2 126
8a0681f9
VZ
127wxToolBarBase::wxToolBarBase()
128{
129 // the list owns the pointers
130 m_tools.DeleteContents(TRUE);
10b959e3 131
8a0681f9 132 m_xMargin = m_yMargin = 0;
10b959e3 133
8a0681f9 134 m_maxRows = m_maxCols = 0;
10b959e3
JS
135}
136
8a0681f9
VZ
137wxToolBarToolBase *wxToolBarBase::AddTool(int id,
138 const wxBitmap& bitmap,
139 const wxBitmap& pushedBitmap,
140 bool toggle,
141 wxCoord WXUNUSED(xPos),
142 wxCoord WXUNUSED(yPos),
143 wxObject *clientData,
144 const wxString& helpString1,
145 const wxString& helpString2)
10b959e3 146{
8a0681f9
VZ
147 return InsertTool(GetToolsCount(), id, bitmap, pushedBitmap,
148 toggle, clientData, helpString1, helpString2);
10b959e3
JS
149}
150
8a0681f9
VZ
151wxToolBarToolBase *wxToolBarBase::InsertTool(size_t pos,
152 int id,
153 const wxBitmap& bitmap,
154 const wxBitmap& pushedBitmap,
155 bool toggle,
156 wxObject *clientData,
157 const wxString& helpString1,
158 const wxString& helpString2)
10b959e3 159{
8a0681f9
VZ
160 wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
161 _T("invalid position in wxToolBar::InsertTool()") );
162
163 wxToolBarToolBase *tool = CreateTool(id, bitmap, pushedBitmap, toggle,
164 clientData, helpString1, helpString2);
165
166 if ( !tool || !DoInsertTool(pos, tool) )
167 {
168 delete tool;
169
170 return NULL;
171 }
172
173 m_tools.Insert(pos, tool);
174
175 return tool;
10b959e3
JS
176}
177
8a0681f9 178wxToolBarToolBase *wxToolBarBase::AddControl(wxControl *control)
10b959e3 179{
8a0681f9 180 return InsertControl(GetToolsCount(), control);
10b959e3
JS
181}
182
8a0681f9 183wxToolBarToolBase *wxToolBarBase::InsertControl(size_t pos, wxControl *control)
10b959e3 184{
8a0681f9
VZ
185 wxCHECK_MSG( control, (wxToolBarToolBase *)NULL,
186 _T("toolbar: can't insert NULL control") );
187
188 wxCHECK_MSG( control->GetParent() == this, (wxToolBarToolBase *)NULL,
189 _T("control must have toolbar as parent") );
190
191 wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
192 _T("invalid position in wxToolBar::InsertControl()") );
193
194 wxToolBarToolBase *tool = CreateTool(control);
195
196 if ( !tool || !DoInsertTool(pos, tool) )
197 {
198 delete tool;
199
200 return NULL;
201 }
202
203 m_tools.Insert(pos, tool);
204
205 return tool;
10b959e3
JS
206}
207
8a0681f9 208wxToolBarToolBase *wxToolBarBase::AddSeparator()
10b959e3 209{
8a0681f9 210 return InsertSeparator(GetToolsCount());
10b959e3
JS
211}
212
8a0681f9 213wxToolBarToolBase *wxToolBarBase::InsertSeparator(size_t pos)
10b959e3 214{
8a0681f9
VZ
215 wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
216 _T("invalid position in wxToolBar::InsertSeparator()") );
217
218 wxToolBarToolBase *tool = CreateTool(wxID_SEPARATOR,
219 wxNullBitmap, wxNullBitmap,
220 FALSE, (wxObject *)NULL,
221 wxEmptyString, wxEmptyString);
222
223 if ( !tool || !DoInsertTool(pos, tool) )
10b959e3 224 {
8a0681f9
VZ
225 delete tool;
226
227 return NULL;
10b959e3 228 }
8a0681f9
VZ
229
230 m_tools.Insert(pos, tool);
231
232 return tool;
10b959e3
JS
233}
234
8a0681f9 235wxToolBarToolBase *wxToolBarBase::RemoveTool(int id)
10b959e3 236{
8a0681f9
VZ
237 size_t pos = 0;
238 wxToolBarToolsList::Node *node;
239 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
10b959e3 240 {
8a0681f9
VZ
241 if ( node->GetData()->GetId() == id )
242 break;
243
244 pos++;
10b959e3 245 }
10b959e3 246
8a0681f9 247 if ( !node )
10b959e3 248 {
8a0681f9
VZ
249 // don't give any error messages - sometimes we might call RemoveTool()
250 // without knowing whether the tool is or not in the toolbar
251 return (wxToolBarToolBase *)NULL;
10b959e3 252 }
10b959e3 253
8a0681f9
VZ
254 wxToolBarToolBase *tool = node->GetData();
255 if ( !DoDeleteTool(pos, tool) )
256 {
257 return (wxToolBarToolBase *)NULL;
258 }
10b959e3 259
8a0681f9
VZ
260 // the node would delete the data, so set it to NULL to avoid this
261 node->SetData(NULL);
10b959e3 262
8a0681f9 263 m_tools.DeleteNode(node);
10b959e3 264
8a0681f9 265 return tool;
10b959e3
JS
266}
267
8a0681f9 268bool wxToolBarBase::DeleteToolByPos(size_t pos)
10b959e3 269{
8a0681f9
VZ
270 wxCHECK_MSG( pos < GetToolsCount(), FALSE,
271 _T("invalid position in wxToolBar::DeleteToolByPos()") );
10b959e3 272
8a0681f9 273 wxToolBarToolsList::Node *node = m_tools.Item(pos);
10b959e3 274
8a0681f9
VZ
275 if ( !DoDeleteTool(pos, node->GetData()) )
276 {
277 return FALSE;
278 }
279
280 m_tools.DeleteNode(node);
281
282 return TRUE;
10b959e3
JS
283}
284
8a0681f9 285bool wxToolBarBase::DeleteTool(int id)
10b959e3 286{
8a0681f9
VZ
287 size_t pos = 0;
288 wxToolBarToolsList::Node *node;
289 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
290 {
291 if ( node->GetData()->GetId() == id )
292 break;
293
294 pos++;
295 }
296
297 if ( !node || !DoDeleteTool(pos, node->GetData()) )
298 {
299 return FALSE;
300 }
301
302 m_tools.DeleteNode(node);
303
304 return TRUE;
10b959e3
JS
305}
306
8a0681f9 307wxToolBarToolBase *wxToolBarBase::FindById(int id) const
10b959e3 308{
8a0681f9
VZ
309 wxToolBarToolBase *tool = (wxToolBarToolBase *)NULL;
310
311 for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
312 node;
313 node = node->GetNext() )
314 {
315 tool = node->GetData();
316 if ( tool->GetId() == id )
317 {
318 // found
319 break;
320 }
d9739886
VZ
321
322 tool = NULL;
8a0681f9
VZ
323 }
324
325 return tool;
10b959e3
JS
326}
327
8a0681f9 328void wxToolBarBase::ClearTools()
10b959e3 329{
8a0681f9 330 m_tools.Clear();
10b959e3
JS
331}
332
8a0681f9 333bool wxToolBarBase::Realize()
10b959e3 334{
8a0681f9 335 return TRUE;
10b959e3
JS
336}
337
8a0681f9 338wxToolBarBase::~wxToolBarBase()
10b959e3 339{
10b959e3
JS
340}
341
8a0681f9
VZ
342// ----------------------------------------------------------------------------
343// wxToolBarBase tools state
344// ----------------------------------------------------------------------------
10b959e3 345
8a0681f9 346void wxToolBarBase::EnableTool(int id, bool enable)
10b959e3 347{
8a0681f9
VZ
348 wxToolBarToolBase *tool = FindById(id);
349 if ( tool )
10b959e3 350 {
8a0681f9
VZ
351 if ( tool->Enable(enable) )
352 {
353 DoEnableTool(tool, enable);
354 }
10b959e3 355 }
8a0681f9 356}
10b959e3 357
8a0681f9
VZ
358void wxToolBarBase::ToggleTool(int id, bool toggle)
359{
360 wxToolBarToolBase *tool = FindById(id);
361 if ( tool && tool->CanBeToggled() )
10b959e3 362 {
8a0681f9
VZ
363 if ( tool->Toggle(toggle) )
364 {
365 DoToggleTool(tool, toggle);
366 }
10b959e3 367 }
10b959e3
JS
368}
369
8a0681f9
VZ
370void wxToolBarBase::SetToggle(int id, bool toggle)
371{
372 wxToolBarToolBase *tool = FindById(id);
373 if ( tool )
10b959e3 374 {
8a0681f9
VZ
375 if ( tool->SetToggle(toggle) )
376 {
377 DoSetToggle(tool, toggle);
378 }
10b959e3 379 }
8a0681f9
VZ
380}
381
382void wxToolBarBase::SetToolShortHelp(int id, const wxString& help)
383{
384 wxToolBarToolBase *tool = FindById(id);
385 if ( tool )
10b959e3 386 {
8a0681f9 387 (void)tool->SetShortHelp(help);
10b959e3 388 }
8a0681f9
VZ
389}
390
391void wxToolBarBase::SetToolLongHelp(int id, const wxString& help)
392{
393 wxToolBarToolBase *tool = FindById(id);
394 if ( tool )
10b959e3 395 {
8a0681f9 396 (void)tool->SetLongHelp(help);
10b959e3 397 }
10b959e3
JS
398}
399
8a0681f9 400wxObject *wxToolBarBase::GetToolClientData(int id) const
10b959e3 401{
8a0681f9
VZ
402 wxToolBarToolBase *tool = FindById(id);
403
404 return tool ? tool->GetClientData() : (wxObject *)NULL;
10b959e3
JS
405}
406
6fd5fa4f
VZ
407void wxToolBarBase::SetToolClientData(int id, wxObject *clientData)
408{
409 wxToolBarToolBase *tool = FindById(id);
410
411 wxCHECK_RET( tool, _T("no such tool in wxToolBar::SetToolClientData") );
412
413 tool->SetClientData(clientData);
414}
415
8a0681f9 416bool wxToolBarBase::GetToolState(int id) const
10b959e3 417{
8a0681f9
VZ
418 wxToolBarToolBase *tool = FindById(id);
419 wxCHECK_MSG( tool, FALSE, _T("no such tool") );
420
421 return tool->IsToggled();
10b959e3
JS
422}
423
8a0681f9 424bool wxToolBarBase::GetToolEnabled(int id) const
10b959e3 425{
8a0681f9
VZ
426 wxToolBarToolBase *tool = FindById(id);
427 wxCHECK_MSG( tool, FALSE, _T("no such tool") );
428
429 return tool->IsEnabled();
10b959e3
JS
430}
431
8a0681f9 432wxString wxToolBarBase::GetToolShortHelp(int id) const
10b959e3 433{
8a0681f9
VZ
434 wxToolBarToolBase *tool = FindById(id);
435 wxCHECK_MSG( tool, _T(""), _T("no such tool") );
436
437 return tool->GetShortHelp();
10b959e3
JS
438}
439
8a0681f9 440wxString wxToolBarBase::GetToolLongHelp(int id) const
10b959e3 441{
8a0681f9
VZ
442 wxToolBarToolBase *tool = FindById(id);
443 wxCHECK_MSG( tool, _T(""), _T("no such tool") );
10b959e3 444
8a0681f9 445 return tool->GetLongHelp();
10b959e3
JS
446}
447
8a0681f9
VZ
448// ----------------------------------------------------------------------------
449// wxToolBarBase geometry
450// ----------------------------------------------------------------------------
451
452void wxToolBarBase::SetMargins(int x, int y)
10b959e3 453{
8a0681f9
VZ
454 m_xMargin = x;
455 m_yMargin = y;
10b959e3
JS
456}
457
8a0681f9 458void wxToolBarBase::SetRows(int WXUNUSED(nRows))
10b959e3 459{
8a0681f9 460 // nothing
10b959e3
JS
461}
462
8a0681f9
VZ
463// ----------------------------------------------------------------------------
464// event processing
465// ----------------------------------------------------------------------------
466
467// Only allow toggle if returns TRUE
468bool wxToolBarBase::OnLeftClick(int id, bool toggleDown)
10b959e3 469{
8a0681f9
VZ
470 wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, id);
471 event.SetEventObject(this);
6bec54e1
VZ
472
473 // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown
474 event.SetInt((int)toggleDown);
475
476 // and SetExtraLong() for backwards compatibility
477 event.SetExtraLong((long)toggleDown);
8a0681f9
VZ
478
479 // Send events to this toolbar instead (and thence up the window hierarchy)
480 GetEventHandler()->ProcessEvent(event);
481
482 return TRUE;
10b959e3
JS
483}
484
8a0681f9
VZ
485// Call when right button down.
486void wxToolBarBase::OnRightClick(int id,
487 long WXUNUSED(x),
488 long WXUNUSED(y))
10b959e3 489{
8a0681f9
VZ
490 wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, id);
491 event.SetEventObject(this);
492 event.SetInt(id);
493
494 GetEventHandler()->ProcessEvent(event);
495}
43d811ea 496
8a0681f9
VZ
497// Called when the mouse cursor enters a tool bitmap (no button pressed).
498// Argument is -1 if mouse is exiting the toolbar.
499// Note that for this event, the id of the window is used,
500// and the integer parameter of wxCommandEvent is used to retrieve
501// the tool id.
502void wxToolBarBase::OnMouseEnter(int id)
503{
504 wxCommandEvent event(wxEVT_COMMAND_TOOL_ENTER, GetId());
505 event.SetEventObject(this);
506 event.SetInt(id);
507
508 (void)GetEventHandler()->ProcessEvent(event);
509
510 wxToolBarToolBase *tool = FindById(id);
511 if ( !tool || !tool->GetLongHelp() )
512 return;
513
514 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
515 if ( !frame )
516 return;
517
518 frame->SetStatusText(tool->GetLongHelp());
519}
520
521// ----------------------------------------------------------------------------
522// UI updates
523// ----------------------------------------------------------------------------
524
525void wxToolBarBase::OnIdle(wxIdleEvent& event)
526{
ac91b9d2 527 DoToolbarUpdates();
8a0681f9
VZ
528
529 event.Skip();
10b959e3
JS
530}
531
532// Do the toolbar button updates (check for EVT_UPDATE_UI handlers)
ac91b9d2
VZ
533void wxToolBarBase::DoToolbarUpdates()
534{
e63fdcd6
JS
535 wxWindow* parent = this;
536 while (parent->GetParent())
537 parent = parent->GetParent();
538
f0e9f0d3 539#ifdef __WXMSW__
e63fdcd6 540 wxWindow* focusWin = wxFindFocusDescendant(parent);
f0e9f0d3
JS
541#else
542 wxWindow* focusWin = (wxWindow*) NULL;
543#endif
e63fdcd6
JS
544
545 wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler() ;
e702ff0f 546
8a0681f9
VZ
547 for ( wxToolBarToolsList::Node* node = m_tools.GetFirst();
548 node;
549 node = node->GetNext() )
ac91b9d2 550 {
8a0681f9 551 int id = node->GetData()->GetId();
ac91b9d2 552
8a0681f9 553 wxUpdateUIEvent event(id);
ac91b9d2
VZ
554 event.SetEventObject(this);
555
8a0681f9 556 if ( evtHandler->ProcessEvent(event) )
ac91b9d2 557 {
8a0681f9
VZ
558 if ( event.GetSetEnabled() )
559 EnableTool(id, event.GetEnabled());
560 if ( event.GetSetChecked() )
561 ToggleTool(id, event.GetChecked());
562#if 0
563 if ( event.GetSetText() )
ac91b9d2 564 // Set tooltip?
8a0681f9 565#endif // 0
ac91b9d2 566 }
ac91b9d2 567 }
10b959e3
JS
568}
569
8a0681f9 570#endif // wxUSE_TOOLBAR