]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/toolbar.cpp
best size taking into account borders
[wxWidgets.git] / src / mac / carbon / toolbar.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: toolbar.cpp
3// Purpose: wxToolBar
a31a5f85 4// Author: Stefan Csomor
e9576ca5
SC
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
84969af7 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: The wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "toolbar.h"
14#endif
15
16#include "wx/wx.h"
519cb848
SC
17
18#if wxUSE_TOOLBAR
19
e9576ca5 20#include "wx/toolbar.h"
2f1ae414
SC
21#include "wx/notebook.h"
22#include "wx/tabctrl.h"
72055702 23#include "wx/bitmap.h"
e9576ca5 24
2f1ae414 25#if !USE_SHARED_LIBRARY
2eb10e2a 26IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
e9576ca5
SC
27
28BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
e044f600 29 EVT_PAINT( wxToolBar::OnPaint )
e9576ca5 30END_EVENT_TABLE()
2f1ae414 31#endif
e9576ca5 32
d497dca4 33#include "wx/mac/uma.h"
bfe9ffbc 34#include "wx/geometry.h"
37e2cb08
SC
35// ----------------------------------------------------------------------------
36// private classes
37// ----------------------------------------------------------------------------
38
39class wxToolBarTool : public wxToolBarToolBase
40{
41public:
42 wxToolBarTool(wxToolBar *tbar,
43 int id,
27e2d606
GD
44 const wxString& label,
45 const wxBitmap& bmpNormal,
46 const wxBitmap& bmpDisabled,
47 wxItemKind kind,
37e2cb08 48 wxObject *clientData,
27e2d606 49 const wxString& shortHelp,
bfe9ffbc
SC
50 const wxString& longHelp) ;
51
37e2cb08
SC
52 wxToolBarTool(wxToolBar *tbar, wxControl *control)
53 : wxToolBarToolBase(tbar, control)
54 {
bfe9ffbc 55 Init() ;
37e2cb08 56 }
bfe9ffbc
SC
57
58 ~wxToolBarTool()
59 {
60 if ( m_controlHandle )
61 DisposeControl( m_controlHandle ) ;
62 }
63
facd6764
SC
64 WXWidget GetControlHandle() { return (WXWidget) m_controlHandle ; }
65 void SetControlHandle( ControlRef handle ) { m_controlHandle = handle ; }
37e2cb08 66
bfe9ffbc
SC
67 void SetSize(const wxSize& size) ;
68 void SetPosition( const wxPoint& position ) ;
69 wxSize GetSize() const
70 {
71 if ( IsControl() )
72 {
73 return GetControl()->GetSize() ;
74 }
75 else if ( IsButton() )
76 {
77 return GetToolBar()->GetToolSize() ;
78 }
79 else
80 {
81 wxSize sz = GetToolBar()->GetToolSize() ;
82 sz.x /= 4 ;
83 sz.y /= 4 ;
84 return sz ;
85 }
86 }
87 wxPoint GetPosition() const
88 {
89 return wxPoint(m_x, m_y);
90 }
91private :
92 void Init()
93 {
94 m_controlHandle = NULL ;
95 }
facd6764 96 ControlRef m_controlHandle ;
37e2cb08 97
bfe9ffbc
SC
98 wxCoord m_x;
99 wxCoord m_y;
37e2cb08
SC
100};
101
facd6764
SC
102static const EventTypeSpec eventList[] =
103{
104 { kEventClassControl , kEventControlHit } ,
105} ;
106
107static pascal OSStatus wxMacToolBarToolControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
108{
109 OSStatus result = eventNotHandledErr ;
110
111 wxMacCarbonEvent cEvent( event ) ;
112
113 ControlRef controlRef ;
114
115 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
116
117 switch( GetEventKind( event ) )
118 {
119 case kEventControlHit :
120 {
121 wxToolBarTool* tbartool = (wxToolBarTool*)data ;
122 if ( tbartool->CanBeToggled() )
123 {
124 tbartool->Toggle( GetControl32BitValue( (ControlRef) tbartool->GetControlHandle() ) ) ;
125 }
126 ((wxToolBar*)tbartool->GetToolBar())->OnLeftClick( tbartool->GetId() , tbartool -> IsToggled() ) ;
127
128 result = noErr;
129 }
130 break ;
131 default :
132 break ;
133 }
134 return result ;
135}
136
137pascal OSStatus wxMacToolBarToolEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
138{
139 OSStatus result = eventNotHandledErr ;
140
141 switch ( GetEventClass( event ) )
142 {
143 case kEventClassControl :
144 result = wxMacToolBarToolControlEventHandler( handler, event, data ) ;
145 break ;
146 default :
147 break ;
148 }
149 return result ;
150}
151
152DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacToolBarToolEventHandler )
153
37e2cb08
SC
154// ============================================================================
155// implementation
156// ============================================================================
157
158// ----------------------------------------------------------------------------
159// wxToolBarTool
160// ----------------------------------------------------------------------------
161
bfe9ffbc
SC
162void wxToolBarTool::SetSize(const wxSize& size)
163{
164 if ( IsControl() )
165 {
166 GetControl()->SetSize( size ) ;
167 }
168}
169
170void wxToolBarTool::SetPosition(const wxPoint& position)
171{
172 m_x = position.x;
173 m_y = position.y;
174
175 if ( IsButton() )
176 {
177 int x , y ;
178 x = y = 0 ;
facd6764
SC
179 int mac_x = position.x ;
180 int mac_y = position.y ;
181#if !TARGET_API_MAC_OSX
182 WindowRef rootwindow = (WindowRef) GetToolBar()->MacGetTopLevelWindowRef() ;
bfe9ffbc 183 GetToolBar()->MacWindowToRootWindow( &x , &y ) ;
facd6764
SC
184 mac_x += x;
185 mac_y += y;
186#endif
bfe9ffbc
SC
187 Rect contrlRect ;
188 GetControlBounds( m_controlHandle , &contrlRect ) ;
189 int former_mac_x = contrlRect.left ;
190 int former_mac_y = contrlRect.top ;
191 wxSize sz = GetToolBar()->GetToolSize() ;
192
193 if ( mac_x != former_mac_x || mac_y != former_mac_y )
194 {
bfe9ffbc 195 UMAMoveControl( m_controlHandle , mac_x , mac_y ) ;
bfe9ffbc
SC
196 }
197 }
198 else if ( IsControl() )
199 {
200 GetControl()->Move( position ) ;
201 }
202}
203
895f5af7
SC
204const short kwxMacToolBarToolDefaultWidth = 24 ;
205const short kwxMacToolBarToolDefaultHeight = 22 ;
206const short kwxMacToolBarTopMargin = 2 ;
207const short kwxMacToolBarLeftMargin = 2 ;
208
bfe9ffbc
SC
209wxToolBarTool::wxToolBarTool(wxToolBar *tbar,
210 int id,
211 const wxString& label,
212 const wxBitmap& bmpNormal,
213 const wxBitmap& bmpDisabled,
214 wxItemKind kind,
215 wxObject *clientData,
216 const wxString& shortHelp,
217 const wxString& longHelp)
218 : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
219 clientData, shortHelp, longHelp)
220{
f4e0be4f
RR
221 Init();
222
223 if (id == wxID_SEPARATOR) return;
bfe9ffbc 224
facd6764 225 WindowRef window = (WindowRef) tbar->MacGetTopLevelWindowRef() ;
bfe9ffbc
SC
226 wxSize toolSize = tbar->GetToolSize() ;
227 Rect toolrect = { 0, 0 , toolSize.y , toolSize.x } ;
228
229 ControlButtonContentInfo info ;
230 wxMacCreateBitmapButton( &info , GetNormalBitmap() ) ;
231
232 SInt16 behaviour = kControlBehaviorOffsetContents ;
233 if ( CanBeToggled() )
234 behaviour += kControlBehaviorToggles ;
bfe9ffbc 235
4c37f124
SC
236 CreateBevelButtonControl( window , &toolrect , CFSTR("") , kControlBevelButtonNormalBevel , behaviour , &info ,
237 0 , 0 , 0 , &m_controlHandle ) ;
238
facd6764
SC
239 InstallControlEventHandler( (ControlRef) m_controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
240 GetEventTypeCount(eventList), eventList, this,NULL);
4c37f124 241
bfe9ffbc
SC
242 UMAShowControl( m_controlHandle ) ;
243 if ( !IsEnabled() )
4c37f124
SC
244 DisableControl( m_controlHandle ) ;
245
bfe9ffbc 246 if ( CanBeToggled() && IsToggled() )
bfe9ffbc 247 ::SetControl32BitValue( m_controlHandle , 1 ) ;
bfe9ffbc 248 else
bfe9ffbc 249 ::SetControl32BitValue( m_controlHandle , 0 ) ;
bfe9ffbc 250
facd6764 251 ControlRef container = (ControlRef) tbar->GetHandle() ;
bfe9ffbc
SC
252 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
253 ::EmbedControl( m_controlHandle , container ) ;
254}
255
2f1ae414 256
37e2cb08 257wxToolBarToolBase *wxToolBar::CreateTool(int id,
27e2d606
GD
258 const wxString& label,
259 const wxBitmap& bmpNormal,
260 const wxBitmap& bmpDisabled,
261 wxItemKind kind,
37e2cb08 262 wxObject *clientData,
27e2d606
GD
263 const wxString& shortHelp,
264 const wxString& longHelp)
37e2cb08 265{
27e2d606
GD
266 return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
267 clientData, shortHelp, longHelp);
37e2cb08
SC
268}
269
270wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
271{
272 return new wxToolBarTool(this, control);
273}
274
37e2cb08 275void wxToolBar::Init()
e9576ca5 276{
e40298d5
JS
277 m_maxWidth = -1;
278 m_maxHeight = -1;
279 m_defaultWidth = kwxMacToolBarToolDefaultWidth;
280 m_defaultHeight = kwxMacToolBarToolDefaultHeight;
e9576ca5
SC
281}
282
283bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
284 long style, const wxString& name)
e40298d5 285{
facd6764
SC
286 if ( !wxToolBarBase::Create( parent , id , pos , size , style ) )
287 return FALSE ;
e40298d5
JS
288
289 return TRUE;
e9576ca5
SC
290}
291
292wxToolBar::~wxToolBar()
bfe9ffbc 293{
7810c95b
SC
294 // we must refresh the frame size when the toolbar is deleted but the frame
295 // is not - otherwise toolbar leaves a hole in the place it used to occupy
e9576ca5
SC
296}
297
37e2cb08 298bool wxToolBar::Realize()
e9576ca5 299{
eb22f2a6 300 if (m_tools.GetCount() == 0)
0b7a8cd3
GD
301 return FALSE;
302
bfe9ffbc
SC
303 int x = m_xMargin + kwxMacToolBarLeftMargin ;
304 int y = m_yMargin + kwxMacToolBarTopMargin ;
0b7a8cd3 305
7c551d95
SC
306 int tw, th;
307 GetSize(& tw, & th);
895f5af7
SC
308
309 int maxWidth = 0 ;
310 int maxHeight = 0 ;
311
bfe9ffbc
SC
312 int maxToolWidth = 0;
313 int maxToolHeight = 0;
314
315 // Find the maximum tool width and height
affd2611 316 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
bfe9ffbc
SC
317 while ( node )
318 {
319 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
320 wxSize sz = tool->GetSize() ;
321
322 if ( sz.x > maxToolWidth )
323 maxToolWidth = sz.x ;
324 if (sz.y> maxToolHeight)
325 maxToolHeight = sz.y;
326
327 node = node->GetNext();
328 }
329
bfe9ffbc 330 node = m_tools.GetFirst();
0b7a8cd3 331 while (node)
7810c95b 332 {
eb22f2a6 333 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
bfe9ffbc 334 wxSize cursize = tool->GetSize() ;
0b7a8cd3 335
bfe9ffbc
SC
336 // for the moment we just do a single row/column alignement
337 if ( x + cursize.x > maxWidth )
338 maxWidth = x + cursize.x ;
339 if ( y + cursize.y > maxHeight )
340 maxHeight = y + cursize.y ;
0b7a8cd3 341
bfe9ffbc
SC
342 tool->SetPosition( wxPoint( x , y ) ) ;
343
344 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
345 {
346 y += cursize.y ;
0b7a8cd3
GD
347 }
348 else
349 {
bfe9ffbc 350 x += cursize.x ;
0b7a8cd3 351 }
bfe9ffbc 352
eb22f2a6 353 node = node->GetNext();
7810c95b 354 }
0b7a8cd3
GD
355
356 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
7810c95b 357 {
0b7a8cd3
GD
358 if ( m_maxRows == 0 )
359 {
360 // if not set yet, only one row
361 SetRows(1);
362 }
363 maxWidth = tw ;
0b7a8cd3
GD
364 maxHeight += m_yMargin + kwxMacToolBarTopMargin;
365 m_maxHeight = maxHeight ;
7810c95b 366 }
0b7a8cd3
GD
367 else
368 {
bfe9ffbc 369 if ( GetToolsCount() > 0 && m_maxRows == 0 )
0b7a8cd3
GD
370 {
371 // if not set yet, have one column
bfe9ffbc 372 SetRows(GetToolsCount());
0b7a8cd3
GD
373 }
374 maxHeight = th ;
0b7a8cd3
GD
375 maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
376 m_maxWidth = maxWidth ;
377 }
378
facd6764 379 SetSize( maxWidth, maxHeight );
9f884528 380 InvalidateBestSize();
0b7a8cd3
GD
381
382 return TRUE;
e9576ca5
SC
383}
384
385void wxToolBar::SetToolBitmapSize(const wxSize& size)
386{
9aad97fd 387 m_defaultWidth = size.x+4; m_defaultHeight = size.y+4;
e9576ca5
SC
388}
389
e9576ca5
SC
390// The button size is bigger than the bitmap size
391wxSize wxToolBar::GetToolSize() const
392{
2f1ae414 393 return wxSize(m_defaultWidth + 4, m_defaultHeight + 4);
e9576ca5
SC
394}
395
37e2cb08 396void wxToolBar::SetRows(int nRows)
e9576ca5 397{
37e2cb08 398 if ( nRows == m_maxRows )
e9576ca5 399 {
37e2cb08
SC
400 // avoid resizing the frame uselessly
401 return;
e9576ca5 402 }
37e2cb08
SC
403
404 m_maxRows = nRows;
e9576ca5
SC
405}
406
c257d44d
SC
407void wxToolBar::MacSuperChangedPosition()
408{
c257d44d 409 wxWindow::MacSuperChangedPosition() ;
bfe9ffbc 410 Realize() ;
c257d44d
SC
411}
412
37e2cb08 413wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
e9576ca5 414{
affd2611 415 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
bfe9ffbc 416 while (node)
e044f600 417 {
bfe9ffbc
SC
418 wxToolBarTool *tool = (wxToolBarTool *)node->GetData() ;
419 wxRect2DInt r( tool->GetPosition() , tool->GetSize() ) ;
420 if ( r.Contains( wxPoint( x , y ) ) )
e044f600 421 {
bfe9ffbc 422 return tool;
e044f600 423 }
bfe9ffbc
SC
424
425 node = node->GetNext();
e044f600 426 }
37e2cb08
SC
427
428 return (wxToolBarToolBase *)NULL;
e9576ca5
SC
429}
430
2f1ae414
SC
431wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
432{
e044f600
RR
433 wxToolBarToolBase* tool = FindToolForPosition( pt.x , pt.y ) ;
434 if ( tool )
435 {
436 return tool->GetShortHelp() ;
437 }
427ff662 438 return wxEmptyString ;
2f1ae414
SC
439}
440
37e2cb08 441void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
e9576ca5 442{
e044f600
RR
443 if (!IsShown())
444 return ;
445
446 wxToolBarTool *tool = (wxToolBarTool *)t;
bfe9ffbc
SC
447 if ( tool->IsControl() )
448 {
449 tool->GetControl()->Enable( enable ) ;
450 }
451 else if ( tool->IsButton() )
452 {
453 if ( enable )
facd6764 454 UMAActivateControl( (ControlRef) tool->GetControlHandle() ) ;
bfe9ffbc 455 else
facd6764 456 UMADeactivateControl( (ControlRef) tool->GetControlHandle() ) ;
bfe9ffbc 457 }
e9576ca5
SC
458}
459
37e2cb08 460void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
e9576ca5 461{
e044f600
RR
462 if (!IsShown())
463 return ;
464
465 wxToolBarTool *tool = (wxToolBarTool *)t;
bfe9ffbc
SC
466 if ( tool->IsButton() )
467 {
facd6764 468 ::SetControl32BitValue( (ControlRef) tool->GetControlHandle() , toggle ) ;
bfe9ffbc 469 }
37e2cb08 470}
7c551d95 471
37e2cb08
SC
472bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos),
473 wxToolBarToolBase *tool)
474{
bfe9ffbc 475 // nothing special to do here - we relayout in Realize() later
37e2cb08 476 tool->Attach(this);
9f884528 477 InvalidateBestSize();
7c551d95 478
37e2cb08
SC
479 return TRUE;
480}
e9576ca5 481
5115c51a 482void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
37e2cb08 483{
5115c51a 484 wxFAIL_MSG( _T("not implemented") );
e9576ca5
SC
485}
486
bfe9ffbc 487bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
37e2cb08 488{
affd2611 489 wxToolBarToolsList::compatibility_iterator node;
bfe9ffbc
SC
490 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
491 {
492 wxToolBarToolBase *tool2 = node->GetData();
493 if ( tool2 == tool )
494 {
495 // let node point to the next node in the list
496 node = node->GetNext();
497
498 break;
499 }
500 }
501
502 wxSize sz = ((wxToolBarTool*)tool)->GetSize() ;
503
504 tool->Detach();
505
506 // and finally reposition all the controls after this one
507
508 for ( /* node -> first after deleted */ ; node; node = node->GetNext() )
509 {
510 wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
511 wxPoint pt = tool2->GetPosition() ;
512
513 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
514 {
515 pt.y -= sz.y ;
516 }
517 else
518 {
519 pt.x -= sz.x ;
520 }
521 tool2->SetPosition( pt ) ;
522 }
523
9f884528 524 InvalidateBestSize();
5115c51a 525 return TRUE ;
37e2cb08 526}
2f1ae414
SC
527
528void wxToolBar::OnPaint(wxPaintEvent& event)
529{
e40298d5
JS
530 wxPaintDC dc(this) ;
531 wxMacPortSetter helper(&dc) ;
facd6764
SC
532 int w, h ;
533 GetSize( &w , &h ) ;
e40298d5 534
1fd1922a 535 Rect toolbarrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) ,
facd6764
SC
536 dc.YLOG2DEVMAC(h) , dc.XLOG2DEVMAC(w) } ;
537/*
538 if( toolbarrect.left < 0 )
539 toolbarrect.left = 0 ;
540 if ( toolbarrect.top < 0 )
541 toolbarrect.top = 0 ;
542*/
1fd1922a 543 UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
785f5eaa 544
facd6764 545 event.Skip() ;
2f1ae414 546}
895f5af7 547
519cb848
SC
548#endif // wxUSE_TOOLBAR
549