]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/tbarbase.cpp
attempts to fix separate compilation (didn't work)
[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
9// Licence: wxWindows licence
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 #include "wx/control.h"
35#endif
36
37#include "wx/frame.h"
38#include "wx/image.h"
39#include "wx/settings.h"
40
41#include "wx/tbarbase.h"
42
43// ----------------------------------------------------------------------------
44// wxWindows macros
45// ----------------------------------------------------------------------------
46
47IMPLEMENT_CLASS(wxToolBarBase, wxControl)
48
49BEGIN_EVENT_TABLE(wxToolBarBase, wxControl)
50END_EVENT_TABLE()
51
52#include "wx/listimpl.cpp"
53
54WX_DEFINE_LIST(wxToolBarToolsList);
55
56// ============================================================================
57// implementation
58// ============================================================================
59
60// ----------------------------------------------------------------------------
61// wxToolBarToolBase
62// ----------------------------------------------------------------------------
63
64bool wxToolBarToolBase::Enable(bool enable)
65{
66 if ( m_enabled == enable )
67 return FALSE;
68
69 m_enabled = enable;
70
71 return TRUE;
72}
73
74bool wxToolBarToolBase::Toggle(bool toggle)
75{
76 wxASSERT_MSG( CanBeToggled(), _T("can't toggle this tool") );
77
78 if ( m_toggled == toggle )
79 return FALSE;
80
81 m_toggled = toggle;
82
83 return TRUE;
84}
85
86bool wxToolBarToolBase::SetToggle(bool toggle)
87{
88 wxItemKind kind = toggle ? wxITEM_CHECK : wxITEM_NORMAL;
89 if ( m_kind == kind )
90 return FALSE;
91
92 m_kind = kind;
93
94 return TRUE;
95}
96
97bool wxToolBarToolBase::SetShortHelp(const wxString& help)
98{
99 if ( m_shortHelpString == help )
100 return FALSE;
101
102 m_shortHelpString = help;
103
104 return TRUE;
105}
106
107bool wxToolBarToolBase::SetLongHelp(const wxString& help)
108{
109 if ( m_longHelpString == help )
110 return FALSE;
111
112 m_longHelpString = help;
113
114 return TRUE;
115}
116
117wxToolBarToolBase::~wxToolBarToolBase()
118{
119}
120
121// ----------------------------------------------------------------------------
122// wxToolBarBase adding/deleting items
123// ----------------------------------------------------------------------------
124
125wxToolBarBase::wxToolBarBase()
126{
127 // the list owns the pointers
128 m_tools.DeleteContents(TRUE);
129
130 m_xMargin = m_yMargin = 0;
131
132 m_maxRows = m_maxCols = 0;
133}
134
135wxToolBarToolBase *wxToolBarBase::DoAddTool(int id,
136 const wxString& label,
137 const wxBitmap& bitmap,
138 const wxBitmap& bmpDisabled,
139 wxItemKind kind,
140 const wxString& shortHelp,
141 const wxString& longHelp,
142 wxObject *clientData,
143 wxCoord WXUNUSED(xPos),
144 wxCoord WXUNUSED(yPos))
145{
146 return InsertTool(GetToolsCount(), id, label, bitmap, bmpDisabled,
147 kind, shortHelp, longHelp, clientData);
148}
149
150wxToolBarToolBase *wxToolBarBase::InsertTool(size_t pos,
151 int id,
152 const wxString& label,
153 const wxBitmap& bitmap,
154 const wxBitmap& bmpDisabled,
155 wxItemKind kind,
156 const wxString& shortHelp,
157 const wxString& longHelp,
158 wxObject *clientData)
159{
160 wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
161 _T("invalid position in wxToolBar::InsertTool()") );
162
163 wxToolBarToolBase *tool = CreateTool(id, label, bitmap, bmpDisabled, kind,
164 clientData, shortHelp, longHelp);
165
166 if ( !InsertTool(pos, tool) )
167 {
168 delete tool;
169
170 return NULL;
171 }
172
173 return tool;
174}
175
176wxToolBarToolBase *wxToolBarBase::AddTool(wxToolBarToolBase *tool)
177{
178 return InsertTool(GetToolsCount(), tool);
179}
180
181wxToolBarToolBase *
182wxToolBarBase::InsertTool(size_t pos, wxToolBarToolBase *tool)
183{
184 wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
185 _T("invalid position in wxToolBar::InsertTool()") );
186
187 if ( !tool || !DoInsertTool(pos, tool) )
188 {
189 return NULL;
190 }
191
192 m_tools.Insert(pos, tool);
193
194 return tool;
195}
196
197wxToolBarToolBase *wxToolBarBase::AddControl(wxControl *control)
198{
199 return InsertControl(GetToolsCount(), control);
200}
201
202wxToolBarToolBase *wxToolBarBase::InsertControl(size_t pos, wxControl *control)
203{
204 wxCHECK_MSG( control, (wxToolBarToolBase *)NULL,
205 _T("toolbar: can't insert NULL control") );
206
207 wxCHECK_MSG( control->GetParent() == this, (wxToolBarToolBase *)NULL,
208 _T("control must have toolbar as parent") );
209
210 wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
211 _T("invalid position in wxToolBar::InsertControl()") );
212
213 wxToolBarToolBase *tool = CreateTool(control);
214
215 if ( !InsertTool(pos, tool) )
216 {
217 delete tool;
218
219 return NULL;
220 }
221
222 return tool;
223}
224
225wxControl *wxToolBarBase::FindControl( int id )
226{
227 for ( wxToolBarToolsList::Node* node = m_tools.GetFirst();
228 node;
229 node = node->GetNext() )
230 {
231 const wxToolBarToolBase * const tool = node->GetData();
232 if ( tool->IsControl() )
233 {
234 wxControl * const control = tool->GetControl();
235
236 if ( !control )
237 {
238 wxFAIL_MSG( _T("NULL control in toolbar?") );
239 }
240 else if ( control->GetId() == id )
241 {
242 // found
243 return control;
244 }
245 }
246 }
247
248 return NULL;
249}
250
251wxToolBarToolBase *wxToolBarBase::AddSeparator()
252{
253 return InsertSeparator(GetToolsCount());
254}
255
256wxToolBarToolBase *wxToolBarBase::InsertSeparator(size_t pos)
257{
258 wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
259 _T("invalid position in wxToolBar::InsertSeparator()") );
260
261 wxToolBarToolBase *tool = CreateTool(wxID_SEPARATOR,
262 wxEmptyString,
263 wxNullBitmap, wxNullBitmap,
264 wxITEM_SEPARATOR, (wxObject *)NULL,
265 wxEmptyString, wxEmptyString);
266
267 if ( !tool || !DoInsertTool(pos, tool) )
268 {
269 delete tool;
270
271 return NULL;
272 }
273
274 m_tools.Insert(pos, tool);
275
276 return tool;
277}
278
279wxToolBarToolBase *wxToolBarBase::RemoveTool(int id)
280{
281 size_t pos = 0;
282 wxToolBarToolsList::Node *node;
283 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
284 {
285 if ( node->GetData()->GetId() == id )
286 break;
287
288 pos++;
289 }
290
291 if ( !node )
292 {
293 // don't give any error messages - sometimes we might call RemoveTool()
294 // without knowing whether the tool is or not in the toolbar
295 return (wxToolBarToolBase *)NULL;
296 }
297
298 wxToolBarToolBase *tool = node->GetData();
299 if ( !DoDeleteTool(pos, tool) )
300 {
301 return (wxToolBarToolBase *)NULL;
302 }
303
304 // the node would delete the data, so set it to NULL to avoid this
305 node->SetData(NULL);
306
307 m_tools.DeleteNode(node);
308
309 return tool;
310}
311
312bool wxToolBarBase::DeleteToolByPos(size_t pos)
313{
314 wxCHECK_MSG( pos < GetToolsCount(), FALSE,
315 _T("invalid position in wxToolBar::DeleteToolByPos()") );
316
317 wxToolBarToolsList::Node *node = m_tools.Item(pos);
318
319 if ( !DoDeleteTool(pos, node->GetData()) )
320 {
321 return FALSE;
322 }
323
324 m_tools.DeleteNode(node);
325
326 return TRUE;
327}
328
329bool wxToolBarBase::DeleteTool(int id)
330{
331 size_t pos = 0;
332 wxToolBarToolsList::Node *node;
333 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
334 {
335 if ( node->GetData()->GetId() == id )
336 break;
337
338 pos++;
339 }
340
341 if ( !node || !DoDeleteTool(pos, node->GetData()) )
342 {
343 return FALSE;
344 }
345
346 m_tools.DeleteNode(node);
347
348 return TRUE;
349}
350
351wxToolBarToolBase *wxToolBarBase::FindById(int id) const
352{
353 wxToolBarToolBase *tool = (wxToolBarToolBase *)NULL;
354
355 for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
356 node;
357 node = node->GetNext() )
358 {
359 tool = node->GetData();
360 if ( tool->GetId() == id )
361 {
362 // found
363 break;
364 }
365
366 tool = NULL;
367 }
368
369 return tool;
370}
371
372void wxToolBarBase::ClearTools()
373{
374 m_tools.Clear();
375}
376
377bool wxToolBarBase::Realize()
378{
379 return TRUE;
380}
381
382wxToolBarBase::~wxToolBarBase()
383{
384}
385
386// ----------------------------------------------------------------------------
387// wxToolBarBase tools state
388// ----------------------------------------------------------------------------
389
390void wxToolBarBase::EnableTool(int id, bool enable)
391{
392 wxToolBarToolBase *tool = FindById(id);
393 if ( tool )
394 {
395 if ( tool->Enable(enable) )
396 {
397 DoEnableTool(tool, enable);
398 }
399 }
400}
401
402void wxToolBarBase::ToggleTool(int id, bool toggle)
403{
404 wxToolBarToolBase *tool = FindById(id);
405 if ( tool && tool->CanBeToggled() )
406 {
407 if ( tool->Toggle(toggle) )
408 {
409 DoToggleTool(tool, toggle);
410 }
411 }
412}
413
414void wxToolBarBase::SetToggle(int id, bool toggle)
415{
416 wxToolBarToolBase *tool = FindById(id);
417 if ( tool )
418 {
419 if ( tool->SetToggle(toggle) )
420 {
421 DoSetToggle(tool, toggle);
422 }
423 }
424}
425
426void wxToolBarBase::SetToolShortHelp(int id, const wxString& help)
427{
428 wxToolBarToolBase *tool = FindById(id);
429 if ( tool )
430 {
431 (void)tool->SetShortHelp(help);
432 }
433}
434
435void wxToolBarBase::SetToolLongHelp(int id, const wxString& help)
436{
437 wxToolBarToolBase *tool = FindById(id);
438 if ( tool )
439 {
440 (void)tool->SetLongHelp(help);
441 }
442}
443
444wxObject *wxToolBarBase::GetToolClientData(int id) const
445{
446 wxToolBarToolBase *tool = FindById(id);
447
448 return tool ? tool->GetClientData() : (wxObject *)NULL;
449}
450
451void wxToolBarBase::SetToolClientData(int id, wxObject *clientData)
452{
453 wxToolBarToolBase *tool = FindById(id);
454
455 wxCHECK_RET( tool, _T("no such tool in wxToolBar::SetToolClientData") );
456
457 tool->SetClientData(clientData);
458}
459
460int wxToolBarBase::GetToolPos(int id) const
461{
462 size_t pos = 0;
463 wxToolBarToolsList::Node *node;
464
465 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
466 {
467 if ( node->GetData()->GetId() == id )
468 return pos;
469
470 pos++;
471 }
472
473 return wxNOT_FOUND;
474}
475
476bool wxToolBarBase::GetToolState(int id) const
477{
478 wxToolBarToolBase *tool = FindById(id);
479 wxCHECK_MSG( tool, FALSE, _T("no such tool") );
480
481 return tool->IsToggled();
482}
483
484bool wxToolBarBase::GetToolEnabled(int id) const
485{
486 wxToolBarToolBase *tool = FindById(id);
487 wxCHECK_MSG( tool, FALSE, _T("no such tool") );
488
489 return tool->IsEnabled();
490}
491
492wxString wxToolBarBase::GetToolShortHelp(int id) const
493{
494 wxToolBarToolBase *tool = FindById(id);
495 wxCHECK_MSG( tool, _T(""), _T("no such tool") );
496
497 return tool->GetShortHelp();
498}
499
500wxString wxToolBarBase::GetToolLongHelp(int id) const
501{
502 wxToolBarToolBase *tool = FindById(id);
503 wxCHECK_MSG( tool, _T(""), _T("no such tool") );
504
505 return tool->GetLongHelp();
506}
507
508// ----------------------------------------------------------------------------
509// wxToolBarBase geometry
510// ----------------------------------------------------------------------------
511
512void wxToolBarBase::SetMargins(int x, int y)
513{
514 m_xMargin = x;
515 m_yMargin = y;
516}
517
518void wxToolBarBase::SetRows(int WXUNUSED(nRows))
519{
520 // nothing
521}
522
523// ----------------------------------------------------------------------------
524// event processing
525// ----------------------------------------------------------------------------
526
527// Only allow toggle if returns TRUE
528bool wxToolBarBase::OnLeftClick(int id, bool toggleDown)
529{
530 wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, id);
531 event.SetEventObject(this);
532
533 // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown
534 event.SetInt((int)toggleDown);
535
536 // and SetExtraLong() for backwards compatibility
537 event.SetExtraLong((long)toggleDown);
538
539 // Send events to this toolbar instead (and thence up the window hierarchy)
540 GetEventHandler()->ProcessEvent(event);
541
542 return TRUE;
543}
544
545// Call when right button down.
546void wxToolBarBase::OnRightClick(int id,
547 long WXUNUSED(x),
548 long WXUNUSED(y))
549{
550 wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, id);
551 event.SetEventObject(this);
552 event.SetInt(id);
553
554 GetEventHandler()->ProcessEvent(event);
555}
556
557// Called when the mouse cursor enters a tool bitmap (no button pressed).
558// Argument is -1 if mouse is exiting the toolbar.
559// Note that for this event, the id of the window is used,
560// and the integer parameter of wxCommandEvent is used to retrieve
561// the tool id.
562void wxToolBarBase::OnMouseEnter(int id)
563{
564 wxCommandEvent event(wxEVT_COMMAND_TOOL_ENTER, GetId());
565 event.SetEventObject(this);
566 event.SetInt(id);
567
568 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
569 if( frame )
570 {
571 wxToolBarToolBase* tool = id == -1 ? (wxToolBarToolBase*)0 : FindById(id);
572 wxString help = tool ? tool->GetLongHelp() : wxString();
573 frame->DoGiveHelp( help, id != -1 );
574 }
575
576 (void)GetEventHandler()->ProcessEvent(event);
577}
578
579// ----------------------------------------------------------------------------
580// UI updates
581// ----------------------------------------------------------------------------
582
583// Do the toolbar button updates (check for EVT_UPDATE_UI handlers)
584void wxToolBarBase::UpdateWindowUI(long flags)
585{
586 wxWindowBase::UpdateWindowUI(flags);
587
588 wxEvtHandler* evtHandler = GetEventHandler() ;
589
590 for ( wxToolBarToolsList::Node* node = m_tools.GetFirst();
591 node;
592 node = node->GetNext() )
593 {
594 int id = node->GetData()->GetId();
595
596 wxUpdateUIEvent event(id);
597 event.SetEventObject(this);
598
599 if ( evtHandler->ProcessEvent(event) )
600 {
601 if ( event.GetSetEnabled() )
602 EnableTool(id, event.GetEnabled());
603 if ( event.GetSetChecked() )
604 ToggleTool(id, event.GetChecked());
605#if 0
606 if ( event.GetSetText() )
607 // Set tooltip?
608#endif // 0
609 }
610 }
611}
612
613// Helper function, used by wxCreateGreyedImage
614
615static void wxGreyOutImage( const wxImage& src,
616 wxImage& dest,
617 const wxColour& darkCol,
618 const wxColour& lightCol,
619 const wxColour& bgCol )
620{
621 // Second attempt, just making things monochrome
622 int width = src.GetWidth();
623 int height = src.GetHeight();
624
625 int redCur, greenCur, blueCur;
626 for ( int x = 0; x < width; x++ )
627 {
628 for ( int y = 1; y < height; y++ )
629 {
630 redCur = src.GetRed(x, y);
631 greenCur = src.GetGreen(x, y);
632 blueCur = src.GetBlue(x, y);
633
634 // Change light things to the background colour
635 if ( redCur >= (lightCol.Red() - 50) && greenCur >= (lightCol.Green() - 50) && blueCur >= (lightCol.Blue() - 50) )
636 {
637 dest.SetRGB(x,y, bgCol.Red(), bgCol.Green(), bgCol.Blue());
638 }
639 else if ( redCur == bgCol.Red() && greenCur == bgCol.Green() && blueCur == bgCol.Blue() )
640 {
641 // Leave the background colour as-is
642 // dest.SetRGB(x,y, bgCol.Red(), bgCol.Green(), bgCol.Blue());
643 }
644 else // if ( redCur <= darkCol.Red() && greenCur <= darkCol.Green() && blueCur <= darkCol.Blue() )
645 {
646 // Change dark things to really dark
647 dest.SetRGB(x,y, darkCol.Red(), darkCol.Green(), darkCol.Blue());
648 }
649 }
650 }
651}
652
653/*
654 * Make a greyed-out image suitable for disabled buttons.
655 * This code is adapted from wxNewBitmapButton in FL.
656 */
657
658bool wxCreateGreyedImage(const wxImage& in, wxImage& out)
659{
660 out = in.Copy();
661
662 // assuming the pixels along the edges are of the background color
663 wxColour bgCol(in.GetRed(0, 0), in.GetGreen(0, 0), in.GetBlue(0, 0));
664
665 wxColour darkCol = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW) ;
666 wxColour lightCol = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT) ;
667
668 wxGreyOutImage(in, out, darkCol, lightCol, bgCol);
669
670 return TRUE;
671}
672
673#endif // wxUSE_TOOLBAR