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" 
  34     #include "wx/control.h" 
  39 #include "wx/settings.h" 
  41 #include "wx/tbarbase.h" 
  43 // ---------------------------------------------------------------------------- 
  45 // ---------------------------------------------------------------------------- 
  47 IMPLEMENT_CLASS(wxToolBarBase
, wxControl
) 
  49 BEGIN_EVENT_TABLE(wxToolBarBase
, wxControl
) 
  50     EVT_IDLE(wxToolBarBase::OnIdle
) 
  53 #include "wx/listimpl.cpp" 
  55 WX_DEFINE_LIST(wxToolBarToolsList
); 
  57 // ============================================================================ 
  59 // ============================================================================ 
  61 // ---------------------------------------------------------------------------- 
  63 // ---------------------------------------------------------------------------- 
  65 bool wxToolBarToolBase::Enable(bool enable
) 
  67     if ( m_enabled 
== enable 
) 
  75 bool wxToolBarToolBase::Toggle(bool toggle
) 
  77     wxASSERT_MSG( CanBeToggled(), _T("can't toggle this tool") ); 
  79     if ( m_toggled 
== toggle 
) 
  87 bool wxToolBarToolBase::SetToggle(bool toggle
) 
  89     wxItemKind kind 
= toggle 
? wxITEM_CHECK 
: wxITEM_NORMAL
; 
  98 bool wxToolBarToolBase::SetShortHelp(const wxString
& help
) 
 100     if ( m_shortHelpString 
== help 
) 
 103     m_shortHelpString 
= help
; 
 108 bool wxToolBarToolBase::SetLongHelp(const wxString
& help
) 
 110     if ( m_longHelpString 
== help 
) 
 113     m_longHelpString 
= help
; 
 118 wxToolBarToolBase::~wxToolBarToolBase() 
 122 // ---------------------------------------------------------------------------- 
 123 // wxToolBarBase adding/deleting items 
 124 // ---------------------------------------------------------------------------- 
 126 wxToolBarBase::wxToolBarBase() 
 128     // the list owns the pointers 
 129     m_tools
.DeleteContents(TRUE
); 
 131     m_xMargin 
= m_yMargin 
= 0; 
 133     m_maxRows 
= m_maxCols 
= 0; 
 136 wxToolBarToolBase 
*wxToolBarBase::DoAddTool(int id
, 
 137                                             const wxString
& label
, 
 138                                             const wxBitmap
& bitmap
, 
 139                                             const wxBitmap
& bmpDisabled
, 
 141                                             const wxString
& shortHelp
, 
 142                                             const wxString
& longHelp
, 
 143                                             wxObject 
*clientData
, 
 144                                             wxCoord 
WXUNUSED(xPos
), 
 145                                             wxCoord 
WXUNUSED(yPos
)) 
 147     return InsertTool(GetToolsCount(), id
, label
, bitmap
, bmpDisabled
, 
 148                       kind
, shortHelp
, longHelp
, clientData
); 
 151 wxToolBarToolBase 
*wxToolBarBase::InsertTool(size_t pos
, 
 153                                              const wxString
& label
, 
 154                                              const wxBitmap
& bitmap
, 
 155                                              const wxBitmap
& bmpDisabled
, 
 157                                              const wxString
& shortHelp
, 
 158                                              const wxString
& longHelp
, 
 159                                              wxObject 
*clientData
) 
 161     wxCHECK_MSG( pos 
<= GetToolsCount(), (wxToolBarToolBase 
*)NULL
, 
 162                  _T("invalid position in wxToolBar::InsertTool()") ); 
 164     wxToolBarToolBase 
*tool 
= CreateTool(id
, label
, bitmap
, bmpDisabled
, kind
, 
 165                                          clientData
, shortHelp
, longHelp
); 
 167     if ( !tool 
|| !DoInsertTool(pos
, tool
) ) 
 174     m_tools
.Insert(pos
, tool
); 
 179 wxToolBarToolBase 
*wxToolBarBase::AddControl(wxControl 
*control
) 
 181     return InsertControl(GetToolsCount(), control
); 
 184 wxToolBarToolBase 
