]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/toolbar.cpp
support undo patch applied
[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
JS
8// Copyright: (c) Stefan Csomor
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
12ed316d 26IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
e9576ca5
SC
27
28BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
e044f600
RR
29 EVT_MOUSE_EVENTS( wxToolBar::OnMouse )
30 EVT_PAINT( wxToolBar::OnPaint )
e9576ca5 31END_EVENT_TABLE()
2f1ae414 32#endif
e9576ca5 33
d497dca4 34#include "wx/mac/uma.h"
bfe9ffbc 35#include "wx/geometry.h"
37e2cb08
SC
36// ----------------------------------------------------------------------------
37// private classes
38// ----------------------------------------------------------------------------
39
40class wxToolBarTool : public wxToolBarToolBase
41{
42public:
43 wxToolBarTool(wxToolBar *tbar,
44 int id,
27e2d606
GD
45 const wxString& label,
46 const wxBitmap& bmpNormal,
47 const wxBitmap& bmpDisabled,
48 wxItemKind kind,
37e2cb08 49 wxObject *clientData,
27e2d606 50 const wxString& shortHelp,
bfe9ffbc
SC
51 const wxString& longHelp) ;
52
37e2cb08
SC
53 wxToolBarTool(wxToolBar *tbar, wxControl *control)
54 : wxToolBarToolBase(tbar, control)
55 {
bfe9ffbc 56 Init() ;
37e2cb08 57 }
bfe9ffbc
SC
58
59 ~wxToolBarTool()
60 {
61 if ( m_controlHandle )
62 DisposeControl( m_controlHandle ) ;
63 }
64
65 ControlHandle GetControlHandle() { return m_controlHandle ; }
66 void SetControlHandle( ControlHandle handle ) { m_controlHandle = handle ; }
37e2cb08 67
bfe9ffbc
SC
68 void SetSize(const wxSize& size) ;
69 void SetPosition( const wxPoint& position ) ;
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 }
92private :
93 void Init()
94 {
95 m_controlHandle = NULL ;
96 }
97 ControlHandle m_controlHandle ;
37e2cb08 98
bfe9ffbc
SC
99 wxCoord m_x;
100 wxCoord m_y;
37e2cb08
SC
101};
102
37e2cb08
SC
103// ============================================================================
104// implementation
105// ============================================================================
106
107// ----------------------------------------------------------------------------
108// wxToolBarTool
109// ----------------------------------------------------------------------------
110
bfe9ffbc
SC
111void wxToolBarTool::SetSize(const wxSize& size)
112{
113 if ( IsControl() )
114 {
115 GetControl()->SetSize( size ) ;
116 }
117}
118
119void wxToolBarTool::SetPosition(const wxPoint& position)
120{
121 m_x = position.x;
122 m_y = position.y;
123
124 if ( IsButton() )
125 {
126 int x , y ;
127 x = y = 0 ;
128 WindowRef rootwindow = (WindowRef) GetToolBar()->MacGetRootWindow() ;
129 GetToolBar()->MacWindowToRootWindow( &x , &y ) ;
130 int mac_x = x + position.x ;
131 int mac_y = y + position.y ;
132
133
134 Rect contrlRect ;
135 GetControlBounds( m_controlHandle , &contrlRect ) ;
136 int former_mac_x = contrlRect.left ;
137 int former_mac_y = contrlRect.top ;
138 wxSize sz = GetToolBar()->GetToolSize() ;
139
140 if ( mac_x != former_mac_x || mac_y != former_mac_y )
141 {
142 {
143 Rect inval = { former_mac_y , former_mac_x , former_mac_y + sz.y , former_mac_x + sz.x } ;
144 InvalWindowRect( rootwindow , &inval ) ;
145 }
146 UMAMoveControl( m_controlHandle , mac_x , mac_y ) ;
147 {
148 Rect inval = { mac_y , mac_x , mac_y + sz.y , mac_x + sz.x } ;
149 InvalWindowRect( rootwindow , &inval ) ;
150 }
151 }
152 }
153 else if ( IsControl() )
154 {
155 GetControl()->Move( position ) ;
156 }
157}
158
895f5af7
SC
159const short kwxMacToolBarToolDefaultWidth = 24 ;
160const short kwxMacToolBarToolDefaultHeight = 22 ;
161const short kwxMacToolBarTopMargin = 2 ;
162const short kwxMacToolBarLeftMargin = 2 ;
163
bfe9ffbc
SC
164wxToolBarTool::wxToolBarTool(wxToolBar *tbar,
165 int id,
166 const wxString& label,
167 const wxBitmap& bmpNormal,
168 const wxBitmap& bmpDisabled,
169 wxItemKind kind,
170 wxObject *clientData,
171 const wxString& shortHelp,
172 const wxString& longHelp)
173 : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
174 clientData, shortHelp, longHelp)
175{
176 Init() ;
177
178 WindowRef window = (WindowRef) tbar->MacGetRootWindow() ;
179 wxSize toolSize = tbar->GetToolSize() ;
180 Rect toolrect = { 0, 0 , toolSize.y , toolSize.x } ;
181
182 ControlButtonContentInfo info ;
183 wxMacCreateBitmapButton( &info , GetNormalBitmap() ) ;
184
185 SInt16 behaviour = kControlBehaviorOffsetContents ;
186 if ( CanBeToggled() )
187 behaviour += kControlBehaviorToggles ;
188
189 if ( info.contentType != kControlNoContent )
190 {
191 m_controlHandle = ::NewControl( window , &toolrect , "\p" , false , 0 ,
192 behaviour + info.contentType , 0 , kControlBevelButtonNormalBevelProc , (long) this ) ;
193
194 ::SetControlData( m_controlHandle , kControlButtonPart , kControlBevelButtonContentTag , sizeof(info) , (char*) &info ) ;
195 }
196 else
197 {
198 m_controlHandle = ::NewControl( window , &toolrect , "\p" , false , 0 ,
199 behaviour , 0 , kControlBevelButtonNormalBevelProc , (long) this ) ;
200 }
201 UMAShowControl( m_controlHandle ) ;
202 if ( !IsEnabled() )
203 {
204 UMADeactivateControl( m_controlHandle ) ;
205 }
206 if ( CanBeToggled() && IsToggled() )
207 {
208 ::SetControl32BitValue( m_controlHandle , 1 ) ;
209 }
210 else
211 {
212 ::SetControl32BitValue( m_controlHandle , 0 ) ;
213 }
214
215 ControlHandle container = (ControlHandle) tbar->MacGetContainerForEmbedding() ;
216 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
217 ::EmbedControl( m_controlHandle , container ) ;
218}
219
2f1ae414 220
37e2cb08 221wxToolBarToolBase *wxToolBar::CreateTool(int id,
27e2d606
GD
222 const wxString& label,
223 const wxBitmap& bmpNormal,
224 const wxBitmap& bmpDisabled,
225 wxItemKind kind,
37e2cb08 226 wxObject *clientData,
27e2d606
GD
227 const wxString& shortHelp,
228 const wxString& longHelp)
37e2cb08 229{
27e2d606
GD
230 return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
231 clientData, shortHelp, longHelp);
37e2cb08
SC
232}
233
234wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
235{
236 return new wxToolBarTool(this, control);
237}
238
37e2cb08 239void wxToolBar::Init()
e9576ca5 240{
e40298d5
JS
241 m_maxWidth = -1;
242 m_maxHeight = -1;
243 m_defaultWidth = kwxMacToolBarToolDefaultWidth;
244 m_defaultHeight = kwxMacToolBarToolDefaultHeight;
e9576ca5
SC
245}
246
247bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
248 long style, const wxString& name)
e40298d5
JS
249{
250 int x = pos.x;
251 int y = pos.y;
252 int width = size.x;
253 int height = size.y;
254
255 if (width <= 0)
256 width = 100;
257 if (height <= 0)
258 height = 30;
259 if (x < 0)
260 x = 0;
261 if (y < 0)
262 y = 0;
263
264 SetName(name);
265
266 m_windowStyle = style;
267 parent->AddChild(this);
268
269 m_backgroundColour = parent->GetBackgroundColour() ;
270 m_foregroundColour = parent->GetForegroundColour() ;
271
272 if (id == -1)
273 m_windowId = NewControlId();
274 else
275 m_windowId = id;
276
277 {
278 m_width = size.x ;
279 m_height = size.y ;
280 int x = pos.x ;
281 int y = pos.y ;
282 AdjustForParentClientOrigin(x, y, wxSIZE_USE_EXISTING);
283 m_x = x ;
284 m_y = y ;
285 }
286
287 return TRUE;
e9576ca5
SC
288}
289
290wxToolBar::~wxToolBar()
bfe9ffbc 291{
7810c95b
SC
292 // we must refresh the frame size when the toolbar is deleted but the frame
293 // is not - otherwise toolbar leaves a hole in the place it used to occupy
e9576ca5
SC
294}
295
37e2cb08 296bool wxToolBar::Realize()
e9576ca5 297{
eb22f2a6 298 if (m_tools.GetCount() == 0)
0b7a8cd3
GD
299 return FALSE;
300
bfe9ffbc
SC
301 int x = m_xMargin + kwxMacToolBarLeftMargin ;
302 int y = m_yMargin + kwxMacToolBarTopMargin ;
0b7a8cd3 303
7c551d95
SC
304 int tw, th;
305 GetSize(& tw, & th);
895f5af7
SC
306
307 int maxWidth = 0 ;
308 int maxHeight = 0 ;
309
bfe9ffbc
SC
310 int maxToolWidth = 0;
311 int maxToolHeight = 0;
312
313 // Find the maximum tool width and height
314 wxToolBarToolsList::Node *node = m_tools.GetFirst();
315 while ( node )
316 {
317 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
318 wxSize sz = tool->GetSize() ;
319
320 if ( sz.x > maxToolWidth )
321 maxToolWidth = sz.x ;
322 if (sz.y> maxToolHeight)
323 maxToolHeight = sz.y;
324
325 node = node->GetNext();
326 }
327
bfe9ffbc 328 node = m_tools.GetFirst();
0b7a8cd3 329 while (node)
7810c95b 330 {
eb22f2a6 331 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
bfe9ffbc 332 wxSize cursize = tool->GetSize() ;
0b7a8cd3 333
bfe9ffbc
SC
334 // for the moment we just do a single row/column alignement
335 if ( x + cursize.x > maxWidth )
336 maxWidth = x + cursize.x ;
337 if ( y + cursize.y > maxHeight )
338 maxHeight = y + cursize.y ;
0b7a8cd3 339
bfe9ffbc
SC
340 tool->SetPosition( wxPoint( x , y ) ) ;
341
342 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
343 {
344 y += cursize.y ;
0b7a8cd3
GD
345 }
346 else
347 {
bfe9ffbc 348 x += cursize.x ;
0b7a8cd3 349 }
bfe9ffbc 350
eb22f2a6 351 node = node->GetNext();
7810c95b 352 }
0b7a8cd3
GD
353
354 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
7810c95b 355 {
0b7a8cd3
GD
356 if ( m_maxRows == 0 )
357 {
358 // if not set yet, only one row
359 SetRows(1);
360 }
361 maxWidth = tw ;
0b7a8cd3
GD
362 maxHeight += m_yMargin + kwxMacToolBarTopMargin;
363 m_maxHeight = maxHeight ;
7810c95b 364 }
0b7a8cd3
GD
365 else
366 {
bfe9ffbc 367 if ( GetToolsCount() > 0 && m_maxRows == 0 )
0b7a8cd3
GD
368 {
369 // if not set yet, have one column
bfe9ffbc 370 SetRows(GetToolsCount());
0b7a8cd3
GD
371 }
372 maxHeight = th ;
0b7a8cd3
GD
373 maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
374 m_maxWidth = maxWidth ;
375 }
376
377 SetSize(maxWidth, maxHeight);
378
379 return TRUE;
e9576ca5
SC
380}
381
382void wxToolBar::SetToolBitmapSize(const wxSize& size)
383{
9aad97fd 384 m_defaultWidth = size.x+4; m_defaultHeight = size.y+4;
e9576ca5
SC
385}
386
e9576ca5
SC
387// The button size is bigger than the bitmap size
388wxSize wxToolBar::GetToolSize() const
389{
2f1ae414 390 return wxSize(m_defaultWidth + 4, m_defaultHeight + 4);
e9576ca5
SC
391}
392
76a5e5d2 393void wxToolBar::MacHandleControlClick( WXWidget control , wxInt16 controlpart )
519cb848 394{
bfe9ffbc
SC
395 wxToolBarToolsList::Node *node;
396 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
e044f600 397 {
bfe9ffbc
SC
398 wxToolBarTool* tool = (wxToolBarTool*) node->GetData() ;
399 if ( tool->IsButton() )
e044f600 400 {
bfe9ffbc
SC
401 if( tool->GetControlHandle() == control )
402 {
403 if ( tool->CanBeToggled() )
404 {
405 tool->Toggle( GetControl32BitValue( (ControlHandle) control ) ) ;
406 }
407 OnLeftClick( tool->GetId() , tool -> IsToggled() ) ;
408 break ;
409 }
e044f600
RR
410 }
411 }
519cb848
SC
412}
413
37e2cb08 414void wxToolBar::SetRows(int nRows)
e9576ca5 415{
37e2cb08 416 if ( nRows == m_maxRows )
e9576ca5 417 {
37e2cb08
SC
418 // avoid resizing the frame uselessly
419 return;
e9576ca5 420 }
37e2cb08
SC
421
422 m_maxRows = nRows;
e9576ca5
SC
423}
424
c257d44d
SC
425void wxToolBar::MacSuperChangedPosition()
426{
c257d44d 427 wxWindow::MacSuperChangedPosition() ;
bfe9ffbc 428 Realize() ;
c257d44d
SC
429}
430
37e2cb08 431wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
e9576ca5 432{
bfe9ffbc
SC
433 wxToolBarToolsList::Node *node = m_tools.GetFirst();
434 while (node)
e044f600 435 {
bfe9ffbc
SC
436 wxToolBarTool *tool = (wxToolBarTool *)node->GetData() ;
437 wxRect2DInt r( tool->GetPosition() , tool->GetSize() ) ;
438 if ( r.Contains( wxPoint( x , y ) ) )
e044f600 439 {
bfe9ffbc 440 return tool;
e044f600 441 }
bfe9ffbc
SC
442
443 node = node->GetNext();
e044f600 444 }
37e2cb08
SC
445
446 return (wxToolBarToolBase *)NULL;
e9576ca5
SC
447}
448
2f1ae414
SC
449wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
450{
e044f600
RR
451 wxToolBarToolBase* tool = FindToolForPosition( pt.x , pt.y ) ;
452 if ( tool )
453 {
454 return tool->GetShortHelp() ;
455 }
427ff662 456 return wxEmptyString ;
2f1ae414
SC
457}
458
37e2cb08 459void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
e9576ca5 460{
e044f600
RR
461 if (!IsShown())
462 return ;
463
464 wxToolBarTool *tool = (wxToolBarTool *)t;
bfe9ffbc
SC
465 if ( tool->IsControl() )
466 {
467 tool->GetControl()->Enable( enable ) ;
468 }
469 else if ( tool->IsButton() )
470 {
471 if ( enable )
472 UMAActivateControl( tool->GetControlHandle() ) ;
473 else
474 UMADeactivateControl( tool->GetControlHandle() ) ;
475 }
e9576ca5
SC
476}
477
37e2cb08 478void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
e9576ca5 479{
e044f600
RR
480 if (!IsShown())
481 return ;
482
483 wxToolBarTool *tool = (wxToolBarTool *)t;
bfe9ffbc
SC
484 if ( tool->IsButton() )
485 {
486 ::SetControl32BitValue( tool->GetControlHandle() , toggle ) ;
487 }
37e2cb08 488}
7c551d95 489
37e2cb08
SC
490bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos),
491 wxToolBarToolBase *tool)
492{
bfe9ffbc 493 // nothing special to do here - we relayout in Realize() later
37e2cb08 494 tool->Attach(this);
7c551d95 495
37e2cb08
SC
496 return TRUE;
497}
e9576ca5 498
5115c51a 499void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
37e2cb08 500{
5115c51a 501 wxFAIL_MSG( _T("not implemented") );
e9576ca5
SC
502}
503
bfe9ffbc 504bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
37e2cb08 505{
bfe9ffbc
SC
506 wxToolBarToolsList::Node *node;
507 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
508 {
509 wxToolBarToolBase *tool2 = node->GetData();
510 if ( tool2 == tool )
511 {
512 // let node point to the next node in the list
513 node = node->GetNext();
514
515 break;
516 }
517 }
518
519 wxSize sz = ((wxToolBarTool*)tool)->GetSize() ;
520
521 tool->Detach();
522
523 // and finally reposition all the controls after this one
524
525 for ( /* node -> first after deleted */ ; node; node = node->GetNext() )
526 {
527 wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
528 wxPoint pt = tool2->GetPosition() ;
529
530 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
531 {
532 pt.y -= sz.y ;
533 }
534 else
535 {
536 pt.x -= sz.x ;
537 }
538 tool2->SetPosition( pt ) ;
539 }
540
5115c51a 541 return TRUE ;
37e2cb08 542}
2f1ae414
SC
543
544void wxToolBar::OnPaint(wxPaintEvent& event)
545{
e40298d5
JS
546 wxPaintDC dc(this) ;
547 wxMacPortSetter helper(&dc) ;
548
1fd1922a
RR
549 Rect toolbarrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) ,
550 dc.YLOG2DEVMAC(m_height) , dc.XLOG2DEVMAC(m_width) } ;
551 UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
552 {
bfe9ffbc
SC
553 wxToolBarToolsList::Node *node;
554 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
1fd1922a 555 {
bfe9ffbc
SC
556 wxToolBarTool* tool = (wxToolBarTool*) node->GetData() ;
557 if ( tool->IsButton() )
1fd1922a 558 {
bfe9ffbc 559 UMADrawControl( tool->GetControlHandle() ) ;
1fd1922a
RR
560 }
561 }
562 }
2f1ae414 563}
895f5af7 564
2f1ae414
SC
565void wxToolBar::OnMouse( wxMouseEvent &event )
566{
1fd1922a
RR
567 if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK )
568 {
569
570 int x = event.m_x ;
571 int y = event.m_y ;
572
573 MacClientToRootWindow( &x , &y ) ;
574
575 ControlHandle control ;
576 Point localwhere ;
577 SInt16 controlpart ;
578 WindowRef window = (WindowRef) MacGetRootWindow() ;
579
580 localwhere.h = x ;
581 localwhere.v = y ;
582
583 short modifiers = 0;
584
585 if ( !event.m_leftDown && !event.m_rightDown )
586 modifiers |= btnState ;
587
588 if ( event.m_shiftDown )
589 modifiers |= shiftKey ;
590
591 if ( event.m_controlDown )
592 modifiers |= controlKey ;
593
594 if ( event.m_altDown )
595 modifiers |= optionKey ;
596
597 if ( event.m_metaDown )
598 modifiers |= cmdKey ;
599
600 controlpart = ::FindControl( localwhere , window , &control ) ;
601 {
602 if ( control && ::IsControlActive( control ) )
603 {
604 {
605 if ( controlpart == kControlIndicatorPart && !UMAHasAppearance() )
606 controlpart = ::HandleControlClick( control , localwhere , modifiers , (ControlActionUPP) NULL ) ;
607 else
608 controlpart = ::HandleControlClick( control , localwhere , modifiers , (ControlActionUPP) -1 ) ;
609 wxTheApp->s_lastMouseDown = 0 ;
610 if ( controlpart && ! ( ( UMAHasAppearance() || (controlpart != kControlIndicatorPart) )
611 && (IsKindOf( CLASSINFO( wxScrollBar ) ) ) ) ) // otherwise we will get the event twice
612 {
613 MacHandleControlClick( control , controlpart ) ;
614 }
615 }
616 }
617 }
618 }
2f1ae414
SC
619}
620
519cb848
SC
621#endif // wxUSE_TOOLBAR
622