]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/window.cpp
1c97b5a05ac541b843d19ea83f5d62ce48a2b679
[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->MacIsUserPane() && thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
169 result = noErr ;
170
171 }
172 break ;
173 case kEventControlVisibilityChanged :
174 thisWindow->MacVisibilityChanged() ;
175 break ;
176 case kEventControlEnabledStateChanged :
177 thisWindow->MacEnabledStateChanged() ;
178 break ;
179 case kEventControlHiliteChanged :
180 thisWindow->MacHiliteChanged() ;
181 break ;
182 default :
183 break ;
184 }
185 return result ;
186 }
187
188 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
189 {
190 OSStatus result = eventNotHandledErr ;
191
192 switch ( GetEventClass( event ) )
193 {
194 case kEventClassControl :
195 result = wxMacWindowControlEventHandler( handler, event, data ) ;
196 break ;
197 default :
198 break ;
199 }
200 return result ;
201 }
202
203 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
204
205 // ---------------------------------------------------------------------------
206 // UserPane events for non OSX builds
207 // ---------------------------------------------------------------------------
208
209 static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
210 {
211 wxWindow * win = wxFindControlFromMacControl(control) ;
212 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
213 win->MacControlUserPaneDrawProc(part) ;
214 }
215
216 static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
217 {
218 wxWindow * win = wxFindControlFromMacControl(control) ;
219 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
220 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
221 }
222
223 static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
224 {
225 wxWindow * win = wxFindControlFromMacControl(control) ;
226 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
227 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
228 }
229
230 static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
231 {
232 wxWindow * win = wxFindControlFromMacControl(control) ;
233 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
234 win->MacControlUserPaneIdleProc() ;
235 }
236
237 static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
238 {
239 wxWindow * win = wxFindControlFromMacControl(control) ;
240 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
241 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
242 }
243
244 static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
245 {
246 wxWindow * win = wxFindControlFromMacControl(control) ;
247 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
248 win->MacControlUserPaneActivateProc(activating) ;
249 }
250
251 static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
252 {
253 wxWindow * win = wxFindControlFromMacControl(control) ;
254 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
255 return win->MacControlUserPaneFocusProc(action) ;
256 }
257
258 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
259 {
260 wxWindow * win = wxFindControlFromMacControl(control) ;
261 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
262 win->MacControlUserPaneBackgroundProc(info) ;
263 }
264
265 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
266 {
267 MacDoRedraw( MacGetVisibleRegion().GetWXHRGN() , 0 ) ;
268 }
269
270 wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
271 {
272 return kControlNoPart ;
273 }
274
275 wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
276 {
277 return kControlNoPart ;
278 }
279
280 void wxWindowMac::MacControlUserPaneIdleProc()
281 {
282 }
283
284 wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
285 {
286 return kControlNoPart ;
287 }
288
289 void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
290 {
291 }
292
293 wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
294 {
295 return kControlNoPart ;
296 }
297
298 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
299 {
300 }
301
302 ControlUserPaneDrawUPP gControlUserPaneDrawUPP = NULL ;
303 ControlUserPaneHitTestUPP gControlUserPaneHitTestUPP = NULL ;
304 ControlUserPaneTrackingUPP gControlUserPaneTrackingUPP = NULL ;
305 ControlUserPaneIdleUPP gControlUserPaneIdleUPP = NULL ;
306 ControlUserPaneKeyDownUPP gControlUserPaneKeyDownUPP = NULL ;
307 ControlUserPaneActivateUPP gControlUserPaneActivateUPP = NULL ;
308 ControlUserPaneFocusUPP gControlUserPaneFocusUPP = NULL ;
309 ControlUserPaneBackgroundUPP gControlUserPaneBackgroundUPP = NULL ;
310
311 // ===========================================================================
312 // implementation
313 // ===========================================================================
314
315 wxList wxWinMacControlList(wxKEY_INTEGER);
316
317 wxWindow *wxFindControlFromMacControl(ControlRef inControl )
318 {
319 wxNode *node = wxWinMacControlList.Find((long)inControl);
320 if (!node)
321 return NULL;
322 return (wxControl *)node->GetData();
323 }
324
325 void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
326 {
327 // adding NULL ControlRef is (first) surely a result of an error and
328 // (secondly) breaks native event processing
329 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
330
331 if ( !wxWinMacControlList.Find((long)inControl) )
332 wxWinMacControlList.Append((long)inControl, control);
333 }
334
335 void wxRemoveMacControlAssociation(wxWindow *control)
336 {
337 wxWinMacControlList.DeleteObject(control);
338 }
339
340 // UPP functions
341 ControlActionUPP wxMacLiveScrollbarActionUPP = NULL ;
342
343 ControlColorUPP wxMacSetupControlBackgroundUPP = NULL ;
344
345 // we have to setup the brush in the current port and return noErr
346 // or return an error code so that the control manager walks further up the
347 // hierarchy to find a correct background
348
349 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor )
350 {
351 OSStatus status = paramErr ;
352 switch( iMessage )
353 {
354 case kControlMsgApplyTextColor :
355 break ;
356 case kControlMsgSetUpBackground :
357 {
358 wxWindow* wx = (wxWindow*) wxFindControlFromMacControl( iControl ) ;
359 if ( wx != NULL )
360 {
361 /*
362 const wxBrush &brush = wx->MacGetBackgroundBrush() ;
363 if ( brush.Ok() )
364 {
365
366 wxDC::MacSetupBackgroundForCurrentPort( brush ) ;
367 */
368 // this clipping is only needed for non HIView
369
370 RgnHandle clip = NewRgn() ;
371 int x = 0 , y = 0;
372
373 wx->MacWindowToRootWindow( &x,&y ) ;
374 CopyRgn( (RgnHandle) wx->MacGetVisibleRegion().GetWXHRGN() , clip ) ;
375 OffsetRgn( clip , x , y ) ;
376 SetClip( clip ) ;
377 DisposeRgn( clip ) ;
378
379 status = noErr ;
380 /*
381 }
382 else if ( wx->MacIsUserPane() )
383 {
384 // if we don't have a valid brush for such a control, we have to call the
385 // setup of our parent ourselves
386 status = SetUpControlBackground( (ControlRef) wx->GetParent()->GetHandle() , iDepth , iIsColor ) ;
387 }
388 */
389 }
390 }
391 break ;
392 default :
393 break ;
394 }
395 return status ;
396 }
397
398
399 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
400 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
401 {
402 if ( partCode != 0)
403 {
404 wxWindow* wx = wxFindControlFromMacControl( control ) ;
405 if ( wx )
406 {
407 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
408 }
409 }
410 }
411
412 // ----------------------------------------------------------------------------
413 // constructors and such
414 // ----------------------------------------------------------------------------
415
416 void wxWindowMac::Init()
417 {
418 m_backgroundTransparent = FALSE;
419
420 // as all windows are created with WS_VISIBLE style...
421 m_isShown = TRUE;
422
423 m_hScrollBar = NULL ;
424 m_vScrollBar = NULL ;
425 m_macBackgroundBrush = wxNullBrush ;
426
427 m_macControl = NULL ;
428
429 m_macIsUserPane = TRUE;
430
431 // make sure all proc ptrs are available
432
433 if ( gControlUserPaneDrawUPP == NULL )
434 {
435 gControlUserPaneDrawUPP = NewControlUserPaneDrawUPP( wxMacControlUserPaneDrawProc ) ;
436 gControlUserPaneHitTestUPP = NewControlUserPaneHitTestUPP( wxMacControlUserPaneHitTestProc ) ;
437 gControlUserPaneTrackingUPP = NewControlUserPaneTrackingUPP( wxMacControlUserPaneTrackingProc ) ;
438 gControlUserPaneIdleUPP = NewControlUserPaneIdleUPP( wxMacControlUserPaneIdleProc ) ;
439 gControlUserPaneKeyDownUPP = NewControlUserPaneKeyDownUPP( wxMacControlUserPaneKeyDownProc ) ;
440 gControlUserPaneActivateUPP = NewControlUserPaneActivateUPP( wxMacControlUserPaneActivateProc ) ;
441 gControlUserPaneFocusUPP = NewControlUserPaneFocusUPP( wxMacControlUserPaneFocusProc ) ;
442 gControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP( wxMacControlUserPaneBackgroundProc ) ;
443 }
444 if ( wxMacLiveScrollbarActionUPP == NULL )
445 {
446 wxMacLiveScrollbarActionUPP = NewControlActionUPP( wxMacLiveScrollbarActionProc );
447 }
448
449 if ( wxMacSetupControlBackgroundUPP == NULL )
450 {
451 wxMacSetupControlBackgroundUPP = NewControlColorUPP( wxMacSetupControlBackground ) ;
452 }
453
454 }
455
456 // Destructor
457 wxWindowMac::~wxWindowMac()
458 {
459 SendDestroyEvent();
460
461 m_isBeingDeleted = TRUE;
462
463 #ifndef __WXUNIVERSAL__
464 // VS: make sure there's no wxFrame with last focus set to us:
465 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
466 {
467 wxFrame *frame = wxDynamicCast(win, wxFrame);
468 if ( frame )
469 {
470 if ( frame->GetLastFocus() == this )
471 {
472 frame->SetLastFocus((wxWindow*)NULL);
473 }
474 break;
475 }
476 }
477 #endif // __WXUNIVERSAL__
478
479 // wxRemoveMacControlAssociation( this ) ;
480 // If we delete an item, we should initialize the parent panel,
481 // because it could now be invalid.
482 wxWindow *parent = GetParent() ;
483 if ( parent )
484 {
485 if (parent->GetDefaultItem() == (wxButton*) this)
486 parent->SetDefaultItem(NULL);
487 }
488 if ( (ControlRef) m_macControl )
489 {
490 // in case the callback might be called during destruction
491 wxRemoveMacControlAssociation( this) ;
492 ::SetControlColorProc( (ControlRef) m_macControl , NULL ) ;
493 ::DisposeControl( (ControlRef) m_macControl ) ;
494 m_macControl = NULL ;
495 }
496
497 if ( g_MacLastWindow == this )
498 {
499 g_MacLastWindow = NULL ;
500 }
501
502 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ;
503 if ( frame )
504 {
505 if ( frame->GetLastFocus() == this )
506 frame->SetLastFocus( NULL ) ;
507 }
508
509 if ( gFocusWindow == this )
510 {
511 gFocusWindow = NULL ;
512 }
513
514 DestroyChildren();
515
516 // delete our drop target if we've got one
517 #if wxUSE_DRAG_AND_DROP
518 if ( m_dropTarget != NULL )
519 {
520 delete m_dropTarget;
521 m_dropTarget = NULL;
522 }
523 #endif // wxUSE_DRAG_AND_DROP
524 }
525
526 //
527
528 void wxWindowMac::MacInstallEventHandler()
529 {
530 InstallControlEventHandler( (ControlRef) m_macControl, GetwxMacWindowEventHandlerUPP(),
531 GetEventTypeCount(eventList), eventList, this,
532 (EventHandlerRef *)&m_macControlEventHandler);
533
534 }
535
536 // Constructor
537 bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
538 const wxPoint& pos,
539 const wxSize& size,
540 long style,
541 const wxString& name)
542 {
543 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") );
544
545 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
546 return FALSE;
547
548 parent->AddChild(this);
549
550 m_windowVariant = parent->GetWindowVariant() ;
551
552 if ( m_macIsUserPane )
553 {
554 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
555
556 UInt32 features = kControlSupportsEmbedding | kControlSupportsLiveFeedback | kControlHasSpecialBackground |
557 kControlSupportsCalcBestRect | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate | kControlWantsIdle;
558
559 ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, kControlSupportsEmbedding , (ControlRef*) &m_macControl);
560
561 MacPostControlCreate(pos,size) ;
562 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneDrawProcTag,
563 sizeof(gControlUserPaneDrawUPP),(Ptr) &gControlUserPaneDrawUPP);
564 #if !TARGET_API_MAC_OSX
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 /*
1727 RgnHandle updateRgn = NewRgn() ;
1728 if ( rect == NULL )
1729 {
1730 CopyRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn ) ;
1731 }
1732 else
1733 {
1734 SetRectRgn( updateRgn , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
1735 SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn , updateRgn ) ;
1736 }
1737 InvalWindowRgn( (WindowRef) MacGetTopLevelWindowRef() , updateRgn ) ;
1738 DisposeRgn(updateRgn) ;
1739 */
1740 if ( IsControlVisible( (ControlRef) m_macControl ) )
1741 {
1742 SetControlVisibility( (ControlRef) m_macControl , false , false ) ;
1743 SetControlVisibility( (ControlRef) m_macControl , true , true ) ;
1744 }
1745 /*
1746 if ( MacGetTopLevelWindow() == NULL )
1747 return ;
1748
1749 if ( !IsControlVisible( (ControlRef) m_macControl ) )
1750 return ;
1751
1752 wxPoint client = GetClientAreaOrigin();
1753 int x1 = -client.x;
1754 int y1 = -client.y;
1755 int x2 = m_width - client.x;
1756 int y2 = m_height - client.y;
1757
1758 if (IsKindOf( CLASSINFO(wxButton)))
1759 {
1760 // buttons have an "aura"
1761 y1 -= 5;
1762 x1 -= 5;
1763 y2 += 5;
1764 x2 += 5;
1765 }
1766
1767 Rect clientrect = { y1, x1, y2, x2 };
1768
1769 if ( rect )
1770 {
1771 Rect r = { rect->y , rect->x , rect->y + rect->height , rect->x + rect->width } ;
1772 SectRect( &clientrect , &r , &clientrect ) ;
1773 }
1774
1775 if ( !EmptyRect( &clientrect ) )
1776 {
1777 int top = 0 , left = 0 ;
1778
1779 MacClientToRootWindow( &left , &top ) ;
1780 OffsetRect( &clientrect , left , top ) ;
1781
1782 MacGetTopLevelWindow()->MacInvalidate( &clientrect , eraseBack ) ;
1783 }
1784 */
1785 #endif
1786 }
1787
1788 void wxWindowMac::MacRedrawControl()
1789 {
1790 /*
1791 if ( (ControlRef) m_macControl && MacGetTopLevelWindowRef() && IsControlVisible( (ControlRef) m_macControl ) )
1792 {
1793 #if TARGET_API_MAC_CARBON
1794 Update() ;
1795 #else
1796 wxClientDC dc(this) ;
1797 wxMacPortSetter helper(&dc) ;
1798 wxMacWindowClipper clipper(this) ;
1799 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
1800 UMADrawControl( (ControlRef) m_macControl ) ;
1801 #endif
1802 }
1803 */
1804 }
1805
1806 /* TODO
1807 void wxWindowMac::OnPaint(wxPaintEvent& event)
1808 {
1809 // why don't we skip that here ?
1810 }
1811 */
1812
1813 wxWindowMac *wxGetActiveWindow()
1814 {
1815 // actually this is a windows-only concept
1816 return NULL;
1817 }
1818
1819 // Coordinates relative to the window
1820 void wxWindowMac::WarpPointer (int x_pos, int y_pos)
1821 {
1822 // We really don't move the mouse programmatically under Mac.
1823 }
1824
1825 void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
1826 {
1827 if ( m_macBackgroundBrush.Ok() == false || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT )
1828 {
1829 event.Skip() ;
1830 }
1831 else
1832 event.GetDC()->Clear() ;
1833 }
1834
1835 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
1836 {
1837 wxWindowDC dc(this) ;
1838 wxMacPortSetter helper(&dc) ;
1839
1840 MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ;
1841 }
1842
1843 int wxWindowMac::GetScrollPos(int orient) const
1844 {
1845 if ( orient == wxHORIZONTAL )
1846 {
1847 if ( m_hScrollBar )
1848 return m_hScrollBar->GetThumbPosition() ;
1849 }
1850 else
1851 {
1852 if ( m_vScrollBar )
1853 return m_vScrollBar->GetThumbPosition() ;
1854 }
1855 return 0;
1856 }
1857
1858 // This now returns the whole range, not just the number
1859 // of positions that we can scroll.
1860 int wxWindowMac::GetScrollRange(int orient) const
1861 {
1862 if ( orient == wxHORIZONTAL )
1863 {
1864 if ( m_hScrollBar )
1865 return m_hScrollBar->GetRange() ;
1866 }
1867 else
1868 {
1869 if ( m_vScrollBar )
1870 return m_vScrollBar->GetRange() ;
1871 }
1872 return 0;
1873 }
1874
1875 int wxWindowMac::GetScrollThumb(int orient) const
1876 {
1877 if ( orient == wxHORIZONTAL )
1878 {
1879 if ( m_hScrollBar )
1880 return m_hScrollBar->GetThumbSize() ;
1881 }
1882 else
1883 {
1884 if ( m_vScrollBar )
1885 return m_vScrollBar->GetThumbSize() ;
1886 }
1887 return 0;
1888 }
1889
1890 void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
1891 {
1892 if ( orient == wxHORIZONTAL )
1893 {
1894 if ( m_hScrollBar )
1895 m_hScrollBar->SetThumbPosition( pos ) ;
1896 }
1897 else
1898 {
1899 if ( m_vScrollBar )
1900 m_vScrollBar->SetThumbPosition( pos ) ;
1901 }
1902 }
1903
1904 void wxWindowMac::MacPaintBorders( int left , int top )
1905 {
1906 if( IsTopLevel() )
1907 return ;
1908
1909 int major,minor;
1910 wxGetOsVersion( &major, &minor );
1911
1912 RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ;
1913 RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ;
1914
1915 RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ;
1916 RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ;
1917 // OS X has lighter border edges than classic:
1918 if (major >= 10)
1919 {
1920 darkShadow.red = 0x8E8E;
1921 darkShadow.green = 0x8E8E;
1922 darkShadow.blue = 0x8E8E;
1923 lightShadow.red = 0xBDBD;
1924 lightShadow.green = 0xBDBD;
1925 lightShadow.blue = 0xBDBD;
1926 }
1927
1928 PenNormal() ;
1929
1930 int w , h ;
1931 GetSize( &w , &h ) ;
1932 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
1933 {
1934 #if wxMAC_USE_THEME_BORDER
1935 Rect rect = { top , left , m_height + top , m_width + left } ;
1936 SInt32 border = 0 ;
1937 /*
1938 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
1939 InsetRect( &rect , border , border );
1940 DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
1941 */
1942
1943 DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
1944 #else
1945 bool sunken = HasFlag( wxSUNKEN_BORDER ) ;
1946 RGBForeColor( &face );
1947 MoveTo( left + 0 , top + h - 2 );
1948 LineTo( left + 0 , top + 0 );
1949 LineTo( left + w - 2 , top + 0 );
1950
1951 MoveTo( left + 2 , top + h - 3 );
1952 LineTo( left + w - 3 , top + h - 3 );
1953 LineTo( left + w - 3 , top + 2 );
1954
1955 RGBForeColor( sunken ? &face : &darkShadow );
1956 MoveTo( left + 0 , top + h - 1 );
1957 LineTo( left + w - 1 , top + h - 1 );
1958 LineTo( left + w - 1 , top + 0 );
1959
1960 RGBForeColor( sunken ? &lightShadow : &white );
1961 MoveTo( left + 1 , top + h - 3 );
1962 LineTo( left + 1, top + 1 );
1963 LineTo( left + w - 3 , top + 1 );
1964
1965 RGBForeColor( sunken ? &white : &lightShadow );
1966 MoveTo( left + 1 , top + h - 2 );
1967 LineTo( left + w - 2 , top + h - 2 );
1968 LineTo( left + w - 2 , top + 1 );
1969
1970 RGBForeColor( sunken ? &darkShadow : &face );
1971 MoveTo( left + 2 , top + h - 4 );
1972 LineTo( left + 2 , top + 2 );
1973 LineTo( left + w - 4 , top + 2 );
1974 #endif
1975 }
1976 else if (HasFlag(wxSIMPLE_BORDER))
1977 {
1978 Rect rect = { top , left , h + top , w + left } ;
1979 RGBForeColor( &darkShadow ) ;
1980 FrameRect( &rect ) ;
1981 }
1982 }
1983
1984 void wxWindowMac::RemoveChild( wxWindowBase *child )
1985 {
1986 if ( child == m_hScrollBar )
1987 m_hScrollBar = NULL ;
1988 if ( child == m_vScrollBar )
1989 m_vScrollBar = NULL ;
1990
1991 wxWindowBase::RemoveChild( child ) ;
1992 }
1993
1994 // New function that will replace some of the above.
1995 void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
1996 int range, bool refresh)
1997 {
1998 if ( orient == wxHORIZONTAL )
1999 {
2000 if ( m_hScrollBar )
2001 {
2002 if ( range == 0 || thumbVisible >= range )
2003 {
2004 if ( m_hScrollBar->IsShown() )
2005 m_hScrollBar->Show(false) ;
2006 }
2007 else
2008 {
2009 if ( !m_hScrollBar->IsShown() )
2010 m_hScrollBar->Show(true) ;
2011 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2012 }
2013 }
2014 }
2015 else
2016 {
2017 if ( m_vScrollBar )
2018 {
2019 if ( range == 0 || thumbVisible >= range )
2020 {
2021 if ( m_vScrollBar->IsShown() )
2022 m_vScrollBar->Show(false) ;
2023 }
2024 else
2025 {
2026 if ( !m_vScrollBar->IsShown() )
2027 m_vScrollBar->Show(true) ;
2028 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2029 }
2030 }
2031 }
2032 MacRepositionScrollBars() ;
2033 }
2034
2035 // Does a physical scroll
2036 void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
2037 {
2038 if( dx == 0 && dy ==0 )
2039 return ;
2040
2041
2042 {
2043 wxClientDC dc(this) ;
2044 wxMacPortSetter helper(&dc) ;
2045
2046 int width , height ;
2047 GetClientSize( &width , &height ) ;
2048
2049
2050 wxPoint pos;
2051 pos.x = pos.y = 0;
2052
2053 Rect scrollrect;
2054 // TODO take out the boundaries
2055 GetControlBounds( (ControlRef) m_macControl, &scrollrect);
2056
2057 RgnHandle updateRgn = NewRgn() ;
2058 if ( rect )
2059 {
2060 Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
2061 dc.XLOG2DEVMAC(rect->x + rect->width) } ;
2062 SectRect( &scrollrect , &r , &scrollrect ) ;
2063 }
2064 ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
2065 #if TARGET_CARBON
2066 //KO: The docs say ScrollRect creates an update region, which thus calls an update event
2067 // but it seems the update only refreshes the background of the control, rather than calling
2068 // kEventControlDraw, so we need to force a proper update here. There has to be a better
2069 // way of doing this... (Note that code below under !TARGET_CARBON does not work either...)
2070 Update();
2071 #endif
2072 // we also have to scroll the update rgn in this rectangle
2073 // in order not to loose updates
2074 #if !TARGET_CARBON
2075 WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ;
2076 RgnHandle formerUpdateRgn = NewRgn() ;
2077 RgnHandle scrollRgn = NewRgn() ;
2078 RectRgn( scrollRgn , &scrollrect ) ;
2079 GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ;
2080 Point pt = {0,0} ;
2081 LocalToGlobal( &pt ) ;
2082 OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ;
2083 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
2084 if ( !EmptyRgn( formerUpdateRgn ) )
2085 {
2086 MacOffsetRgn( formerUpdateRgn , dx , dy ) ;
2087 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
2088 InvalWindowRgn(rootWindow , formerUpdateRgn ) ;
2089 }
2090 InvalWindowRgn(rootWindow , updateRgn ) ;
2091 DisposeRgn( updateRgn ) ;
2092 DisposeRgn( formerUpdateRgn ) ;
2093 DisposeRgn( scrollRgn ) ;
2094 #endif
2095 }
2096
2097 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
2098 {
2099 wxWindowMac *child = node->GetData();
2100 if (child == m_vScrollBar) continue;
2101 if (child == m_hScrollBar) continue;
2102 if (child->IsTopLevel()) continue;
2103
2104 int x,y;
2105 child->GetPosition( &x, &y );
2106 int w,h;
2107 child->GetSize( &w, &h );
2108 if (rect)
2109 {
2110 wxRect rc(x,y,w,h);
2111 if (rect->Intersects(rc))
2112 child->SetSize( x+dx, y+dy, w, h );
2113 }
2114 else
2115 {
2116 child->SetSize( x+dx, y+dy, w, h );
2117 }
2118 }
2119
2120 // TODO remove, was moved higher up Update() ;
2121
2122 }
2123
2124 void wxWindowMac::MacOnScroll(wxScrollEvent &event )
2125 {
2126 if ( event.m_eventObject == m_vScrollBar || event.m_eventObject == m_hScrollBar )
2127 {
2128 wxScrollWinEvent wevent;
2129 wevent.SetPosition(event.GetPosition());
2130 wevent.SetOrientation(event.GetOrientation());
2131 wevent.m_eventObject = this;
2132
2133 if (event.m_eventType == wxEVT_SCROLL_TOP)
2134 wevent.m_eventType = wxEVT_SCROLLWIN_TOP;
2135 else if (event.m_eventType == wxEVT_SCROLL_BOTTOM)
2136 wevent.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
2137 else if (event.m_eventType == wxEVT_SCROLL_LINEUP)
2138 wevent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
2139 else if (event.m_eventType == wxEVT_SCROLL_LINEDOWN)
2140 wevent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
2141 else if (event.m_eventType == wxEVT_SCROLL_PAGEUP)
2142 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
2143 else if (event.m_eventType == wxEVT_SCROLL_PAGEDOWN)
2144 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
2145 else if (event.m_eventType == wxEVT_SCROLL_THUMBTRACK)
2146 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
2147 else if (event.m_eventType == wxEVT_SCROLL_THUMBRELEASE)
2148 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
2149
2150 GetEventHandler()->ProcessEvent(wevent);
2151 }
2152 }
2153
2154 // Get the window with the focus
2155 wxWindowMac *wxWindowBase::FindFocus()
2156 {
2157 return gFocusWindow ;
2158 }
2159
2160 void wxWindowMac::OnSetFocus(wxFocusEvent& event)
2161 {
2162 // panel wants to track the window which was the last to have focus in it,
2163 // so we want to set ourselves as the window which last had focus
2164 //
2165 // notice that it's also important to do it upwards the tree becaus
2166 // otherwise when the top level panel gets focus, it won't set it back to
2167 // us, but to some other sibling
2168
2169 // CS:don't know if this is still needed:
2170 //wxChildFocusEvent eventFocus(this);
2171 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2172
2173 event.Skip();
2174 }
2175
2176 void wxWindowMac::OnInternalIdle()
2177 {
2178 // This calls the UI-update mechanism (querying windows for
2179 // menu/toolbar/control state information)
2180 if (wxUpdateUIEvent::CanUpdate(this))
2181 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
2182 }
2183
2184 // Raise the window to the top of the Z order
2185 void wxWindowMac::Raise()
2186 {
2187 }
2188
2189 // Lower the window to the bottom of the Z order
2190 void wxWindowMac::Lower()
2191 {
2192 }
2193
2194
2195 // static wxWindow *gs_lastWhich = NULL;
2196
2197 bool wxWindowMac::MacSetupCursor( const wxPoint& pt)
2198 {
2199 // first trigger a set cursor event
2200
2201 wxPoint clientorigin = GetClientAreaOrigin() ;
2202 wxSize clientsize = GetClientSize() ;
2203 wxCursor cursor ;
2204 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
2205 {
2206 wxSetCursorEvent event( pt.x , pt.y );
2207
2208 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2209 if ( processedEvtSetCursor && event.HasCursor() )
2210 {
2211 cursor = event.GetCursor() ;
2212 }
2213 else
2214 {
2215
2216 // the test for processedEvtSetCursor is here to prevent using m_cursor
2217 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2218 // it - this is a way to say that our cursor shouldn't be used for this
2219 // point
2220 if ( !processedEvtSetCursor && m_cursor.Ok() )
2221 {
2222 cursor = m_cursor ;
2223 }
2224 if ( wxIsBusy() )
2225 {
2226 }
2227 else
2228 {
2229 if ( !GetParent() )
2230 cursor = *wxSTANDARD_CURSOR ;
2231 }
2232 }
2233 if ( cursor.Ok() )
2234 cursor.MacInstall() ;
2235 }
2236 return cursor.Ok() ;
2237 }
2238
2239 wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
2240 {
2241 if ( m_tooltip )
2242 {
2243 return m_tooltip->GetTip() ;
2244 }
2245 return wxEmptyString ;
2246 }
2247
2248 void wxWindowMac::Update()
2249 {
2250 #if TARGET_API_MAC_OSX
2251 HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ;
2252 #else
2253 ::Draw1Control( (ControlRef) m_macControl ) ;
2254 #endif
2255 }
2256
2257 wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
2258 {
2259 wxTopLevelWindowMac* win = NULL ;
2260 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
2261 if ( window )
2262 {
2263 win = wxFindWinFromMacWindow( window ) ;
2264 }
2265 return win ;
2266 }
2267 wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
2268 {
2269
2270 Rect r ;
2271 RgnHandle visRgn = NewRgn() ;
2272 RgnHandle tempRgn = NewRgn() ;
2273 if ( IsControlVisible( (ControlRef) m_macControl ) )
2274 {
2275 GetControlBounds( (ControlRef) m_macControl , &r ) ;
2276 if (! MacGetTopLevelWindow()->MacUsesCompositing() )
2277 {
2278 MacRootWindowToWindow( &r.left , & r.top ) ;
2279 MacRootWindowToWindow( &r.right , & r.bottom ) ;
2280 }
2281 else
2282 {
2283 r.right -= r.left ;
2284 r.bottom -= r.top ;
2285 r.left = 0 ;
2286 r.top = 0 ;
2287 }
2288 if ( includeOuterStructures )
2289 InsetRect( &r , -3 , -3 ) ;
2290 RectRgn( visRgn , &r ) ;
2291 if ( !IsTopLevel() )
2292 {
2293 wxWindow* child = this ;
2294 wxWindow* parent = child->GetParent() ;
2295 while( parent )
2296 {
2297 int x , y ;
2298 wxSize size ;
2299 // we have to find a better clipping algorithm here, in order not to clip things
2300 // positioned like status and toolbar
2301 if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ )
2302 {
2303 size = parent->GetSize() ;
2304 x = y = 0 ;
2305 }
2306 else
2307 {
2308 size = parent->GetClientSize() ;
2309 wxPoint origin = parent->GetClientAreaOrigin() ;
2310 x = origin.x ;
2311 y = origin.y ;
2312 }
2313 parent->MacWindowToRootWindow( &x, &y ) ;
2314 MacRootWindowToWindow( &x , &y ) ;
2315
2316 SetRectRgn( tempRgn ,
2317 x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
2318 x + size.x - parent->MacGetRightBorderSize(),
2319 y + size.y - parent->MacGetBottomBorderSize()) ;
2320
2321 SectRgn( visRgn , tempRgn , visRgn ) ;
2322 if ( parent->IsTopLevel() )
2323 break ;
2324 child = parent ;
2325 parent = child->GetParent() ;
2326 }
2327 }
2328 }
2329
2330 wxRegion vis = visRgn ;
2331 DisposeRgn( visRgn ) ;
2332 DisposeRgn( tempRgn ) ;
2333 return vis ;
2334 }
2335
2336 /*
2337 This function must not change the updatergn !
2338 */
2339 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
2340 {
2341 // we let the OS handle root control redraws
2342 if ( m_macControl == MacGetTopLevelWindow()->GetHandle() )
2343 return false ;
2344
2345 RgnHandle updatergn = (RgnHandle) updatergnr ;
2346 bool handled = false ;
2347
2348 // calculate a client-origin version of the update rgn and set m_updateRegion to that
2349 {
2350 RgnHandle newupdate = NewRgn() ;
2351 wxSize point = GetClientSize() ;
2352 wxPoint origin = GetClientAreaOrigin() ;
2353 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ;
2354 SectRgn( newupdate , updatergn , newupdate ) ;
2355 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
2356 m_updateRegion = newupdate ;
2357 DisposeRgn( newupdate ) ;
2358 }
2359
2360 if ( !EmptyRgn(updatergn) )
2361 {
2362 wxWindowDC dc(this);
2363 if (!EmptyRgn(updatergn))
2364 dc.SetClippingRegion(wxRegion(updatergn));
2365
2366 wxEraseEvent eevent( GetId(), &dc );
2367 eevent.SetEventObject( this );
2368 GetEventHandler()->ProcessEvent( eevent );
2369
2370 if ( !m_updateRegion.Empty() )
2371 {
2372 // paint the window itself
2373 wxPaintEvent event;
2374 event.m_timeStamp = time ;
2375 event.SetEventObject(this);
2376 handled = GetEventHandler()->ProcessEvent(event);
2377
2378 // paint custom borders
2379 wxNcPaintEvent eventNc( GetId() );
2380 eventNc.SetEventObject( this );
2381 GetEventHandler()->ProcessEvent( eventNc );
2382 }
2383 }
2384 return handled ;
2385 }
2386
2387 void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
2388 {
2389 RgnHandle updatergn = (RgnHandle) updatergnr ;
2390 // updatergn is always already clipped to our boundaries
2391 // if we are in compositing mode then it is in relative to the upper left of the control
2392 // if we are in non-compositing, then it is relatvie to the uppder left of the content area
2393 // of the toplevel window
2394 // it is in window coordinates, not in client coordinates
2395
2396 // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates
2397 RgnHandle ownUpdateRgn = NewRgn() ;
2398 CopyRgn( updatergn , ownUpdateRgn ) ;
2399
2400 if ( MacGetTopLevelWindow()->MacUsesCompositing() == false )
2401 {
2402 Rect bounds;
2403 UMAGetControlBoundsInWindowCoords( (ControlRef)m_macControl, &bounds );
2404 RgnHandle controlRgn = NewRgn();
2405 RectRgn( controlRgn, &bounds );
2406 //KO: This sets the ownUpdateRgn to the area of this control that is inside
2407 // the window update region
2408 SectRgn( ownUpdateRgn, controlRgn, ownUpdateRgn );
2409 DisposeRgn( controlRgn );
2410
2411 //KO: convert ownUpdateRgn to local coordinates
2412 OffsetRgn( ownUpdateRgn, -bounds.left, -bounds.top );
2413 }
2414
2415 MacDoRedraw( ownUpdateRgn , time ) ;
2416 DisposeRgn( ownUpdateRgn ) ;
2417
2418 }
2419
2420 WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
2421 {
2422 wxWindowMac *iter = (wxWindowMac*)this ;
2423
2424 while( iter )
2425 {
2426 if ( iter->IsTopLevel() )
2427 return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
2428
2429 iter = iter->GetParent() ;
2430 }
2431 wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ;
2432 return NULL ;
2433 }
2434
2435 void wxWindowMac::MacCreateScrollBars( long style )
2436 {
2437 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
2438
2439 bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
2440 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ;
2441 int width, height ;
2442 GetClientSize( &width , &height ) ;
2443
2444 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2445 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2446 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2447 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2448
2449 m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint,
2450 vSize , wxVERTICAL);
2451
2452 if ( style & wxVSCROLL )
2453 {
2454
2455 }
2456 else
2457 {
2458 m_vScrollBar->Show(false) ;
2459 }
2460 m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint,
2461 hSize , wxHORIZONTAL);
2462 if ( style & wxHSCROLL )
2463 {
2464 }
2465 else
2466 {
2467 m_hScrollBar->Show(false) ;
2468 }
2469
2470 // because the create does not take into account the client area origin
2471 MacRepositionScrollBars() ; // we might have a real position shift
2472 }
2473
2474 void wxWindowMac::MacRepositionScrollBars()
2475 {
2476 bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
2477 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ;
2478
2479 // get real client area
2480
2481 int width ;
2482 int height ;
2483 GetSize( &width , &height ) ;
2484
2485 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
2486 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
2487
2488 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2489 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2490 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2491 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2492
2493 int x = 0 ;
2494 int y = 0 ;
2495 int w ;
2496 int h ;
2497 GetSize( &w , &h ) ;
2498
2499 MacClientToRootWindow( &x , &y ) ;
2500 MacClientToRootWindow( &w , &h ) ;
2501
2502 wxWindowMac *iter = (wxWindowMac*)this ;
2503
2504 int totW = 10000 , totH = 10000;
2505 while( iter )
2506 {
2507 if ( iter->IsTopLevel() )
2508 {
2509 iter->GetSize( &totW , &totH ) ;
2510 break ;
2511 }
2512
2513 iter = iter->GetParent() ;
2514 }
2515
2516 if ( x == 0 )
2517 {
2518 hPoint.x = -1 ;
2519 hSize.x += 1 ;
2520 }
2521 if ( y == 0 )
2522 {
2523 vPoint.y = -1 ;
2524 vSize.y += 1 ;
2525 }
2526
2527 if ( w-x >= totW )
2528 {
2529 hSize.x += 1 ;
2530 vPoint.x += 1 ;
2531 }
2532
2533 if ( h-y >= totH )
2534 {
2535 vSize.y += 1 ;
2536 hPoint.y += 1 ;
2537 }
2538
2539 if ( m_vScrollBar )
2540 {
2541 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE);
2542 }
2543 if ( m_hScrollBar )
2544 {
2545 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE);
2546 }
2547 }
2548
2549 bool wxWindowMac::AcceptsFocus() const
2550 {
2551 return MacCanFocus() && wxWindowBase::AcceptsFocus();
2552 }
2553
2554 void wxWindowMac::MacSuperChangedPosition()
2555 {
2556 // only window-absolute structures have to be moved i.e. controls
2557
2558 wxWindowListNode *node = GetChildren().GetFirst();
2559 while ( node )
2560 {
2561 wxWindowMac *child = node->GetData();
2562 child->MacSuperChangedPosition() ;
2563 node = node->GetNext();
2564 }
2565 }
2566
2567 void wxWindowMac::MacTopLevelWindowChangedPosition()
2568 {
2569 // only screen-absolute structures have to be moved i.e. glcanvas
2570
2571 wxWindowListNode *node = GetChildren().GetFirst();
2572 while ( node )
2573 {
2574 wxWindowMac *child = node->GetData();
2575 child->MacTopLevelWindowChangedPosition() ;
2576 node = node->GetNext();
2577 }
2578 }
2579
2580 long wxWindowMac::MacGetLeftBorderSize( ) const
2581 {
2582 if( IsTopLevel() )
2583 return 0 ;
2584
2585 if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER )
2586 {
2587 SInt32 border = 3 ;
2588 #if wxMAC_USE_THEME_BORDER
2589 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2590 #endif
2591 return border ;
2592 }
2593 else if ( m_windowStyle &wxDOUBLE_BORDER)
2594 {
2595 SInt32 border = 3 ;
2596 #if wxMAC_USE_THEME_BORDER
2597 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2598 #endif
2599 return border ;
2600 }
2601 else if (m_windowStyle &wxSIMPLE_BORDER)
2602 {
2603 return 1 ;
2604 }
2605 return 0 ;
2606 }
2607
2608 long wxWindowMac::MacGetRightBorderSize( ) const
2609 {
2610 // they are all symmetric in mac themes
2611 return MacGetLeftBorderSize() ;
2612 }
2613
2614 long wxWindowMac::MacGetTopBorderSize( ) const
2615 {
2616 // they are all symmetric in mac themes
2617 return MacGetLeftBorderSize() ;
2618 }
2619
2620 long wxWindowMac::MacGetBottomBorderSize( ) const
2621 {
2622 // they are all symmetric in mac themes
2623 return MacGetLeftBorderSize() ;
2624 }
2625
2626 long wxWindowMac::MacRemoveBordersFromStyle( long style )
2627 {
2628 return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ;
2629 }
2630
2631 // Find the wxWindowMac at the current mouse position, returning the mouse
2632 // position.
2633 wxWindowMac* wxFindWindowAtPointer(wxPoint& pt)
2634 {
2635 pt = wxGetMousePosition();
2636 wxWindowMac* found = wxFindWindowAtPoint(pt);
2637 return found;
2638 }
2639
2640 // Get the current mouse position.
2641 wxPoint wxGetMousePosition()
2642 {
2643 int x, y;
2644 wxGetMousePosition(& x, & y);
2645 return wxPoint(x, y);
2646 }
2647
2648 void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
2649 {
2650 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
2651 {
2652 // copied from wxGTK : CS
2653 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
2654 // except that:
2655 //
2656 // (a) it's a command event and so is propagated to the parent
2657 // (b) under MSW it can be generated from kbd too
2658 // (c) it uses screen coords (because of (a))
2659 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
2660 this->GetId(),
2661 this->ClientToScreen(event.GetPosition()));
2662 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
2663 event.Skip() ;
2664 }
2665 else if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK )
2666 {
2667
2668 int x = event.m_x ;
2669 int y = event.m_y ;
2670
2671 if ( MacGetTopLevelWindow()->MacUsesCompositing() == false )
2672 {
2673 // OS Needs it in tlw content area coordinates
2674 MacClientToRootWindow( &x , &y ) ;
2675 }
2676 else
2677 {
2678 // OS Needs it in window not client coordinates
2679 wxPoint origin = GetClientAreaOrigin() ;
2680 x += origin.x ;
2681 y += origin.y ;
2682 }
2683 Point localwhere ;
2684 SInt16 controlpart ;
2685
2686 localwhere.h = x ;
2687 localwhere.v = y ;
2688
2689 short modifiers = 0;
2690
2691 if ( !event.m_leftDown && !event.m_rightDown )
2692 modifiers |= btnState ;
2693
2694 if ( event.m_shiftDown )
2695 modifiers |= shiftKey ;
2696
2697 if ( event.m_controlDown )
2698 modifiers |= controlKey ;
2699
2700 if ( event.m_altDown )
2701 modifiers |= optionKey ;
2702
2703 if ( event.m_metaDown )
2704 modifiers |= cmdKey ;
2705
2706 bool handled = false ;
2707
2708 if ( ::IsControlActive( (ControlRef) m_macControl ) )
2709 {
2710 controlpart = ::HandleControlClick( (ControlRef) m_macControl , localwhere , modifiers , (ControlActionUPP) -1 ) ;
2711 wxTheApp->s_lastMouseDown = 0 ;
2712 if ( controlpart != kControlNoPart )
2713 {
2714 MacHandleControlClick((WXWidget) (ControlRef) m_macControl , controlpart , false /* mouse not down anymore */ ) ;
2715 handled = true ;
2716 }
2717 }
2718 if ( !handled )
2719 event.Skip() ;
2720 }
2721 else
2722 {
2723 event.Skip() ;
2724 }
2725 }
2726
2727 void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
2728 {
2729 wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ;
2730 }
2731
2732 Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size )
2733 {
2734 int x ,y , w ,h ;
2735
2736 window->MacGetBoundsForControl( pos , size , x , y, w, h ) ;
2737 Rect bounds = { y , x , y+h , x+w };
2738 return bounds ;
2739 }
2740
2741