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) 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "tbarbase.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  43 #include "wx/tbarbase.h" 
  45 // ---------------------------------------------------------------------------- 
  47 // ---------------------------------------------------------------------------- 
  49 IMPLEMENT_CLASS(wxToolBarBase
, wxControl
) 
  51 BEGIN_EVENT_TABLE(wxToolBarBase
, wxControl
) 
  52     EVT_IDLE(wxToolBarBase::OnIdle
) 
  55 #include "wx/listimpl.cpp" 
  57 WX_DEFINE_LIST(wxToolBarToolsList
); 
  59 // ============================================================================ 
  61 // ============================================================================ 
  63 // ---------------------------------------------------------------------------- 
  65 // ---------------------------------------------------------------------------- 
  67 bool wxToolBarToolBase::Enable(bool enable
) 
  69     if ( m_enabled 
== enable 
) 
  77 bool wxToolBarToolBase::Toggle(bool toggle
) 
  79     wxASSERT_MSG( m_isToggle
, _T("can't toggle this tool") ); 
  81     if ( m_toggled 
== toggle 
) 
  89 bool wxToolBarToolBase::SetToggle(bool toggle
) 
  91     if ( m_isToggle 
== toggle 
) 
  99 bool wxToolBarToolBase::SetShortHelp(const wxString
& help
) 
 101     if ( m_shortHelpString 
== help 
) 
 104     m_shortHelpString 
= help
; 
 109 bool wxToolBarToolBase::SetLongHelp(const wxString
& help
) 
 111     if ( m_longHelpString 
== help 
) 
 114     m_longHelpString 
= help
; 
 119 wxToolBarToolBase::~wxToolBarToolBase() 
 123 // ---------------------------------------------------------------------------- 
 124 // wxToolBarBase adding/deleting items 
 125 // ---------------------------------------------------------------------------- 
 127 wxToolBarBase::wxToolBarBase() 
 129     // the list owns the pointers 
 130     m_tools
.DeleteContents(TRUE
); 
 132     m_xMargin 
= m_yMargin 
= 0; 
 134     m_maxRows 
= m_maxCols 
= 0; 
 137 wxToolBarToolBase 
*wxToolBarBase::AddTool(int id
, 
 138                                           const wxBitmap
& bitmap
, 
 139                                           const wxBitmap
& pushedBitmap
, 
 141                                           wxCoord 
WXUNUSED(xPos
), 
 142                                           wxCoord 
WXUNUSED(yPos
), 
 143                                           wxObject 
*clientData
, 
 144                                           const wxString
& helpString1
, 
 145                                           const wxString
& helpString2
) 
 147     return InsertTool(GetToolsCount(), id
, bitmap
, pushedBitmap
, 
 148                       toggle
, clientData
, helpString1
, helpString2
); 
 151 wxToolBarToolBase 
*wxToolBarBase::InsertTool(size_t pos
, 
 153                                              const wxBitmap
& bitmap
, 
 154                                              const wxBitmap
& pushedBitmap
, 
 156                                              wxObject 
*clientData
, 
 157                                              const wxString
& helpString1
, 
 158                                              const wxString
& helpString2
) 
 160     wxCHECK_MSG( pos 
<= GetToolsCount(), (wxToolBarToolBase 
*)NULL
, 
 161                  _T("invalid position in wxToolBar::InsertTool()") ); 
 163     wxToolBarToolBase 
*tool 
= CreateTool(id
, bitmap
, pushedBitmap
, toggle
, 
 164                                          clientData
, helpString1
, helpString2
); 
 166     if ( !tool 
|| !DoInsertTool(pos
, tool
) ) 
 173     m_tools
.Insert(pos
, tool
); 
 178 wxToolBarToolBase 
*wxToolBarBase::AddControl(wxControl 
*control
) 
 180     return InsertControl(GetToolsCount(), control
); 
 183 wxToolBarToolBase 
*wxToolBarBase::InsertControl(size_t pos
, wxControl 
*control
) 
 185     wxCHECK_MSG( control
, (wxToolBarToolBase 
*)NULL
, 
 186                  _T("toolbar: can't insert NULL control") ); 
 188     wxCHECK_MSG( control
->GetParent() == this, (wxToolBarToolBase 
*)NULL
, 
 189                  _T("control must have toolbar as parent") ); 
 191     wxCHECK_MSG( pos 
<= GetToolsCount(), (wxToolBarToolBase 
*)NULL
, 
 192                  _T("invalid position in wxToolBar::InsertControl()") ); 
 194     wxToolBarToolBase 
*tool 
= CreateTool(control
); 
 196     if ( !tool 
|| !DoInsertTool(pos
, tool
) ) 
 203     m_tools
.Insert(pos
, tool
); 
 208 wxToolBarToolBase 
