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
9 // Licence: wxWindows licence
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/toolbar.h"
43 // ----------------------------------------------------------------------------
45 // ----------------------------------------------------------------------------
47 IMPLEMENT_CLASS(wxToolBarBase
, wxControl
)
49 BEGIN_EVENT_TABLE(wxToolBarBase
, wxControl
)
52 #include "wx/listimpl.cpp"
54 WX_DEFINE_LIST(wxToolBarToolsList
);
56 // ============================================================================
58 // ============================================================================
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 bool wxToolBarToolBase::Enable(bool enable
)
66 if ( m_enabled
== enable
)
74 bool wxToolBarToolBase::Toggle(bool toggle
)
76 wxASSERT_MSG( CanBeToggled(), _T("can't toggle this tool") );
78 if ( m_toggled
== toggle
)
86 bool wxToolBarToolBase::SetToggle(bool toggle
)
88 wxItemKind kind
= toggle
? wxITEM_CHECK
: wxITEM_NORMAL
;
97 bool wxToolBarToolBase::SetShortHelp(const wxString
& help
)
99 if ( m_shortHelpString
== help
)
102 m_shortHelpString
= help
;
107 bool wxToolBarToolBase::SetLongHelp(const wxString
& help
)
109 if ( m_longHelpString
== help
)
112 m_longHelpString
= help
;
117 wxToolBarToolBase::~wxToolBarToolBase()
121 // ----------------------------------------------------------------------------
122 // wxToolBarBase adding/deleting items
123 // ----------------------------------------------------------------------------
125 wxToolBarBase::wxToolBarBase()
127 // the list owns the pointers
128 m_xMargin
= m_yMargin
= 0;
130 m_maxRows
= m_maxCols
= 0;
133 wxToolBarToolBase
*wxToolBarBase::DoAddTool(int id
,
134 const wxString
& label
,
135 const wxBitmap
& bitmap
,
136 const wxBitmap
& bmpDisabled
,
138 const wxString
& shortHelp
,
139 const wxString
& longHelp
,
140 wxObject
*clientData
,
141 wxCoord
WXUNUSED(xPos
),
142 wxCoord
WXUNUSED(yPos
))
144 return InsertTool(GetToolsCount(), id
, label
, bitmap
, bmpDisabled
,
145 kind
, shortHelp
, longHelp
, clientData
);
148 wxToolBarToolBase
*wxToolBarBase::InsertTool(size_t pos
,
150 const wxString
& label
,
151 const wxBitmap
& bitmap
,
152 const wxBitmap
& bmpDisabled
,
154 const wxString
& shortHelp
,
155 const wxString
& longHelp
,
156 wxObject
*clientData
)
158 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
159 _T("invalid position in wxToolBar::InsertTool()") );
161 wxToolBarToolBase
*tool
= CreateTool(id
, label
, bitmap
, bmpDisabled
, kind
,
162 clientData
, shortHelp
, longHelp
);
164 if ( !InsertTool(pos
, tool
) )
174 wxToolBarToolBase
*wxToolBarBase::AddTool(wxToolBarToolBase
*tool
)
176 return InsertTool(GetToolsCount(), tool
);
180 wxToolBarBase::InsertTool(size_t pos
, wxToolBarToolBase
*tool
)
182 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
183 _T("invalid position in wxToolBar::InsertTool()") );
185 if ( !tool
|| !DoInsertTool(pos
, tool
) )
190 m_tools
.Insert(pos
, tool
);
195 wxToolBarToolBase
*wxToolBarBase::AddControl(wxControl
*control
)
197 return InsertControl(GetToolsCount(), control
);
200 wxToolBarToolBase
*wxToolBarBase::InsertControl(size_t pos
, wxControl
*control
)
202 wxCHECK_MSG( control
, (wxToolBarToolBase
*)NULL
,
203 _T("toolbar: can't insert NULL control") );
205 wxCHECK_MSG( control
->GetParent() == this, (wxToolBarToolBase
*)NULL
,
206 _T("control must have toolbar as parent") );
208 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
209 _T("invalid position in wxToolBar::InsertControl()") );
211 wxToolBarToolBase
*tool
= CreateTool(control
);
213 if ( !InsertTool(pos
, tool
) )
223 wxControl
*wxToolBarBase::FindControl( int id
)
225 for ( wxToolBarToolsList::compatibility_iterator node
= m_tools
.GetFirst();
227 node
= node
->GetNext() )
229 const wxToolBarToolBase
* const tool
= node
->GetData();
230 if ( tool
->IsControl() )
232 wxControl
* const control
= tool
->GetControl();
236 wxFAIL_MSG( _T("NULL control in toolbar?") );
238 else if ( control
->GetId() == id
)
249 wxToolBarToolBase
*wxToolBarBase::AddSeparator()
251 return InsertSeparator(GetToolsCount());
254 wxToolBarToolBase
*wxToolBarBase::InsertSeparator(size_t pos
)
256 wxCHECK_MSG( pos
<= GetToolsCount(), (wxToolBarToolBase
*)NULL
,
257 _T("invalid position in wxToolBar::InsertSeparator()") );
259 wxToolBarToolBase
*tool
= CreateTool(wxID_SEPARATOR
,
261 wxNullBitmap
, wxNullBitmap
,
262 wxITEM_SEPARATOR
, (wxObject
*)NULL
,
263 wxEmptyString
, wxEmptyString
);
265 if ( !tool
|| !DoInsertTool(pos
, tool
) )
272 m_tools
.Insert(pos
, tool
);
277 wxToolBarToolBase
*wxToolBarBase::RemoveTool(int id
)
280 wxToolBarToolsList::compatibility_iterator node
;
281 for ( node
= m_tools
.GetFirst(); node
; node
= node
->GetNext() )
283 if ( node
->GetData()->GetId() == id
)
291 // don't give any error messages - sometimes we might call RemoveTool()
292 // without knowing whether the tool is or not in the toolbar
293 return (wxToolBarToolBase
*)NULL
;
296 wxToolBarToolBase
*tool
= node
->GetData();
297 if ( !DoDeleteTool(pos
, tool
) )
299 return (wxToolBarToolBase
*)NULL
;
307 bool wxToolBarBase::DeleteToolByPos(size_t pos
)
309 wxCHECK_MSG( pos
< GetToolsCount(), FALSE
,
310 _T("invalid position in wxToolBar::DeleteToolByPos()") );
312 wxToolBarToolsList::compatibility_iterator node
= m_tools
.Item(pos
);
314 if ( !DoDeleteTool(pos
, node
->GetData()) )
319 delete node
->GetData();
325 bool wxToolBarBase::DeleteTool(int id
)
328 wxToolBarToolsList::compatibility_iterator node
;
329 for ( node
= m_tools
.GetFirst(); node
; node
= node
->GetNext() )
331 if ( node
->GetData()->GetId() == id
)
337 if ( !node
|| !DoDeleteTool(pos
, node
->GetData()) )
342 delete node
->GetData();
348 wxToolBarToolBase
*wxToolBarBase::FindById(int id
) const
350 wxToolBarToolBase
*tool
= (wxToolBarToolBase
*)NULL
;
352 for ( wxToolBarToolsList::compatibility_iterator node
= m_tools
.GetFirst();
354 node
= node
->GetNext() )
356 tool
= node
->GetData();
357 if ( tool
->GetId() == id
)
369 void wxToolBarBase::ClearTools()
371 WX_CLEAR_LIST(wxToolBarToolsList
, m_tools
);
374 bool wxToolBarBase::Realize()
379 wxToolBarBase::~wxToolBarBase()
381 WX_CLEAR_LIST(wxToolBarToolsList
, m_tools
);
384 // ----------------------------------------------------------------------------
385 // wxToolBarBase tools state
386 // ----------------------------------------------------------------------------
388 void wxToolBarBase::EnableTool(int id
, bool enable
)
390 wxToolBarToolBase
*tool
= FindById(id
);
393 if ( tool
->Enable(enable
) )
395 DoEnableTool(tool
, enable
);
400 void wxToolBarBase::ToggleTool(int id
, bool toggle
)
402 wxToolBarToolBase
*tool
= FindById(id
);
403 if ( tool
&& tool
->CanBeToggled() )
405 if ( tool
->Toggle(toggle
) )
407 DoToggleTool(tool
, toggle
);
412 void wxToolBarBase::SetToggle(int id
, bool toggle
)
414 wxToolBarToolBase
*tool
= FindById(id
);
417 if ( tool
->SetToggle(toggle
) )
419 DoSetToggle(tool
, toggle
);
424 void wxToolBarBase::SetToolShortHelp(int id
, const wxString
& help
)
426 wxToolBarToolBase
*tool
= FindById(id
);
429 (void)tool
->SetShortHelp(help
);
433 void wxToolBarBase::SetToolLongHelp(int id
, const wxString
& help
)
435 wxToolBarToolBase
*tool
= FindById(id
);
438 (void)tool
->SetLongHelp(help
);
442 wxObject
*wxToolBarBase::GetToolClientData(int id
) const
444 wxToolBarToolBase
*tool
= FindById(id
);
446 return tool
? tool
->GetClientData() : (wxObject
*)NULL
;
449 void wxToolBarBase::SetToolClientData(int id
, wxObject
*clientData
)
451 wxToolBarToolBase
*tool
= FindById(id
);
453 wxCHECK_RET( tool
, _T("no such tool in wxToolBar::SetToolClientData") );
455 tool
->SetClientData(clientData
);
458 int wxToolBarBase::GetToolPos(int id
) const
461 wxToolBarToolsList::compatibility_iterator node
;
463 for ( node
= m_tools
.GetFirst(); node
; node
= node
->GetNext() )
465 if ( node
->GetData()->GetId() == id
)
474 bool wxToolBarBase::GetToolState(int id
) const
476 wxToolBarToolBase
*tool
= FindById(id
);
477 wxCHECK_MSG( tool
, FALSE
, _T("no such tool") );
479 return tool
->IsToggled();
482 bool wxToolBarBase::GetToolEnabled(int id
) const
484 wxToolBarToolBase
*tool
= FindById(id
);
485 wxCHECK_MSG( tool
, FALSE
, _T("no such tool") );
487 return tool
->IsEnabled();
490 wxString
wxToolBarBase::GetToolShortHelp(int id
) const
492 wxToolBarToolBase
*tool
= FindById(id
);
493 wxCHECK_MSG( tool
, _T(""), _T("no such tool") );
495 return tool
->GetShortHelp();
498 wxString
wxToolBarBase::GetToolLongHelp(int id
) const
500 wxToolBarToolBase
*tool
= FindById(id
);
501 wxCHECK_MSG( tool
, _T(""), _T("no such tool") );
503 return tool
->GetLongHelp();
506 // ----------------------------------------------------------------------------
507 // wxToolBarBase geometry
508 // ----------------------------------------------------------------------------
510 void wxToolBarBase::SetMargins(int x
, int y
)
516 void wxToolBarBase::SetRows(int WXUNUSED(nRows
))
521 // ----------------------------------------------------------------------------
523 // ----------------------------------------------------------------------------
525 // Only allow toggle if returns TRUE
526 bool wxToolBarBase::OnLeftClick(int id
, bool toggleDown
)
528 wxCommandEvent
event(wxEVT_COMMAND_TOOL_CLICKED
, id
);
529 event
.SetEventObject(this);
531 // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown
532 event
.SetInt((int)toggleDown
);
534 // and SetExtraLong() for backwards compatibility
535 event
.SetExtraLong((long)toggleDown
);
537 // Send events to this toolbar instead (and thence up the window hierarchy)
538 GetEventHandler()->ProcessEvent(event
);
543 // Call when right button down.
544 void wxToolBarBase::OnRightClick(int id
,
548 wxCommandEvent
event(wxEVT_COMMAND_TOOL_RCLICKED
, id
);
549 event
.SetEventObject(this);
552 GetEventHandler()->ProcessEvent(event
);
555 // Called when the mouse cursor enters a tool bitmap (no button pressed).
556 // Argument is -1 if mouse is exiting the toolbar.
557 // Note that for this event, the id of the window is used,
558 // and the integer parameter of wxCommandEvent is used to retrieve
560 void wxToolBarBase::OnMouseEnter(int id
)
562 wxCommandEvent
event(wxEVT_COMMAND_TOOL_ENTER
, GetId());
563 event
.SetEventObject(this);
566 wxFrame
*frame
= wxDynamicCast(GetParent(), wxFrame
);
569 wxToolBarToolBase
* tool
= id
== -1 ? (wxToolBarToolBase
*)0 : FindById(id
);
570 wxString help
= tool
? tool
->GetLongHelp() : wxString();
571 frame
->DoGiveHelp( help
, id
!= -1 );
574 (void)GetEventHandler()->ProcessEvent(event
);
577 // ----------------------------------------------------------------------------
579 // ----------------------------------------------------------------------------
581 // Do the toolbar button updates (check for EVT_UPDATE_UI handlers)
582 void wxToolBarBase::UpdateWindowUI(long flags
)
584 wxWindowBase::UpdateWindowUI(flags
);
586 wxEvtHandler
* evtHandler
= GetEventHandler() ;
588 for ( wxToolBarToolsList::compatibility_iterator node
= m_tools
.GetFirst();
590 node
= node
->GetNext() )
592 int id
= node
->GetData()->GetId();
594 wxUpdateUIEvent
event(id
);
595 event
.SetEventObject(this);
597 if ( evtHandler
->ProcessEvent(event
) )
599 if ( event
.GetSetEnabled() )
600 EnableTool(id
, event
.GetEnabled());
601 if ( event
.GetSetChecked() )
602 ToggleTool(id
, event
.GetChecked());
604 if ( event
.GetSetText() )
611 // Helper function, used by wxCreateGreyedImage
613 static void wxGreyOutImage( const wxImage
& src
,
615 const wxColour
& darkCol
,
616 const wxColour
& lightCol
,
617 const wxColour
& bgCol
)
619 // Second attempt, just making things monochrome
620 int width
= src
.GetWidth();
621 int height
= src
.GetHeight();
623 int redCur
, greenCur
, blueCur
;
624 for ( int x
= 0; x
< width
; x
++ )
626 for ( int y
= 1; y
< height
; y
++ )
628 redCur
= src
.GetRed(x
, y
);
629 greenCur
= src
.GetGreen(x
, y
);
630 blueCur
= src
.GetBlue(x
, y
);
632 // Change light things to the background colour
633 if ( redCur
>= (lightCol
.Red() - 50) && greenCur
>= (lightCol
.Green() - 50) && blueCur
>= (lightCol
.Blue() - 50) )
635 dest
.SetRGB(x
,y
, bgCol
.Red(), bgCol
.Green(), bgCol
.Blue());
637 else if ( redCur
== bgCol
.Red() && greenCur
== bgCol
.Green() && blueCur
== bgCol
.Blue() )
639 // Leave the background colour as-is
640 // dest.SetRGB(x,y, bgCol.Red(), bgCol.Green(), bgCol.Blue());
642 else // if ( redCur <= darkCol.Red() && greenCur <= darkCol.Green() && blueCur <= darkCol.Blue() )
644 // Change dark things to really dark
645 dest
.SetRGB(x
,y
, darkCol
.Red(), darkCol
.Green(), darkCol
.Blue());
652 * Make a greyed-out image suitable for disabled buttons.
653 * This code is adapted from wxNewBitmapButton in FL.
656 bool wxCreateGreyedImage(const wxImage
& in
, wxImage
& out
)
660 // assuming the pixels along the edges are of the background color
661 wxColour
bgCol(in
.GetRed(0, 0), in
.GetGreen(0, 0), in
.GetBlue(0, 0));
663 wxColour darkCol
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
) ;
664 wxColour lightCol
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT
) ;
666 wxGreyOutImage(in
, out
, darkCol
, lightCol
, bgCol
);
671 #endif // wxUSE_TOOLBAR