*wxToolBarBase::InsertControl(size_t pos
, wxControl 
*control
) 
 186     wxCHECK_MSG( control
, (wxToolBarToolBase 
*)NULL
, 
 187                  _T("toolbar: can't insert NULL control") ); 
 189     wxCHECK_MSG( control
->GetParent() == this, (wxToolBarToolBase 
*)NULL
, 
 190                  _T("control must have toolbar as parent") ); 
 192     wxCHECK_MSG( pos 
<= GetToolsCount(), (wxToolBarToolBase 
*)NULL
, 
 193                  _T("invalid position in wxToolBar::InsertControl()") ); 
 195     wxToolBarToolBase 
*tool 
= CreateTool(control
); 
 197     if ( !tool 
|| !DoInsertTool(pos
, tool
) ) 
 204     m_tools
.Insert(pos
, tool
); 
 209 wxToolBarToolBase 
*wxToolBarBase::AddSeparator() 
 211     return InsertSeparator(GetToolsCount()); 
 214 wxToolBarToolBase 
*wxToolBarBase::InsertSeparator(size_t pos
) 
 216     wxCHECK_MSG( pos 
<= GetToolsCount(), (wxToolBarToolBase 
*)NULL
, 
 217                  _T("invalid position in wxToolBar::InsertSeparator()") ); 
 219     wxToolBarToolBase 
*tool 
= CreateTool(wxID_SEPARATOR
, 
 221                                          wxNullBitmap
, wxNullBitmap
, 
 222                                          wxITEM_SEPARATOR
, (wxObject 
*)NULL
, 
 223                                          wxEmptyString
, wxEmptyString
); 
 225     if ( !tool 
|| !DoInsertTool(pos
, tool
) ) 
 232     m_tools
.Insert(pos
, tool
); 
 237 wxToolBarToolBase 
*wxToolBarBase::RemoveTool(int id
) 
 240     wxToolBarToolsList::Node 
*node
; 
 241     for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 243         if ( node
->GetData()->GetId() == id 
) 
 251         // don't give any error messages - sometimes we might call RemoveTool() 
 252         // without knowing whether the tool is or not in the toolbar 
 253         return (wxToolBarToolBase 
*)NULL
; 
 256     wxToolBarToolBase 
*tool 
= node
->GetData(); 
 257     if ( !DoDeleteTool(pos
, tool
) ) 
 259         return (wxToolBarToolBase 
*)NULL
; 
 262     // the node would delete the data, so set it to NULL to avoid this 
 265     m_tools
.DeleteNode(node
); 
 270 bool wxToolBarBase::DeleteToolByPos(size_t pos
) 
 272     wxCHECK_MSG( pos 
< GetToolsCount(), FALSE
, 
 273                  _T("invalid position in wxToolBar::DeleteToolByPos()") ); 
 275     wxToolBarToolsList::Node 
*node 
= m_tools
.Item(pos
); 
 277     if ( !DoDeleteTool(pos
, node
->GetData()) ) 
 282     m_tools
.DeleteNode(node
); 
 287 bool wxToolBarBase::DeleteTool(int id
) 
 290     wxToolBarToolsList::Node 
*node
; 
 291     for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 293         if ( node
->GetData()->GetId() == id 
) 
 299     if ( !node 
|| !DoDeleteTool(pos
, node
->GetData()) ) 
 304     m_tools
.DeleteNode(node
); 
 309 wxToolBarToolBase 
*wxToolBarBase::FindById(int id
) const 
 311     wxToolBarToolBase 
*tool 
= (wxToolBarToolBase 
*)NULL
; 
 313     for ( wxToolBarToolsList::Node 
*node 
= m_tools
.GetFirst(); 
 315           node 
= node
->GetNext() ) 
 317         tool 
= node
->GetData(); 
 318         if ( tool
->GetId() == id 
) 
 330 void wxToolBarBase::ClearTools() 
 335 bool wxToolBarBase::Realize() 
 340 wxToolBarBase::~wxToolBarBase() 
 344 // ---------------------------------------------------------------------------- 
 345 // wxToolBarBase tools state 
 346 // ---------------------------------------------------------------------------- 
 348 void wxToolBarBase::EnableTool(int id
, bool enable
) 
 350     wxToolBarToolBase 
*tool 
= FindById(id
); 
 353         if ( tool
->Enable(enable
) ) 
 355             DoEnableTool(tool
, enable
); 
 360 void wxToolBarBase::ToggleTool(int id
, bool toggle
) 
 362     wxToolBarToolBase 
*tool 
= FindById(id
); 
 363     if ( tool 
&& tool
->CanBeToggled() ) 
 365         if ( tool
->Toggle(toggle
) ) 
 367             DoToggleTool(tool
, toggle
); 
 372 void wxToolBarBase::SetToggle(int id
, bool toggle
) 
 374     wxToolBarToolBase 