*wxToolBarBase::AddSeparator() 
 210     return InsertSeparator(GetToolsCount()); 
 213 wxToolBarToolBase 
*wxToolBarBase::InsertSeparator(size_t pos
) 
 215     wxCHECK_MSG( pos 
<= GetToolsCount(), (wxToolBarToolBase 
*)NULL
, 
 216                  _T("invalid position in wxToolBar::InsertSeparator()") ); 
 218     wxToolBarToolBase 
*tool 
= CreateTool(wxID_SEPARATOR
, 
 219                                          wxNullBitmap
, wxNullBitmap
, 
 220                                          FALSE
, (wxObject 
*)NULL
, 
 221                                          wxEmptyString
, wxEmptyString
); 
 223     if ( !tool 
|| !DoInsertTool(pos
, tool
) ) 
 230     m_tools
.Insert(pos
, tool
); 
 235 wxToolBarToolBase 
*wxToolBarBase::RemoveTool(int id
) 
 238     wxToolBarToolsList::Node 
*node
; 
 239     for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 241         if ( node
->GetData()->GetId() == id 
) 
 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
; 
 254     wxToolBarToolBase 
*tool 
= node
->GetData(); 
 255     if ( !DoDeleteTool(pos
, tool
) ) 
 257         return (wxToolBarToolBase 
*)NULL
; 
 260     // the node would delete the data, so set it to NULL to avoid this 
 263     m_tools
.DeleteNode(node
); 
 268 bool wxToolBarBase::DeleteToolByPos(size_t pos
) 
 270     wxCHECK_MSG( pos 
< GetToolsCount(), FALSE
, 
 271                  _T("invalid position in wxToolBar::DeleteToolByPos()") ); 
 273     wxToolBarToolsList::Node 
*node 
= m_tools
.Item(pos
); 
 275     if ( !DoDeleteTool(pos
, node
->GetData()) ) 
 280     m_tools
.DeleteNode(node
); 
 285 bool wxToolBarBase::DeleteTool(int id
) 
 288     wxToolBarToolsList::Node 
*node
; 
 289     for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 291         if ( node
->GetData()->GetId() == id 
) 
 297     if ( !node 
|| !DoDeleteTool(pos
, node
->GetData()) ) 
 302     m_tools
.DeleteNode(node
); 
 307 wxToolBarToolBase 
*wxToolBarBase::FindById(int id
) const 
 309     wxToolBarToolBase 
*tool 
= (wxToolBarToolBase 
*)NULL
; 
 311     for ( wxToolBarToolsList::Node 
*node 
= m_tools
.GetFirst(); 
 313           node 
= node
->GetNext() ) 
 315         tool 
= node
->GetData(); 
 316         if ( tool
->GetId() == id 
) 
 326 void wxToolBarBase::ClearTools() 
 331 bool wxToolBarBase::Realize() 
 336 wxToolBarBase::~wxToolBarBase() 
 340 // ---------------------------------------------------------------------------- 
 341 // wxToolBarBase tools state 
 342 // ---------------------------------------------------------------------------- 
 344 void wxToolBarBase::EnableTool(int id
, bool enable
) 
 346     wxToolBarToolBase 
*tool 
= FindById(id
); 
 349         if ( tool
->Enable(enable
) ) 
 351             DoEnableTool(tool
, enable
); 
 356 void wxToolBarBase::ToggleTool(int id
, bool toggle
) 
 358     wxToolBarToolBase 
*tool 
= FindById(id
); 
 359     if ( tool 
&& tool
->CanBeToggled() ) 
 361         if ( tool
->Toggle(toggle
) ) 
 363             DoToggleTool(tool
, toggle
); 
 368 void wxToolBarBase::SetToggle(int id
, bool toggle
) 
 370     wxToolBarToolBase 
*tool 
= FindById(id
); 
 373         if ( tool
->SetToggle(toggle
) ) 
 375             DoSetToggle(tool
, toggle
); 
 380 void wxToolBarBase::SetToolShortHelp(int id
, const wxString
& help
) 
 382     wxToolBarToolBase 
*tool 
= FindById(id
); 
 385         (void)tool
->SetShortHelp(help
); 
 389 void wxToolBarBase::SetToolLongHelp(int id
, const wxString
& help
) 
 391     wxToolBarToolBase 
*tool 
= FindById(id
); 
 394         (void)tool
->SetLongHelp(help
); 
 398 wxObject 
*wxToolBarBase::GetToolClientData(int id
) const 
 400     wxToolBarToolBase 
*tool 
= FindById(id
); 
 402     return tool 
? tool
->GetClientData() : (wxObject 
*)NULL
; 
 405 void wxToolBarBase::SetToolClientData(int id
, wxObject 
*clientData
) 
 407     wxToolBarToolBase 
