]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/window.cpp
attempt to work around SDK specific problems
[wxWidgets.git] / src / mac / carbon / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: windows.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "window.h"
14 #endif
15
16 #include "wx/setup.h"
17 #include "wx/menu.h"
18 #include "wx/window.h"
19 #include "wx/dc.h"
20 #include "wx/dcclient.h"
21 #include "wx/utils.h"
22 #include "wx/app.h"
23 #include "wx/panel.h"
24 #include "wx/layout.h"
25 #include "wx/dialog.h"
26 #include "wx/scrolbar.h"
27 #include "wx/statbox.h"
28 #include "wx/button.h"
29 #include "wx/settings.h"
30 #include "wx/msgdlg.h"
31 #include "wx/frame.h"
32 #include "wx/tooltip.h"
33 #include "wx/statusbr.h"
34 #include "wx/menuitem.h"
35 #include "wx/spinctrl.h"
36 #include "wx/log.h"
37 #include "wx/geometry.h"
38
39 #include "wx/toolbar.h"
40 #include "wx/dc.h"
41
42 #if wxUSE_CARET
43 #include "wx/caret.h"
44 #endif // wxUSE_CARET
45
46 #define wxWINDOW_HSCROLL 5998
47 #define wxWINDOW_VSCROLL 5997
48 #define MAC_SCROLLBAR_SIZE 16
49
50 #include "wx/mac/uma.h"
51 #ifndef __DARWIN__
52 #include <Windows.h>
53 #include <ToolUtils.h>
54 #endif
55
56 #if TARGET_API_MAC_OSX
57 #ifndef __HIVIEW__
58 #include <HIToolbox/HIView.h>
59 #endif
60 #endif
61
62 #if wxUSE_DRAG_AND_DROP
63 #include "wx/dnd.h"
64 #endif
65
66 #include <string.h>
67
68 extern wxList wxPendingDelete;
69 wxWindowMac* gFocusWindow = NULL ;
70
71 #ifdef __WXUNIVERSAL__
72 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
73 #else // __WXMAC__
74 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
75 #endif // __WXUNIVERSAL__/__WXMAC__
76
77 #if !USE_SHARED_LIBRARY
78
79 BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
80 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
81 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
82 // TODO EVT_PAINT(wxWindowMac::OnPaint)
83 EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged)
84 EVT_INIT_DIALOG(wxWindowMac::OnInitDialog)
85 EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
86 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
87 END_EVENT_TABLE()
88
89 #endif
90
91 #define wxMAC_DEBUG_REDRAW 0
92 #ifndef wxMAC_DEBUG_REDRAW
93 #define wxMAC_DEBUG_REDRAW 0
94 #endif
95
96 #define wxMAC_USE_THEME_BORDER 0
97
98 // ---------------------------------------------------------------------------
99 // Carbon Events
100 // ---------------------------------------------------------------------------
101
102 extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
103 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ;
104
105 #ifndef MAC_OS_X_VERSION_10_3
106 enum {
107 kEventControlVisibilityChanged = 157
108 };
109 #endif
110
111 static const EventTypeSpec eventList[] =
112 {
113 #if TARGET_API_MAC_OSX
114 { kEventClassControl , kEventControlDraw } ,
115 { kEventClassControl , kEventControlVisibilityChanged } ,
116 { kEventClassControl , kEventControlEnabledStateChanged } ,
117 { kEventClassControl , kEventControlHiliteChanged } ,
118 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
119 // { kEventClassControl , kEventControlBoundsChanged } ,
120
121 {}
122 #else
123 {}
124 #endif
125 } ;
126
127 static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
128 {
129 OSStatus result = eventNotHandledErr ;
130
131 wxMacCarbonEvent cEvent( event ) ;
132
133 ControlRef controlRef ;
134 wxWindowMac* thisWindow = (wxWindowMac*) data ;
135
136 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
137
138 switch( GetEventKind( event ) )
139 {
140 case kEventControlDraw :
141 {
142 RgnHandle updateRgn = NULL ;
143
144 wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
145 if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
146 {
147 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
148 }
149 else
150 {
151 // unfortunately this update region may be incorrect (tree ctrl sample )
152 // so we have to reset it
153 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
154 }
155 // GrafPtr myport = cEvent.GetParameter<GrafPtr>(kEventParamGrafPort,typeGrafPtr) ;
156
157 #if 0 // in case we would need a coregraphics compliant background erase first
158 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
159 if ( thisWindow->MacIsUserPane() )
160 {
161 HIRect bounds;
162 err = HIViewGetBounds( controlRef, &bounds );
163 CGContextSetRGBFillColor( cgContext, 1 , 1 , 1 , 1 );
164 // CGContextSetRGBFillColor( cgContext, .95, .95, .95, 1 );
165 CGContextFillRect( cgContext, bounds );
166 }
167 #endif
168 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
169 result = noErr ;
170 else
171 result = eventNotHandledErr;
172 }
173 break ;
174 case kEventControlVisibilityChanged :
175 thisWindow->MacVisibilityChanged() ;
176 break ;
177 case kEventControlEnabledStateChanged :
178 thisWindow->MacEnabledStateChanged() ;
179 break ;
180 case kEventControlHiliteChanged :
181 thisWindow->MacHiliteChanged() ;
182 break ;
183 default :
184 break ;
185 }
186 return result ;
187 }
188
189 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
190 {
191 OSStatus result = eventNotHandledErr ;
192
193 switch ( GetEventClass( event ) )
194 {
195 case kEventClassControl :
196 result = wxMacWindowControlEventHandler( handler, event, data ) ;
197 break ;
198 default :
199 break ;
200 }
201 return result ;
202 }
203
204 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
205
206 // ---------------------------------------------------------------------------
207 // UserPane events for non OSX builds
208 // ---------------------------------------------------------------------------
209
210 static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
211 {
212 wxWindow * win = wxFindControlFromMacControl(control) ;
213 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
214 win->MacControlUserPaneDrawProc(part) ;
215 }
216
217 static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
218 {
219 wxWindow * win = wxFindControlFromMacControl(control) ;
220 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
221 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
222 }
223
224 static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
225 {
226 wxWindow * win = wxFindControlFromMacControl(control) ;
227 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
228 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
229 }
230
231 static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
232 {
233 wxWindow * win = wxFindControlFromMacControl(control) ;
234 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
235 win->MacControlUserPaneIdleProc() ;
236 }
237
238 static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
239 {
240 wxWindow * win = wxFindControlFromMacControl(control) ;
241 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
242 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
243 }
244
245 static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
246 {
247 wxWindow * win = wxFindControlFromMacControl(control) ;
248 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
249 win->MacControlUserPaneActivateProc(activating) ;
250 }
251
252 static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
253 {
254 wxWindow * win = wxFindControlFromMacControl(control) ;
255 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
256 return win->MacControlUserPaneFocusProc(action) ;
257 }
258
259 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
260 {
261 wxWindow * win = wxFindControlFromMacControl(control) ;
262 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
263 win->MacControlUserPaneBackgroundProc(info) ;
264 }
265
266 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
267 {
268 MacDoRedraw( MacGetVisibleRegion().GetWXHRGN() , 0 ) ;
269 }
270
271 wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
272 {
273 return kControlNoPart ;
274 }
275
276 wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
277 {
278 return kControlNoPart ;
279 }
280
281 void wxWindowMac::MacControlUserPaneIdleProc()
282 {
283 }
284
285 wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
286 {
287 return kControlNoPart ;
288 }
289
290 void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
291 {
292 }
293
294 wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
295 {
296 return kControlNoPart ;
297 }
298
299 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
300 {
301 }
302
303 ControlUserPaneDrawUPP gControlUserPaneDrawUPP = NULL ;
304 ControlUserPaneHitTestUPP gControlUserPaneHitTestUPP = NULL ;
305 ControlUserPaneTrackingUPP gControlUserPaneTrackingUPP = NULL ;
306 ControlUserPaneIdleUPP gControlUserPaneIdleUPP = NULL ;
307 ControlUserPaneKeyDownUPP gControlUserPaneKeyDownUPP = NULL ;
308 ControlUserPaneActivateUPP gControlUserPaneActivateUPP = NULL ;
309 ControlUserPaneFocusUPP gControlUserPaneFocusUPP = NULL ;
310 ControlUserPaneBackgroundUPP gControlUserPaneBackgroundUPP = NULL ;
311
312 // ===========================================================================
313 // implementation
314 // ===========================================================================
315
316 wxList wxWinMacControlList(wxKEY_INTEGER);
317
318 wxWindow *wxFindControlFromMacControl(ControlRef inControl )
319 {
320 wxNode *node = wxWinMacControlList.Find((long)inControl);
321 if (!node)
322 return NULL;
323 return (wxControl *)node->GetData();
324 }
325
326 void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
327 {
328 // adding NULL ControlRef is (first) surely a result of an error and
329 // (secondly) breaks native event processing
330 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
331
332 if ( !wxWinMacControlList.Find((long)inControl) )
333 wxWinMacControlList.Append((long)inControl, control);
334 }
335
336 void wxRemoveMacControlAssociation(wxWindow *control)
337 {
338 wxWinMacControlList.DeleteObject(control);
339 }
340
341 // UPP functions
342 ControlActionUPP wxMacLiveScrollbarActionUPP = NULL ;
343
344 ControlColorUPP wxMacSetupControlBackgroundUPP = NULL ;
345
346 // we have to setup the brush in the current port and return noErr
347 // or return an error code so that the control manager walks further up the
348 // hierarchy to find a correct background
349
350 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor )
351 {
352 OSStatus status = paramErr ;
353 switch( iMessage )
354 {
355 case kControlMsgApplyTextColor :
356 break ;
357 case kControlMsgSetUpBackground :
358 {
359 wxWindow* wx = (wxWindow*) wxFindControlFromMacControl( iControl ) ;
360 if ( wx != NULL )
361 {
362 /*
363 const wxBrush &brush = wx->MacGetBackgroundBrush() ;
364 if ( brush.Ok() )
365 {
366
367 wxDC::MacSetupBackgroundForCurrentPort( brush ) ;
368 */
369 // this clipping is only needed for non HIView
370
371 RgnHandle clip = NewRgn() ;
372 int x = 0 , y = 0;
373
374 wx->MacWindowToRootWindow( &x,&y ) ;
375 CopyRgn( (RgnHandle) wx->MacGetVisibleRegion().GetWXHRGN() , clip ) ;
376 OffsetRgn( clip , x , y ) ;
377 SetClip( clip ) ;
378 DisposeRgn( clip ) ;
379
380 status = noErr ;
381 /*
382 }
383 else if ( wx->MacIsUserPane() )
384 {
385 // if we don't have a valid brush for such a control, we have to call the
386 // setup of our parent ourselves
387 status = SetUpControlBackground( (ControlRef) wx->GetParent()->GetHandle() , iDepth , iIsColor ) ;
388 }
389 */
390 }
391 }
392 break ;
393 default :
394 break ;
395 }
396 return status ;
397 }
398
399
400 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
401 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
402 {
403 if ( partCode != 0)
404 {
405 wxWindow* wx = wxFindControlFromMacControl( control ) ;
406 if ( wx )
407 {
408 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
409 }
410 }
411 }
412
413 // ----------------------------------------------------------------------------
414 // constructors and such
415 // ----------------------------------------------------------------------------
416
417 void wxWindowMac::Init()
418 {
419 m_backgroundTransparent = FALSE;
420
421 // as all windows are created with WS_VISIBLE style...
422 m_isShown = TRUE;
423
424 m_hScrollBar = NULL ;
425 m_vScrollBar = NULL ;
426 m_macBackgroundBrush = wxNullBrush ;
427
428 m_macControl = NULL ;
429
430 m_macIsUserPane = TRUE;
431
432 // make sure all proc ptrs are available
433
434 if ( gControlUserPaneDrawUPP == NULL )
435 {
436 gControlUserPaneDrawUPP = NewControlUserPaneDrawUPP( wxMacControlUserPaneDrawProc ) ;
437 gControlUserPaneHitTestUPP = NewControlUserPaneHitTestUPP( wxMacControlUserPaneHitTestProc ) ;
438 gControlUserPaneTrackingUPP = NewControlUserPaneTrackingUPP( wxMacControlUserPaneTrackingProc ) ;
439 gControlUserPaneIdleUPP = NewControlUserPaneIdleUPP( wxMacControlUserPaneIdleProc ) ;
440 gControlUserPaneKeyDownUPP = NewControlUserPaneKeyDownUPP( wxMacControlUserPaneKeyDownProc ) ;
441 gControlUserPaneActivateUPP = NewControlUserPaneActivateUPP( wxMacControlUserPaneActivateProc ) ;
442 gControlUserPaneFocusUPP = NewControlUserPaneFocusUPP( wxMacControlUserPaneFocusProc ) ;
443 gControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP( wxMacControlUserPaneBackgroundProc ) ;
444 }
445 if ( wxMacLiveScrollbarActionUPP == NULL )
446 {
447 wxMacLiveScrollbarActionUPP = NewControlActionUPP( wxMacLiveScrollbarActionProc );
448 }
449
450 if ( wxMacSetupControlBackgroundUPP == NULL )
451 {
452 wxMacSetupControlBackgroundUPP = NewControlColorUPP( wxMacSetupControlBackground ) ;
453 }
454
455 }
456
457 // Destructor
458 wxWindowMac::~wxWindowMac()
459 {
460 SendDestroyEvent();
461
462 m_isBeingDeleted = TRUE;
463
464 #ifndef __WXUNIVERSAL__
465 // VS: make sure there's no wxFrame with last focus set to us:
466 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
467 {
468 wxFrame *frame = wxDynamicCast(win, wxFrame);
469 if ( frame )
470 {
471 if ( frame->GetLastFocus() == this )
472 {
473 frame->SetLastFocus((wxWindow*)NULL);
474 }
475 break;
476 }
477 }
478 #endif // __WXUNIVERSAL__
479
480 // wxRemoveMacControlAssociation( this ) ;
481 // If we delete an item, we should initialize the parent panel,
482 // because it could now be invalid.
483 wxWindow *parent = GetParent() ;
484 if ( parent )
485 {
486 if (parent->GetDefaultItem() == (wxButton*) this)
487 parent->SetDefaultItem(NULL);
488 }
489 if ( (ControlRef) m_macControl )
490 {
491 // in case the callback might be called during destruction
492 wxRemoveMacControlAssociation( this) ;
493 ::SetControlColorProc( (ControlRef) m_macControl , NULL ) ;
494 ::DisposeControl( (ControlRef) m_macControl ) ;
495 m_macControl = NULL ;
496 }
497
498 if ( g_MacLastWindow == this )
499 {
500 g_MacLastWindow = NULL ;
501 }
502
503 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ;
504 if ( frame )
505 {
506 if ( frame->GetLastFocus() == this )
507 frame->SetLastFocus( NULL ) ;
508 }
509
510 if ( gFocusWindow == this )
511 {
512 gFocusWindow = NULL ;
513 }
514
515 DestroyChildren();
516
517 // delete our drop target if we've got one
518 #if wxUSE_DRAG_AND_DROP
519 if ( m_dropTarget != NULL )
520 {
521 delete m_dropTarget;
522 m_dropTarget = NULL;
523 }
524 #endif // wxUSE_DRAG_AND_DROP
525 }
526
527 //
528
529 void wxWindowMac::MacInstallEventHandler()
530 {
531 InstallControlEventHandler( (ControlRef) m_macControl, GetwxMacWindowEventHandlerUPP(),
532 GetEventTypeCount(eventList), eventList, this,
533 (EventHandlerRef *)&m_macControlEventHandler);
534
535 }
536
537 // Constructor
538 bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
539 const wxPoint& pos,
540 const wxSize& size,
541 long style,
542 const wxString& name)
543 {
544 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") );
545
546 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
547 return FALSE;
548
549 parent->AddChild(this);
550
551 m_windowVariant = parent->GetWindowVariant() ;
552
553 if ( m_macIsUserPane )
554 {
555 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
556
557 UInt32 features = kControlSupportsEmbedding | kControlSupportsLiveFeedback /*| kControlHasSpecialBackground */ | kControlSupportsCalcBestRect | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate | kControlWantsIdle;
558
559 ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features, (ControlRef*) &m_macControl);
560
561 MacPostControlCreate(pos,size) ;
562 #if !TARGET_API_MAC_OSX
563 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneDrawProcTag,
564 sizeof(gControlUserPaneDrawUPP),(Ptr) &gControlUserPaneDrawUPP);
565 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneHitTestProcTag,
566 sizeof(gControlUserPaneHitTestUPP),(Ptr) &gControlUserPaneHitTestUPP);
567 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneTrackingProcTag,
568 sizeof(gControlUserPaneTrackingUPP),(Ptr) &gControlUserPaneTrackingUPP);
569 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneIdleProcTag,
570 sizeof(gControlUserPaneIdleUPP),(Ptr) &gControlUserPaneIdleUPP);
571 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneKeyDownProcTag,
572 sizeof(gControlUserPaneKeyDownUPP),(Ptr) &gControlUserPaneKeyDownUPP);
573 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneActivateProcTag,
574 sizeof(gControlUserPaneActivateUPP),(Ptr) &gControlUserPaneActivateUPP);
575 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneFocusProcTag,
576 sizeof(gControlUserPaneFocusUPP),(Ptr) &gControlUserPaneFocusUPP);
577 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneBackgroundProcTag,
578 sizeof(gControlUserPaneBackgroundUPP),(Ptr) &gControlUserPaneBackgroundUPP);
579 #endif
580 }
581 #ifndef __WXUNIVERSAL__
582 // Don't give scrollbars to wxControls unless they ask for them
583 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) ||
584 (IsKindOf(CLASSINFO(wxControl)) && ( style & wxHSCROLL || style & wxVSCROLL)))
585 {
586 MacCreateScrollBars( style ) ;
587 }
588 #endif
589
590 wxWindowCreateEvent event(this);
591 GetEventHandler()->AddPendingEvent(event);
592
593 return TRUE;
594 }
595
596 void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size)
597 {
598 wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ;
599
600 wxAssociateControlWithMacControl( (ControlRef) m_macControl , this ) ;
601 ::SetControlReference( (ControlRef) m_macControl , (long) this ) ;
602
603 MacInstallEventHandler();
604
605 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
606 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
607 ::EmbedControl( (ControlRef) m_macControl , container ) ;
608
609 // adjust font, controlsize etc
610 DoSetWindowVariant( m_windowVariant ) ;
611
612 #if !TARGET_API_MAC_OSX
613 // eventually we can fix some clipping issues be reactivating this hook
614 //if ( m_macIsUserPane )
615 // SetControlColorProc( (ControlRef) m_macControl , wxMacSetupControlBackgroundUPP ) ;
616 #endif
617
618 UMASetControlTitle( (ControlRef) m_macControl , wxStripMenuCodes(m_label) , m_font.GetEncoding() ) ;
619
620 wxSize new_size = size ;
621 if (!m_macIsUserPane)
622 {
623 wxSize best_size( DoGetBestSize() );
624
625 if (size.x == -1) {
626 new_size.x = best_size.x;
627 }
628 if (size.y == -1) {
629 new_size.y = best_size.y;
630 }
631 SetSize( pos.x, pos.y , new_size.x, new_size.y,wxSIZE_USE_EXISTING );
632 }
633
634 SetCursor( *wxSTANDARD_CURSOR ) ;
635
636 }
637
638 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
639 {
640 wxASSERT( m_macControl != NULL ) ;
641
642 m_windowVariant = variant ;
643
644 ControlSize size ;
645 ThemeFontID themeFont = kThemeSystemFont ;
646
647 // we will get that from the settings later
648 // and make this NORMAL later, but first
649 // we have a few calculations that we must fix
650
651 switch ( variant )
652 {
653 case wxWINDOW_VARIANT_NORMAL :
654 size = kControlSizeNormal;
655 themeFont = kThemeSystemFont ;
656 break ;
657 case wxWINDOW_VARIANT_SMALL :
658 size = kControlSizeSmall;
659 themeFont = kThemeSmallSystemFont ;
660 break ;
661 case wxWINDOW_VARIANT_MINI :
662 if (UMAGetSystemVersion() >= 0x1030 )
663 {
664 // not always defined in the headers
665 size = 3 ;
666 themeFont = 109 ;
667 }
668 else
669 {
670 size = kControlSizeSmall;
671 themeFont = kThemeSmallSystemFont ;
672 }
673 break ;
674 case wxWINDOW_VARIANT_LARGE :
675 size = kControlSizeLarge;
676 themeFont = kThemeSystemFont ;
677 break ;
678 default:
679 wxFAIL_MSG(_T("unexpected window variant"));
680 break ;
681 }
682 ::SetControlData( (ControlRef) m_macControl , kControlEntireControl, kControlSizeTag, sizeof( ControlSize ), &size );
683
684 wxFont font ;
685 font.MacCreateThemeFont( themeFont ) ;
686 SetFont( font ) ;
687 }
688
689 void wxWindowMac::MacUpdateControlFont()
690 {
691 ControlFontStyleRec fontStyle;
692 if ( m_font.MacGetThemeFontID() != kThemeCurrentPortFont )
693 {
694 switch( m_font.MacGetThemeFontID() )
695 {
696 case kThemeSmallSystemFont : fontStyle.font = kControlFontSmallSystemFont ; break ;
697 case 109 /*mini font */ : fontStyle.font = -5 ; break ;
698 case kThemeSystemFont : fontStyle.font = kControlFontBigSystemFont ; break ;
699 default : fontStyle.font = kControlFontBigSystemFont ; break ;
700 }
701 fontStyle.flags = kControlUseFontMask ;
702 }
703 else
704 {
705 fontStyle.font = m_font.MacGetFontNum() ;
706 fontStyle.style = m_font.MacGetFontStyle() ;
707 fontStyle.size = m_font.MacGetFontSize() ;
708 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ;
709 }
710
711 fontStyle.just = teJustLeft ;
712 fontStyle.flags |= kControlUseJustMask ;
713 if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
714 fontStyle.just = teJustCenter ;
715 else if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_RIGHT )
716 fontStyle.just = teJustRight ;
717
718
719 fontStyle.foreColor = MAC_WXCOLORREF(GetForegroundColour().GetPixel() ) ;
720 fontStyle.flags |= kControlUseForeColorMask ;
721
722 ::SetControlFontStyle( (ControlRef) m_macControl , &fontStyle );
723 Refresh() ;
724 }
725
726 bool wxWindowMac::SetFont(const wxFont& font)
727 {
728 bool retval = !wxWindowBase::SetFont( font ) ;
729
730 MacUpdateControlFont() ;
731
732 return retval;
733 }
734
735 bool wxWindowMac::SetForegroundColour(const wxColour& col )
736 {
737 if ( !wxWindowBase::SetForegroundColour(col) )
738 return false ;
739
740 MacUpdateControlFont() ;
741
742 return true ;
743 }
744
745 bool wxWindowMac::SetBackgroundColour(const wxColour& col )
746 {
747 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
748 return false ;
749
750 wxBrush brush ;
751 if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
752 {
753 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
754 }
755 else if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) )
756 {
757 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
758 }
759 else
760 {
761 brush.SetColour( col ) ;
762 }
763 MacSetBackgroundBrush( brush ) ;
764
765 MacUpdateControlFont() ;
766
767 return true ;
768 }
769
770
771 bool wxWindowMac::MacCanFocus() const
772 {
773 wxASSERT( m_macControl != NULL ) ;
774
775 return true ;
776 }
777
778
779 void wxWindowMac::SetFocus()
780 {
781 if ( gFocusWindow == this )
782 return ;
783
784 if ( AcceptsFocus() )
785 {
786 if (gFocusWindow )
787 {
788 #if wxUSE_CARET
789 // Deal with caret
790 if ( gFocusWindow->m_caret )
791 {
792 gFocusWindow->m_caret->OnKillFocus();
793 }
794 #endif // wxUSE_CARET
795 #ifndef __WXUNIVERSAL__
796 wxWindow* control = wxDynamicCast( gFocusWindow , wxWindow ) ;
797 // TODO we must use the built-in focusing
798 if ( control && control->GetHandle() /* && control->MacIsReallyShown() */ )
799 {
800 UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetTopLevelWindowRef() , (ControlRef) control->GetHandle() , kControlFocusNoPart ) ;
801 control->MacRedrawControl() ;
802 }
803 #endif
804 // Without testing the window id, for some reason
805 // a kill focus event can still be sent to
806 // the control just being focussed.
807 int thisId = this->m_windowId;
808 int gFocusWindowId = gFocusWindow->m_windowId;
809 if (gFocusWindowId != thisId)
810 {
811 wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId);
812 event.SetEventObject(gFocusWindow);
813 gFocusWindow->GetEventHandler()->ProcessEvent(event) ;
814 }
815 }
816 gFocusWindow = this ;
817 {
818 #if wxUSE_CARET
819 // Deal with caret
820 if ( m_caret )
821 {
822 m_caret->OnSetFocus();
823 }
824 #endif // wxUSE_CARET
825 // panel wants to track the window which was the last to have focus in it
826 wxChildFocusEvent eventFocus(this);
827 GetEventHandler()->ProcessEvent(eventFocus);
828
829 #ifndef __WXUNIVERSAL__
830 wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ;
831 if ( control && control->GetHandle() )
832 {
833 UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetTopLevelWindowRef() , (ControlRef) control->GetHandle() , kControlFocusNextPart ) ;
834 }
835 #endif
836 wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
837 event.SetEventObject(this);
838 GetEventHandler()->ProcessEvent(event) ;
839 }
840 }
841 }
842
843
844 void wxWindowMac::DoCaptureMouse()
845 {
846 wxTheApp->s_captureWindow = this ;
847 }
848
849 wxWindow* wxWindowBase::GetCapture()
850 {
851 return wxTheApp->s_captureWindow ;
852 }
853
854 void wxWindowMac::DoReleaseMouse()
855 {
856 wxTheApp->s_captureWindow = NULL ;
857 }
858
859 #if wxUSE_DRAG_AND_DROP
860
861 void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
862 {
863 if ( m_dropTarget != 0 ) {
864 delete m_dropTarget;
865 }
866
867 m_dropTarget = pDropTarget;
868 if ( m_dropTarget != 0 )
869 {
870 // TODO
871 }
872 }
873
874 #endif
875
876 // Old style file-manager drag&drop
877 void wxWindowMac::DragAcceptFiles(bool accept)
878 {
879 // TODO
880 }
881
882 void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y,
883 int& w, int& h) const
884 {
885 Rect bounds ;
886 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
887
888
889 x = bounds.left ;
890 y = bounds.top ;
891 w = bounds.right - bounds.left ;
892 h = bounds.bottom - bounds.top ;
893
894 wxTopLevelWindow* tlw = wxDynamicCast( this , wxTopLevelWindow ) ;
895 if ( tlw )
896 {
897 Point tlworigin = { 0 , 0 } ;
898 GrafPtr port ;
899 ::GetPort( &port ) ;
900 ::SetPort( UMAGetWindowPort( (WindowRef) tlw->MacGetWindowRef() ) ) ;
901 ::LocalToGlobal( &tlworigin ) ;
902 ::SetPort( port ) ;
903 x = tlworigin.h ;
904 y = tlworigin.v ;
905 }
906 }
907
908 bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos,
909 const wxSize& size,
910 int& x, int& y,
911 int& w, int& h) const
912 {
913 x = (int)pos.x;
914 y = (int)pos.y;
915 // todo the default calls may be used as soon as PostCreateControl Is moved here
916 w = size.x ; // WidthDefault( size.x );
917 h = size.y ; // HeightDefault( size.y ) ;
918 #if !TARGET_API_MAC_OSX
919 GetParent()->MacWindowToRootWindow( &x , &y ) ;
920 #endif
921
922 return true ;
923 }
924
925 // Get total size
926 void wxWindowMac::DoGetSize(int *x, int *y) const
927 {
928 #if TARGET_API_MAC_OSX
929 int x1 , y1 , w1 ,h1 ;
930 MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ;
931 if(x) *x = w1 ;
932 if(y) *y = h1 ;
933
934 #else
935 Rect bounds ;
936 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
937 if(x) *x = bounds.right - bounds.left ;
938 if(y) *y = bounds.bottom - bounds.top ;
939 #endif
940 }
941
942 void wxWindowMac::DoGetPosition(int *x, int *y) const
943 {
944 #if TARGET_API_MAC_OSX
945 int x1 , y1 , w1 ,h1 ;
946 MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ;
947 if ( !IsTopLevel() )
948 {
949 wxWindow *parent = GetParent();
950 if ( parent )
951 {
952 wxPoint pt(parent->GetClientAreaOrigin());
953 x1 -= pt.x ;
954 y1 -= pt.y ;
955 }
956 }
957 if(x) *x = x1 ;
958 if(y) *y = y1 ;
959 #else
960 Rect bounds ;
961 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
962 wxCHECK_RET( GetParent() , wxT("Missing Parent") ) ;
963
964 int xx = bounds.left ;
965 int yy = bounds.top ;
966
967 if ( !GetParent()->IsTopLevel() )
968 {
969 GetControlBounds( (ControlRef) GetParent()->GetHandle() , &bounds ) ;
970
971 xx -= bounds.left ;
972 yy -= bounds.top ;
973 }
974
975 wxPoint pt(GetParent()->GetClientAreaOrigin());
976 xx -= pt.x;
977 yy -= pt.y;
978
979 if(x) *x = xx;
980 if(y) *y = yy;
981 #endif
982 }
983
984 void wxWindowMac::DoScreenToClient(int *x, int *y) const
985 {
986 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
987
988 wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ;
989
990 {
991 Point localwhere = {0,0} ;
992
993 if(x) localwhere.h = * x ;
994 if(y) localwhere.v = * y ;
995
996 wxMacPortSaver s((GrafPtr)GetWindowPort( window )) ;
997 ::GlobalToLocal( &localwhere ) ;
998 if(x) *x = localwhere.h ;
999 if(y) *y = localwhere.v ;
1000
1001 }
1002 MacRootWindowToWindow( x , y ) ;
1003
1004 wxPoint origin = GetClientAreaOrigin() ;
1005 if(x) *x -= origin.x ;
1006 if(y) *y -= origin.y ;
1007 }
1008
1009 void wxWindowMac::DoClientToScreen(int *x, int *y) const
1010 {
1011 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1012 wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ;
1013
1014 wxPoint origin = GetClientAreaOrigin() ;
1015 if(x) *x += origin.x ;
1016 if(y) *y += origin.y ;
1017
1018 MacWindowToRootWindow( x , y ) ;
1019
1020 {
1021 Point localwhere = { 0,0 };
1022 if(x) localwhere.h = * x ;
1023 if(y) localwhere.v = * y ;
1024
1025 wxMacPortSaver s((GrafPtr)GetWindowPort( window )) ;
1026 ::LocalToGlobal( &localwhere ) ;
1027 if(x) *x = localwhere.h ;
1028 if(y) *y = localwhere.v ;
1029 }
1030 }
1031
1032 void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
1033 {
1034 wxPoint origin = GetClientAreaOrigin() ;
1035 if(x) *x += origin.x ;
1036 if(y) *y += origin.y ;
1037
1038 MacWindowToRootWindow( x , y ) ;
1039 }
1040
1041 void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1042 {
1043 MacRootWindowToWindow( x , y ) ;
1044
1045 wxPoint origin = GetClientAreaOrigin() ;
1046 if(x) *x -= origin.x ;
1047 if(y) *y -= origin.y ;
1048 }
1049
1050 void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1051 {
1052 #if TARGET_API_MAC_OSX
1053 HIPoint pt ;
1054 if ( x ) pt.x = *x ;
1055 if ( y ) pt.y = *y ;
1056
1057 HIViewConvertPoint( &pt , (ControlRef) m_macControl , (ControlRef) MacGetTopLevelWindow()->GetHandle() ) ;
1058
1059 if ( x ) *x = (int) pt.x ;
1060 if ( y ) *y = (int) pt.y ;
1061 #else
1062 if ( !IsTopLevel() )
1063 {
1064 Rect bounds ;
1065 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
1066 if(x) *x += bounds.left ;
1067 if(y) *y += bounds.top ;
1068 }
1069 #endif
1070 }
1071
1072 void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1073 {
1074 int x1 , y1 ;
1075 if ( x ) x1 = *x ;
1076 if ( y ) y1 = *y ;
1077 MacWindowToRootWindow( &x1 , &y1 ) ;
1078 if ( x ) *x = x1 ;
1079 if ( y ) *y = y1 ;
1080 }
1081
1082 void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
1083 {
1084 #if TARGET_API_MAC_OSX
1085 HIPoint pt ;
1086 if ( x ) pt.x = *x ;
1087 if ( y ) pt.y = *y ;
1088
1089 HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , (ControlRef) m_macControl ) ;
1090
1091 if ( x ) *x = (int) pt.x ;
1092 if ( y ) *y = (int) pt.y ;
1093 #else
1094 if ( !IsTopLevel() )
1095 {
1096 Rect bounds ;
1097 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
1098 if(x) *x -= bounds.left ;
1099 if(y) *y -= bounds.top ;
1100 }
1101 #endif
1102 }
1103
1104 void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
1105 {
1106 int x1 , y1 ;
1107 if ( x ) x1 = *x ;
1108 if ( y ) y1 = *y ;
1109 MacRootWindowToWindow( &x1 , &y1 ) ;
1110 if ( x ) *x = x1 ;
1111 if ( y ) *y = y1 ;
1112 }
1113
1114 wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1115 {
1116 wxSize sizeTotal = size;
1117
1118 RgnHandle rgn = NewRgn() ;
1119
1120 Rect content ;
1121
1122 if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr )
1123 {
1124 GetRegionBounds( rgn , &content ) ;
1125 DisposeRgn( rgn ) ;
1126 }
1127 else
1128 {
1129 GetControlBounds( (ControlRef) m_macControl , &content ) ;
1130 }
1131 Rect structure ;
1132 GetControlBounds( (ControlRef) m_macControl , &structure ) ;
1133 #if !TARGET_API_MAC_OSX
1134 OffsetRect( &content , -structure.left , -structure.top ) ;
1135 #endif
1136
1137 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
1138 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top ) ;
1139
1140 sizeTotal.x += MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
1141 sizeTotal.y += MacGetTopBorderSize( ) + MacGetBottomBorderSize( ) ;
1142
1143 return sizeTotal;
1144 }
1145
1146
1147 // Get size *available for subwindows* i.e. excluding menu bar etc.
1148 void wxWindowMac::DoGetClientSize(int *x, int *y) const
1149 {
1150 int ww, hh;
1151
1152 RgnHandle rgn = NewRgn() ;
1153 Rect content ;
1154 if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr )
1155 {
1156 GetRegionBounds( rgn , &content ) ;
1157 DisposeRgn( rgn ) ;
1158 }
1159 else
1160 {
1161 GetControlBounds( (ControlRef) m_macControl , &content ) ;
1162 }
1163 #if !TARGET_API_MAC_OSX
1164 Rect structure ;
1165 GetControlBounds( (ControlRef) m_macControl , &structure ) ;
1166 OffsetRect( &content , -structure.left , -structure.top ) ;
1167 #endif
1168 ww = content.right - content.left ;
1169 hh = content.bottom - content.top ;
1170
1171 ww -= MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
1172 hh -= MacGetTopBorderSize( ) + MacGetBottomBorderSize( );
1173
1174 if ( (m_vScrollBar && m_vScrollBar->IsShown()) || (m_hScrollBar && m_hScrollBar->IsShown()) )
1175 {
1176 int x1 = 0 ;
1177 int y1 = 0 ;
1178 int w ;
1179 int h ;
1180 GetSize( &w , &h ) ;
1181
1182 MacClientToRootWindow( &x1 , &y1 ) ;
1183 MacClientToRootWindow( &w , &h ) ;
1184
1185 wxWindowMac *iter = (wxWindowMac*)this ;
1186
1187 int totW = 10000 , totH = 10000;
1188 while( iter )
1189 {
1190 if ( iter->IsTopLevel() )
1191 {
1192 iter->GetSize( &totW , &totH ) ;
1193 break ;
1194 }
1195
1196 iter = iter->GetParent() ;
1197 }
1198
1199 if (m_hScrollBar && m_hScrollBar->IsShown() )
1200 {
1201 hh -= MAC_SCROLLBAR_SIZE;
1202 if ( h-y1 >= totH )
1203 {
1204 hh += 1 ;
1205 }
1206 }
1207 if (m_vScrollBar && m_vScrollBar->IsShown() )
1208 {
1209 ww -= MAC_SCROLLBAR_SIZE;
1210 if ( w-x1 >= totW )
1211 {
1212 ww += 1 ;
1213 }
1214 }
1215 }
1216 if(x) *x = ww;
1217 if(y) *y = hh;
1218
1219 }
1220
1221 bool wxWindowMac::SetCursor(const wxCursor& cursor)
1222 {
1223 if (m_cursor == cursor)
1224 return FALSE;
1225
1226 if (wxNullCursor == cursor)
1227 {
1228 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
1229 return FALSE ;
1230 }
1231 else
1232 {
1233 if ( ! wxWindowBase::SetCursor( cursor ) )
1234 return FALSE ;
1235 }
1236
1237 wxASSERT_MSG( m_cursor.Ok(),
1238 wxT("cursor must be valid after call to the base version"));
1239
1240 /*
1241
1242 TODO why do we have to use current coordinates ?
1243
1244 Point pt ;
1245 wxWindowMac *mouseWin ;
1246 GetMouse( &pt ) ;
1247
1248 // Change the cursor NOW if we're within the correct window
1249
1250
1251 if ( MacGetWindowFromPoint( wxPoint( pt.h , pt.v ) , &mouseWin ) )
1252 {
1253 if ( mouseWin == this && !wxIsBusy() )
1254 {
1255 m_cursor.MacInstall() ;
1256 }
1257 }
1258 */
1259 if ( !wxIsBusy() )
1260 {
1261 m_cursor.MacInstall() ;
1262 }
1263
1264 return TRUE ;
1265 }
1266
1267 #if wxUSE_MENUS
1268 bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1269 {
1270 menu->SetInvokingWindow(this);
1271 menu->UpdateUI();
1272 ClientToScreen( &x , &y ) ;
1273
1274 menu->MacBeforeDisplay( true ) ;
1275 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ;
1276 if ( HiWord(menuResult) != 0 )
1277 {
1278 MenuCommand id ;
1279 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ;
1280 wxMenuItem* item = NULL ;
1281 wxMenu* realmenu ;
1282 item = menu->FindItem(id, &realmenu) ;
1283 if (item->IsCheckable())
1284 {
1285 item->Check( !item->IsChecked() ) ;
1286 }
1287 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1288 }
1289 menu->MacAfterDisplay( true ) ;
1290
1291 menu->SetInvokingWindow(NULL);
1292
1293 return TRUE;
1294 }
1295 #endif
1296
1297 // ----------------------------------------------------------------------------
1298 // tooltips
1299 // ----------------------------------------------------------------------------
1300
1301 #if wxUSE_TOOLTIPS
1302
1303 void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
1304 {
1305 wxWindowBase::DoSetToolTip(tooltip);
1306
1307 if ( m_tooltip )
1308 m_tooltip->SetWindow(this);
1309 }
1310
1311 #endif // wxUSE_TOOLTIPS
1312
1313 void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
1314 {
1315 int former_x , former_y , former_w, former_h ;
1316 #if !TARGET_API_MAC_OSX
1317 DoGetPosition( &former_x , &former_y ) ;
1318 DoGetSize( &former_w , &former_h ) ;
1319 #else
1320 MacGetPositionAndSizeFromControl( former_x , former_y , former_w , former_h ) ;
1321 #endif
1322
1323 int actualWidth = width;
1324 int actualHeight = height;
1325 int actualX = x;
1326 int actualY = y;
1327
1328 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
1329 actualWidth = m_minWidth;
1330 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
1331 actualHeight = m_minHeight;
1332 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
1333 actualWidth = m_maxWidth;
1334 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
1335 actualHeight = m_maxHeight;
1336
1337 bool doMove = false ;
1338 bool doResize = false ;
1339
1340 if ( actualX != former_x || actualY != former_y )
1341 {
1342 doMove = true ;
1343 }
1344 if ( actualWidth != former_w || actualHeight != former_h )
1345 {
1346 doResize = true ;
1347 }
1348
1349 if ( doMove || doResize )
1350 {
1351 Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) ) ;
1352 #if TARGET_API_MAC_OSX
1353 SetControlBounds( (ControlRef) m_macControl , &r ) ;
1354 #else
1355 if ( doMove )
1356 MoveControl( (ControlRef) m_macControl , r.left , r.top ) ;
1357 if ( doSize )
1358 SizeControl( (ControlRef) m_macControl , r.right-r.left , r.bottom-r.top ) ;
1359 #endif
1360 MacRepositionScrollBars() ;
1361 if ( doMove )
1362 {
1363 wxPoint point(actualX,actualY);
1364 wxMoveEvent event(point, m_windowId);
1365 event.SetEventObject(this);
1366 GetEventHandler()->ProcessEvent(event) ;
1367 }
1368 if ( doResize )
1369 {
1370 MacRepositionScrollBars() ;
1371 wxSize size(actualWidth, actualHeight);
1372 wxSizeEvent event(size, m_windowId);
1373 event.SetEventObject(this);
1374 GetEventHandler()->ProcessEvent(event);
1375 }
1376 }
1377
1378 }
1379
1380 wxSize wxWindowMac::DoGetBestSize() const
1381 {
1382 if ( m_macIsUserPane || IsTopLevel() )
1383 return wxWindowBase::DoGetBestSize() ;
1384
1385 Rect bestsize = { 0 , 0 , 0 , 0 } ;
1386 short baselineoffset ;
1387 int bestWidth, bestHeight ;
1388 ::GetBestControlRect( (ControlRef) m_macControl , &bestsize , &baselineoffset ) ;
1389
1390 if ( EmptyRect( &bestsize ) )
1391 {
1392 baselineoffset = 0;
1393 bestsize.left = bestsize.top = 0 ;
1394 bestsize.right = 16 ;
1395 bestsize.bottom = 16 ;
1396 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1397 {
1398 bestsize.bottom = 16 ;
1399 }
1400 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1401 {
1402 bestsize.bottom = 24 ;
1403 }
1404 else
1405 {
1406 // return wxWindowBase::DoGetBestSize() ;
1407 }
1408 }
1409
1410 bestWidth = bestsize.right - bestsize.left ;
1411 bestHeight = bestsize.bottom - bestsize.top ;
1412 if ( bestHeight < 10 )
1413 bestHeight = 13 ;
1414
1415 return wxSize(bestWidth, bestHeight);
1416 // return wxWindowBase::DoGetBestSize() ;
1417 }
1418
1419
1420 // set the size of the window: if the dimensions are positive, just use them,
1421 // but if any of them is equal to -1, it means that we must find the value for
1422 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1423 // which case -1 is a valid value for x and y)
1424 //
1425 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1426 // the width/height to best suit our contents, otherwise we reuse the current
1427 // width/height
1428 void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1429 {
1430 // get the current size and position...
1431 int currentX, currentY;
1432 GetPosition(&currentX, &currentY);
1433
1434 int currentW,currentH;
1435 GetSize(&currentW, &currentH);
1436
1437 // ... and don't do anything (avoiding flicker) if it's already ok
1438 if ( x == currentX && y == currentY &&
1439 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
1440 {
1441 // TODO REMOVE
1442 MacRepositionScrollBars() ; // we might have a real position shift
1443 return;
1444 }
1445
1446 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1447 x = currentX;
1448 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1449 y = currentY;
1450
1451 AdjustForParentClientOrigin(x, y, sizeFlags);
1452
1453 wxSize size(-1, -1);
1454 if ( width == -1 )
1455 {
1456 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
1457 {
1458 size = DoGetBestSize();
1459 width = size.x;
1460 }
1461 else
1462 {
1463 // just take the current one
1464 width = currentW;
1465 }
1466 }
1467
1468 if ( height == -1 )
1469 {
1470 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
1471 {
1472 if ( size.x == -1 )
1473 {
1474 size = DoGetBestSize();
1475 }
1476 //else: already called DoGetBestSize() above
1477
1478 height = size.y;
1479 }
1480 else
1481 {
1482 // just take the current one
1483 height = currentH;
1484 }
1485 }
1486
1487 DoMoveWindow(x, y, width, height);
1488
1489 }
1490
1491 wxPoint wxWindowMac::GetClientAreaOrigin() const
1492 {
1493 RgnHandle rgn = NewRgn() ;
1494 Rect content ;
1495 GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) ;
1496 GetRegionBounds( rgn , &content ) ;
1497 DisposeRgn( rgn ) ;
1498 #if !TARGET_API_MAC_OSX
1499 Rect structure ;
1500 GetControlBounds( (ControlRef) m_macControl , &structure ) ;
1501 OffsetRect( &content , -structure.left , -structure.top ) ;
1502 #endif
1503
1504 return wxPoint( content.left + MacGetLeftBorderSize( ) , content.top + MacGetTopBorderSize( ) );
1505 }
1506
1507 void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
1508 {
1509 if ( clientheight != -1 || clientheight != -1 )
1510 {
1511 int currentclientwidth , currentclientheight ;
1512 int currentwidth , currentheight ;
1513
1514 GetClientSize( &currentclientwidth , &currentclientheight ) ;
1515 GetSize( &currentwidth , &currentheight ) ;
1516
1517 DoSetSize( -1 , -1 , currentwidth + clientwidth - currentclientwidth ,
1518 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
1519 }
1520 }
1521
1522 void wxWindowMac::SetTitle(const wxString& title)
1523 {
1524 m_label = wxStripMenuCodes(title) ;
1525
1526 if ( m_macControl )
1527 {
1528 UMASetControlTitle( (ControlRef) m_macControl , m_label , m_font.GetEncoding() ) ;
1529 }
1530 Refresh() ;
1531 }
1532
1533 wxString wxWindowMac::GetTitle() const
1534 {
1535 return m_label ;
1536 }
1537
1538 bool wxWindowMac::Show(bool show)
1539 {
1540 if ( !wxWindowBase::Show(show) )
1541 return FALSE;
1542
1543 // TODO use visibilityChanged Carbon Event for OSX
1544 bool former = MacIsReallyShown() ;
1545
1546 SetControlVisibility( (ControlRef) m_macControl , show , true ) ;
1547 if ( former != MacIsReallyShown() )
1548 MacPropagateVisibilityChanged() ;
1549 return TRUE;
1550 }
1551
1552 bool wxWindowMac::Enable(bool enable)
1553 {
1554 wxASSERT( m_macControl != NULL ) ;
1555 if ( !wxWindowBase::Enable(enable) )
1556 return FALSE;
1557
1558 bool former = MacIsReallyEnabled() ;
1559 if ( enable )
1560 EnableControl( (ControlRef) m_macControl ) ;
1561 else
1562 DisableControl( (ControlRef) m_macControl ) ;
1563
1564 if ( former != MacIsReallyEnabled() )
1565 MacPropagateEnabledStateChanged() ;
1566 return TRUE;
1567 }
1568
1569 //
1570 // status change propagations (will be not necessary for OSX later )
1571 //
1572
1573 void wxWindowMac::MacPropagateVisibilityChanged()
1574 {
1575 #if !TARGET_API_MAC_OSX
1576 MacVisibilityChanged() ;
1577
1578 wxWindowListNode *node = GetChildren().GetFirst();
1579 while ( node )
1580 {
1581 wxWindowMac *child = node->GetData();
1582 if ( child->IsShown() )
1583 child->MacPropagateVisibilityChanged( ) ;
1584 node = node->GetNext();
1585 }
1586 #endif
1587 }
1588
1589 void wxWindowMac::MacPropagateEnabledStateChanged( )
1590 {
1591 #if !TARGET_API_MAC_OSX
1592 MacEnabledStateChanged() ;
1593
1594 wxWindowListNode *node = GetChildren().GetFirst();
1595 while ( node )
1596 {
1597 wxWindowMac *child = node->GetData();
1598 if ( child->IsEnabled() )
1599 child->MacPropagateEnabledStateChanged() ;
1600 node = node->GetNext();
1601 }
1602 #endif
1603 }
1604
1605 void wxWindowMac::MacPropagateHiliteChanged( )
1606 {
1607 #if !TARGET_API_MAC_OSX
1608 MacHiliteChanged() ;
1609
1610 wxWindowListNode *node = GetChildren().GetFirst();
1611 while ( node )
1612 {
1613 wxWindowMac *child = node->GetData();
1614 // if ( child->IsEnabled() )
1615 child->MacPropagateHiliteChanged() ;
1616 node = node->GetNext();
1617 }
1618 #endif
1619 }
1620
1621 //
1622 // status change notifications
1623 //
1624
1625 void wxWindowMac::MacVisibilityChanged()
1626 {
1627 }
1628
1629 void wxWindowMac::MacHiliteChanged()
1630 {
1631 }
1632
1633 void wxWindowMac::MacEnabledStateChanged()
1634 {
1635 }
1636
1637 //
1638 // status queries on the inherited window's state
1639 //
1640
1641 bool wxWindowMac::MacIsReallyShown()
1642 {
1643 // only under OSX the visibility of the TLW is taken into account
1644 #if TARGET_API_MAC_OSX
1645 return IsControlVisible( (ControlRef) m_macControl ) ;
1646 #else
1647 wxWindow* win = this ;
1648 while( win->IsShown() )
1649 {
1650 if ( win->IsTopLevel() )
1651 return true ;
1652
1653 win = win->GetParent() ;
1654 if ( win == NULL )
1655 return true ;
1656
1657 } ;
1658 return false ;
1659 #endif
1660 }
1661
1662 bool wxWindowMac::MacIsReallyEnabled()
1663 {
1664 return IsControlEnabled( (ControlRef) m_macControl ) ;
1665 }
1666
1667 bool wxWindowMac::MacIsReallyHilited()
1668 {
1669 return IsControlActive( (ControlRef) m_macControl ) ;
1670 }
1671
1672 //
1673 //
1674 //
1675
1676 int wxWindowMac::GetCharHeight() const
1677 {
1678 wxClientDC dc ( (wxWindowMac*)this ) ;
1679 return dc.GetCharHeight() ;
1680 }
1681
1682 int wxWindowMac::GetCharWidth() const
1683 {
1684 wxClientDC dc ( (wxWindowMac*)this ) ;
1685 return dc.GetCharWidth() ;
1686 }
1687
1688 void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
1689 int *descent, int *externalLeading, const wxFont *theFont ) const
1690 {
1691 const wxFont *fontToUse = theFont;
1692 if ( !fontToUse )
1693 fontToUse = &m_font;
1694
1695 wxClientDC dc( (wxWindowMac*) this ) ;
1696 long lx,ly,ld,le ;
1697 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
1698 if ( externalLeading )
1699 *externalLeading = le ;
1700 if ( descent )
1701 *descent = ld ;
1702 if ( x )
1703 *x = lx ;
1704 if ( y )
1705 *y = ly ;
1706 }
1707
1708 /*
1709 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1710 * we always intersect with the entire window, not only with the client area
1711 */
1712
1713 void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
1714 {
1715 #if TARGET_API_MAC_OSX
1716 if ( rect == NULL )
1717 HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ;
1718 else
1719 {
1720 RgnHandle update = NewRgn() ;
1721 SetRectRgn( update , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
1722 SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , update , update ) ;
1723 HIViewSetNeedsDisplayInRegion( (ControlRef) m_macControl , update , true ) ;
1724 }
1725 #else
1726 if ( IsControlVisible( (ControlRef) m_macControl ) )
1727 {
1728 SetControlVisibility( (ControlRef) m_macControl , false , false ) ;
1729 SetControlVisibility( (ControlRef) m_macControl , true , true ) ;
1730 }
1731 /*
1732 if ( MacGetTopLevelWindow() == NULL )
1733 return ;
1734
1735 if ( !IsControlVisible( (ControlRef) m_macControl ) )
1736 return ;
1737
1738 wxPoint client = GetClientAreaOrigin();
1739 int x1 = -client.x;
1740 int y1 = -client.y;
1741 int x2 = m_width - client.x;
1742 int y2 = m_height - client.y;
1743
1744 if (IsKindOf( CLASSINFO(wxButton)))
1745 {
1746 // buttons have an "aura"
1747 y1 -= 5;
1748 x1 -= 5;
1749 y2 += 5;
1750 x2 += 5;
1751 }
1752
1753 Rect clientrect = { y1, x1, y2, x2 };
1754
1755 if ( rect )
1756 {
1757 Rect r = { rect->y , rect->x , rect->y + rect->height , rect->x + rect->width } ;
1758 SectRect( &clientrect , &r , &clientrect ) ;
1759 }
1760
1761 if ( !EmptyRect( &clientrect ) )
1762 {
1763 int top = 0 , left = 0 ;
1764
1765 MacClientToRootWindow( &left , &top ) ;
1766 OffsetRect( &clientrect , left , top ) ;
1767
1768 MacGetTopLevelWindow()->MacInvalidate( &clientrect , eraseBack ) ;
1769 }
1770 */
1771 #endif
1772 }
1773
1774 void wxWindowMac::MacRedrawControl()
1775 {
1776 /*
1777 if ( (ControlRef) m_macControl && MacGetTopLevelWindowRef() && IsControlVisible( (ControlRef) m_macControl ) )
1778 {
1779 #if TARGET_API_MAC_CARBON
1780 Update() ;
1781 #else
1782 wxClientDC dc(this) ;
1783 wxMacPortSetter helper(&dc) ;
1784 wxMacWindowClipper clipper(this) ;
1785 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
1786 UMADrawControl( (ControlRef) m_macControl ) ;
1787 #endif
1788 }
1789 */
1790 }
1791
1792 /* TODO
1793 void wxWindowMac::OnPaint(wxPaintEvent& event)
1794 {
1795 // why don't we skip that here ?
1796 }
1797 */
1798
1799 wxWindowMac *wxGetActiveWindow()
1800 {
1801 // actually this is a windows-only concept
1802 return NULL;
1803 }
1804
1805 // Coordinates relative to the window
1806 void wxWindowMac::WarpPointer (int x_pos, int y_pos)
1807 {
1808 // We really don't move the mouse programmatically under Mac.
1809 }
1810
1811 void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
1812 {
1813 if ( m_macBackgroundBrush.Ok() == false || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT )
1814 {
1815 event.Skip() ;
1816 }
1817 else
1818 event.GetDC()->Clear() ;
1819 }
1820
1821 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
1822 {
1823 wxWindowDC dc(this) ;
1824 wxMacPortSetter helper(&dc) ;
1825
1826 MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ;
1827 }
1828
1829 int wxWindowMac::GetScrollPos(int orient) const
1830 {
1831 if ( orient == wxHORIZONTAL )
1832 {
1833 if ( m_hScrollBar )
1834 return m_hScrollBar->GetThumbPosition() ;
1835 }
1836 else
1837 {
1838 if ( m_vScrollBar )
1839 return m_vScrollBar->GetThumbPosition() ;
1840 }
1841 return 0;
1842 }
1843
1844 // This now returns the whole range, not just the number
1845 // of positions that we can scroll.
1846 int wxWindowMac::GetScrollRange(int orient) const
1847 {
1848 if ( orient == wxHORIZONTAL )
1849 {
1850 if ( m_hScrollBar )
1851 return m_hScrollBar->GetRange() ;
1852 }
1853 else
1854 {
1855 if ( m_vScrollBar )
1856 return m_vScrollBar->GetRange() ;
1857 }
1858 return 0;
1859 }
1860
1861 int wxWindowMac::GetScrollThumb(int orient) const
1862 {
1863 if ( orient == wxHORIZONTAL )
1864 {
1865 if ( m_hScrollBar )
1866 return m_hScrollBar->GetThumbSize() ;
1867 }
1868 else
1869 {
1870 if ( m_vScrollBar )
1871 return m_vScrollBar->GetThumbSize() ;
1872 }
1873 return 0;
1874 }
1875
1876 void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
1877 {
1878 if ( orient == wxHORIZONTAL )
1879 {
1880 if ( m_hScrollBar )
1881 m_hScrollBar->SetThumbPosition( pos ) ;
1882 }
1883 else
1884 {
1885 if ( m_vScrollBar )
1886 m_vScrollBar->SetThumbPosition( pos ) ;
1887 }
1888 }
1889
1890 void wxWindowMac::MacPaintBorders( int left , int top )
1891 {
1892 if( IsTopLevel() )
1893 return ;
1894
1895 int major,minor;
1896 wxGetOsVersion( &major, &minor );
1897
1898 RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ;
1899 RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ;
1900
1901 RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ;
1902 RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ;
1903 // OS X has lighter border edges than classic:
1904 if (major >= 10)
1905 {
1906 darkShadow.red = 0x8E8E;
1907 darkShadow.green = 0x8E8E;
1908 darkShadow.blue = 0x8E8E;
1909 lightShadow.red = 0xBDBD;
1910 lightShadow.green = 0xBDBD;
1911 lightShadow.blue = 0xBDBD;
1912 }
1913
1914 PenNormal() ;
1915
1916 int w , h ;
1917 GetSize( &w , &h ) ;
1918 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
1919 {
1920 #if wxMAC_USE_THEME_BORDER
1921 Rect rect = { top , left , m_height + top , m_width + left } ;
1922 SInt32 border = 0 ;
1923 /*
1924 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
1925 InsetRect( &rect , border , border );
1926 DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
1927 */
1928
1929 DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
1930 #else
1931 bool sunken = HasFlag( wxSUNKEN_BORDER ) ;
1932 RGBForeColor( &face );
1933 MoveTo( left + 0 , top + h - 2 );
1934 LineTo( left + 0 , top + 0 );
1935 LineTo( left + w - 2 , top + 0 );
1936
1937 MoveTo( left + 2 , top + h - 3 );
1938 LineTo( left + w - 3 , top + h - 3 );
1939 LineTo( left + w - 3 , top + 2 );
1940
1941 RGBForeColor( sunken ? &face : &darkShadow );
1942 MoveTo( left + 0 , top + h - 1 );
1943 LineTo( left + w - 1 , top + h - 1 );
1944 LineTo( left + w - 1 , top + 0 );
1945
1946 RGBForeColor( sunken ? &lightShadow : &white );
1947 MoveTo( left + 1 , top + h - 3 );
1948 LineTo( left + 1, top + 1 );
1949 LineTo( left + w - 3 , top + 1 );
1950
1951 RGBForeColor( sunken ? &white : &lightShadow );
1952 MoveTo( left + 1 , top + h - 2 );
1953 LineTo( left + w - 2 , top + h - 2 );
1954 LineTo( left + w - 2 , top + 1 );
1955
1956 RGBForeColor( sunken ? &darkShadow : &face );
1957 MoveTo( left + 2 , top + h - 4 );
1958 LineTo( left + 2 , top + 2 );
1959 LineTo( left + w - 4 , top + 2 );
1960 #endif
1961 }
1962 else if (HasFlag(wxSIMPLE_BORDER))
1963 {
1964 Rect rect = { top , left , h + top , w + left } ;
1965 RGBForeColor( &darkShadow ) ;
1966 FrameRect( &rect ) ;
1967 }
1968 }
1969
1970 void wxWindowMac::RemoveChild( wxWindowBase *child )
1971 {
1972 if ( child == m_hScrollBar )
1973 m_hScrollBar = NULL ;
1974 if ( child == m_vScrollBar )
1975 m_vScrollBar = NULL ;
1976
1977 wxWindowBase::RemoveChild( child ) ;
1978 }
1979
1980 // New function that will replace some of the above.
1981 void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
1982 int range, bool refresh)
1983 {
1984 if ( orient == wxHORIZONTAL )
1985 {
1986 if ( m_hScrollBar )
1987 {
1988 if ( range == 0 || thumbVisible >= range )
1989 {
1990 if ( m_hScrollBar->IsShown() )
1991 m_hScrollBar->Show(false) ;
1992 }
1993 else
1994 {
1995 if ( !m_hScrollBar->IsShown() )
1996 m_hScrollBar->Show(true) ;
1997 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
1998 }
1999 }
2000 }
2001 else
2002 {
2003 if ( m_vScrollBar )
2004 {
2005 if ( range == 0 || thumbVisible >= range )
2006 {
2007 if ( m_vScrollBar->IsShown() )
2008 m_vScrollBar->Show(false) ;
2009 }
2010 else
2011 {
2012 if ( !m_vScrollBar->IsShown() )
2013 m_vScrollBar->Show(true) ;
2014 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2015 }
2016 }
2017 }
2018 MacRepositionScrollBars() ;
2019 }
2020
2021 // Does a physical scroll
2022 void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
2023 {
2024 if( dx == 0 && dy ==0 )
2025 return ;
2026
2027
2028 {
2029 wxClientDC dc(this) ;
2030 wxMacPortSetter helper(&dc) ;
2031
2032 int width , height ;
2033 GetClientSize( &width , &height ) ;
2034
2035
2036 wxPoint pos;
2037 pos.x = pos.y = 0;
2038
2039 Rect scrollrect;
2040 // TODO take out the boundaries
2041 GetControlBounds( (ControlRef) m_macControl, &scrollrect);
2042
2043 RgnHandle updateRgn = NewRgn() ;
2044 if ( rect )
2045 {
2046 Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
2047 dc.XLOG2DEVMAC(rect->x + rect->width) } ;
2048 SectRect( &scrollrect , &r , &scrollrect ) ;
2049 }
2050 ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
2051 #if TARGET_CARBON
2052 //KO: The docs say ScrollRect creates an update region, which thus calls an update event
2053 // but it seems the update only refreshes the background of the control, rather than calling
2054 // kEventControlDraw, so we need to force a proper update here. There has to be a better
2055 // way of doing this... (Note that code below under !TARGET_CARBON does not work either...)
2056 Update();
2057 #endif
2058 // we also have to scroll the update rgn in this rectangle
2059 // in order not to loose updates
2060 #if !TARGET_CARBON
2061 WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ;
2062 RgnHandle formerUpdateRgn = NewRgn() ;
2063 RgnHandle scrollRgn = NewRgn() ;
2064 RectRgn( scrollRgn , &scrollrect ) ;
2065 GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ;
2066 Point pt = {0,0} ;
2067 LocalToGlobal( &pt ) ;
2068 OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ;
2069 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
2070 if ( !EmptyRgn( formerUpdateRgn ) )
2071 {
2072 MacOffsetRgn( formerUpdateRgn , dx , dy ) ;
2073 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
2074 InvalWindowRgn(rootWindow , formerUpdateRgn ) ;
2075 }
2076 InvalWindowRgn(rootWindow , updateRgn ) ;
2077 DisposeRgn( updateRgn ) ;
2078 DisposeRgn( formerUpdateRgn ) ;
2079 DisposeRgn( scrollRgn ) ;
2080 #endif
2081 }
2082
2083 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
2084 {
2085 wxWindowMac *child = node->GetData();
2086 if (child == m_vScrollBar) continue;
2087 if (child == m_hScrollBar) continue;
2088 if (child->IsTopLevel()) continue;
2089
2090 int x,y;
2091 child->GetPosition( &x, &y );
2092 int w,h;
2093 child->GetSize( &w, &h );
2094 if (rect)
2095 {
2096 wxRect rc(x,y,w,h);
2097 if (rect->Intersects(rc))
2098 child->SetSize( x+dx, y+dy, w, h );
2099 }
2100 else
2101 {
2102 child->SetSize( x+dx, y+dy, w, h );
2103 }
2104 }
2105
2106 // TODO remove, was moved higher up Update() ;
2107
2108 }
2109
2110 void wxWindowMac::MacOnScroll(wxScrollEvent &event )
2111 {
2112 if ( event.m_eventObject == m_vScrollBar || event.m_eventObject == m_hScrollBar )
2113 {
2114 wxScrollWinEvent wevent;
2115 wevent.SetPosition(event.GetPosition());
2116 wevent.SetOrientation(event.GetOrientation());
2117 wevent.m_eventObject = this;
2118
2119 if (event.m_eventType == wxEVT_SCROLL_TOP)
2120 wevent.m_eventType = wxEVT_SCROLLWIN_TOP;
2121 else if (event.m_eventType == wxEVT_SCROLL_BOTTOM)
2122 wevent.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
2123 else if (event.m_eventType == wxEVT_SCROLL_LINEUP)
2124 wevent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
2125 else if (event.m_eventType == wxEVT_SCROLL_LINEDOWN)
2126 wevent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
2127 else if (event.m_eventType == wxEVT_SCROLL_PAGEUP)
2128 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
2129 else if (event.m_eventType == wxEVT_SCROLL_PAGEDOWN)
2130 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
2131 else if (event.m_eventType == wxEVT_SCROLL_THUMBTRACK)
2132 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
2133 else if (event.m_eventType == wxEVT_SCROLL_THUMBRELEASE)
2134 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
2135
2136 GetEventHandler()->ProcessEvent(wevent);
2137 }
2138 }
2139
2140 // Get the window with the focus
2141 wxWindowMac *wxWindowBase::FindFocus()
2142 {
2143 return gFocusWindow ;
2144 }
2145
2146 void wxWindowMac::OnSetFocus(wxFocusEvent& event)
2147 {
2148 // panel wants to track the window which was the last to have focus in it,
2149 // so we want to set ourselves as the window which last had focus
2150 //
2151 // notice that it's also important to do it upwards the tree becaus
2152 // otherwise when the top level panel gets focus, it won't set it back to
2153 // us, but to some other sibling
2154
2155 // CS:don't know if this is still needed:
2156 //wxChildFocusEvent eventFocus(this);
2157 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2158
2159 event.Skip();
2160 }
2161
2162 void wxWindowMac::OnInternalIdle()
2163 {
2164 // This calls the UI-update mechanism (querying windows for
2165 // menu/toolbar/control state information)
2166 if (wxUpdateUIEvent::CanUpdate(this))
2167 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
2168 }
2169
2170 // Raise the window to the top of the Z order
2171 void wxWindowMac::Raise()
2172 {
2173 }
2174
2175 // Lower the window to the bottom of the Z order
2176 void wxWindowMac::Lower()
2177 {
2178 }
2179
2180
2181 // static wxWindow *gs_lastWhich = NULL;
2182
2183 bool wxWindowMac::MacSetupCursor( const wxPoint& pt)
2184 {
2185 // first trigger a set cursor event
2186
2187 wxPoint clientorigin = GetClientAreaOrigin() ;
2188 wxSize clientsize = GetClientSize() ;
2189 wxCursor cursor ;
2190 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
2191 {
2192 wxSetCursorEvent event( pt.x , pt.y );
2193
2194 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2195 if ( processedEvtSetCursor && event.HasCursor() )
2196 {
2197 cursor = event.GetCursor() ;
2198 }
2199 else
2200 {
2201
2202 // the test for processedEvtSetCursor is here to prevent using m_cursor
2203 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2204 // it - this is a way to say that our cursor shouldn't be used for this
2205 // point
2206 if ( !processedEvtSetCursor && m_cursor.Ok() )
2207 {
2208 cursor = m_cursor ;
2209 }
2210 if ( wxIsBusy() )
2211 {
2212 }
2213 else
2214 {
2215 if ( !GetParent() )
2216 cursor = *wxSTANDARD_CURSOR ;
2217 }
2218 }
2219 if ( cursor.Ok() )
2220 cursor.MacInstall() ;
2221 }
2222 return cursor.Ok() ;
2223 }
2224
2225 wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
2226 {
2227 if ( m_tooltip )
2228 {
2229 return m_tooltip->GetTip() ;
2230 }
2231 return wxEmptyString ;
2232 }
2233
2234 void wxWindowMac::Update()
2235 {
2236 #if TARGET_API_MAC_OSX
2237 HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ;
2238 #else
2239 ::Draw1Control( (ControlRef) m_macControl ) ;
2240 #endif
2241 }
2242
2243 wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
2244 {
2245 wxTopLevelWindowMac* win = NULL ;
2246 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
2247 if ( window )
2248 {
2249 win = wxFindWinFromMacWindow( window ) ;
2250 }
2251 return win ;
2252 }
2253 wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
2254 {
2255
2256 Rect r ;
2257 RgnHandle visRgn = NewRgn() ;
2258 RgnHandle tempRgn = NewRgn() ;
2259 if ( IsControlVisible( (ControlRef) m_macControl ) )
2260 {
2261 GetControlBounds( (ControlRef) m_macControl , &r ) ;
2262 if (! MacGetTopLevelWindow()->MacUsesCompositing() )
2263 {
2264 MacRootWindowToWindow( &r.left , & r.top ) ;
2265 MacRootWindowToWindow( &r.right , & r.bottom ) ;
2266 }
2267 else
2268 {
2269 r.right -= r.left ;
2270 r.bottom -= r.top ;
2271 r.left = 0 ;
2272 r.top = 0 ;
2273 }
2274 if ( includeOuterStructures )
2275 InsetRect( &r , -3 , -3 ) ;
2276 RectRgn( visRgn , &r ) ;
2277 if ( !IsTopLevel() )
2278 {
2279 wxWindow* child = this ;
2280 wxWindow* parent = child->GetParent() ;
2281 while( parent )
2282 {
2283 int x , y ;
2284 wxSize size ;
2285 // we have to find a better clipping algorithm here, in order not to clip things
2286 // positioned like status and toolbar
2287 if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ )
2288 {
2289 size = parent->GetSize() ;
2290 x = y = 0 ;
2291 }
2292 else
2293 {
2294 size = parent->GetClientSize() ;
2295 wxPoint origin = parent->GetClientAreaOrigin() ;
2296 x = origin.x ;
2297 y = origin.y ;
2298 }
2299 parent->MacWindowToRootWindow( &x, &y ) ;
2300 MacRootWindowToWindow( &x , &y ) ;
2301
2302 SetRectRgn( tempRgn ,
2303 x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
2304 x + size.x - parent->MacGetRightBorderSize(),
2305 y + size.y - parent->MacGetBottomBorderSize()) ;
2306
2307 SectRgn( visRgn , tempRgn , visRgn ) ;
2308 if ( parent->IsTopLevel() )
2309 break ;
2310 child = parent ;
2311 parent = child->GetParent() ;
2312 }
2313 }
2314 }
2315
2316 wxRegion vis = visRgn ;
2317 DisposeRgn( visRgn ) ;
2318 DisposeRgn( tempRgn ) ;
2319 return vis ;
2320 }
2321
2322 /*
2323 This function must not change the updatergn !
2324 */
2325 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
2326 {
2327 // we let the OS handle root control redraws
2328 if ( m_macControl == MacGetTopLevelWindow()->GetHandle() )
2329 return false ;
2330
2331 RgnHandle updatergn = (RgnHandle) updatergnr ;
2332 bool handled = false ;
2333
2334 // calculate a client-origin version of the update rgn and set m_updateRegion to that
2335 {
2336 RgnHandle newupdate = NewRgn() ;
2337 wxSize point = GetClientSize() ;
2338 wxPoint origin = GetClientAreaOrigin() ;
2339 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ;
2340 SectRgn( newupdate , updatergn , newupdate ) ;
2341 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
2342 m_updateRegion = newupdate ;
2343 DisposeRgn( newupdate ) ;
2344 }
2345
2346 if ( !EmptyRgn(updatergn) )
2347 {
2348 wxWindowDC dc(this);
2349 if (!EmptyRgn(updatergn))
2350 dc.SetClippingRegion(wxRegion(updatergn));
2351
2352 wxEraseEvent eevent( GetId(), &dc );
2353 eevent.SetEventObject( this );
2354 GetEventHandler()->ProcessEvent( eevent );
2355
2356 if ( !m_updateRegion.Empty() )
2357 {
2358 // paint the window itself
2359 wxPaintEvent event;
2360 event.m_timeStamp = time ;
2361 event.SetEventObject(this);
2362 handled = GetEventHandler()->ProcessEvent(event);
2363
2364 // paint custom borders
2365 wxNcPaintEvent eventNc( GetId() );
2366 eventNc.SetEventObject( this );
2367 GetEventHandler()->ProcessEvent( eventNc );
2368 }
2369 }
2370 return handled ;
2371 }
2372
2373 void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
2374 {
2375 RgnHandle updatergn = (RgnHandle) updatergnr ;
2376 // updatergn is always already clipped to our boundaries
2377 // if we are in compositing mode then it is in relative to the upper left of the control
2378 // if we are in non-compositing, then it is relatvie to the uppder left of the content area
2379 // of the toplevel window
2380 // it is in window coordinates, not in client coordinates
2381
2382 // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates
2383 RgnHandle ownUpdateRgn = NewRgn() ;
2384 CopyRgn( updatergn , ownUpdateRgn ) ;
2385
2386 if ( MacGetTopLevelWindow()->MacUsesCompositing() == false )
2387 {
2388 Rect bounds;
2389 UMAGetControlBoundsInWindowCoords( (ControlRef)m_macControl, &bounds );
2390 RgnHandle controlRgn = NewRgn();
2391 RectRgn( controlRgn, &bounds );
2392 //KO: This sets the ownUpdateRgn to the area of this control that is inside
2393 // the window update region
2394 SectRgn( ownUpdateRgn, controlRgn, ownUpdateRgn );
2395 DisposeRgn( controlRgn );
2396
2397 //KO: convert ownUpdateRgn to local coordinates
2398 OffsetRgn( ownUpdateRgn, -bounds.left, -bounds.top );
2399 }
2400
2401 MacDoRedraw( ownUpdateRgn , time ) ;
2402 DisposeRgn( ownUpdateRgn ) ;
2403
2404 }
2405
2406 WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
2407 {
2408 wxWindowMac *iter = (wxWindowMac*)this ;
2409
2410 while( iter )
2411 {
2412 if ( iter->IsTopLevel() )
2413 return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
2414
2415 iter = iter->GetParent() ;
2416 }
2417 wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ;
2418 return NULL ;
2419 }
2420
2421 void wxWindowMac::MacCreateScrollBars( long style )
2422 {
2423 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
2424
2425 bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
2426 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ;
2427 int width, height ;
2428 GetClientSize( &width , &height ) ;
2429
2430 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2431 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2432 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2433 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2434
2435 m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint,
2436 vSize , wxVERTICAL);
2437
2438 if ( style & wxVSCROLL )
2439 {
2440
2441 }
2442 else
2443 {
2444 m_vScrollBar->Show(false) ;
2445 }
2446 m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint,
2447 hSize , wxHORIZONTAL);
2448 if ( style & wxHSCROLL )
2449 {
2450 }
2451 else
2452 {
2453 m_hScrollBar->Show(false) ;
2454 }
2455
2456 // because the create does not take into account the client area origin
2457 MacRepositionScrollBars() ; // we might have a real position shift
2458 }
2459
2460 void wxWindowMac::MacRepositionScrollBars()
2461 {
2462 bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
2463 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ;
2464
2465 // get real client area
2466
2467 int width ;
2468 int height ;
2469 GetSize( &width , &height ) ;
2470
2471 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
2472 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
2473
2474 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2475 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2476 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2477 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2478
2479 int x = 0 ;
2480 int y = 0 ;
2481 int w ;
2482 int h ;
2483 GetSize( &w , &h ) ;
2484
2485 MacClientToRootWindow( &x , &y ) ;
2486 MacClientToRootWindow( &w , &h ) ;
2487
2488 wxWindowMac *iter = (wxWindowMac*)this ;
2489
2490 int totW = 10000 , totH = 10000;
2491 while( iter )
2492 {
2493 if ( iter->IsTopLevel() )
2494 {
2495 iter->GetSize( &totW , &totH ) ;
2496 break ;
2497 }
2498
2499 iter = iter->GetParent() ;
2500 }
2501
2502 if ( x == 0 )
2503 {
2504 hPoint.x = -1 ;
2505 hSize.x += 1 ;
2506 }
2507 if ( y == 0 )
2508 {
2509 vPoint.y = -1 ;
2510 vSize.y += 1 ;
2511 }
2512
2513 if ( w-x >= totW )
2514 {
2515 hSize.x += 1 ;
2516 vPoint.x += 1 ;
2517 }
2518
2519 if ( h-y >= totH )
2520 {
2521 vSize.y += 1 ;
2522 hPoint.y += 1 ;
2523 }
2524
2525 if ( m_vScrollBar )
2526 {
2527 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE);
2528 }
2529 if ( m_hScrollBar )
2530 {
2531 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE);
2532 }
2533 }
2534
2535 bool wxWindowMac::AcceptsFocus() const
2536 {
2537 return MacCanFocus() && wxWindowBase::AcceptsFocus();
2538 }
2539
2540 void wxWindowMac::MacSuperChangedPosition()
2541 {
2542 // only window-absolute structures have to be moved i.e. controls
2543
2544 wxWindowListNode *node = GetChildren().GetFirst();
2545 while ( node )
2546 {
2547 wxWindowMac *child = node->GetData();
2548 child->MacSuperChangedPosition() ;
2549 node = node->GetNext();
2550 }
2551 }
2552
2553 void wxWindowMac::MacTopLevelWindowChangedPosition()
2554 {
2555 // only screen-absolute structures have to be moved i.e. glcanvas
2556
2557 wxWindowListNode *node = GetChildren().GetFirst();
2558 while ( node )
2559 {
2560 wxWindowMac *child = node->GetData();
2561 child->MacTopLevelWindowChangedPosition() ;
2562 node = node->GetNext();
2563 }
2564 }
2565
2566 long wxWindowMac::MacGetLeftBorderSize( ) const
2567 {
2568 if( IsTopLevel() )
2569 return 0 ;
2570
2571 if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER )
2572 {
2573 SInt32 border = 3 ;
2574 #if wxMAC_USE_THEME_BORDER
2575 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2576 #endif
2577 return border ;
2578 }
2579 else if ( m_windowStyle &wxDOUBLE_BORDER)
2580 {
2581 SInt32 border = 3 ;
2582 #if wxMAC_USE_THEME_BORDER
2583 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2584 #endif
2585 return border ;
2586 }
2587 else if (m_windowStyle &wxSIMPLE_BORDER)
2588 {
2589 return 1 ;
2590 }
2591 return 0 ;
2592 }
2593
2594 long wxWindowMac::MacGetRightBorderSize( ) const
2595 {
2596 // they are all symmetric in mac themes
2597 return MacGetLeftBorderSize() ;
2598 }
2599
2600 long wxWindowMac::MacGetTopBorderSize( ) const
2601 {
2602 // they are all symmetric in mac themes
2603 return MacGetLeftBorderSize() ;
2604 }
2605
2606 long wxWindowMac::MacGetBottomBorderSize( ) const
2607 {
2608 // they are all symmetric in mac themes
2609 return MacGetLeftBorderSize() ;
2610 }
2611
2612 long wxWindowMac::MacRemoveBordersFromStyle( long style )
2613 {
2614 return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ;
2615 }
2616
2617 // Find the wxWindowMac at the current mouse position, returning the mouse
2618 // position.
2619 wxWindowMac* wxFindWindowAtPointer(wxPoint& pt)
2620 {
2621 pt = wxGetMousePosition();
2622 wxWindowMac* found = wxFindWindowAtPoint(pt);
2623 return found;
2624 }
2625
2626 // Get the current mouse position.
2627 wxPoint wxGetMousePosition()
2628 {
2629 int x, y;
2630 wxGetMousePosition(& x, & y);
2631 return wxPoint(x, y);
2632 }
2633
2634 void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
2635 {
2636 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
2637 {
2638 // copied from wxGTK : CS
2639 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
2640 // except that:
2641 //
2642 // (a) it's a command event and so is propagated to the parent
2643 // (b) under MSW it can be generated from kbd too
2644 // (c) it uses screen coords (because of (a))
2645 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
2646 this->GetId(),
2647 this->ClientToScreen(event.GetPosition()));
2648 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
2649 event.Skip() ;
2650 }
2651 else if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK )
2652 {
2653
2654 int x = event.m_x ;
2655 int y = event.m_y ;
2656
2657 if ( MacGetTopLevelWindow()->MacUsesCompositing() == false )
2658 {
2659 // OS Needs it in tlw content area coordinates
2660 MacClientToRootWindow( &x , &y ) ;
2661 }
2662 else
2663 {
2664 // OS Needs it in window not client coordinates
2665 wxPoint origin = GetClientAreaOrigin() ;
2666 x += origin.x ;
2667 y += origin.y ;
2668 }
2669 Point localwhere ;
2670 SInt16 controlpart ;
2671
2672 localwhere.h = x ;
2673 localwhere.v = y ;
2674
2675 short modifiers = 0;
2676
2677 if ( !event.m_leftDown && !event.m_rightDown )
2678 modifiers |= btnState ;
2679
2680 if ( event.m_shiftDown )
2681 modifiers |= shiftKey ;
2682
2683 if ( event.m_controlDown )
2684 modifiers |= controlKey ;
2685
2686 if ( event.m_altDown )
2687 modifiers |= optionKey ;
2688
2689 if ( event.m_metaDown )
2690 modifiers |= cmdKey ;
2691
2692 bool handled = false ;
2693
2694 if ( ::IsControlActive( (ControlRef) m_macControl ) )
2695 {
2696 controlpart = ::HandleControlClick( (ControlRef) m_macControl , localwhere , modifiers , (ControlActionUPP) -1 ) ;
2697 wxTheApp->s_lastMouseDown = 0 ;
2698 if ( controlpart != kControlNoPart )
2699 {
2700 MacHandleControlClick((WXWidget) (ControlRef) m_macControl , controlpart , false /* mouse not down anymore */ ) ;
2701 handled = true ;
2702 }
2703 }
2704 if ( !handled )
2705 event.Skip() ;
2706 }
2707 else
2708 {
2709 event.Skip() ;
2710 }
2711 }
2712
2713 void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
2714 {
2715 wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ;
2716 }
2717
2718 Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size )
2719 {
2720 int x ,y , w ,h ;
2721
2722 window->MacGetBoundsForControl( pos , size , x , y, w, h ) ;
2723 Rect bounds = { y , x , y+h , x+w };
2724 return bounds ;
2725 }
2726
2727