]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/toolbar.cpp
Made all of the GNOME print support based
[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 ) ;
a2fe01c9 69
bfe9ffbc
SC
70 wxSize GetSize() const
71 {
72 if ( IsControl() )
73 {
74 return GetControl()->GetSize() ;
75 }
76 else if ( IsButton() )
77 {
78 return GetToolBar()->GetToolSize() ;
79 }
80 else
81 {
82 wxSize sz = GetToolBar()->GetToolSize() ;
83 sz.x /= 4 ;
84 sz.y /= 4 ;
85 return sz ;
86 }
87 }
88 wxPoint GetPosition() const
89 {
90 return wxPoint(m_x, m_y);
91 }
a2fe01c9 92 bool DoEnable( bool enable ) ;
bfe9ffbc
SC
93private :
94 void Init()
95 {
96 m_controlHandle = NULL ;
97 }
facd6764 98 ControlRef m_controlHandle ;
37e2cb08 99
bfe9ffbc
SC
100 wxCoord m_x;
101 wxCoord m_y;
37e2cb08
SC
102};
103
facd6764
SC
104static const EventTypeSpec eventList[] =
105{
106 { kEventClassControl , kEventControlHit } ,
107} ;
108
109static pascal OSStatus wxMacToolBarToolControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
110{
111 OSStatus result = eventNotHandledErr ;
112
113 wxMacCarbonEvent cEvent( event ) ;
114
115 ControlRef controlRef ;
116
117 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
118
119 switch( GetEventKind( event ) )
120 {
121 case kEventControlHit :
122 {
123 wxToolBarTool* tbartool = (wxToolBarTool*)data ;
124 if ( tbartool->CanBeToggled() )
125 {
214b9484 126 ((wxToolBar*)tbartool->GetToolBar())->ToggleTool(tbartool->GetId(), GetControl32BitValue((ControlRef)tbartool->GetControlHandle()));
facd6764
SC
127 }
128 ((wxToolBar*)tbartool->GetToolBar())->OnLeftClick( tbartool->GetId() , tbartool -> IsToggled() ) ;
facd6764
SC
129 result = noErr;
130 }
131 break ;
132 default :
133 break ;
134 }
135 return result ;
136}
137
138pascal OSStatus wxMacToolBarToolEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
139{
140 OSStatus result = eventNotHandledErr ;
141
142 switch ( GetEventClass( event ) )
143 {
144 case kEventClassControl :
145 result = wxMacToolBarToolControlEventHandler( handler, event, data ) ;
146 break ;
147 default :
148 break ;
149 }
150 return result ;
151}
152
153DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacToolBarToolEventHandler )
154
37e2cb08
SC
155// ============================================================================
156// implementation
157// ============================================================================
158
159// ----------------------------------------------------------------------------
160// wxToolBarTool
161// ----------------------------------------------------------------------------
162
a2fe01c9
SC
163bool wxToolBarTool::DoEnable(bool enable)
164{
165 if ( IsControl() )
166 {
167 GetControl()->Enable( enable ) ;
168 }
169 else if ( IsButton() )
170 {
171#if TARGET_API_MAC_OSX
172 if ( enable )
173 EnableControl( m_controlHandle ) ;
174 else
175 DisableControl( m_controlHandle ) ;
176#else
177 if ( enable )
178 ActivateControl( m_controlHandle ) ;
179 else
180 DeactivateControl( m_controlHandle ) ;
181#endif
182 }
183 return true ;
184}
bfe9ffbc
SC
185void wxToolBarTool::SetSize(const wxSize& size)
186{
187 if ( IsControl() )
188 {
189 GetControl()->SetSize( size ) ;
190 }
191}
192
193void wxToolBarTool::SetPosition(const wxPoint& position)
194{
195 m_x = position.x;
196 m_y = position.y;
197
198 if ( IsButton() )
199 {
200 int x , y ;
201 x = y = 0 ;
facd6764
SC
202 int mac_x = position.x ;
203 int mac_y = position.y ;
204#if !TARGET_API_MAC_OSX
205 WindowRef rootwindow = (WindowRef) GetToolBar()->MacGetTopLevelWindowRef() ;
bfe9ffbc 206 GetToolBar()->MacWindowToRootWindow( &x , &y ) ;
facd6764
SC
207 mac_x += x;
208 mac_y += y;
209#endif
bfe9ffbc
SC
210 Rect contrlRect ;
211 GetControlBounds( m_controlHandle , &contrlRect ) ;
212 int former_mac_x = contrlRect.left ;
213 int former_mac_y = contrlRect.top ;
80e3f464 214 GetToolBar()->GetToolSize() ;
bfe9ffbc
SC
215
216 if ( mac_x != former_mac_x || mac_y != former_mac_y )
217 {
bfe9ffbc 218 UMAMoveControl( m_controlHandle , mac_x , mac_y ) ;
bfe9ffbc
SC
219 }
220 }
221 else if ( IsControl() )
222 {
223 GetControl()->Move( position ) ;
224 }
225}
226
895f5af7
SC
227const short kwxMacToolBarToolDefaultWidth = 24 ;
228const short kwxMacToolBarToolDefaultHeight = 22 ;
229const short kwxMacToolBarTopMargin = 2 ;
230const short kwxMacToolBarLeftMargin = 2 ;
231
bfe9ffbc
SC
232wxToolBarTool::wxToolBarTool(wxToolBar *tbar,
233 int id,
234 const wxString& label,
235 const wxBitmap& bmpNormal,
236 const wxBitmap& bmpDisabled,
237 wxItemKind kind,
238 wxObject *clientData,
239 const wxString& shortHelp,
240 const wxString& longHelp)
241 : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
242 clientData, shortHelp, longHelp)
243{
f4e0be4f
RR
244 Init();
245
246 if (id == wxID_SEPARATOR) return;
bfe9ffbc 247
facd6764 248 WindowRef window = (WindowRef) tbar->MacGetTopLevelWindowRef() ;
bfe9ffbc
SC
249 wxSize toolSize = tbar->GetToolSize() ;
250 Rect toolrect = { 0, 0 , toolSize.y , toolSize.x } ;
251
252 ControlButtonContentInfo info ;
253 wxMacCreateBitmapButton( &info , GetNormalBitmap() ) ;
254
255 SInt16 behaviour = kControlBehaviorOffsetContents ;
256 if ( CanBeToggled() )
257 behaviour += kControlBehaviorToggles ;
bfe9ffbc 258
4c37f124
SC
259 CreateBevelButtonControl( window , &toolrect , CFSTR("") , kControlBevelButtonNormalBevel , behaviour , &info ,
260 0 , 0 , 0 , &m_controlHandle ) ;
261
facd6764
SC
262 InstallControlEventHandler( (ControlRef) m_controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
263 GetEventTypeCount(eventList), eventList, this,NULL);
4c37f124 264
bfe9ffbc 265 UMAShowControl( m_controlHandle ) ;
4c37f124 266
bfe9ffbc 267 if ( CanBeToggled() && IsToggled() )
bfe9ffbc 268 ::SetControl32BitValue( m_controlHandle , 1 ) ;
bfe9ffbc 269 else
bfe9ffbc 270 ::SetControl32BitValue( m_controlHandle , 0 ) ;
bfe9ffbc 271
facd6764 272 ControlRef container = (ControlRef) tbar->GetHandle() ;
bfe9ffbc
SC
273 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
274 ::EmbedControl( m_controlHandle , container ) ;
275}
276
2f1ae414 277
37e2cb08 278wxToolBarToolBase *wxToolBar::CreateTool(int id,
27e2d606
GD
279 const wxString& label,
280 const wxBitmap& bmpNormal,
281 const wxBitmap& bmpDisabled,
282 wxItemKind kind,
37e2cb08 283 wxObject *clientData,
27e2d606
GD
284 const wxString& shortHelp,
285 const wxString& longHelp)
37e2cb08 286{
27e2d606
GD
287 return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
288 clientData, shortHelp, longHelp);
37e2cb08
SC
289}
290
291wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
292{
293 return new wxToolBarTool(this, control);
294}
295
37e2cb08 296void wxToolBar::Init()
e9576ca5 297{
e40298d5
JS
298 m_maxWidth = -1;
299 m_maxHeight = -1;
300 m_defaultWidth = kwxMacToolBarToolDefaultWidth;
301 m_defaultHeight = kwxMacToolBarToolDefaultHeight;
e9576ca5
SC
302}
303
304bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
305 long style, const wxString& name)
e40298d5 306{
facd6764
SC
307 if ( !wxToolBarBase::Create( parent , id , pos , size , style ) )
308 return FALSE ;
e40298d5
JS
309
310 return TRUE;
e9576ca5
SC
311}
312
313wxToolBar::~wxToolBar()
bfe9ffbc 314{
7810c95b
SC
315 // we must refresh the frame size when the toolbar is deleted but the frame
316 // is not - otherwise toolbar leaves a hole in the place it used to occupy
e9576ca5
SC
317}
318
37e2cb08 319bool wxToolBar::Realize()
e9576ca5 320{
eb22f2a6 321 if (m_tools.GetCount() == 0)
0b7a8cd3
GD
322 return FALSE;
323
bfe9ffbc
SC
324 int x = m_xMargin + kwxMacToolBarLeftMargin ;
325 int y = m_yMargin + kwxMacToolBarTopMargin ;
0b7a8cd3 326
7c551d95
SC
327 int tw, th;
328 GetSize(& tw, & th);
895f5af7
SC
329
330 int maxWidth = 0 ;
331 int maxHeight = 0 ;
332
bfe9ffbc
SC
333 int maxToolWidth = 0;
334 int maxToolHeight = 0;
335
336 // Find the maximum tool width and height
affd2611 337 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
bfe9ffbc
SC
338 while ( node )
339 {
340 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
341 wxSize sz = tool->GetSize() ;
342
343 if ( sz.x > maxToolWidth )
344 maxToolWidth = sz.x ;
345 if (sz.y> maxToolHeight)
346 maxToolHeight = sz.y;
347
348 node = node->GetNext();
349 }
350
214b9484 351 bool lastWasRadio = FALSE;
bfe9ffbc 352 node = m_tools.GetFirst();
0b7a8cd3 353 while (node)
7810c95b 354 {
eb22f2a6 355 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
bfe9ffbc 356 wxSize cursize = tool->GetSize() ;
0b7a8cd3 357
214b9484
RD
358 bool isRadio = FALSE;
359
360 if ( tool->IsButton() && tool->GetKind() == wxITEM_RADIO )
361 {
362 if ( !lastWasRadio )
363 {
364 if (tool->Toggle(true))
365 {
366 DoToggleTool(tool, true);
367 }
368 }
369 isRadio = TRUE;
370 }
371 else
372 {
373 isRadio = FALSE;
374 }
375 lastWasRadio = isRadio;
376
bfe9ffbc
SC
377 // for the moment we just do a single row/column alignement
378 if ( x + cursize.x > maxWidth )
379 maxWidth = x + cursize.x ;
380 if ( y + cursize.y > maxHeight )
381 maxHeight = y + cursize.y ;
0b7a8cd3 382
bfe9ffbc
SC
383 tool->SetPosition( wxPoint( x , y ) ) ;
384
385 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
386 {
387 y += cursize.y ;
0b7a8cd3
GD
388 }
389 else
390 {
bfe9ffbc 391 x += cursize.x ;
0b7a8cd3 392 }
bfe9ffbc 393
eb22f2a6 394 node = node->GetNext();
7810c95b 395 }
0b7a8cd3
GD
396
397 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
7810c95b 398 {
0b7a8cd3
GD
399 if ( m_maxRows == 0 )
400 {
401 // if not set yet, only one row
402 SetRows(1);
403 }
90d3f91a 404 m_minWidth = maxWidth;
0b7a8cd3 405 maxWidth = tw ;
0b7a8cd3 406 maxHeight += m_yMargin + kwxMacToolBarTopMargin;
90d3f91a 407 m_minHeight = m_maxHeight = maxHeight ;
7810c95b 408 }
0b7a8cd3
GD
409 else
410 {
bfe9ffbc 411 if ( GetToolsCount() > 0 && m_maxRows == 0 )
0b7a8cd3
GD
412 {
413 // if not set yet, have one column
bfe9ffbc 414 SetRows(GetToolsCount());
0b7a8cd3 415 }
90d3f91a 416 m_minHeight = maxHeight;
0b7a8cd3 417 maxHeight = th ;
0b7a8cd3 418 maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
90d3f91a 419 m_minWidth = m_maxWidth = maxWidth ;
0b7a8cd3
GD
420 }
421
facd6764 422 SetSize( maxWidth, maxHeight );
9f884528 423 InvalidateBestSize();
0b7a8cd3
GD
424
425 return TRUE;
e9576ca5
SC
426}
427
428void wxToolBar::SetToolBitmapSize(const wxSize& size)
429{
9aad97fd 430 m_defaultWidth = size.x+4; m_defaultHeight = size.y+4;
e9576ca5
SC
431}
432
e9576ca5
SC
433// The button size is bigger than the bitmap size
434wxSize wxToolBar::GetToolSize() const
435{
2f1ae414 436 return wxSize(m_defaultWidth + 4, m_defaultHeight + 4);
e9576ca5
SC
437}
438
37e2cb08 439void wxToolBar::SetRows(int nRows)
e9576ca5 440{
37e2cb08 441 if ( nRows == m_maxRows )
e9576ca5 442 {
37e2cb08
SC
443 // avoid resizing the frame uselessly
444 return;
e9576ca5 445 }
37e2cb08
SC
446
447 m_maxRows = nRows;
e9576ca5
SC
448}
449
c257d44d
SC
450void wxToolBar::MacSuperChangedPosition()
451{
c257d44d 452 wxWindow::MacSuperChangedPosition() ;
bfe9ffbc 453 Realize() ;
c257d44d
SC
454}
455
37e2cb08 456wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
e9576ca5 457{
affd2611 458 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
bfe9ffbc 459 while (node)
e044f600 460 {
bfe9ffbc
SC
461 wxToolBarTool *tool = (wxToolBarTool *)node->GetData() ;
462 wxRect2DInt r( tool->GetPosition() , tool->GetSize() ) ;
463 if ( r.Contains( wxPoint( x , y ) ) )
e044f600 464 {
bfe9ffbc 465 return tool;
e044f600 466 }
bfe9ffbc
SC
467
468 node = node->GetNext();
e044f600 469 }
37e2cb08
SC
470
471 return (wxToolBarToolBase *)NULL;
e9576ca5
SC
472}
473
2f1ae414
SC
474wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
475{
e044f600
RR
476 wxToolBarToolBase* tool = FindToolForPosition( pt.x , pt.y ) ;
477 if ( tool )
478 {
479 return tool->GetShortHelp() ;
480 }
427ff662 481 return wxEmptyString ;
2f1ae414
SC
482}
483
37e2cb08 484void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
e9576ca5 485{
a2fe01c9 486 ((wxToolBarTool*)t)->DoEnable( enable ) ;
e9576ca5
SC
487}
488
37e2cb08 489void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
e9576ca5 490{
e044f600 491 wxToolBarTool *tool = (wxToolBarTool *)t;
bfe9ffbc
SC
492 if ( tool->IsButton() )
493 {
facd6764 494 ::SetControl32BitValue( (ControlRef) tool->GetControlHandle() , toggle ) ;
bfe9ffbc 495 }
37e2cb08 496}
7c551d95 497
37e2cb08
SC
498bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos),
499 wxToolBarToolBase *tool)
500{
bfe9ffbc 501 // nothing special to do here - we relayout in Realize() later
37e2cb08 502 tool->Attach(this);
9f884528 503 InvalidateBestSize();
7c551d95 504
37e2cb08
SC
505 return TRUE;
506}
e9576ca5 507
5115c51a 508void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
37e2cb08 509{
5115c51a 510 wxFAIL_MSG( _T("not implemented") );
e9576ca5
SC
511}
512
bfe9ffbc 513bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
37e2cb08 514{
affd2611 515 wxToolBarToolsList::compatibility_iterator node;
bfe9ffbc
SC
516 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
517 {
518 wxToolBarToolBase *tool2 = node->GetData();
519 if ( tool2 == tool )
520 {
521 // let node point to the next node in the list
522 node = node->GetNext();
523
524 break;
525 }
526 }
527
528 wxSize sz = ((wxToolBarTool*)tool)->GetSize() ;
529
530 tool->Detach();
531
532 // and finally reposition all the controls after this one
533
534 for ( /* node -> first after deleted */ ; node; node = node->GetNext() )
535 {
536 wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
537 wxPoint pt = tool2->GetPosition() ;
538
539 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
540 {
541 pt.y -= sz.y ;
542 }
543 else
544 {
545 pt.x -= sz.x ;
546 }
547 tool2->SetPosition( pt ) ;
548 }
549
9f884528 550 InvalidateBestSize();
5115c51a 551 return TRUE ;
37e2cb08 552}
2f1ae414
SC
553
554void wxToolBar::OnPaint(wxPaintEvent& event)
555{
e40298d5
JS
556 wxPaintDC dc(this) ;
557 wxMacPortSetter helper(&dc) ;
facd6764
SC
558 int w, h ;
559 GetSize( &w , &h ) ;
e40298d5 560
1fd1922a 561 Rect toolbarrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) ,
facd6764
SC
562 dc.YLOG2DEVMAC(h) , dc.XLOG2DEVMAC(w) } ;
563/*
564 if( toolbarrect.left < 0 )
565 toolbarrect.left = 0 ;
566 if ( toolbarrect.top < 0 )
567 toolbarrect.top = 0 ;
568*/
01ffa8f7
SC
569 if ( !MacGetTopLevelWindow()->MacGetMetalAppearance() )
570 {
571 UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
572 }
573 else
574 {
575#if TARGET_API_MAC_OSX
576#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
577 if ( UMAGetSystemVersion() >= 0x1030 )
578 {
579 HIRect hiToolbarrect = CGRectMake( dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) ,
580 dc.YLOG2DEVREL(h) , dc.XLOG2DEVREL(w) );
581 CGContextRef cgContext ;
582 Rect bounds ;
583 GetPortBounds( (CGrafPtr) dc.m_macPort , &bounds ) ;
584 QDBeginCGContext( (CGrafPtr) dc.m_macPort , &cgContext ) ;
585 CGContextTranslateCTM( cgContext , 0 , bounds.bottom - bounds.top ) ;
586 CGContextScaleCTM( cgContext , 1 , -1 ) ;
785f5eaa 587
01ffa8f7
SC
588 {
589 HIThemeBackgroundDrawInfo drawInfo ;
590 drawInfo.version = 0 ;
591 drawInfo.state = kThemeStateActive ;
592 drawInfo.kind = kThemeBackgroundMetal ;
593 HIThemeApplyBackground( &hiToolbarrect, &drawInfo , cgContext,kHIThemeOrientationNormal) ;
594 }
595 QDEndCGContext( (CGrafPtr) dc.m_macPort , &cgContext ) ;
596 }
597 else
598#endif
599 {
600 UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
601 }
602#endif
603 }
facd6764 604 event.Skip() ;
2f1ae414 605}
895f5af7 606
519cb848
SC
607#endif // wxUSE_TOOLBAR
608