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