*tool 
= FindById(id
); 
 377         if ( tool
->SetToggle(toggle
) ) 
 379             DoSetToggle(tool
, toggle
); 
 384 void wxToolBarBase::SetToolShortHelp(int id
, const wxString
& help
) 
 386     wxToolBarToolBase 
*tool 
= FindById(id
); 
 389         (void)tool
->SetShortHelp(help
); 
 393 void wxToolBarBase::SetToolLongHelp(int id
, const wxString
& help
) 
 395     wxToolBarToolBase 
*tool 
= FindById(id
); 
 398         (void)tool
->SetLongHelp(help
); 
 402 wxObject 
*wxToolBarBase::GetToolClientData(int id
) const 
 404     wxToolBarToolBase 
*tool 
= FindById(id
); 
 406     return tool 
? tool
->GetClientData() : (wxObject 
*)NULL
; 
 409 void wxToolBarBase::SetToolClientData(int id
, wxObject 
*clientData
) 
 411     wxToolBarToolBase 
*tool 
= FindById(id
); 
 413     wxCHECK_RET( tool
, _T("no such tool in wxToolBar::SetToolClientData") ); 
 415     tool
->SetClientData(clientData
); 
 418 bool wxToolBarBase::GetToolState(int id
) const 
 420     wxToolBarToolBase 
*tool 
= FindById(id
); 
 421     wxCHECK_MSG( tool
, FALSE
, _T("no such tool") ); 
 423     return tool
->IsToggled(); 
 426 bool wxToolBarBase::GetToolEnabled(int id
) const 
 428     wxToolBarToolBase 
*tool 
= FindById(id
); 
 429     wxCHECK_MSG( tool
, FALSE
, _T("no such tool") ); 
 431     return tool
->IsEnabled(); 
 434 wxString 
wxToolBarBase::GetToolShortHelp(int id
) const 
 436     wxToolBarToolBase 
*tool 
= FindById(id
); 
 437     wxCHECK_MSG( tool
, _T(""), _T("no such tool") ); 
 439     return tool
->GetShortHelp(); 
 442 wxString 
wxToolBarBase::GetToolLongHelp(int id
) const 
 444     wxToolBarToolBase 
*tool 
= FindById(id
); 
 445     wxCHECK_MSG( tool
, _T(""), _T("no such tool") ); 
 447     return tool
->GetLongHelp(); 
 450 // ---------------------------------------------------------------------------- 
 451 // wxToolBarBase geometry 
 452 // ---------------------------------------------------------------------------- 
 454 void wxToolBarBase::SetMargins(int x
, int y
) 
 460 void wxToolBarBase::SetRows(int WXUNUSED(nRows
)) 
 465 // ---------------------------------------------------------------------------- 
 467 // ---------------------------------------------------------------------------- 
 469 // Only allow toggle if returns TRUE 
 470 bool wxToolBarBase::OnLeftClick(int id
, bool toggleDown
) 
 472     wxCommandEvent 
event(wxEVT_COMMAND_TOOL_CLICKED
, id
); 
 473     event
.SetEventObject(this); 
 475     // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown 
 476     event
.SetInt((int)toggleDown
); 
 478     // and SetExtraLong() for backwards compatibility 
 479     event
