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