*tool 
= FindById(id
); 
 409     wxCHECK_RET( tool
, _T("no such tool in wxToolBar::SetToolClientData") ); 
 411     tool
->SetClientData(clientData
); 
 414 bool wxToolBarBase::GetToolState(int id
) const 
 416     wxToolBarToolBase 
*tool 
= FindById(id
); 
 417     wxCHECK_MSG( tool
, FALSE
, _T("no such tool") ); 
 419     return tool
->IsToggled(); 
 422 bool wxToolBarBase::GetToolEnabled(int id
) const 
 424     wxToolBarToolBase 
*tool 
= FindById(id
); 
 425     wxCHECK_MSG( tool
, FALSE
, _T("no such tool") ); 
 427     return tool
->IsEnabled(); 
 430 wxString 
wxToolBarBase::GetToolShortHelp(int id
) const 
 432     wxToolBarToolBase 
*tool 
= FindById(id
); 
 433     wxCHECK_MSG( tool
, _T(""), _T("no such tool") ); 
 435     return tool
->GetShortHelp(); 
 438 wxString 
wxToolBarBase::GetToolLongHelp(int id
) const 
 440     wxToolBarToolBase 
*tool 
= FindById(id
); 
 441     wxCHECK_MSG( tool
, _T(""), _T("no such tool") ); 
 443     return tool
->GetLongHelp(); 
 446 // ---------------------------------------------------------------------------- 
 447 // wxToolBarBase geometry 
 448 // ---------------------------------------------------------------------------- 
 450 void wxToolBarBase::SetMargins(int x
, int y
) 
 456 void wxToolBarBase::SetRows(int WXUNUSED(nRows
)) 
 461 // ---------------------------------------------------------------------------- 
 463 // ---------------------------------------------------------------------------- 
 465 // Only allow toggle if returns TRUE 
 466 bool wxToolBarBase::OnLeftClick(int id
, bool toggleDown
) 
 468     wxCommandEvent 
event(wxEVT_COMMAND_TOOL_CLICKED
, id
); 
 469     event
.SetEventObject(this); 
 471     // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown 
 472     event
.SetInt((int)toggleDown
); 
 474     // and SetExtraLong() for backwards compatibility 
 475     event
.SetExtraLong((long)toggleDown
); 
 477     // Send events to this toolbar instead (and thence up the window hierarchy) 
 478     GetEventHandler()->ProcessEvent(event
); 
 483 // Call when right button down. 
 484 void wxToolBarBase::OnRightClick(int id
, 
 488     wxCommandEvent 
event(wxEVT_COMMAND_TOOL_RCLICKED
, id
); 
 489     event
.SetEventObject(this); 
 492     GetEventHandler()->ProcessEvent(event
); 
 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 
 500 void wxToolBarBase::OnMouseEnter(int id
) 
 502     wxCommandEvent 
event(wxEVT_COMMAND_TOOL_ENTER
, GetId()); 
 503     event
.SetEventObject(this); 
 506     (void)GetEventHandler()->ProcessEvent(event
); 
 508     wxToolBarToolBase 
*tool 
= FindById(id
); 
 509     if ( !tool 
|| !tool
->GetLongHelp() ) 
 512     wxFrame 
*frame 
= wxDynamicCast(GetParent(), wxFrame
); 
 516     frame
->SetStatusText(tool
->GetLongHelp()); 
 519 // ---------------------------------------------------------------------------- 
 521 // ---------------------------------------------------------------------------- 
 523 void wxToolBarBase::OnIdle(wxIdleEvent
& event
) 
 530 // Do the toolbar button updates (check for EVT_UPDATE_UI handlers) 
 531 void wxToolBarBase::DoToolbarUpdates() 
 533     wxWindow
* parent 
= this; 
 534     while (parent
->GetParent()) 
 535         parent 
= parent
->GetParent(); 
 538     wxWindow
* focusWin 
= wxFindFocusDescendant(parent
); 
 540     wxWindow
* focusWin 
= (wxWindow
*) NULL
; 
 543     wxEvtHandler
* evtHandler 
= focusWin 
? focusWin
->GetEventHandler() : GetEventHandler() ; 
 545     for ( wxToolBarToolsList::Node
* node 
= m_tools
.GetFirst(); 
 547           node 
= node
->GetNext() ) 
 549         int id 
= node
->GetData()->GetId(); 
 551         wxUpdateUIEvent 
event(id
); 
 552         event
.SetEventObject(this); 
 554         if ( evtHandler
->ProcessEvent(event
) ) 
 556             if ( event
.GetSetEnabled() ) 
 557                 EnableTool(id
, event
.GetEnabled()); 
 558             if ( event
.GetSetChecked() ) 
 559                 ToggleTool(id
, event
.GetChecked()); 
 561             if ( event
.GetSetText() ) 
 568 #endif // wxUSE_TOOLBAR