1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/tbarbase.cpp
3 // Purpose: wxToolBarBase implementation
4 // Author: Julian Smart
5 // Modified by: VZ at 11.12.99 (wxScrollableToolBar split off)
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/toolbar.h"
32 #include "wx/control.h"
34 #include "wx/settings.h"
35 #if WXWIN_COMPATIBILITY_2_8
37 #endif // WXWIN_COMPATIBILITY_2_8
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 BEGIN_EVENT_TABLE(wxToolBarBase
, wxControl
)
47 #include "wx/listimpl.cpp"
49 WX_DEFINE_LIST(wxToolBarToolsList
)
51 // ============================================================================
53 // ============================================================================
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 IMPLEMENT_DYNAMIC_CLASS(wxToolBarToolBase
, wxObject
)
61 bool wxToolBarToolBase::Enable(bool enable
)
63 if ( m_enabled
== enable
)
71 bool wxToolBarToolBase::Toggle(bool toggle
)
73 wxASSERT_MSG( CanBeToggled(), _T("can't toggle this tool") );
75 if ( m_toggled
== toggle
)
83 bool wxToolBarToolBase::SetToggle(bool toggle
)
85 wxItemKind kind
= toggle
? wxITEM_CHECK
: wxITEM_NORMAL
;
94 bool wxToolBarToolBase::SetShortHelp(const wxString
& help
)
96 if ( m_shortHelpString
== help
)
99 m_shortHelpString
= help
;
104 bool wxToolBarToolBase::SetLongHelp(const wxString
& help
)
106 if ( m_longHelpString
== help
)
109 m_longHelpString
= help
;
114 // ----------------------------------------------------------------------------
115 // wxToolBarBase adding/deleting items
116 // ----------------------------------------------------------------------------
118 wxToolBarBase::wxToolBarBase()
120 // the list owns the pointers
121 m_xMargin
= m_yMargin
= 0;
122 m_maxRows
= m_maxCols
= 0;
123 m_toolPacking
= m_toolSeparation
= 0;
125 m_defaultHeight
= 15;
128 void wxToolBarBase::FixupStyle()
130 if ( !HasFlag(wxTB_TOP
| wxTB_LEFT
| wxTB_RIGHT
| wxTB_BOTTOM
) )
132 // this is the default
133 m_windowStyle
|= wxTB_TOP
;
137 wxToolBarToolBase
*wxToolBarBase::DoAddTool(int id
,
138 const wxString
& label
,
139 const wxBitmap
& bitmap
,
140 const wxBitmap
& bmpDisabled
,
142 const wxString
& shortHelp
,
143 const wxString
& longHelp
,
144 wxObject
*clientData
,
145 wxCoord
WXUNUSED(xPos
),
146 wxCoord
WXUNUSED(yPos
))
148 InvalidateBestSize();
149 return InsertTool(GetToolsCount(), id
, label
, bitmap
, bmpDisabled
,
150 kind
, shortHelp
, longHelp
, clientData
);
153 wxToolBarToolBase
*wxToolBarBase::InsertTool(size_t pos
,
155 const wxString
& label
,
156 const wxBitmap
& bitmap
,
157 const wxBitmap
& bmpDisabled
,
159 const wxString
& shortHelp
,
160 const wxString
& longHelp
,
161 wxObject
*clientData
)
163 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
164 _T("invalid position in wxToolBar::InsertTool()") );
166 wxToolBarToolBase
*tool
= CreateTool(id
, label
, bitmap
, bmpDisabled
, kind
,
167 clientData
, shortHelp
, longHelp
);
169 if ( !InsertTool(pos
, tool
) )
179 wxToolBarToolBase
*wxToolBarBase::AddTool(wxToolBarToolBase
*tool
)
181 return InsertTool(GetToolsCount(), tool
);
185 wxToolBarBase::InsertTool(size_t pos
, wxToolBarToolBase
*tool
)
187 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
188 _T("invalid position in wxToolBar::InsertTool()") );
190 if ( !tool
|| !DoInsertTool(pos
, tool
) )
195 m_tools
.Insert(pos
, tool
);
201 wxToolBarBase::AddControl(wxControl
*control
, const wxString
& label
)
203 return InsertControl(GetToolsCount(), control
, label
);
207 wxToolBarBase::InsertControl(size_t pos
,
209 const wxString
& label
)
211 wxCHECK_MSG( control
, (wxToolBarToolBase
*)NULL
,
212 _T("toolbar: can't insert NULL control") );
214 wxCHECK_MSG( control
->GetParent() == this, (wxToolBarToolBase
*)NULL
,
215 _T("control must have toolbar as parent") );
217 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
218 _T("invalid position in wxToolBar::InsertControl()") );
220 wxToolBarToolBase
*tool
= CreateTool(control
, label
);
222 if ( !InsertTool(pos
, tool
) )
232 wxControl
*wxToolBarBase::FindControl( int id
)
234 for ( wxToolBarToolsList::compatibility_iterator node
= m_tools
.GetFirst();
236 node
= node
->GetNext() )
238 const wxToolBarToolBase
* const tool
= node
->GetData();
239 if ( tool
->IsControl() )
241 wxControl
* const control
= tool
->GetControl();
245 wxFAIL_MSG( _T("NULL control in toolbar?") );
247 else if ( control
->GetId() == id
)
258 wxToolBarToolBase
*wxToolBarBase::AddSeparator()
260 return InsertSeparator(GetToolsCount());
263 wxToolBarToolBase
*wxToolBarBase::InsertSeparator(size_t pos
)
265 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
266 _T("invalid position in wxToolBar::InsertSeparator()") );
268 wxToolBarToolBase
*tool
= CreateTool(wxID_SEPARATOR
,
270 wxNullBitmap
, wxNullBitmap
,
271 wxITEM_SEPARATOR
, (wxObject
*)NULL
,
272 wxEmptyString
, wxEmptyString
);
274 if ( !tool
|| !DoInsertTool(pos
, tool
) )
281 m_tools
.Insert(pos
, tool
);
286 wxToolBarToolBase
*wxToolBarBase::RemoveTool(int id
)
289 wxToolBarToolsList::compatibility_iterator node
;
290 for ( node
= m_tools
.GetFirst(); node
; node
= node
->GetNext() )
292 if ( node
->GetData()->GetId() == id
)
300 // don't give any error messages - sometimes we might call RemoveTool()
301 // without knowing whether the tool is or not in the toolbar
302 return (wxToolBarToolBase
*)NULL
;
305 wxToolBarToolBase
*tool
= node
->GetData();
306 if ( !DoDeleteTool(pos
, tool
) )
308 return (wxToolBarToolBase
*)NULL
;
316 bool wxToolBarBase::DeleteToolByPos(size_t pos
)
318 wxCHECK_MSG( pos
< GetToolsCount(), false,
319 _T("invalid position in wxToolBar::DeleteToolByPos()") );
321 wxToolBarToolsList::compatibility_iterator node
= m_tools
.Item(pos
);
323 if ( !DoDeleteTool(pos
, node
->GetData()) )
328 delete node
->GetData();
334 bool wxToolBarBase::DeleteTool(int id
)
337 wxToolBarToolsList::compatibility_iterator node
;
338 for ( node
= m_tools
.GetFirst(); node
; node
= node
->GetNext() )
340 if ( node
->GetData()->GetId() == id
)
346 if ( !node
|| !DoDeleteTool(pos
, node
->GetData()) )
351 delete node
->GetData();
357 wxToolBarToolBase
*wxToolBarBase::FindById(int id
) const
359 wxToolBarToolBase
*tool
= (wxToolBarToolBase
*)NULL
;
361 for ( wxToolBarToolsList::compatibility_iterator node
= m_tools
.GetFirst();
363 node
= node
->GetNext() )
365 tool
= node
->GetData();
366 if ( tool
->GetId() == id
)
378 void wxToolBarBase::UnToggleRadioGroup(wxToolBarToolBase
*tool
)
380 wxCHECK_RET( tool
, _T("NULL tool in wxToolBarTool::UnToggleRadioGroup") );
382 if ( !tool
->IsButton() || tool
->GetKind() != wxITEM_RADIO
)
385 wxToolBarToolsList::compatibility_iterator node
= m_tools
.Find(tool
);
386 wxCHECK_RET( node
, _T("invalid tool in wxToolBarTool::UnToggleRadioGroup") );
388 wxToolBarToolsList::compatibility_iterator nodeNext
= node
->GetNext();
391 wxToolBarToolBase
*toolNext
= nodeNext
->GetData();
393 if ( !toolNext
->IsButton() || toolNext
->GetKind() != wxITEM_RADIO
)
396 if ( toolNext
->Toggle(false) )
398 DoToggleTool(toolNext
, false);
401 nodeNext
= nodeNext
->GetNext();
404 wxToolBarToolsList::compatibility_iterator nodePrev
= node
->GetPrevious();
407 wxToolBarToolBase
*toolNext
= nodePrev
->GetData();
409 if ( !toolNext
->IsButton() || toolNext
->GetKind() != wxITEM_RADIO
)
412 if ( toolNext
->Toggle(false) )
414 DoToggleTool(toolNext
, false);
417 nodePrev
= nodePrev
->GetPrevious();
421 void wxToolBarBase::ClearTools()
423 while ( GetToolsCount() )
429 bool wxToolBarBase::Realize()
434 wxToolBarBase::~wxToolBarBase()
436 WX_CLEAR_LIST(wxToolBarToolsList
, m_tools
);
438 // notify the frame that it doesn't have a tool bar any longer to avoid
440 wxFrame
*frame
= wxDynamicCast(GetParent(), wxFrame
);
441 if ( frame
&& frame
->GetToolBar() == this )
443 frame
->SetToolBar(NULL
);
447 // ----------------------------------------------------------------------------
448 // wxToolBarBase tools state
449 // ----------------------------------------------------------------------------
451 void wxToolBarBase::EnableTool(int id
, bool enable
)
453 wxToolBarToolBase
*tool
= FindById(id
);
456 if ( tool
->Enable(enable
) )
458 DoEnableTool(tool
, enable
);
463 void wxToolBarBase::ToggleTool(int id
, bool toggle
)
465 wxToolBarToolBase
*tool
= FindById(id
);
466 if ( tool
&& tool
->CanBeToggled() )
468 if ( tool
->Toggle(toggle
) )
470 UnToggleRadioGroup(tool
);
471 DoToggleTool(tool
, toggle
);
476 void wxToolBarBase::SetToggle(int id
, bool toggle
)
478 wxToolBarToolBase
*tool
= FindById(id
);
481 if ( tool
->SetToggle(toggle
) )
483 DoSetToggle(tool
, toggle
);
488 void wxToolBarBase::SetToolShortHelp(int id
, const wxString
& help
)
490 wxToolBarToolBase
*tool
= FindById(id
);
493 (void)tool
->SetShortHelp(help
);
497 void wxToolBarBase::SetToolLongHelp(int id
, const wxString
& help
)
499 wxToolBarToolBase
*tool
= FindById(id
);
502 (void)tool
->SetLongHelp(help
);
506 wxObject
*wxToolBarBase::GetToolClientData(int id
) const
508 wxToolBarToolBase
*tool
= FindById(id
);
510 return tool
? tool
->GetClientData() : (wxObject
*)NULL
;
513 void wxToolBarBase::SetToolClientData(int id
, wxObject
*clientData
)
515 wxToolBarToolBase
*tool
= FindById(id
);
517 wxCHECK_RET( tool
, _T("no such tool in wxToolBar::SetToolClientData") );
519 tool
->SetClientData(clientData
);
522 int wxToolBarBase::GetToolPos(int id
) const
525 wxToolBarToolsList::compatibility_iterator node
;
527 for ( node
= m_tools
.GetFirst(); node
; node
= node
->GetNext() )
529 if ( node
->GetData()->GetId() == id
)
538 bool wxToolBarBase::GetToolState(int id
) const
540 wxToolBarToolBase
*tool
= FindById(id
);
541 wxCHECK_MSG( tool
, false, _T("no such tool") );
543 return tool
->IsToggled();
546 bool wxToolBarBase::GetToolEnabled(int id
) const
548 wxToolBarToolBase
*tool
= FindById(id
);
549 wxCHECK_MSG( tool
, false, _T("no such tool") );
551 return tool
->IsEnabled();
554 wxString
wxToolBarBase::GetToolShortHelp(int id
) const
556 wxToolBarToolBase
*tool
= FindById(id
);
557 wxCHECK_MSG( tool
, wxEmptyString
, _T("no such tool") );
559 return tool
->GetShortHelp();
562 wxString
wxToolBarBase::GetToolLongHelp(int id
) const
564 wxToolBarToolBase
*tool
= FindById(id
);
565 wxCHECK_MSG( tool
, wxEmptyString
, _T("no such tool") );
567 return tool
->GetLongHelp();
570 // ----------------------------------------------------------------------------
571 // wxToolBarBase geometry
572 // ----------------------------------------------------------------------------
574 void wxToolBarBase::SetMargins(int x
, int y
)
580 void wxToolBarBase::SetRows(int WXUNUSED(nRows
))
585 // ----------------------------------------------------------------------------
587 // ----------------------------------------------------------------------------
589 // Only allow toggle if returns true
590 bool wxToolBarBase::OnLeftClick(int id
, bool toggleDown
)
592 wxCommandEvent
event(wxEVT_COMMAND_TOOL_CLICKED
, id
);
593 event
.SetEventObject(this);
595 // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown
596 event
.SetInt((int)toggleDown
);
598 // and SetExtraLong() for backwards compatibility
599 event
.SetExtraLong((long)toggleDown
);
601 // Send events to this toolbar instead (and thence up the window hierarchy)
602 GetEventHandler()->ProcessEvent(event
);
607 // Call when right button down.
608 void wxToolBarBase::OnRightClick(int id
,
612 wxCommandEvent
event(wxEVT_COMMAND_TOOL_RCLICKED
, id
);
613 event
.SetEventObject(this);
616 GetEventHandler()->ProcessEvent(event
);
619 // Called when the mouse cursor enters a tool bitmap (no button pressed).
620 // Argument is wxID_ANY if mouse is exiting the toolbar.
621 // Note that for this event, the id of the window is used,
622 // and the integer parameter of wxCommandEvent is used to retrieve
624 void wxToolBarBase::OnMouseEnter(int id
)
626 wxCommandEvent
event(wxEVT_COMMAND_TOOL_ENTER
, GetId());
627 event
.SetEventObject(this);
630 wxFrame
*frame
= wxDynamicCast(GetParent(), wxFrame
);
634 wxToolBarToolBase
* tool
= id
== wxID_ANY
? (wxToolBarToolBase
*)NULL
: FindById(id
);
636 help
= tool
->GetLongHelp();
637 frame
->DoGiveHelp( help
, id
!= wxID_ANY
);
640 (void)GetEventHandler()->ProcessEvent(event
);
643 // ----------------------------------------------------------------------------
645 // ----------------------------------------------------------------------------
647 // Do the toolbar button updates (check for EVT_UPDATE_UI handlers)
648 void wxToolBarBase::UpdateWindowUI(long flags
)
650 wxWindowBase::UpdateWindowUI(flags
);
652 // don't waste time updating state of tools in a hidden toolbar
656 // There is no sense in updating the toolbar UI
657 // if the parent window is about to get destroyed
658 wxWindow
*tlw
= wxGetTopLevelParent( this );
659 if (tlw
&& wxPendingDelete
.Member( tlw
))
662 wxEvtHandler
* evtHandler
= GetEventHandler() ;
664 for ( wxToolBarToolsList::compatibility_iterator node
= m_tools
.GetFirst();
666 node
= node
->GetNext() )
668 int id
= node
->GetData()->GetId();
670 wxUpdateUIEvent
event(id
);
671 event
.SetEventObject(this);
673 if ( evtHandler
->ProcessEvent(event
) )
675 if ( event
.GetSetEnabled() )
676 EnableTool(id
, event
.GetEnabled());
677 if ( event
.GetSetChecked() )
678 ToggleTool(id
, event
.GetChecked());
680 if ( event
.GetSetText() )
687 #if WXWIN_COMPATIBILITY_2_8
689 bool wxCreateGreyedImage(const wxImage
& in
, wxImage
& out
)
692 out
= in
.ConvertToGreyscale();
695 #endif // wxUSE_IMAGE
700 #endif // WXWIN_COMPATIBILITY_2_8
702 #endif // wxUSE_TOOLBAR