]> git.saurik.com Git - wxWidgets.git/blame - src/mac/toolbar.cpp
OS/2 fix in setdrive.
[wxWidgets.git] / src / mac / toolbar.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: toolbar.cpp
3// Purpose: wxToolBar
4// Author: AUTHOR
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
2f1ae414 8// Copyright: (c) AUTHORy
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"
e9576ca5 22
2f1ae414 23#if !USE_SHARED_LIBRARY
12ed316d 24IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
e9576ca5
SC
25
26BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
2f1ae414
SC
27 EVT_MOUSE_EVENTS( wxToolBar::OnMouse )
28 EVT_PAINT( wxToolBar::OnPaint )
e9576ca5 29END_EVENT_TABLE()
2f1ae414 30#endif
e9576ca5 31
519cb848
SC
32#include <wx/mac/uma.h>
33
37e2cb08
SC
34// ----------------------------------------------------------------------------
35// private classes
36// ----------------------------------------------------------------------------
37
38class wxToolBarTool : public wxToolBarToolBase
39{
40public:
41 wxToolBarTool(wxToolBar *tbar,
42 int id,
43 const wxBitmap& bitmap1,
44 const wxBitmap& bitmap2,
45 bool toggle,
46 wxObject *clientData,
47 const wxString& shortHelpString,
48 const wxString& longHelpString)
49 : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle,
50 clientData, shortHelpString, longHelpString)
51 {
52 m_nSepCount = 0;
2f1ae414 53 m_index = -1 ;
37e2cb08
SC
54 }
55
56 wxToolBarTool(wxToolBar *tbar, wxControl *control)
57 : wxToolBarToolBase(tbar, control)
58 {
59 m_nSepCount = 1;
2f1ae414 60 m_index = -1 ;
37e2cb08
SC
61 }
62
63 // set/get the number of separators which we use to cover the space used by
64 // a control in the toolbar
65 void SetSeparatorsCount(size_t count) { m_nSepCount = count; }
66 size_t GetSeparatorsCount() const { return m_nSepCount; }
67
68 int m_index ;
69private:
70 size_t m_nSepCount;
71};
72
73
74// ============================================================================
75// implementation
76// ============================================================================
77
78// ----------------------------------------------------------------------------
79// wxToolBarTool
80// ----------------------------------------------------------------------------
81
895f5af7
SC
82const short kwxMacToolBarToolDefaultWidth = 24 ;
83const short kwxMacToolBarToolDefaultHeight = 22 ;
84const short kwxMacToolBarTopMargin = 2 ;
85const short kwxMacToolBarLeftMargin = 2 ;
86
2f1ae414 87
37e2cb08
SC
88wxToolBarToolBase *wxToolBar::CreateTool(int id,
89 const wxBitmap& bitmap1,
90 const wxBitmap& bitmap2,
91 bool toggle,
92 wxObject *clientData,
93 const wxString& shortHelpString,
94 const wxString& longHelpString)
95{
96 return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle,
97 clientData, shortHelpString, longHelpString);
98}
99
100wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
101{
102 return new wxToolBarTool(this, control);
103}
104
37e2cb08 105void wxToolBar::Init()
e9576ca5
SC
106{
107 m_maxWidth = -1;
108 m_maxHeight = -1;
895f5af7
SC
109 m_defaultWidth = kwxMacToolBarToolDefaultWidth;
110 m_defaultHeight = kwxMacToolBarToolDefaultHeight;
e9576ca5
SC
111}
112
113bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
114 long style, const wxString& name)
115{
e9576ca5 116
519cb848
SC
117 int x = pos.x;
118 int y = pos.y;
119 int width = size.x;
120 int height = size.y;
e9576ca5 121
519cb848
SC
122 if (width <= 0)
123 width = 100;
124 if (height <= 0)
125 height = 30;
126 if (x < 0)
127 x = 0;
128 if (y < 0)
129 y = 0;
e9576ca5 130
895f5af7
SC
131 SetName(name);
132
133 m_windowStyle = style;
134 parent->AddChild(this);
135
136 m_backgroundColour = parent->GetBackgroundColour() ;
137 m_foregroundColour = parent->GetForegroundColour() ;
138
139 if (id == -1)
140 m_windowId = NewControlId();
141 else
142 m_windowId = id;
143
144 {
145 m_width = size.x ;
146 m_height = size.y ;
147 int x = pos.x ;
148 int y = pos.y ;
149 AdjustForParentClientOrigin(x, y, wxSIZE_USE_EXISTING);
150 m_x = x ;
151 m_y = y ;
152 }
153
e9576ca5
SC
154}
155
156wxToolBar::~wxToolBar()
157{
7810c95b
SC
158 // we must refresh the frame size when the toolbar is deleted but the frame
159 // is not - otherwise toolbar leaves a hole in the place it used to occupy
e9576ca5
SC
160}
161
2f1ae414
SC
162PicHandle MakePict(GWorldPtr wp, GWorldPtr mask ) ;
163PicHandle MakePict(GWorldPtr wp, GWorldPtr mask )
519cb848
SC
164{
165 CGrafPtr origPort ;
166 GDHandle origDev ;
167
168 PicHandle pict; // this is the Picture we give back
169
170 RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ;
2f1ae414
SC
171 RGBColor white = { 0xffff ,0xffff , 0xffff } ;
172 RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ;
519cb848 173
2f1ae414
SC
174 unsigned char *maskimage = NULL ;
175 Rect portRect ;
176 GetPortBounds( wp , &portRect ) ;
177 int width = portRect.right - portRect.left ;
178 int height = portRect.bottom - portRect.top ;
519cb848 179
2f1ae414
SC
180 LockPixels( GetGWorldPixMap( wp ) ) ;
181 GetGWorld( &origPort , &origDev ) ;
519cb848 182
2f1ae414
SC
183 if ( mask )
184 {
185
186 maskimage = (unsigned char*) malloc( width * height ) ;
187 SetGWorld( mask , NULL ) ;
188 LockPixels( GetGWorldPixMap( mask ) ) ;
189 for ( int y = 0 ; y < height ; ++y )
190 {
191 for( int x = 0 ; x < width ; ++x )
192 {
193 RGBColor col ;
194
195 GetCPixel( x + portRect.left , y + portRect.top , &col ) ;
196 maskimage[y*width + x] = ( col.red == 0 ) ; // for monochrome masks
197 }
198 }
199 UnlockPixels( GetGWorldPixMap( mask ) ) ;
200 }
519cb848 201
519cb848
SC
202 SetGWorld( wp , NULL ) ;
203
2f1ae414 204 pict = OpenPicture(&portRect); // open a picture, this disables drawing
519cb848
SC
205 if(!pict)
206 return NULL;
2f1ae414
SC
207
208 RGBBackColor( &gray ) ;
209 RGBForeColor( &black ) ;
210 EraseRect(&portRect) ;
519cb848 211 RGBBackColor( &white ) ;
2f1ae414
SC
212
213 if ( maskimage )
214 {
215 for ( int y = 0 ; y < height ; ++y )
216 {
217 for( int x = 0 ; x < width ; ++x )
218 {
219 if ( maskimage[y*width + x] )
220 {
221 RGBColor col ;
222
223 GetCPixel( x + portRect.left , y + portRect.top , &col ) ;
224 SetCPixel( x + portRect.left , y + portRect.top , &col ) ;
225 }
226 }
227 }
228 free( maskimage ) ;
229 maskimage = NULL ;
230 }
231 else
232 {
233 CopyBits(GetPortBitMapForCopyBits(wp), // src PixMap - we copy image over itself -
234 GetPortBitMapForCopyBits(wp), // dst PixMap - no drawing occurs -
235 &portRect, // srcRect - it will be recorded and compressed -
236 &portRect, // dstRect - into the picture that is open -
519cb848
SC
237 srcCopy,NULL); // copyMode and no clip region
238
2f1ae414 239 }
519cb848 240 ClosePicture(); // We are done recording the picture
2f1ae414 241 UnlockPixels( GetGWorldPixMap( wp ) ) ;
519cb848
SC
242 SetGWorld( origPort , origDev ) ;
243 return pict; // return our groovy pict handle
244}
245
37e2cb08 246bool wxToolBar::Realize()
e9576ca5 247{
519cb848
SC
248 if (m_tools.Number() == 0)
249 return FALSE;
e9576ca5 250
80645074
SC
251 Point localOrigin ;
252 Rect clipRect ;
253 WindowRef window ;
254 wxWindow *win ;
255
7810c95b 256 GetParent()->MacGetPortParams( &localOrigin , &clipRect , &window , &win ) ;
80645074
SC
257
258 Rect toolbarrect = { m_y + localOrigin.v , m_x + localOrigin.h ,
259 m_y + m_height + localOrigin.v , m_x + m_width + localOrigin.h} ;
519cb848 260 ControlFontStyleRec controlstyle ;
80645074 261
519cb848
SC
262 controlstyle.flags = kControlUseFontMask ;
263 controlstyle.font = kControlFontSmallSystemFont ;
264
265 wxNode *node = m_tools.First();
266 int noButtons = 0;
267 int x = 0 ;
7c551d95
SC
268 wxSize toolSize = GetToolSize() ;
269 int tw, th;
270 GetSize(& tw, & th);
895f5af7
SC
271
272 int maxWidth = 0 ;
273 int maxHeight = 0 ;
274
519cb848
SC
275 while (node)
276 {
277 wxToolBarTool *tool = (wxToolBarTool *)node->Data();
37e2cb08 278 wxBitmapRefData * bmap = (wxBitmapRefData*) ( tool->GetBitmap1().GetRefData()) ;
519cb848 279
2f1ae414 280 if( !tool->IsSeparator() )
519cb848 281 {
895f5af7 282 Rect toolrect = { toolbarrect.top + m_yMargin + kwxMacToolBarTopMargin, toolbarrect.left + x + m_xMargin + kwxMacToolBarLeftMargin , 0 , 0 } ;
7c551d95
SC
283 toolrect.right = toolrect.left + toolSize.x ;
284 toolrect.bottom = toolrect.top + toolSize.y ;
519cb848
SC
285
286 PicHandle icon = NULL ;
287 if ( bmap )
288 {
289 if ( bmap->m_bitmapType == kMacBitmapTypePict )
290 icon = bmap->m_hPict ;
291 else if ( bmap->m_bitmapType == kMacBitmapTypeGrafWorld )
292 {
2f1ae414
SC
293 if ( tool->GetBitmap1().GetMask() )
294 {
295 icon = MakePict( bmap->m_hBitmap , tool->GetBitmap1().GetMask()->GetMaskBitmap() ) ;
296 }
297 else
298 {
299 icon = MakePict( bmap->m_hBitmap , NULL ) ;
300 }
519cb848
SC
301 }
302 }
303
304 ControlHandle m_macToolHandle ;
2f1ae414 305
8208e181
SC
306 SInt16 behaviour = kControlBehaviorOffsetContents ;
307 if ( tool->CanBeToggled() )
308 behaviour += kControlBehaviorToggles ;
309
519cb848
SC
310 if ( icon )
311 {
312 m_macToolHandle = UMANewControl( window , &toolrect , "\p" , true , 0 ,
8208e181 313 behaviour + kControlContentPictHandle , 0 , kControlBevelButtonNormalBevelProc , (long) this ) ;
519cb848
SC
314 ControlButtonContentInfo info ;
315
316 info.contentType = kControlContentPictHandle ;
317 info.u.picture = icon ;
318
319 UMASetControlData( m_macToolHandle , kControlButtonPart , kControlBevelButtonContentTag , sizeof(info) , (char*) &info ) ;
320 }
321 else
322 {
323 m_macToolHandle = UMANewControl( window , &toolrect , "\p" , true , 0 ,
8208e181 324 behaviour , 0 , kControlBevelButtonNormalBevelProc , (long) this ) ;
519cb848
SC
325 }
326 m_macToolHandles.Add( m_macToolHandle ) ;
2f1ae414
SC
327 tool->m_index = m_macToolHandles.Count() -1 ;
328 if ( !tool->IsEnabled() )
329 {
330 UMADeactivateControl( m_macToolHandle ) ;
331 }
332 if ( tool->CanBeToggled() && tool->IsToggled() )
333 {
334 ::SetControlValue( m_macToolHandle , 1 ) ;
335 }
519cb848 336 UMASetControlFontStyle( m_macToolHandle , &controlstyle ) ;
2f1ae414
SC
337 ControlHandle container = GetParent()->MacGetContainerForEmbedding() ;
338 wxASSERT_MSG( container != NULL , "No valid mac container control" ) ;
339 UMAEmbedControl( m_macToolHandle , container ) ;
519cb848 340
7c551d95 341 x += (int)toolSize.x;
519cb848
SC
342 noButtons ++;
343 }
344 else
345 {
346 m_macToolHandles.Add( NULL ) ;
7c551d95 347 x += (int)toolSize.x / 4;
519cb848 348 }
895f5af7
SC
349 if ( toolbarrect.left + x + m_xMargin + kwxMacToolBarLeftMargin- m_x - localOrigin.h > maxWidth)
350 maxWidth = toolbarrect.left + x + kwxMacToolBarLeftMargin+ m_xMargin - m_x - localOrigin.h;
351 if (toolbarrect.top + m_yMargin + kwxMacToolBarTopMargin - m_y - localOrigin.v > maxHeight)
352 maxHeight = toolbarrect.top + kwxMacToolBarTopMargin + m_yMargin - m_y - localOrigin.v ;
7c551d95 353
519cb848
SC
354 node = node->Next();
355 }
356
7c551d95
SC
357 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
358 {
7810c95b
SC
359 if ( m_maxRows == 0 )
360 {
361 // if not set yet, only one row
362 SetRows(1);
363 }
895f5af7
SC
364 maxWidth = tw ;
365 maxHeight += toolSize.y;
366 maxHeight += m_yMargin + kwxMacToolBarTopMargin;
367 m_maxHeight = maxHeight ;
7c551d95
SC
368 }
369 else
370 {
7810c95b
SC
371 if ( noButtons > 0 && m_maxRows == 0 )
372 {
373 // if not set yet, have one column
374 SetRows(noButtons);
375 }
895f5af7
SC
376 maxHeight = th ;
377 maxWidth += toolSize.x;
378 maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
379 m_maxWidth = maxWidth ;
7c551d95
SC
380 }
381
895f5af7 382 SetSize(maxWidth, maxHeight);
7c551d95 383
519cb848 384 return TRUE;
e9576ca5
SC
385}
386
387void wxToolBar::SetToolBitmapSize(const wxSize& size)
388{
389 m_defaultWidth = size.x; m_defaultHeight = size.y;
e9576ca5
SC
390}
391
e9576ca5
SC
392// The button size is bigger than the bitmap size
393wxSize wxToolBar::GetToolSize() const
394{
2f1ae414 395 return wxSize(m_defaultWidth + 4, m_defaultHeight + 4);
e9576ca5
SC
396}
397
519cb848
SC
398void wxToolBar::MacHandleControlClick( ControlHandle control , SInt16 controlpart )
399{
400 int index = 0 ;
401 for ( index = 0 ; index < m_macToolHandles.Count() ; ++index )
402 {
403 if ( m_macToolHandles[index] == (void*) control )
404 {
2f1ae414
SC
405 wxToolBarTool *tool = (wxToolBarTool *)m_tools.Nth( index )->Data();
406 if ( tool->CanBeToggled() )
407 {
408 tool->Toggle( GetControlValue( control ) ) ;
409 }
410 OnLeftClick( tool->GetId() , tool -> IsToggled() ) ;
411 break ;
519cb848
SC
412 }
413 }
414}
415
37e2cb08 416void wxToolBar::SetRows(int nRows)
e9576ca5 417{
37e2cb08 418 if ( nRows == m_maxRows )
e9576ca5 419 {
37e2cb08
SC
420 // avoid resizing the frame uselessly
421 return;
e9576ca5 422 }
37e2cb08
SC
423
424 m_maxRows = nRows;
e9576ca5
SC
425}
426
37e2cb08 427wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
e9576ca5 428{
37e2cb08 429 MacClientToRootWindow( &x , &y ) ;
2f1ae414 430 Point pt = { y ,x } ;
37e2cb08
SC
431
432 int index = 0 ;
433 for ( index = 0 ; index < m_macToolHandles.Count() ; ++index )
434 {
2f1ae414 435 if ( m_macToolHandles[index] )
37e2cb08 436 {
2f1ae414
SC
437 Rect bounds ;
438 GetControlBounds((ControlHandle) m_macToolHandles[index], &bounds ) ;
439 if ( PtInRect( pt , &bounds ) )
440 {
441 return (wxToolBarTool*) (m_tools.Nth( index )->Data() ) ;
442 }
37e2cb08
SC
443 }
444 }
445
446 return (wxToolBarToolBase *)NULL;
e9576ca5
SC
447}
448
2f1ae414
SC
449wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
450{
451 wxToolBarToolBase* tool = FindToolForPosition( pt.x , pt.y ) ;
452 if ( tool )
453 {
454 return tool->GetShortHelp() ;
455 }
456 return "" ;
457}
458
37e2cb08 459void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
e9576ca5 460{
37e2cb08 461 wxToolBarTool *tool = (wxToolBarTool *)t;
2f1ae414
SC
462 if ( tool->m_index < 0 )
463 return ;
464
8208e181 465 ControlHandle control = (ControlHandle) m_macToolHandles[ tool->m_index ] ;
2f1ae414
SC
466
467 if ( enable )
468 UMAActivateControl( control ) ;
8208e181 469 else
2f1ae414 470 UMADeactivateControl( control ) ;
e9576ca5
SC
471}
472
37e2cb08 473void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
e9576ca5 474{
37e2cb08 475 wxToolBarTool *tool = (wxToolBarTool *)t;
2f1ae414
SC
476 if ( tool->m_index < 0 )
477 return ;
8208e181
SC
478
479 ControlHandle control = (ControlHandle) m_macToolHandles[ tool->m_index ] ;
480 ::SetControlValue( control , toggle ) ;
37e2cb08 481}
7c551d95 482
37e2cb08
SC
483bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos),
484 wxToolBarToolBase *tool)
485{
486 // nothing special to do here - we really create the toolbar buttons in
487 // Realize() later
488 tool->Attach(this);
7c551d95 489
37e2cb08
SC
490 return TRUE;
491}
e9576ca5 492
37e2cb08
SC
493void wxToolBar::DoSetToggle(wxToolBarToolBase *t, bool toggle)
494{
495 wxToolBarTool *tool = (wxToolBarTool *)t;
496 // TODO: set toggle state
e9576ca5
SC
497}
498
37e2cb08
SC
499bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
500{
501 return TRUE ;
502}
2f1ae414
SC
503
504void wxToolBar::OnPaint(wxPaintEvent& event)
505{
80645074
SC
506 Point localOrigin ;
507 Rect clipRect ;
508 WindowRef window ;
509 wxWindow *win ;
510
7810c95b 511 GetParent()->MacGetPortParams( &localOrigin , &clipRect , &window , &win ) ;
80645074
SC
512 if ( window && win )
513 {
514 wxMacDrawingHelper help( win ) ;
515 // the mac control manager always assumes to have the origin at 0,0
516 SetOrigin( 0 , 0 ) ;
517
518 bool hasTabBehind = false ;
519 wxWindow* parent = GetParent() ;
520 while ( parent )
521 {
522 if( parent->MacGetWindowData() )
523 {
524 UMASetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , kThemeBrushDialogBackgroundActive , false ) ;
525 break ;
526 }
527
528 if( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) ))
529 {
530 if ( ((wxControl*)parent)->GetMacControl() )
531 SetUpControlBackground( ((wxControl*)parent)->GetMacControl() , -1 , true ) ;
532 break ;
533 }
534
535 parent = parent->GetParent() ;
536 }
895f5af7 537
80645074 538 Rect toolbarrect = { m_y + localOrigin.v , m_x + localOrigin.h ,
895f5af7 539 m_y + localOrigin.v + m_height , m_x + localOrigin.h + m_width } ;
80645074
SC
540
541 UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
542 {
543 int index = 0 ;
544 for ( index = 0 ; index < m_macToolHandles.Count() ; ++index )
545 {
546 if ( m_macToolHandles[index] )
547 {
548 UMADrawControl( (ControlHandle) m_macToolHandles[index] ) ;
549 }
550 }
551 }
552 UMASetThemeWindowBackground( win->MacGetWindowData()->m_macWindow , win->MacGetWindowData()->m_macWindowBackgroundTheme , false ) ;
553 wxDC::MacInvalidateSetup() ;
554 }
2f1ae414 555}
895f5af7 556
2f1ae414
SC
557void wxToolBar::OnMouse( wxMouseEvent &event )
558{
559
560 if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK )
561 {
562
563 int x = event.m_x ;
564 int y = event.m_y ;
565
566 MacClientToRootWindow( &x , &y ) ;
567
568 ControlHandle control ;
569 Point localwhere ;
570 GrafPtr port ;
571 SInt16 controlpart ;
572 WindowRef window = GetMacRootWindow() ;
573
574 localwhere.h = x ;
575 localwhere.v = y ;
576
577 short modifiers = 0;
578
579 if ( !event.m_leftDown && !event.m_rightDown )
580 modifiers |= btnState ;
581
582 if ( event.m_shiftDown )
583 modifiers |= shiftKey ;
584
585 if ( event.m_controlDown )
586 modifiers |= controlKey ;
587
588 if ( event.m_altDown )
589 modifiers |= optionKey ;
590
591 if ( event.m_metaDown )
592 modifiers |= cmdKey ;
593
594 controlpart = FindControl( localwhere , window , &control ) ;
595 {
2f1ae414
SC
596 if ( control && UMAIsControlActive( control ) )
597 {
598 {
599 if ( controlpart == kControlIndicatorPart && !UMAHasAppearance() )
600 controlpart = UMAHandleControlClick( control , localwhere , modifiers , (ControlActionUPP) NULL ) ;
601 else
602 controlpart = UMAHandleControlClick( control , localwhere , modifiers , (ControlActionUPP) -1 ) ;
603 wxTheApp->s_lastMouseDown = 0 ;
604 if ( controlpart && ! ( ( UMAHasAppearance() || (controlpart != kControlIndicatorPart) )
605 && (IsKindOf( CLASSINFO( wxScrollBar ) ) ) ) ) // otherwise we will get the event twice
606 {
607 MacHandleControlClick( control , controlpart ) ;
608 }
609 }
610 }
611 }
612 }
613}
614
519cb848
SC
615#endif // wxUSE_TOOLBAR
616