.SetExtraLong((long)toggleDown
); 
 481     // Send events to this toolbar instead (and thence up the window hierarchy) 
 482     GetEventHandler()->ProcessEvent(event
); 
 487 // Call when right button down. 
 488 void wxToolBarBase::OnRightClick(int id
, 
 492     wxCommandEvent 
event(wxEVT_COMMAND_TOOL_RCLICKED
, id
); 
 493     event
.SetEventObject(this); 
 496     GetEventHandler()->ProcessEvent(event
); 
 499 // Called when the mouse cursor enters a tool bitmap (no button pressed). 
 500 // Argument is -1 if mouse is exiting the toolbar. 
 501 // Note that for this event, the id of the window is used, 
 502 // and the integer parameter of wxCommandEvent is used to retrieve 
 504 void wxToolBarBase::OnMouseEnter(int id
) 
 506     wxCommandEvent 
event(wxEVT_COMMAND_TOOL_ENTER
, GetId()); 
 507     event
.SetEventObject(this); 
 510     (void)GetEventHandler()->ProcessEvent(event
); 
 512     wxFrame 
*frame 
= wxDynamicCast(GetParent(), wxFrame
); 
 520         wxToolBarToolBase 
*tool 
= FindById(id
); 
 522             helpstring 
= tool
->GetLongHelp(); 
 525     // set the status text anyhow, even if the string is empty: this ensures 
 526     // that it is cleared when the mouse leaves the toolbar or enters a tool 
 528     frame
->SetStatusText(helpstring
); 
 531 // ---------------------------------------------------------------------------- 
 533 // ---------------------------------------------------------------------------- 
 535 void wxToolBarBase::OnIdle(wxIdleEvent
& event
) 
 542 // Do the toolbar button updates (check for EVT_UPDATE_UI handlers) 
 543 void wxToolBarBase::DoToolbarUpdates() 
 545     wxWindow
* parent 
= this; 
 546     while (parent
->GetParent()) 
 547         parent 
= parent
->GetParent(); 
 550     wxWindow
* focusWin 
= wxFindFocusDescendant(parent
); 
 552     wxWindow
* focusWin 
= (wxWindow
*) NULL
; 
 555     wxEvtHandler
* evtHandler 
= focusWin 
? focusWin
->GetEventHandler() : GetEventHandler() ; 
 557     for ( wxToolBarToolsList::Node
* node 
= m_tools
.GetFirst(); 
 559           node 
= node
->GetNext() ) 
 561         int id 
= node
->GetData()->GetId(); 
 563         wxUpdateUIEvent 
event(id
); 
 564         event
.SetEventObject(this); 
 566         if ( evtHandler
->ProcessEvent(event
) ) 
 568             if ( event
.GetSetEnabled() ) 
 569                 EnableTool(id
, event
.GetEnabled()); 
 570             if ( event
.GetSetChecked() ) 
 571                 ToggleTool(id
, event
.GetChecked()); 
 573             if ( event
.GetSetText() ) 
 580 // Helper function, used by wxCreateGreyedImage 
 582 static void wxGreyOutImage( const wxImage
& src
, 
 584                             const wxColour
& darkCol
, 
 585                             const wxColour
& lightCol
, 
 586                             const wxColour
& bgCol 
) 
 588     // Second attempt, just making things monochrome 
 589     int width 
= src
.GetWidth(); 
 590     int height 
= src
.GetHeight(); 
 592     int redCur
, greenCur
, blueCur
; 
 593     for ( int x 
= 0; x 
< width
; x
++ ) 
 595         for ( int y 
= 1; y 
< height
; y
++ ) 
 597             redCur 
= src
.GetRed(x
, y
); 
 598             greenCur 
= src
.GetGreen(x
, y
); 
 599             blueCur 
= src
.GetBlue(x
, y
); 
 601             // Change light things to the background colour 
 602             if ( redCur 
>= (lightCol
.Red() - 50) && greenCur 
>= (lightCol
.Green() - 50) && blueCur 
>= (lightCol
.Blue() - 50) ) 
 604                 dest
.SetRGB(x
,y
, bgCol
.Red(), bgCol
.Green(), bgCol
.Blue()); 
 606             else if ( redCur 
== bgCol
.Red() && greenCur 
== bgCol
.Green() && blueCur 
== bgCol
.Blue() ) 
 608                 // Leave the background colour as-is 
 609                 // dest.SetRGB(x,y, bgCol.Red(), bgCol.Green(), bgCol.Blue()); 
 611             else // if ( redCur <= darkCol.Red() && greenCur <= darkCol.Green() && blueCur <= darkCol.Blue() ) 
 613                 // Change dark things to really dark 
 614                 dest
.SetRGB(x
,y
, darkCol
.Red(), darkCol
.Green(), darkCol
.Blue()); 
 621  * Make a greyed-out image suitable for disabled buttons. 
 622  * This code is adapted from wxNewBitmapButton in FL. 
 625 bool wxCreateGreyedImage(const wxImage
& in
, wxImage
& out
) 
 629     // assuming the pixels along the edges are of the background color 
 630     wxColour 
bgCol(in
.GetRed(0, 0), in
.GetGreen(0, 0), in
.GetBlue(0, 0)); 
 632     wxColour darkCol 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
) ; 
 633     wxColour lightCol 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT
) ; 
 635     wxGreyOutImage(in
, out
, darkCol
, lightCol
, bgCol
); 
 640 #endif // wxUSE_TOOLBAR