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