]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/window.cpp
added wxWindow::GetPrev/NextSibling()
[wxWidgets.git] / src / mac / carbon / window.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/carbon/window.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#include "wx/wxprec.h"
13
14#include "wx/window.h"
15
16#ifndef WX_PRECOMP
17 #include "wx/log.h"
18 #include "wx/app.h"
19 #include "wx/utils.h"
20 #include "wx/panel.h"
21 #include "wx/frame.h"
22 #include "wx/dc.h"
23 #include "wx/dcclient.h"
24 #include "wx/button.h"
25 #include "wx/menu.h"
26 #include "wx/dialog.h"
27 #include "wx/settings.h"
28 #include "wx/msgdlg.h"
29 #include "wx/scrolbar.h"
30 #include "wx/statbox.h"
31 #include "wx/textctrl.h"
32 #include "wx/toolbar.h"
33 #include "wx/layout.h"
34 #include "wx/statusbr.h"
35 #include "wx/menuitem.h"
36 #include "wx/treectrl.h"
37 #include "wx/listctrl.h"
38#endif
39
40#include "wx/tooltip.h"
41#include "wx/spinctrl.h"
42#include "wx/geometry.h"
43
44#if wxUSE_LISTCTRL
45 #include "wx/listctrl.h"
46#endif
47
48#if wxUSE_TREECTRL
49 #include "wx/treectrl.h"
50#endif
51
52#if wxUSE_CARET
53 #include "wx/caret.h"
54#endif
55
56#if wxUSE_POPUPWIN
57 #include "wx/popupwin.h"
58#endif
59
60#if wxUSE_DRAG_AND_DROP
61#include "wx/dnd.h"
62#endif
63
64#include "wx/mac/uma.h"
65
66#define MAC_SCROLLBAR_SIZE 15
67#define MAC_SMALL_SCROLLBAR_SIZE 11
68
69#ifndef __DARWIN__
70#include <Windows.h>
71#include <ToolUtils.h>
72#include <MacTextEditor.h>
73#endif
74
75#if TARGET_API_MAC_OSX
76#ifndef __HIVIEW__
77 #include <HIToolbox/HIView.h>
78#endif
79#endif
80
81#include <string.h>
82
83#ifdef __WXUNIVERSAL__
84 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
85#else
86 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
87#endif
88
89BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
90 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
91 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
92#if TARGET_API_MAC_OSX
93 EVT_PAINT(wxWindowMac::OnPaint)
94#endif
95 EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
96 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus)
97 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
98END_EVENT_TABLE()
99
100#define wxMAC_DEBUG_REDRAW 0
101#ifndef wxMAC_DEBUG_REDRAW
102#define wxMAC_DEBUG_REDRAW 0
103#endif
104
105// ---------------------------------------------------------------------------
106// Utility Routines to move between different coordinate systems
107// ---------------------------------------------------------------------------
108
109/*
110 * Right now we have the following setup :
111 * a border that is not part of the native control is always outside the
112 * control's border (otherwise we loose all native intelligence, future ways
113 * may be to have a second embedding control responsible for drawing borders
114 * and backgrounds eventually)
115 * so all this border calculations have to be taken into account when calling
116 * native methods or getting native oriented data
117 * so we have three coordinate systems here
118 * wx client coordinates
119 * wx window coordinates (including window frames)
120 * native coordinates
121 */
122
123//
124// originating from native control
125//
126
127
128void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle )
129{
130 OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
131}
132
133void wxMacNativeToWindow( const wxWindow* window , Rect *rect )
134{
135 OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
136}
137
138//
139// directed towards native control
140//
141
142void wxMacWindowToNative( const wxWindow* window , RgnHandle handle )
143{
144 OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() );
145}
146
147void wxMacWindowToNative( const wxWindow* window , Rect *rect )
148{
149 OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ;
150}
151
152// ---------------------------------------------------------------------------
153// Carbon Events
154// ---------------------------------------------------------------------------
155
156static const EventTypeSpec eventList[] =
157{
158 { kEventClassCommand, kEventProcessCommand } ,
159 { kEventClassCommand, kEventCommandUpdateStatus } ,
160
161 { kEventClassControl , kEventControlGetClickActivation } ,
162 { kEventClassControl , kEventControlHit } ,
163
164 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
165 { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,
166
167 { kEventClassControl , kEventControlDraw } ,
168#if TARGET_API_MAC_OSX
169 { kEventClassControl , kEventControlVisibilityChanged } ,
170 { kEventClassControl , kEventControlEnabledStateChanged } ,
171 { kEventClassControl , kEventControlHiliteChanged } ,
172
173 { kEventClassControl , kEventControlActivate } ,
174 { kEventClassControl , kEventControlDeactivate } ,
175#endif
176 { kEventClassControl , kEventControlSetFocusPart } ,
177
178 { kEventClassService , kEventServiceGetTypes },
179 { kEventClassService , kEventServiceCopy },
180 { kEventClassService , kEventServicePaste },
181
182// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
183// { kEventClassControl , kEventControlBoundsChanged } ,
184} ;
185
186static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
187{
188 OSStatus result = eventNotHandledErr ;
189
190 wxMacCarbonEvent cEvent( event ) ;
191
192 ControlRef controlRef ;
193 wxWindowMac* thisWindow = (wxWindowMac*) data ;
194
195 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
196
197 switch ( GetEventKind( event ) )
198 {
199#if TARGET_API_MAC_OSX
200 case kEventControlDraw :
201 {
202 RgnHandle updateRgn = NULL ;
203 RgnHandle allocatedRgn = NULL ;
204 wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
205
206 if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
207 {
208 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
209 }
210 else
211 {
212 if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 )
213 {
214 // as this update region is in native window locals we must adapt it to wx window local
215 allocatedRgn = NewRgn() ;
216 CopyRgn( updateRgn , allocatedRgn ) ;
217
218 // hide the given region by the new region that must be shifted
219 wxMacNativeToWindow( thisWindow , allocatedRgn ) ;
220 updateRgn = allocatedRgn ;
221 }
222 }
223
224 Rect rgnBounds ;
225 GetRegionBounds( updateRgn , &rgnBounds ) ;
226
227#if wxMAC_DEBUG_REDRAW
228 if ( thisWindow->MacIsUserPane() )
229 {
230 static float color = 0.5 ;
231 static channel = 0 ;
232 HIRect bounds;
233 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
234
235 HIViewGetBounds( controlRef, &bounds );
236 CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
237 channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
238 CGContextFillRect( cgContext, bounds );
239 color += 0.1 ;
240 if ( color > 0.9 )
241 {
242 color = 0.5 ;
243 channel++ ;
244 if ( channel == 3 )
245 channel = 0 ;
246 }
247 }
248#endif
249
250 {
251 bool created = false ;
252 CGContextRef cgContext = NULL ;
253 OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
254 wxASSERT_MSG( err == noErr , wxT("Unable to retrieve CGContextRef") ) ;
255 thisWindow->MacSetCGContextRef( cgContext ) ;
256
257 {
258 wxMacCGContextStateSaver sg( cgContext ) ;
259 float alpha = 1.0 ;
260 {
261 wxWindow* iter = thisWindow ;
262 while ( iter )
263 {
264 alpha *= (float) iter->GetTransparent()/255.0 ;
265 if ( iter->IsTopLevel() )
266 iter = NULL ;
267 else
268 iter = iter->GetParent() ;
269 }
270 }
271 CGContextSetAlpha( cgContext , alpha ) ;
272
273 if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
274 {
275 HIRect bounds;
276 HIViewGetBounds( controlRef, &bounds );
277 CGContextClearRect( cgContext, bounds );
278 }
279
280 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
281 result = noErr ;
282
283 thisWindow->MacSetCGContextRef( NULL ) ;
284 }
285
286 if ( created )
287 CGContextRelease( cgContext ) ;
288 }
289
290 if ( allocatedRgn )
291 DisposeRgn( allocatedRgn ) ;
292 }
293 break ;
294
295 case kEventControlVisibilityChanged :
296 thisWindow->MacVisibilityChanged() ;
297 break ;
298
299 case kEventControlEnabledStateChanged :
300 thisWindow->MacEnabledStateChanged() ;
301 break ;
302
303 case kEventControlHiliteChanged :
304 thisWindow->MacHiliteChanged() ;
305 break ;
306
307 case kEventControlActivate :
308 case kEventControlDeactivate :
309 // FIXME: we should have a virtual function for this!
310#if wxUSE_TREECTRL
311 if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) )
312 thisWindow->Refresh();
313#endif
314#if wxUSE_LISTCTRL
315 if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) )
316 thisWindow->Refresh();
317#endif
318 break ;
319#endif // TARGET_API_MAC_OSX
320
321 // we emulate this event under Carbon CFM
322 case kEventControlSetFocusPart :
323 {
324 Boolean focusEverything = false ;
325 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
326
327 if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
328 {
329 }
330
331 if ( thisWindow->MacIsUserPane() )
332 result = noErr ;
333
334 if ( controlPart == kControlFocusNoPart )
335 {
336#if wxUSE_CARET
337 if ( thisWindow->GetCaret() )
338 thisWindow->GetCaret()->OnKillFocus();
339#endif
340
341 static bool inKillFocusEvent = false ;
342
343 if ( !inKillFocusEvent )
344 {
345 inKillFocusEvent = true ;
346 wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
347 event.SetEventObject(thisWindow);
348 thisWindow->GetEventHandler()->ProcessEvent(event) ;
349 inKillFocusEvent = false ;
350 }
351 }
352 else
353 {
354 // panel wants to track the window which was the last to have focus in it
355 wxChildFocusEvent eventFocus(thisWindow);
356 thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
357
358#if wxUSE_CARET
359 if ( thisWindow->GetCaret() )
360 thisWindow->GetCaret()->OnSetFocus();
361#endif
362
363 wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
364 event.SetEventObject(thisWindow);
365 thisWindow->GetEventHandler()->ProcessEvent(event) ;
366 }
367 }
368 break ;
369
370 case kEventControlHit :
371 result = thisWindow->MacControlHit( handler , event ) ;
372 break ;
373
374 case kEventControlGetClickActivation :
375 {
376 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
377 WindowRef owner = cEvent.GetParameter<WindowRef>(kEventParamWindowRef);
378 if ( !IsWindowActive(owner) )
379 {
380 cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ;
381 result = noErr ;
382 }
383 }
384 break ;
385
386 default :
387 break ;
388 }
389
390 return result ;
391}
392
393static pascal OSStatus
394wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler),
395 EventRef event,
396 void *data)
397{
398 OSStatus result = eventNotHandledErr ;
399
400 wxMacCarbonEvent cEvent( event ) ;
401
402 ControlRef controlRef ;
403 wxWindowMac* thisWindow = (wxWindowMac*) data ;
404 wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ;
405 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
406
407 switch ( GetEventKind( event ) )
408 {
409 case kEventServiceGetTypes :
410 if ( textCtrl )
411 {
412 long from, to ;
413 textCtrl->GetSelection( &from , &to ) ;
414
415 CFMutableArrayRef copyTypes = 0 , pasteTypes = 0;
416 if ( from != to )
417 copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ;
418 if ( textCtrl->IsEditable() )
419 pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ;
420
421 static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
422 for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i )
423 {
424 CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]);
425 if ( typestring )
426 {
427 if ( copyTypes )
428 CFArrayAppendValue(copyTypes, typestring) ;
429 if ( pasteTypes )
430 CFArrayAppendValue(pasteTypes, typestring) ;
431
432 CFRelease( typestring ) ;
433 }
434 }
435
436 result = noErr ;
437 }
438 break ;
439
440 case kEventServiceCopy :
441 if ( textCtrl )
442 {
443 long from, to ;
444
445 textCtrl->GetSelection( &from , &to ) ;
446 wxString val = textCtrl->GetValue() ;
447 val = val.Mid( from , to - from ) ;
448 PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
449 verify_noerr( PasteboardClear( pasteboard ) ) ;
450 PasteboardSynchronize( pasteboard );
451 // TODO add proper conversion
452 CFDataRef data = CFDataCreate( kCFAllocatorDefault, (const UInt8*)val.c_str(), val.length() );
453 PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0);
454 CFRelease( data );
455 result = noErr ;
456 }
457 break ;
458
459 case kEventServicePaste :
460 if ( textCtrl )
461 {
462 PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
463 PasteboardSynchronize( pasteboard );
464 ItemCount itemCount;
465 verify_noerr( PasteboardGetItemCount( pasteboard, &itemCount ) );
466 for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ )
467 {
468 PasteboardItemID itemID;
469 if ( PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ) == noErr )
470 {
471 CFDataRef flavorData = NULL;
472 if ( PasteboardCopyItemFlavorData( pasteboard, itemID, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData ) == noErr )
473 {
474 CFIndex flavorDataSize = CFDataGetLength( flavorData );
475 char *content = new char[flavorDataSize+1] ;
476 memcpy( content, CFDataGetBytePtr( flavorData ), flavorDataSize );
477 content[flavorDataSize]=0;
478 CFRelease( flavorData );
479#if wxUSE_UNICODE
480 textCtrl->WriteText( wxString( content , wxConvLocal ) );
481#else
482 textCtrl->WriteText( wxString( content ) ) ;
483#endif
484
485 delete[] content ;
486 result = noErr ;
487 }
488 }
489 }
490 }
491 break ;
492
493 default:
494 break ;
495 }
496
497 return result ;
498}
499
500pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
501{
502 OSStatus result = eventNotHandledErr ;
503 wxWindowMac* focus = (wxWindowMac*) data ;
504
505 wchar_t* uniChars = NULL ;
506 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
507
508 UniChar* charBuf = NULL;
509 ByteCount dataSize = 0 ;
510 int numChars = 0 ;
511 UniChar buf[2] ;
512 if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr )
513 {
514 numChars = dataSize / sizeof( UniChar) + 1;
515 charBuf = buf ;
516
517 if ( (size_t) numChars * 2 > sizeof(buf) )
518 charBuf = new UniChar[ numChars ] ;
519 else
520 charBuf = buf ;
521
522 uniChars = new wchar_t[ numChars ] ;
523 GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
524 charBuf[ numChars - 1 ] = 0;
525#if SIZEOF_WCHAR_T == 2
526 uniChars = (wchar_t*) charBuf ;
527/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
528#else
529 // the resulting string will never have more chars than the utf16 version, so this is safe
530 wxMBConvUTF16 converter ;
531 numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ;
532#endif
533 }
534
535 switch ( GetEventKind( event ) )
536 {
537 case kEventTextInputUpdateActiveInputArea :
538 {
539 // An IME input event may return several characters, but we need to send one char at a time to
540 // EVT_CHAR
541 for (int pos=0 ; pos < numChars ; pos++)
542 {
543 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
544 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
545 wxTheApp->MacSetCurrentEvent( event , handler ) ;
546
547 UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?';
548/*
549 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
550 multiple times to update the active range during inline input, so this handler will often receive
551 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
552 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
553 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
554 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
555 should add new event types to support advanced text input. For now, I would keep things as they are.
556
557 However, the code that was being used caused additional problems:
558 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
559 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
560 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
561 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
562 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
563 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
564 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
565 overlap with Unicode within the (7-bit) ASCII range.
566 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
567 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
568 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
569 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
570 I don't have time to look into that right now.
571 -- CL
572*/
573 if ( wxTheApp->MacSendCharEvent(
574 focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
575 {
576 result = noErr ;
577 }
578
579 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
580 }
581 }
582 break ;
583 case kEventTextInputUnicodeForKeyEvent :
584 {
585 UInt32 keyCode, modifiers ;
586 Point point ;
587 EventRef rawEvent ;
588 unsigned char charCode ;
589
590 GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ;
591 GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
592 GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
593 GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
594 GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
595
596 UInt32 message = (keyCode << 8) + charCode;
597
598 // An IME input event may return several characters, but we need to send one char at a time to
599 // EVT_CHAR
600 for (int pos=0 ; pos < numChars ; pos++)
601 {
602 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
603 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
604 wxTheApp->MacSetCurrentEvent( event , handler ) ;
605
606 if ( wxTheApp->MacSendCharEvent(
607 focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) )
608 {
609 result = noErr ;
610 }
611
612 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
613 }
614 }
615 break;
616 default:
617 break ;
618 }
619
620 delete [] uniChars ;
621 if ( charBuf != buf )
622 delete [] charBuf ;
623
624 return result ;
625}
626
627static pascal OSStatus
628wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler),
629 EventRef event,
630 void *data)
631{
632 OSStatus result = eventNotHandledErr ;
633 wxWindowMac* focus = (wxWindowMac*) data ;
634
635 HICommand command ;
636
637 wxMacCarbonEvent cEvent( event ) ;
638 cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ;
639
640 wxMenuItem* item = NULL ;
641 wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
642 int id = wxMacCommandToId( command.commandID ) ;
643
644 if ( item )
645 {
646 wxASSERT( itemMenu != NULL ) ;
647
648 switch ( cEvent.GetKind() )
649 {
650 case kEventProcessCommand :
651 result = itemMenu->MacHandleCommandProcess( item, id, focus );
652 break ;
653
654 case kEventCommandUpdateStatus:
655 result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus );
656 break ;
657
658 default :
659 break ;
660 }
661 }
662 return result ;
663}
664
665pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
666{
667 EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
668 EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ;
669 wxTheApp->MacSetCurrentEvent( event , handler ) ;
670 OSStatus result = eventNotHandledErr ;
671
672 switch ( GetEventClass( event ) )
673 {
674 case kEventClassCommand :
675 result = wxMacWindowCommandEventHandler( handler , event , data ) ;
676 break ;
677
678 case kEventClassControl :
679 result = wxMacWindowControlEventHandler( handler, event, data ) ;
680 break ;
681
682 case kEventClassService :
683 result = wxMacWindowServiceEventHandler( handler, event , data ) ;
684 break ;
685
686 case kEventClassTextInput :
687 result = wxMacUnicodeTextEventHandler( handler , event , data ) ;
688 break ;
689
690 default :
691 break ;
692 }
693
694 wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ;
695
696 return result ;
697}
698
699DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
700
701#if !TARGET_API_MAC_OSX
702
703// ---------------------------------------------------------------------------
704// UserPane events for non OSX builds
705// ---------------------------------------------------------------------------
706
707static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
708{
709 wxWindow * win = wxFindControlFromMacControl(control) ;
710 if ( win )
711 win->MacControlUserPaneDrawProc(part) ;
712}
713wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP , wxMacControlUserPaneDrawProc ) ;
714
715static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
716{
717 wxWindow * win = wxFindControlFromMacControl(control) ;
718 if ( win )
719 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
720 else
721 return kControlNoPart ;
722}
723wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP , wxMacControlUserPaneHitTestProc ) ;
724
725static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
726{
727 wxWindow * win = wxFindControlFromMacControl(control) ;
728 if ( win )
729 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
730 else
731 return kControlNoPart ;
732}
733wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP , wxMacControlUserPaneTrackingProc ) ;
734
735static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
736{
737 wxWindow * win = wxFindControlFromMacControl(control) ;
738 if ( win )
739 win->MacControlUserPaneIdleProc() ;
740}
741wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP , wxMacControlUserPaneIdleProc ) ;
742
743static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
744{
745 wxWindow * win = wxFindControlFromMacControl(control) ;
746 if ( win )
747 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
748 else
749 return kControlNoPart ;
750}
751wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP , wxMacControlUserPaneKeyDownProc ) ;
752
753static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
754{
755 wxWindow * win = wxFindControlFromMacControl(control) ;
756 if ( win )
757 win->MacControlUserPaneActivateProc(activating) ;
758}
759wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP , wxMacControlUserPaneActivateProc ) ;
760
761static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
762{
763 wxWindow * win = wxFindControlFromMacControl(control) ;
764 if ( win )
765 return win->MacControlUserPaneFocusProc(action) ;
766 else
767 return kControlNoPart ;
768}
769wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP , wxMacControlUserPaneFocusProc ) ;
770
771static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
772{
773 wxWindow * win = wxFindControlFromMacControl(control) ;
774 if ( win )
775 win->MacControlUserPaneBackgroundProc(info) ;
776}
777wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP , wxMacControlUserPaneBackgroundProc ) ;
778
779void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
780{
781 int x = 0 , y = 0;
782 RgnHandle rgn = NewRgn() ;
783 GetClip( rgn ) ;
784 MacWindowToRootWindow( &x, &y ) ;
785 OffsetRgn( rgn , -x , -y ) ;
786 wxMacWindowStateSaver sv( this ) ;
787 SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
788 MacDoRedraw( rgn , 0 ) ;
789 DisposeRgn( rgn ) ;
790}
791
792wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
793{
794 return kControlNoPart ;
795}
796
797wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
798{
799 return kControlNoPart ;
800}
801
802void wxWindowMac::MacControlUserPaneIdleProc()
803{
804}
805
806wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
807{
808 return kControlNoPart ;
809}
810
811void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
812{
813}
814
815wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
816{
817 if ( AcceptsFocus() )
818 return 1 ;
819 else
820 return kControlNoPart ;
821}
822
823void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
824{
825}
826
827#endif
828
829// ---------------------------------------------------------------------------
830// Scrollbar Tracking for all
831// ---------------------------------------------------------------------------
832
833pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
834pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
835{
836 if ( partCode != 0)
837 {
838 wxWindow* wx = wxFindControlFromMacControl( control ) ;
839 if ( wx )
840 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
841 }
842}
843wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ;
844
845// ===========================================================================
846// implementation
847// ===========================================================================
848
849WX_DECLARE_HASH_MAP(ControlRef, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap);
850
851static MacControlMap wxWinMacControlList;
852
853wxWindow *wxFindControlFromMacControl(ControlRef inControl )
854{
855 MacControlMap::iterator node = wxWinMacControlList.find(inControl);
856
857 return (node == wxWinMacControlList.end()) ? NULL : node->second;
858}
859
860void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
861{
862 // adding NULL ControlRef is (first) surely a result of an error and
863 // (secondly) breaks native event processing
864 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
865
866 wxWinMacControlList[inControl] = control;
867}
868
869void wxRemoveMacControlAssociation(wxWindow *control)
870{
871 // iterate over all the elements in the class
872 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
873 // we should go on...
874
875 bool found = true ;
876 while ( found )
877 {
878 found = false ;
879 MacControlMap::iterator it;
880 for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it )
881 {
882 if ( it->second == control )
883 {
884 wxWinMacControlList.erase(it);
885 found = true ;
886 break;
887 }
888 }
889 }
890}
891
892// ----------------------------------------------------------------------------
893 // constructors and such
894// ----------------------------------------------------------------------------
895
896wxWindowMac::wxWindowMac()
897{
898 Init();
899}
900
901wxWindowMac::wxWindowMac(wxWindowMac *parent,
902 wxWindowID id,
903 const wxPoint& pos ,
904 const wxSize& size ,
905 long style ,
906 const wxString& name )
907{
908 Init();
909 Create(parent, id, pos, size, style, name);
910}
911
912void wxWindowMac::Init()
913{
914 m_peer = NULL ;
915 m_frozenness = 0 ;
916 m_macAlpha = 255 ;
917 m_cgContextRef = NULL ;
918
919 // as all windows are created with WS_VISIBLE style...
920 m_isShown = true;
921
922 m_hScrollBar = NULL ;
923 m_vScrollBar = NULL ;
924 m_hScrollBarAlwaysShown = false;
925 m_vScrollBarAlwaysShown = false;
926
927 m_macBackgroundBrush = wxNullBrush ;
928
929 m_macIsUserPane = true;
930 m_clipChildren = false ;
931 m_cachedClippedRectValid = false ;
932
933 // we need a valid font for the encodings
934 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
935}
936
937wxWindowMac::~wxWindowMac()
938{
939 SendDestroyEvent();
940
941 m_isBeingDeleted = true;
942
943 MacInvalidateBorders() ;
944
945#ifndef __WXUNIVERSAL__
946 // VS: make sure there's no wxFrame with last focus set to us:
947 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
948 {
949 wxFrame *frame = wxDynamicCast(win, wxFrame);
950 if ( frame )
951 {
952 if ( frame->GetLastFocus() == this )
953 frame->SetLastFocus((wxWindow*)NULL);
954 break;
955 }
956 }
957#endif
958
959 // destroy children before destroying this window itself
960 DestroyChildren();
961
962 // wxRemoveMacControlAssociation( this ) ;
963 // If we delete an item, we should initialize the parent panel,
964 // because it could now be invalid.
965 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
966 if ( tlw )
967 {
968 if ( tlw->GetDefaultItem() == (wxButton*) this)
969 tlw->SetDefaultItem(NULL);
970 }
971
972 if ( m_peer && m_peer->Ok() )
973 {
974 // in case the callback might be called during destruction
975 wxRemoveMacControlAssociation( this) ;
976 ::RemoveEventHandler( (EventHandlerRef ) m_macControlEventHandler ) ;
977 // we currently are not using this hook
978 // ::SetControlColorProc( *m_peer , NULL ) ;
979 m_peer->Dispose() ;
980 }
981
982 if ( g_MacLastWindow == this )
983 g_MacLastWindow = NULL ;
984
985#ifndef __WXUNIVERSAL__
986 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ;
987 if ( frame )
988 {
989 if ( frame->GetLastFocus() == this )
990 frame->SetLastFocus( NULL ) ;
991 }
992#endif
993
994 // delete our drop target if we've got one
995#if wxUSE_DRAG_AND_DROP
996 if ( m_dropTarget != NULL )
997 {
998 delete m_dropTarget;
999 m_dropTarget = NULL;
1000 }
1001#endif
1002
1003 delete m_peer ;
1004}
1005
1006WXWidget wxWindowMac::GetHandle() const
1007{
1008 return (WXWidget) m_peer->GetControlRef() ;
1009}
1010
1011void wxWindowMac::MacInstallEventHandler( WXWidget control )
1012{
1013 wxAssociateControlWithMacControl( (ControlRef) control , this ) ;
1014 InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(),
1015 GetEventTypeCount(eventList), eventList, this,
1016 (EventHandlerRef *)&m_macControlEventHandler);
1017
1018#if !TARGET_API_MAC_OSX
1019 if ( (ControlRef) control == m_peer->GetControlRef() )
1020 {
1021 m_peer->SetData<ControlUserPaneDrawUPP>(kControlEntireControl, kControlUserPaneDrawProcTag, GetwxMacControlUserPaneDrawProc()) ;
1022 m_peer->SetData<ControlUserPaneHitTestUPP>(kControlEntireControl, kControlUserPaneHitTestProcTag, GetwxMacControlUserPaneHitTestProc()) ;
1023 m_peer->SetData<ControlUserPaneTrackingUPP>(kControlEntireControl, kControlUserPaneTrackingProcTag, GetwxMacControlUserPaneTrackingProc()) ;
1024 m_peer->SetData<ControlUserPaneIdleUPP>(kControlEntireControl, kControlUserPaneIdleProcTag, GetwxMacControlUserPaneIdleProc()) ;
1025 m_peer->SetData<ControlUserPaneKeyDownUPP>(kControlEntireControl, kControlUserPaneKeyDownProcTag, GetwxMacControlUserPaneKeyDownProc()) ;
1026 m_peer->SetData<ControlUserPaneActivateUPP>(kControlEntireControl, kControlUserPaneActivateProcTag, GetwxMacControlUserPaneActivateProc()) ;
1027 m_peer->SetData<ControlUserPaneFocusUPP>(kControlEntireControl, kControlUserPaneFocusProcTag, GetwxMacControlUserPaneFocusProc()) ;
1028 m_peer->SetData<ControlUserPaneBackgroundUPP>(kControlEntireControl, kControlUserPaneBackgroundProcTag, GetwxMacControlUserPaneBackgroundProc()) ;
1029 }
1030#endif
1031}
1032
1033// Constructor
1034bool wxWindowMac::Create(wxWindowMac *parent,
1035 wxWindowID id,
1036 const wxPoint& pos,
1037 const wxSize& size,
1038 long style,
1039 const wxString& name)
1040{
1041 wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
1042
1043 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
1044 return false;
1045
1046 m_windowVariant = parent->GetWindowVariant() ;
1047
1048 if ( m_macIsUserPane )
1049 {
1050 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
1051
1052 UInt32 features = 0
1053 | kControlSupportsEmbedding
1054 | kControlSupportsLiveFeedback
1055 | kControlGetsFocusOnClick
1056// | kControlHasSpecialBackground
1057// | kControlSupportsCalcBestRect
1058 | kControlHandlesTracking
1059 | kControlSupportsFocus
1060 | kControlWantsActivate
1061 | kControlWantsIdle ;
1062
1063 m_peer = new wxMacControl(this) ;
1064 OSStatus err =::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() );
1065 verify_noerr( err );
1066
1067 MacPostControlCreate(pos, size) ;
1068 }
1069
1070#ifndef __WXUNIVERSAL__
1071 // Don't give scrollbars to wxControls unless they ask for them
1072 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar)))
1073 || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL))))
1074 {
1075 MacCreateScrollBars( style ) ;
1076 }
1077#endif
1078
1079 wxWindowCreateEvent event(this);
1080 GetEventHandler()->AddPendingEvent(event);
1081
1082 return true;
1083}
1084
1085void wxWindowMac::MacChildAdded()
1086{
1087 if ( m_vScrollBar )
1088 m_vScrollBar->Raise() ;
1089 if ( m_hScrollBar )
1090 m_hScrollBar->Raise() ;
1091}
1092
1093void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size)
1094{
1095 wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ;
1096
1097 m_peer->SetReference( (URefCon) this ) ;
1098 GetParent()->AddChild( this );
1099
1100 MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() );
1101
1102 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
1103 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
1104 ::EmbedControl( m_peer->GetControlRef() , container ) ;
1105 GetParent()->MacChildAdded() ;
1106
1107 // adjust font, controlsize etc
1108 DoSetWindowVariant( m_windowVariant ) ;
1109
1110 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
1111
1112 if (!m_macIsUserPane)
1113 SetInitialSize(size);
1114
1115 SetCursor( *wxSTANDARD_CURSOR ) ;
1116}
1117
1118void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
1119{
1120 // Don't assert, in case we set the window variant before
1121 // the window is created
1122 // wxASSERT( m_peer->Ok() ) ;
1123
1124 m_windowVariant = variant ;
1125
1126 if (m_peer == NULL || !m_peer->Ok())
1127 return;
1128
1129 ControlSize size ;
1130 ThemeFontID themeFont = kThemeSystemFont ;
1131
1132 // we will get that from the settings later
1133 // and make this NORMAL later, but first
1134 // we have a few calculations that we must fix
1135
1136 switch ( variant )
1137 {
1138 case wxWINDOW_VARIANT_NORMAL :
1139 size = kControlSizeNormal;
1140 themeFont = kThemeSystemFont ;
1141 break ;
1142
1143 case wxWINDOW_VARIANT_SMALL :
1144 size = kControlSizeSmall;
1145 themeFont = kThemeSmallSystemFont ;
1146 break ;
1147
1148 case wxWINDOW_VARIANT_MINI :
1149 // not always defined in the headers
1150 size = 3 ;
1151 themeFont = 109 ;
1152 break ;
1153
1154 case wxWINDOW_VARIANT_LARGE :
1155 size = kControlSizeLarge;
1156 themeFont = kThemeSystemFont ;
1157 break ;
1158
1159 default:
1160 wxFAIL_MSG(_T("unexpected window variant"));
1161 break ;
1162 }
1163
1164 m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
1165
1166 wxFont font ;
1167 font.MacCreateThemeFont( themeFont ) ;
1168 SetFont( font ) ;
1169}
1170
1171void wxWindowMac::MacUpdateControlFont()
1172{
1173 m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1174 // do not trigger refreshes upon invisible and possible partly created objects
1175 if ( MacIsReallyShown() )
1176 Refresh() ;
1177}
1178
1179bool wxWindowMac::SetFont(const wxFont& font)
1180{
1181 bool retval = wxWindowBase::SetFont( font );
1182
1183 MacUpdateControlFont() ;
1184
1185 return retval;
1186}
1187
1188bool wxWindowMac::SetForegroundColour(const wxColour& col )
1189{
1190 bool retval = wxWindowBase::SetForegroundColour( col );
1191
1192 if (retval)
1193 MacUpdateControlFont();
1194
1195 return retval;
1196}
1197
1198bool wxWindowMac::SetBackgroundColour(const wxColour& col )
1199{
1200 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
1201 return false ;
1202
1203 wxBrush brush ;
1204 wxColour newCol(GetBackgroundColour());
1205
1206 if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) )
1207 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
1208 else if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) )
1209 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
1210 else
1211 brush.SetColour( newCol ) ;
1212
1213 MacSetBackgroundBrush( brush ) ;
1214 MacUpdateControlFont() ;
1215
1216 return true ;
1217}
1218
1219void wxWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
1220{
1221 m_macBackgroundBrush = brush ;
1222 m_peer->SetBackground( brush ) ;
1223}
1224
1225bool wxWindowMac::MacCanFocus() const
1226{
1227 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1228 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1229 // but the value range is nowhere documented
1230 Boolean keyExistsAndHasValidFormat ;
1231 CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1232 kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat );
1233
1234 if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 )
1235 {
1236 return true ;
1237 }
1238 else
1239 {
1240 UInt32 features = 0 ;
1241 m_peer->GetFeatures( &features ) ;
1242
1243 return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
1244 }
1245}
1246
1247void wxWindowMac::SetFocus()
1248{
1249 if ( !AcceptsFocus() )
1250 return ;
1251
1252 wxWindow* former = FindFocus() ;
1253 if ( former == this )
1254 return ;
1255
1256 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1257 // we can only leave in case of an error
1258 OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
1259 if ( err == errCouldntSetFocus )
1260 return ;
1261
1262 SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() );
1263
1264#if !TARGET_API_MAC_OSX
1265 // emulate carbon events when running under CarbonLib where they are not natively available
1266 if ( former )
1267 {
1268 EventRef evRef = NULL ;
1269
1270 err = MacCreateEvent(
1271 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1272 kEventAttributeUserEvent , &evRef );
1273 verify_noerr( err );
1274
1275 wxMacCarbonEvent cEvent( evRef ) ;
1276 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
1277 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
1278
1279 wxMacWindowEventHandler( NULL , evRef , former ) ;
1280 ReleaseEvent( evRef ) ;
1281 }
1282
1283 // send new focus event
1284 {
1285 EventRef evRef = NULL ;
1286
1287 err = MacCreateEvent(
1288 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1289 kEventAttributeUserEvent , &evRef );
1290 verify_noerr( err );
1291
1292 wxMacCarbonEvent cEvent( evRef ) ;
1293 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
1294 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
1295
1296 wxMacWindowEventHandler( NULL , evRef , this ) ;
1297 ReleaseEvent( evRef ) ;
1298 }
1299#endif
1300}
1301
1302void wxWindowMac::DoCaptureMouse()
1303{
1304 wxApp::s_captureWindow = this ;
1305}
1306
1307wxWindow * wxWindowBase::GetCapture()
1308{
1309 return wxApp::s_captureWindow ;
1310}
1311
1312void wxWindowMac::DoReleaseMouse()
1313{
1314 wxApp::s_captureWindow = NULL ;
1315}
1316
1317#if wxUSE_DRAG_AND_DROP
1318
1319void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
1320{
1321 if ( m_dropTarget != NULL )
1322 delete m_dropTarget;
1323
1324 m_dropTarget = pDropTarget;
1325 if ( m_dropTarget != NULL )
1326 {
1327 // TODO:
1328 }
1329}
1330
1331#endif
1332
1333// Old-style File Manager Drag & Drop
1334void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept))
1335{
1336 // TODO:
1337}
1338
1339// Returns the size of the native control. In the case of the toplevel window
1340// this is the content area root control
1341
1342void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x),
1343 int& WXUNUSED(y),
1344 int& WXUNUSED(w),
1345 int& WXUNUSED(h)) const
1346{
1347 wxFAIL_MSG( wxT("Not currently supported") ) ;
1348}
1349
1350// From a wx position / size calculate the appropriate size of the native control
1351
1352bool wxWindowMac::MacGetBoundsForControl(
1353 const wxPoint& pos,
1354 const wxSize& size,
1355 int& x, int& y,
1356 int& w, int& h , bool adjustOrigin ) const
1357{
1358 // the desired size, minus the border pixels gives the correct size of the control
1359 x = (int)pos.x;
1360 y = (int)pos.y;
1361
1362 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1363 w = wxMax(size.x, 0) ; // WidthDefault( size.x );
1364 h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ;
1365
1366 x += MacGetLeftBorderSize() ;
1367 y += MacGetTopBorderSize() ;
1368 w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1369 h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1370
1371 if ( adjustOrigin )
1372 AdjustForParentClientOrigin( x , y ) ;
1373
1374 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1375 if ( !GetParent()->IsTopLevel() )
1376 {
1377 x -= GetParent()->MacGetLeftBorderSize() ;
1378 y -= GetParent()->MacGetTopBorderSize() ;
1379 }
1380
1381 return true ;
1382}
1383
1384// Get window size (not client size)
1385void wxWindowMac::DoGetSize(int *x, int *y) const
1386{
1387 Rect bounds ;
1388 m_peer->GetRect( &bounds ) ;
1389
1390 if (x)
1391 *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1392 if (y)
1393 *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1394}
1395
1396// get the position of the bounds of this window in client coordinates of its parent
1397void wxWindowMac::DoGetPosition(int *x, int *y) const
1398{
1399 Rect bounds ;
1400 m_peer->GetRect( &bounds ) ;
1401
1402 int x1 = bounds.left ;
1403 int y1 = bounds.top ;
1404
1405 // get the wx window position from the native one
1406 x1 -= MacGetLeftBorderSize() ;
1407 y1 -= MacGetTopBorderSize() ;
1408
1409 if ( !IsTopLevel() )
1410 {
1411 wxWindow *parent = GetParent();
1412 if ( parent )
1413 {
1414 // we must first adjust it to be in window coordinates of the parent,
1415 // as otherwise it gets lost by the ClientAreaOrigin fix
1416 x1 += parent->MacGetLeftBorderSize() ;
1417 y1 += parent->MacGetTopBorderSize() ;
1418
1419 // and now to client coordinates
1420 wxPoint pt(parent->GetClientAreaOrigin());
1421 x1 -= pt.x ;
1422 y1 -= pt.y ;
1423 }
1424 }
1425
1426 if (x)
1427 *x = x1 ;
1428 if (y)
1429 *y = y1 ;
1430}
1431
1432void wxWindowMac::DoScreenToClient(int *x, int *y) const
1433{
1434 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1435 wxCHECK_RET( window , wxT("TopLevel Window missing") ) ;
1436
1437 Point localwhere = { 0, 0 } ;
1438
1439 if (x)
1440 localwhere.h = *x ;
1441 if (y)
1442 localwhere.v = *y ;
1443
1444 wxMacGlobalToLocal( window , &localwhere ) ;
1445
1446 if (x)
1447 *x = localwhere.h ;
1448 if (y)
1449 *y = localwhere.v ;
1450
1451 MacRootWindowToWindow( x , y ) ;
1452
1453 wxPoint origin = GetClientAreaOrigin() ;
1454 if (x)
1455 *x -= origin.x ;
1456 if (y)
1457 *y -= origin.y ;
1458}
1459
1460void wxWindowMac::DoClientToScreen(int *x, int *y) const
1461{
1462 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1463 wxCHECK_RET( window , wxT("TopLevel window missing") ) ;
1464
1465 wxPoint origin = GetClientAreaOrigin() ;
1466 if (x)
1467 *x += origin.x ;
1468 if (y)
1469 *y += origin.y ;
1470
1471 MacWindowToRootWindow( x , y ) ;
1472
1473 Point localwhere = { 0, 0 };
1474 if (x)
1475 localwhere.h = *x ;
1476 if (y)
1477 localwhere.v = *y ;
1478
1479 wxMacLocalToGlobal( window, &localwhere ) ;
1480
1481 if (x)
1482 *x = localwhere.h ;
1483 if (y)
1484 *y = localwhere.v ;
1485}
1486
1487void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
1488{
1489 wxPoint origin = GetClientAreaOrigin() ;
1490 if (x)
1491 *x += origin.x ;
1492 if (y)
1493 *y += origin.y ;
1494
1495 MacWindowToRootWindow( x , y ) ;
1496}
1497
1498void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1499{
1500 MacRootWindowToWindow( x , y ) ;
1501
1502 wxPoint origin = GetClientAreaOrigin() ;
1503 if (x)
1504 *x -= origin.x ;
1505 if (y)
1506 *y -= origin.y ;
1507}
1508
1509void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1510{
1511 wxPoint pt ;
1512
1513 if (x)
1514 pt.x = *x ;
1515 if (y)
1516 pt.y = *y ;
1517
1518 if ( !IsTopLevel() )
1519 {
1520 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1521 if (top)
1522 {
1523 pt.x -= MacGetLeftBorderSize() ;
1524 pt.y -= MacGetTopBorderSize() ;
1525 wxMacControl::Convert( &pt , m_peer , top->m_peer ) ;
1526 }
1527 }
1528
1529 if (x)
1530 *x = (int) pt.x ;
1531 if (y)
1532 *y = (int) pt.y ;
1533}
1534
1535void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1536{
1537 int x1 , y1 ;
1538
1539 if (x)
1540 x1 = *x ;
1541 if (y)
1542 y1 = *y ;
1543
1544 MacWindowToRootWindow( &x1 , &y1 ) ;
1545
1546 if (x)
1547 *x = x1 ;
1548 if (y)
1549 *y = y1 ;
1550}
1551
1552void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
1553{
1554 wxPoint pt ;
1555
1556 if (x)
1557 pt.x = *x ;
1558 if (y)
1559 pt.y = *y ;
1560
1561 if ( !IsTopLevel() )
1562 {
1563 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1564 if (top)
1565 {
1566 wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
1567 pt.x += MacGetLeftBorderSize() ;
1568 pt.y += MacGetTopBorderSize() ;
1569 }
1570 }
1571
1572 if (x)
1573 *x = (int) pt.x ;
1574 if (y)
1575 *y = (int) pt.y ;
1576}
1577
1578void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
1579{
1580 int x1 , y1 ;
1581
1582 if (x)
1583 x1 = *x ;
1584 if (y)
1585 y1 = *y ;
1586
1587 MacRootWindowToWindow( &x1 , &y1 ) ;
1588
1589 if (x)
1590 *x = x1 ;
1591 if (y)
1592 *y = y1 ;
1593}
1594
1595void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1596{
1597 RgnHandle rgn = NewRgn() ;
1598
1599 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
1600 {
1601 Rect structure, content ;
1602
1603 GetRegionBounds( rgn , &content ) ;
1604 m_peer->GetRect( &structure ) ;
1605 OffsetRect( &structure, -structure.left , -structure.top ) ;
1606
1607 left = content.left - structure.left ;
1608 top = content.top - structure.top ;
1609 right = structure.right - content.right ;
1610 bottom = structure.bottom - content.bottom ;
1611 }
1612 else
1613 {
1614 left = top = right = bottom = 0 ;
1615 }
1616
1617 DisposeRgn( rgn ) ;
1618}
1619
1620wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1621{
1622 wxSize sizeTotal = size;
1623
1624 RgnHandle rgn = NewRgn() ;
1625 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
1626 {
1627 Rect content, structure ;
1628 GetRegionBounds( rgn , &content ) ;
1629 m_peer->GetRect( &structure ) ;
1630
1631 // structure is in parent coordinates, but we only need width and height, so it's ok
1632
1633 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
1634 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top) ;
1635 }
1636
1637 DisposeRgn( rgn ) ;
1638
1639 sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1640 sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1641
1642 return sizeTotal;
1643}
1644
1645// Get size *available for subwindows* i.e. excluding menu bar etc.
1646void wxWindowMac::DoGetClientSize( int *x, int *y ) const
1647{
1648 int ww, hh;
1649
1650 RgnHandle rgn = NewRgn() ;
1651 Rect content ;
1652 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
1653 GetRegionBounds( rgn , &content ) ;
1654 else
1655 m_peer->GetRect( &content ) ;
1656 DisposeRgn( rgn ) ;
1657
1658 ww = content.right - content.left ;
1659 hh = content.bottom - content.top ;
1660
1661 if (m_hScrollBar && m_hScrollBar->IsShown() )
1662 hh -= m_hScrollBar->GetSize().y ;
1663
1664 if (m_vScrollBar && m_vScrollBar->IsShown() )
1665 ww -= m_vScrollBar->GetSize().x ;
1666
1667 if (x)
1668 *x = ww;
1669 if (y)
1670 *y = hh;
1671}
1672
1673bool wxWindowMac::SetCursor(const wxCursor& cursor)
1674{
1675 if (m_cursor.IsSameAs(cursor))
1676 return false;
1677
1678 if (!cursor.IsOk())
1679 {
1680 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
1681 return false ;
1682 }
1683 else
1684 {
1685 if ( ! wxWindowBase::SetCursor( cursor ) )
1686 return false ;
1687 }
1688
1689 wxASSERT_MSG( m_cursor.Ok(),
1690 wxT("cursor must be valid after call to the base version"));
1691
1692 wxWindowMac *mouseWin = 0 ;
1693 {
1694 wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ;
1695 WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ;
1696
1697 ControlPartCode part ;
1698 ControlRef control ;
1699 Point pt ;
1700 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1701 HIPoint hiPoint ;
1702 HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint);
1703 pt.h = hiPoint.x;
1704 pt.v = hiPoint.y;
1705 #else
1706 CGrafPtr savePort ;
1707 Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ;
1708
1709 // TODO: If we ever get a GetCurrentEvent... replacement
1710 // for the mouse position, use it...
1711
1712
1713 GetMouse( &pt ) ;
1714#endif
1715 control = FindControlUnderMouse( pt , window , &part ) ;
1716 if ( control )
1717 mouseWin = wxFindControlFromMacControl( control ) ;
1718
1719#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1720 if ( swapped )
1721 QDSwapPort( savePort , NULL ) ;
1722#endif
1723 }
1724
1725 if ( mouseWin == this && !wxIsBusy() )
1726 m_cursor.MacInstall() ;
1727
1728 return true ;
1729}
1730
1731#if wxUSE_MENUS
1732bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1733{
1734#ifndef __WXUNIVERSAL__
1735 menu->SetInvokingWindow((wxWindow*)this);
1736 menu->UpdateUI();
1737
1738 if ( x == wxDefaultCoord && y == wxDefaultCoord )
1739 {
1740 wxPoint mouse = wxGetMousePosition();
1741 x = mouse.x;
1742 y = mouse.y;
1743 }
1744 else
1745 {
1746 ClientToScreen( &x , &y ) ;
1747 }
1748
1749 menu->MacBeforeDisplay( true ) ;
1750 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ;
1751 if ( HiWord(menuResult) != 0 )
1752 {
1753 MenuCommand macid;
1754 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid );
1755 int id = wxMacCommandToId( macid );
1756 wxMenuItem* item = NULL ;
1757 wxMenu* realmenu ;
1758 item = menu->FindItem( id, &realmenu ) ;
1759 if ( item )
1760 {
1761 if (item->IsCheckable())
1762 item->Check( !item->IsChecked() ) ;
1763
1764 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1765 }
1766 }
1767
1768 menu->MacAfterDisplay( true ) ;
1769 menu->SetInvokingWindow( NULL );
1770
1771 return true;
1772#else
1773 // actually this shouldn't be called, because universal is having its own implementation
1774 return false;
1775#endif
1776}
1777#endif
1778
1779// ----------------------------------------------------------------------------
1780// tooltips
1781// ----------------------------------------------------------------------------
1782
1783#if wxUSE_TOOLTIPS
1784
1785void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
1786{
1787 wxWindowBase::DoSetToolTip(tooltip);
1788
1789 if ( m_tooltip )
1790 m_tooltip->SetWindow(this);
1791}
1792
1793#endif
1794
1795void wxWindowMac::MacInvalidateBorders()
1796{
1797 if ( m_peer == NULL )
1798 return ;
1799
1800 bool vis = MacIsReallyShown() ;
1801 if ( !vis )
1802 return ;
1803
1804 int outerBorder = MacGetLeftBorderSize() ;
1805 if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
1806 outerBorder += 4 ;
1807
1808 if ( outerBorder == 0 )
1809 return ;
1810
1811 // now we know that we have something to do at all
1812
1813 // as the borders are drawn on the parent we have to properly invalidate all these areas
1814 RgnHandle updateInner , updateOuter;
1815 Rect rect ;
1816
1817 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1818 updateInner = NewRgn() ;
1819 updateOuter = NewRgn() ;
1820
1821 m_peer->GetRect( &rect ) ;
1822 RectRgn( updateInner, &rect ) ;
1823 InsetRect( &rect , -outerBorder , -outerBorder ) ;
1824 RectRgn( updateOuter, &rect ) ;
1825 DiffRgn( updateOuter, updateInner , updateOuter ) ;
1826
1827 GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ;
1828
1829 DisposeRgn( updateOuter ) ;
1830 DisposeRgn( updateInner ) ;
1831}
1832
1833void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
1834{
1835 // this is never called for a toplevel window, so we know we have a parent
1836 int former_x , former_y , former_w, former_h ;
1837
1838 // Get true coordinates of former position
1839 DoGetPosition( &former_x , &former_y ) ;
1840 DoGetSize( &former_w , &former_h ) ;
1841
1842 wxWindow *parent = GetParent();
1843 if ( parent )
1844 {
1845 wxPoint pt(parent->GetClientAreaOrigin());
1846 former_x += pt.x ;
1847 former_y += pt.y ;
1848 }
1849
1850 int actualWidth = width ;
1851 int actualHeight = height ;
1852 int actualX = x;
1853 int actualY = y;
1854
1855 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
1856 actualWidth = m_minWidth;
1857 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
1858 actualHeight = m_minHeight;
1859 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
1860 actualWidth = m_maxWidth;
1861 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
1862 actualHeight = m_maxHeight;
1863
1864 bool doMove = false, doResize = false ;
1865
1866 if ( actualX != former_x || actualY != former_y )
1867 doMove = true ;
1868
1869 if ( actualWidth != former_w || actualHeight != former_h )
1870 doResize = true ;
1871
1872 if ( doMove || doResize )
1873 {
1874 // as the borders are drawn outside the native control, we adjust now
1875
1876 wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ),
1877 wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1878 actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1879
1880 Rect r ;
1881 wxMacRectToNative( &bounds , &r ) ;
1882
1883 if ( !GetParent()->IsTopLevel() )
1884 wxMacWindowToNative( GetParent() , &r ) ;
1885
1886 MacInvalidateBorders() ;
1887
1888 m_cachedClippedRectValid = false ;
1889 m_peer->SetRect( &r ) ;
1890
1891 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1892
1893 MacInvalidateBorders() ;
1894
1895 MacRepositionScrollBars() ;
1896 if ( doMove )
1897 {
1898 wxPoint point(actualX, actualY);
1899 wxMoveEvent event(point, m_windowId);
1900 event.SetEventObject(this);
1901 GetEventHandler()->ProcessEvent(event) ;
1902 }
1903
1904 if ( doResize )
1905 {
1906 MacRepositionScrollBars() ;
1907 wxSize size(actualWidth, actualHeight);
1908 wxSizeEvent event(size, m_windowId);
1909 event.SetEventObject(this);
1910 GetEventHandler()->ProcessEvent(event);
1911 }
1912 }
1913}
1914
1915wxSize wxWindowMac::DoGetBestSize() const
1916{
1917 if ( m_macIsUserPane || IsTopLevel() )
1918 return wxWindowBase::DoGetBestSize() ;
1919
1920 Rect bestsize = { 0 , 0 , 0 , 0 } ;
1921 int bestWidth, bestHeight ;
1922
1923 m_peer->GetBestRect( &bestsize ) ;
1924 if ( EmptyRect( &bestsize ) )
1925 {
1926 bestsize.left =
1927 bestsize.top = 0 ;
1928 bestsize.right =
1929 bestsize.bottom = 16 ;
1930
1931 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1932 {
1933 bestsize.bottom = 16 ;
1934 }
1935#if wxUSE_SPINBTN
1936 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1937 {
1938 bestsize.bottom = 24 ;
1939 }
1940#endif
1941 else
1942 {
1943 // return wxWindowBase::DoGetBestSize() ;
1944 }
1945 }
1946
1947 bestWidth = bestsize.right - bestsize.left ;
1948 bestHeight = bestsize.bottom - bestsize.top ;
1949 if ( bestHeight < 10 )
1950 bestHeight = 13 ;
1951
1952 return wxSize(bestWidth, bestHeight);
1953}
1954
1955// set the size of the window: if the dimensions are positive, just use them,
1956// but if any of them is equal to -1, it means that we must find the value for
1957// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1958// which case -1 is a valid value for x and y)
1959//
1960// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1961// the width/height to best suit our contents, otherwise we reuse the current
1962// width/height
1963void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1964{
1965 // get the current size and position...
1966 int currentX, currentY;
1967 int currentW, currentH;
1968
1969 GetPosition(&currentX, &currentY);
1970 GetSize(&currentW, &currentH);
1971
1972 // ... and don't do anything (avoiding flicker) if it's already ok
1973 if ( x == currentX && y == currentY &&
1974 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
1975 {
1976 // TODO: REMOVE
1977 MacRepositionScrollBars() ; // we might have a real position shift
1978
1979 return;
1980 }
1981
1982 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1983 {
1984 if ( x == wxDefaultCoord )
1985 x = currentX;
1986 if ( y == wxDefaultCoord )
1987 y = currentY;
1988 }
1989
1990 AdjustForParentClientOrigin( x, y, sizeFlags );
1991
1992 wxSize size = wxDefaultSize;
1993 if ( width == wxDefaultCoord )
1994 {
1995 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
1996 {
1997 size = DoGetBestSize();
1998 width = size.x;
1999 }
2000 else
2001 {
2002 // just take the current one
2003 width = currentW;
2004 }
2005 }
2006
2007 if ( height == wxDefaultCoord )
2008 {
2009 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
2010 {
2011 if ( size.x == wxDefaultCoord )
2012 size = DoGetBestSize();
2013 // else: already called DoGetBestSize() above
2014
2015 height = size.y;
2016 }
2017 else
2018 {
2019 // just take the current one
2020 height = currentH;
2021 }
2022 }
2023
2024 DoMoveWindow( x, y, width, height );
2025}
2026
2027wxPoint wxWindowMac::GetClientAreaOrigin() const
2028{
2029 RgnHandle rgn = NewRgn() ;
2030 Rect content ;
2031 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
2032 {
2033 GetRegionBounds( rgn , &content ) ;
2034 }
2035 else
2036 {
2037 content.left =
2038 content.top = 0 ;
2039 }
2040
2041 DisposeRgn( rgn ) ;
2042
2043 return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() );
2044}
2045
2046void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
2047{
2048 if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord )
2049 {
2050 int currentclientwidth , currentclientheight ;
2051 int currentwidth , currentheight ;
2052
2053 GetClientSize( &currentclientwidth , &currentclientheight ) ;
2054 GetSize( &currentwidth , &currentheight ) ;
2055
2056 DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth ,
2057 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
2058 }
2059}
2060
2061void wxWindowMac::SetLabel(const wxString& title)
2062{
2063 m_label = title ;
2064
2065 if ( m_peer && m_peer->Ok() )
2066 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
2067
2068 // do not trigger refreshes upon invisible and possible partly created objects
2069 if ( MacIsReallyShown() )
2070 Refresh() ;
2071}
2072
2073wxString wxWindowMac::GetLabel() const
2074{
2075 return m_label ;
2076}
2077
2078bool wxWindowMac::Show(bool show)
2079{
2080 bool former = MacIsReallyShown() ;
2081 if ( !wxWindowBase::Show(show) )
2082 return false;
2083
2084 // TODO: use visibilityChanged Carbon Event for OSX
2085 if ( m_peer )
2086 m_peer->SetVisibility( show , true ) ;
2087
2088 if ( former != MacIsReallyShown() )
2089 MacPropagateVisibilityChanged() ;
2090
2091 return true;
2092}
2093
2094void wxWindowMac::DoEnable(bool enable)
2095{
2096 m_peer->Enable( enable ) ;
2097}
2098
2099//
2100// status change propagations (will be not necessary for OSX later )
2101//
2102
2103void wxWindowMac::MacPropagateVisibilityChanged()
2104{
2105#if !TARGET_API_MAC_OSX
2106 MacVisibilityChanged() ;
2107
2108 wxWindowMac *child;
2109 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2110 while ( node )
2111 {
2112 child = node->GetData();
2113 if ( child->IsShown() )
2114 child->MacPropagateVisibilityChanged() ;
2115
2116 node = node->GetNext();
2117 }
2118#endif
2119}
2120
2121void wxWindowMac::OnEnabled(bool WXUNUSED(enabled))
2122{
2123#if !TARGET_API_MAC_OSX
2124 MacEnabledStateChanged() ;
2125#endif
2126}
2127
2128void wxWindowMac::MacPropagateHiliteChanged()
2129{
2130#if !TARGET_API_MAC_OSX
2131 MacHiliteChanged() ;
2132
2133 wxWindowMac *child;
2134 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2135 while ( node )
2136 {
2137 child = node->GetData();
2138 if (child /* && child->IsEnabled() */)
2139 child->MacPropagateHiliteChanged() ;
2140
2141 node = node->GetNext();
2142 }
2143#endif
2144}
2145
2146//
2147// status change notifications
2148//
2149
2150void wxWindowMac::MacVisibilityChanged()
2151{
2152}
2153
2154void wxWindowMac::MacHiliteChanged()
2155{
2156}
2157
2158void wxWindowMac::MacEnabledStateChanged()
2159{
2160}
2161
2162//
2163// status queries on the inherited window's state
2164//
2165
2166bool wxWindowMac::MacIsReallyShown()
2167{
2168 // only under OSX the visibility of the TLW is taken into account
2169 if ( m_isBeingDeleted )
2170 return false ;
2171
2172#if TARGET_API_MAC_OSX
2173 if ( m_peer && m_peer->Ok() )
2174 return m_peer->IsVisible();
2175#endif
2176
2177 wxWindow* win = this ;
2178 while ( win->IsShown() )
2179 {
2180 if ( win->IsTopLevel() )
2181 return true ;
2182
2183 win = win->GetParent() ;
2184 if ( win == NULL )
2185 return true ;
2186 }
2187
2188 return false ;
2189}
2190
2191bool wxWindowMac::MacIsReallyEnabled()
2192{
2193 return m_peer->IsEnabled() ;
2194}
2195
2196bool wxWindowMac::MacIsReallyHilited()
2197{
2198 return m_peer->IsActive();
2199}
2200
2201void wxWindowMac::MacFlashInvalidAreas()
2202{
2203#if TARGET_API_MAC_OSX
2204 HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ;
2205#endif
2206}
2207
2208int wxWindowMac::GetCharHeight() const
2209{
2210 wxClientDC dc( (wxWindowMac*)this ) ;
2211
2212 return dc.GetCharHeight() ;
2213}
2214
2215int wxWindowMac::GetCharWidth() const
2216{
2217 wxClientDC dc( (wxWindowMac*)this ) ;
2218
2219 return dc.GetCharWidth() ;
2220}
2221
2222void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
2223 int *descent, int *externalLeading, const wxFont *theFont ) const
2224{
2225 const wxFont *fontToUse = theFont;
2226 if ( !fontToUse )
2227 fontToUse = &m_font;
2228
2229 wxClientDC dc( (wxWindowMac*) this ) ;
2230 wxCoord lx,ly,ld,le ;
2231 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
2232 if ( externalLeading )
2233 *externalLeading = le ;
2234 if ( descent )
2235 *descent = ld ;
2236 if ( x )
2237 *x = lx ;
2238 if ( y )
2239 *y = ly ;
2240}
2241
2242/*
2243 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2244 * we always intersect with the entire window, not only with the client area
2245 */
2246
2247void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
2248{
2249 if ( m_peer == NULL )
2250 return ;
2251
2252 if ( !MacIsReallyShown() )
2253 return ;
2254
2255 if ( rect )
2256 {
2257 Rect r ;
2258
2259 wxMacRectToNative( rect , &r ) ;
2260 m_peer->SetNeedsDisplay( &r ) ;
2261 }
2262 else
2263 {
2264 m_peer->SetNeedsDisplay() ;
2265 }
2266}
2267
2268void wxWindowMac::Freeze()
2269{
2270#if TARGET_API_MAC_OSX
2271 if ( !m_frozenness++ )
2272 {
2273 if ( m_peer && m_peer->Ok() )
2274 m_peer->SetDrawingEnabled( false ) ;
2275 }
2276#endif
2277}
2278
2279void wxWindowMac::Thaw()
2280{
2281#if TARGET_API_MAC_OSX
2282 wxASSERT_MSG( m_frozenness > 0, wxT("Thaw() without matching Freeze()") );
2283
2284 if ( !--m_frozenness )
2285 {
2286 if ( m_peer && m_peer->Ok() )
2287 {
2288 m_peer->SetDrawingEnabled( true ) ;
2289 m_peer->InvalidateWithChildren() ;
2290 }
2291 }
2292#endif
2293}
2294
2295bool wxWindowMac::IsFrozen() const
2296{
2297 return m_frozenness != 0;
2298}
2299
2300wxWindowMac *wxGetActiveWindow()
2301{
2302 // actually this is a windows-only concept
2303 return NULL;
2304}
2305
2306// Coordinates relative to the window
2307void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos))
2308{
2309 // We really don't move the mouse programmatically under Mac.
2310}
2311
2312void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
2313{
2314 if ( MacGetTopLevelWindow() == NULL )
2315 return ;
2316
2317#if TARGET_API_MAC_OSX
2318 if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT
2319 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
2320 {
2321 event.Skip() ;
2322 }
2323 else
2324#endif
2325 {
2326 event.GetDC()->Clear() ;
2327 }
2328}
2329
2330void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
2331{
2332 event.Skip() ;
2333}
2334
2335int wxWindowMac::GetScrollPos(int orient) const
2336{
2337 if ( orient == wxHORIZONTAL )
2338 {
2339 if ( m_hScrollBar )
2340 return m_hScrollBar->GetThumbPosition() ;
2341 }
2342 else
2343 {
2344 if ( m_vScrollBar )
2345 return m_vScrollBar->GetThumbPosition() ;
2346 }
2347
2348 return 0;
2349}
2350
2351// This now returns the whole range, not just the number
2352// of positions that we can scroll.
2353int wxWindowMac::GetScrollRange(int orient) const
2354{
2355 if ( orient == wxHORIZONTAL )
2356 {
2357 if ( m_hScrollBar )
2358 return m_hScrollBar->GetRange() ;
2359 }
2360 else
2361 {
2362 if ( m_vScrollBar )
2363 return m_vScrollBar->GetRange() ;
2364 }
2365
2366 return 0;
2367}
2368
2369int wxWindowMac::GetScrollThumb(int orient) const
2370{
2371 if ( orient == wxHORIZONTAL )
2372 {
2373 if ( m_hScrollBar )
2374 return m_hScrollBar->GetThumbSize() ;
2375 }
2376 else
2377 {
2378 if ( m_vScrollBar )
2379 return m_vScrollBar->GetThumbSize() ;
2380 }
2381
2382 return 0;
2383}
2384
2385void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
2386{
2387 if ( orient == wxHORIZONTAL )
2388 {
2389 if ( m_hScrollBar )
2390 m_hScrollBar->SetThumbPosition( pos ) ;
2391 }
2392 else
2393 {
2394 if ( m_vScrollBar )
2395 m_vScrollBar->SetThumbPosition( pos ) ;
2396 }
2397}
2398
2399void
2400wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag)
2401{
2402 bool needVisibilityUpdate = false;
2403
2404 if ( m_hScrollBarAlwaysShown != hflag )
2405 {
2406 m_hScrollBarAlwaysShown = hflag;
2407 needVisibilityUpdate = true;
2408 }
2409
2410 if ( m_vScrollBarAlwaysShown != vflag )
2411 {
2412 m_vScrollBarAlwaysShown = vflag;
2413 needVisibilityUpdate = true;
2414 }
2415
2416 if ( needVisibilityUpdate )
2417 DoUpdateScrollbarVisibility();
2418}
2419
2420//
2421// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2422// our own window origin is at leftOrigin/rightOrigin
2423//
2424
2425void wxWindowMac::MacPaintGrowBox()
2426{
2427 if ( IsTopLevel() )
2428 return ;
2429
2430 if ( MacHasScrollBarCorner() )
2431 {
2432 Rect rect ;
2433
2434 CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ;
2435 wxASSERT( cgContext ) ;
2436
2437 m_peer->GetRect( &rect ) ;
2438
2439 int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
2440 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2441 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
2442 CGContextSaveGState( cgContext );
2443
2444 if ( m_macBackgroundBrush.Ok() && m_macBackgroundBrush.GetStyle() != wxTRANSPARENT )
2445 {
2446 wxMacCoreGraphicsColour bkgnd( m_macBackgroundBrush ) ;
2447 bkgnd.Apply( cgContext );
2448 }
2449 else
2450 {
2451 CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 );
2452 }
2453 CGContextFillRect( cgContext, cgrect );
2454 CGContextRestoreGState( cgContext );
2455 }
2456}
2457
2458void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) )
2459{
2460 if ( IsTopLevel() )
2461 return ;
2462
2463 Rect rect ;
2464 bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
2465
2466 // back to the surrounding frame rectangle
2467 m_peer->GetRect( &rect ) ;
2468 InsetRect( &rect, -1 , -1 ) ;
2469
2470 {
2471 CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
2472 rect.bottom - rect.top ) ;
2473
2474 HIThemeFrameDrawInfo info ;
2475 memset( &info, 0 , sizeof(info) ) ;
2476
2477 info.version = 0 ;
2478 info.kind = 0 ;
2479 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2480 info.isFocused = hasFocus ;
2481
2482 CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
2483 wxASSERT( cgContext ) ;
2484
2485 if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2486 {
2487 info.kind = kHIThemeFrameTextFieldSquare ;
2488 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2489 }
2490 else if ( HasFlag(wxSIMPLE_BORDER) )
2491 {
2492 info.kind = kHIThemeFrameListBox ;
2493 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2494 }
2495 else if ( hasFocus )
2496 {
2497 HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
2498 }
2499#if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
2500 m_peer->GetRect( &rect ) ;
2501 if ( MacHasScrollBarCorner() )
2502 {
2503 int variant = (m_hScrollBar == NULL ? m_vScrollBar : m_hScrollBar ) ->GetWindowVariant();
2504 int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
2505 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2506 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
2507 HIThemeGrowBoxDrawInfo info ;
2508 memset( &info, 0, sizeof(info) ) ;
2509 info.version = 0 ;
2510 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2511 info.kind = kHIThemeGrowBoxKindNone ;
2512 // contrary to the docs ...SizeSmall does not work
2513 info.size = kHIThemeGrowBoxSizeNormal ;
2514 info.direction = 0 ;
2515 HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ;
2516 }
2517#endif
2518 }
2519}
2520
2521void wxWindowMac::RemoveChild( wxWindowBase *child )
2522{
2523 if ( child == m_hScrollBar )
2524 m_hScrollBar = NULL ;
2525 if ( child == m_vScrollBar )
2526 m_vScrollBar = NULL ;
2527
2528 wxWindowBase::RemoveChild( child ) ;
2529}
2530
2531void wxWindowMac::DoUpdateScrollbarVisibility()
2532{
2533 bool triggerSizeEvent = false;
2534
2535 if ( m_hScrollBar )
2536 {
2537 bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded();
2538
2539 if ( m_hScrollBar->IsShown() != showHScrollBar )
2540 {
2541 m_hScrollBar->Show( showHScrollBar );
2542 triggerSizeEvent = true;
2543 }
2544 }
2545
2546 if ( m_vScrollBar)
2547 {
2548 bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded();
2549
2550 if ( m_vScrollBar->IsShown() != showVScrollBar )
2551 {
2552 m_vScrollBar->Show( showVScrollBar ) ;
2553 triggerSizeEvent = true;
2554 }
2555 }
2556
2557 MacRepositionScrollBars() ;
2558 if ( triggerSizeEvent )
2559 {
2560 wxSizeEvent event(GetSize(), m_windowId);
2561 event.SetEventObject(this);
2562 GetEventHandler()->ProcessEvent(event);
2563 }
2564}
2565
2566// New function that will replace some of the above.
2567void wxWindowMac::SetScrollbar(int orient, int pos, int thumb,
2568 int range, bool refresh)
2569{
2570 if ( orient == wxHORIZONTAL && m_hScrollBar )
2571 m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
2572 else if ( orient == wxVERTICAL && m_vScrollBar )
2573 m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
2574
2575 DoUpdateScrollbarVisibility();
2576}
2577
2578// Does a physical scroll
2579void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
2580{
2581 if ( dx == 0 && dy == 0 )
2582 return ;
2583
2584 int width , height ;
2585 GetClientSize( &width , &height ) ;
2586
2587 {
2588 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2589 // area is scrolled, this does not occur if width and height are 2 pixels less,
2590 // TODO: write optimal workaround
2591 wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
2592 if ( rect )
2593 scrollrect.Intersect( *rect ) ;
2594
2595 if ( m_peer->GetNeedsDisplay() )
2596 {
2597 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2598 // in case there is already a pending redraw on that area
2599 // either immediate redraw or full invalidate
2600#if 1
2601 // is the better overall solution, as it does not slow down scrolling
2602 m_peer->SetNeedsDisplay() ;
2603#else
2604 // this would be the preferred version for fast drawing controls
2605 HIViewRender(m_peer->GetControlRef()) ;
2606#endif
2607 }
2608
2609 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2610 scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2611 m_peer->ScrollRect( &scrollrect , dx , dy ) ;
2612
2613#if 0
2614 // this would be the preferred version for fast drawing controls
2615 HIViewRender(m_peer->GetControlRef()) ;
2616#endif
2617 }
2618
2619 wxWindowMac *child;
2620 int x, y, w, h;
2621 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
2622 {
2623 child = node->GetData();
2624 if (child == NULL)
2625 continue;
2626 if (child == m_vScrollBar)
2627 continue;
2628 if (child == m_hScrollBar)
2629 continue;
2630 if (child->IsTopLevel())
2631 continue;
2632
2633 child->GetPosition( &x, &y );
2634 child->GetSize( &w, &h );
2635 if (rect)
2636 {
2637 wxRect rc( x, y, w, h );
2638 if (rect->Intersects( rc ))
2639 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
2640 }
2641 else
2642 {
2643 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
2644 }
2645 }
2646}
2647
2648void wxWindowMac::MacOnScroll( wxScrollEvent &event )
2649{
2650 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
2651 {
2652 wxScrollWinEvent wevent;
2653 wevent.SetPosition(event.GetPosition());
2654 wevent.SetOrientation(event.GetOrientation());
2655 wevent.SetEventObject(this);
2656
2657 if (event.GetEventType() == wxEVT_SCROLL_TOP)
2658 wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
2659 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
2660 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
2661 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
2662 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
2663 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
2664 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
2665 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
2666 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
2667 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
2668 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
2669 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
2670 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
2671 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
2672 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
2673
2674 GetEventHandler()->ProcessEvent(wevent);
2675 }
2676}
2677
2678// Get the window with the focus
2679wxWindowMac *wxWindowBase::DoFindFocus()
2680{
2681 ControlRef control ;
2682 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2683 return wxFindControlFromMacControl( control ) ;
2684}
2685
2686void wxWindowMac::OnSetFocus( wxFocusEvent& event )
2687{
2688 // panel wants to track the window which was the last to have focus in it,
2689 // so we want to set ourselves as the window which last had focus
2690 //
2691 // notice that it's also important to do it upwards the tree because
2692 // otherwise when the top level panel gets focus, it won't set it back to
2693 // us, but to some other sibling
2694
2695 // CS: don't know if this is still needed:
2696 //wxChildFocusEvent eventFocus(this);
2697 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2698
2699 if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() )
2700 {
2701 GetParent()->Refresh() ;
2702 wxMacWindowStateSaver sv( this ) ;
2703 Rect rect ;
2704
2705 m_peer->GetRect( &rect ) ;
2706 // auf den umgebenden Rahmen zurチᅡ゚ck
2707 InsetRect( &rect, -1 , -1 ) ;
2708
2709 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
2710 if ( top )
2711 {
2712 wxPoint pt(0, 0) ;
2713 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
2714 rect.left += pt.x ;
2715 rect.right += pt.x ;
2716 rect.top += pt.y ;
2717 rect.bottom += pt.y ;
2718 }
2719
2720 bool bIsFocusEvent = (event.GetEventType() == wxEVT_SET_FOCUS);
2721 DrawThemeFocusRect( &rect , bIsFocusEvent ) ;
2722 if ( !bIsFocusEvent )
2723 {
2724 // as this erases part of the frame we have to redraw borders
2725 // and because our z-ordering is not always correct (staticboxes)
2726 // we have to invalidate things, we cannot simple redraw
2727 MacInvalidateBorders() ;
2728 }
2729 }
2730
2731 event.Skip();
2732}
2733
2734void wxWindowMac::OnInternalIdle()
2735{
2736 // This calls the UI-update mechanism (querying windows for
2737 // menu/toolbar/control state information)
2738 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
2739 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
2740}
2741
2742// Raise the window to the top of the Z order
2743void wxWindowMac::Raise()
2744{
2745 m_peer->SetZOrder( true , NULL ) ;
2746}
2747
2748// Lower the window to the bottom of the Z order
2749void wxWindowMac::Lower()
2750{
2751 m_peer->SetZOrder( false , NULL ) ;
2752}
2753
2754// static wxWindow *gs_lastWhich = NULL;
2755
2756bool wxWindowMac::MacSetupCursor( const wxPoint& pt )
2757{
2758 // first trigger a set cursor event
2759
2760 wxPoint clientorigin = GetClientAreaOrigin() ;
2761 wxSize clientsize = GetClientSize() ;
2762 wxCursor cursor ;
2763 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
2764 {
2765 wxSetCursorEvent event( pt.x , pt.y );
2766
2767 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2768 if ( processedEvtSetCursor && event.HasCursor() )
2769 {
2770 cursor = event.GetCursor() ;
2771 }
2772 else
2773 {
2774 // the test for processedEvtSetCursor is here to prevent using m_cursor
2775 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2776 // it - this is a way to say that our cursor shouldn't be used for this
2777 // point
2778 if ( !processedEvtSetCursor && m_cursor.Ok() )
2779 cursor = m_cursor ;
2780
2781 if ( !wxIsBusy() && !GetParent() )
2782 cursor = *wxSTANDARD_CURSOR ;
2783 }
2784
2785 if ( cursor.Ok() )
2786 cursor.MacInstall() ;
2787 }
2788
2789 return cursor.Ok() ;
2790}
2791
2792wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) )
2793{
2794#if wxUSE_TOOLTIPS
2795 if ( m_tooltip )
2796 return m_tooltip->GetTip() ;
2797#endif
2798
2799 return wxEmptyString ;
2800}
2801
2802void wxWindowMac::ClearBackground()
2803{
2804 Refresh() ;
2805 Update() ;
2806}
2807
2808void wxWindowMac::Update()
2809{
2810#if TARGET_API_MAC_OSX
2811 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
2812 if (top)
2813 top->MacPerformUpdates() ;
2814#else
2815 ::Draw1Control( m_peer->GetControlRef() ) ;
2816#endif
2817}
2818
2819wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
2820{
2821 wxTopLevelWindowMac* win = NULL ;
2822 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
2823 if ( window )
2824 win = wxFindWinFromMacWindow( window ) ;
2825
2826 return win ;
2827}
2828
2829const wxRect& wxWindowMac::MacGetClippedClientRect() const
2830{
2831 MacUpdateClippedRects() ;
2832
2833 return m_cachedClippedClientRect ;
2834}
2835
2836const wxRect& wxWindowMac::MacGetClippedRect() const
2837{
2838 MacUpdateClippedRects() ;
2839
2840 return m_cachedClippedRect ;
2841}
2842
2843const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2844{
2845 MacUpdateClippedRects() ;
2846
2847 return m_cachedClippedRectWithOuterStructure ;
2848}
2849
2850const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
2851{
2852 static wxRegion emptyrgn ;
2853
2854 if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ )
2855 {
2856 MacUpdateClippedRects() ;
2857 if ( includeOuterStructures )
2858 return m_cachedClippedRegionWithOuterStructure ;
2859 else
2860 return m_cachedClippedRegion ;
2861 }
2862 else
2863 {
2864 return emptyrgn ;
2865 }
2866}
2867
2868void wxWindowMac::MacUpdateClippedRects() const
2869{
2870 if ( m_cachedClippedRectValid )
2871 return ;
2872
2873 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2874 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2875 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2876 // to add focus borders everywhere
2877
2878 Rect r, rIncludingOuterStructures ;
2879
2880 m_peer->GetRect( &r ) ;
2881 r.left -= MacGetLeftBorderSize() ;
2882 r.top -= MacGetTopBorderSize() ;
2883 r.bottom += MacGetBottomBorderSize() ;
2884 r.right += MacGetRightBorderSize() ;
2885
2886 r.right -= r.left ;
2887 r.bottom -= r.top ;
2888 r.left = 0 ;
2889 r.top = 0 ;
2890
2891 rIncludingOuterStructures = r ;
2892 InsetRect( &rIncludingOuterStructures , -4 , -4 ) ;
2893
2894 wxRect cl = GetClientRect() ;
2895 Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ;
2896
2897 int x , y ;
2898 wxSize size ;
2899 const wxWindow* child = this ;
2900 const wxWindow* parent = NULL ;
2901
2902 while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL )
2903 {
2904 if ( parent->MacIsChildOfClientArea(child) )
2905 {
2906 size = parent->GetClientSize() ;
2907 wxPoint origin = parent->GetClientAreaOrigin() ;
2908 x = origin.x ;
2909 y = origin.y ;
2910 }
2911 else
2912 {
2913 // this will be true for scrollbars, toolbars etc.
2914 size = parent->GetSize() ;
2915 y = parent->MacGetTopBorderSize() ;
2916 x = parent->MacGetLeftBorderSize() ;
2917 size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ;
2918 size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ;
2919 }
2920
2921 parent->MacWindowToRootWindow( &x, &y ) ;
2922 MacRootWindowToWindow( &x , &y ) ;
2923
2924 Rect rparent = { y , x , y + size.y , x + size.x } ;
2925
2926 // the wxwindow and client rects will always be clipped
2927 SectRect( &r , &rparent , &r ) ;
2928 SectRect( &rClient , &rparent , &rClient ) ;
2929
2930 // the structure only at 'hard' borders
2931 if ( parent->MacClipChildren() ||
2932 ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) )
2933 {
2934 SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ;
2935 }
2936
2937 child = parent ;
2938 }
2939
2940 m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ;
2941 m_cachedClippedClientRect = wxRect( rClient.left , rClient.top ,
2942 rClient.right - rClient.left , rClient.bottom - rClient.top ) ;
2943 m_cachedClippedRectWithOuterStructure = wxRect(
2944 rIncludingOuterStructures.left , rIncludingOuterStructures.top ,
2945 rIncludingOuterStructures.right - rIncludingOuterStructures.left ,
2946 rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ;
2947
2948 m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ;
2949 m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ;
2950 m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ;
2951
2952 m_cachedClippedRectValid = true ;
2953}
2954
2955/*
2956 This function must not change the updatergn !
2957 */
2958bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
2959{
2960 bool handled = false ;
2961 Rect updatebounds ;
2962 RgnHandle updatergn = (RgnHandle) updatergnr ;
2963 GetRegionBounds( updatergn , &updatebounds ) ;
2964
2965 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
2966
2967 if ( !EmptyRgn(updatergn) )
2968 {
2969 RgnHandle newupdate = NewRgn() ;
2970 wxSize point = GetClientSize() ;
2971 wxPoint origin = GetClientAreaOrigin() ;
2972 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y + point.y ) ;
2973 SectRgn( newupdate , updatergn , newupdate ) ;
2974
2975 // first send an erase event to the entire update area
2976 {
2977 // for the toplevel window this really is the entire area
2978 // for all the others only their client area, otherwise they
2979 // might be drawing with full alpha and eg put blue into
2980 // the grow-box area of a scrolled window (scroll sample)
2981 wxDC* dc = new wxWindowDC(this);
2982 if ( IsTopLevel() )
2983 dc->SetClippingRegion(wxRegion(updatergn));
2984 else
2985 dc->SetClippingRegion(wxRegion(newupdate));
2986
2987 wxEraseEvent eevent( GetId(), dc );
2988 eevent.SetEventObject( this );
2989 GetEventHandler()->ProcessEvent( eevent );
2990 delete dc ;
2991 }
2992
2993 MacPaintGrowBox();
2994
2995 // calculate a client-origin version of the update rgn and set m_updateRegion to that
2996 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
2997 m_updateRegion = newupdate ;
2998 DisposeRgn( newupdate ) ;
2999
3000 if ( !m_updateRegion.Empty() )
3001 {
3002 // paint the window itself
3003
3004 wxPaintEvent event;
3005 event.SetTimestamp(time);
3006 event.SetEventObject(this);
3007 GetEventHandler()->ProcessEvent(event);
3008 handled = true ;
3009 }
3010
3011 // now we cannot rely on having its borders drawn by a window itself, as it does not
3012 // get the updateRgn wide enough to always do so, so we do it from the parent
3013 // this would also be the place to draw any custom backgrounds for native controls
3014 // in Composited windowing
3015 wxPoint clientOrigin = GetClientAreaOrigin() ;
3016
3017 wxWindowMac *child;
3018 int x, y, w, h;
3019 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
3020 {
3021 child = node->GetData();
3022 if (child == NULL)
3023 continue;
3024 if (child == m_vScrollBar)
3025 continue;
3026 if (child == m_hScrollBar)
3027 continue;
3028 if (child->IsTopLevel())
3029 continue;
3030 if (!child->IsShown())
3031 continue;
3032
3033 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3034
3035 child->GetPosition( &x, &y );
3036 child->GetSize( &w, &h );
3037 Rect childRect = { y , x , y + h , x + w } ;
3038 OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ;
3039 InsetRect( &childRect , -10 , -10) ;
3040
3041 if ( RectInRgn( &childRect , updatergn ) )
3042 {
3043 // paint custom borders
3044 wxNcPaintEvent eventNc( child->GetId() );
3045 eventNc.SetEventObject( child );
3046 if ( !child->GetEventHandler()->ProcessEvent( eventNc ) )
3047 {
3048 child->MacPaintBorders(0, 0) ;
3049 }
3050 }
3051 }
3052 }
3053
3054 return handled ;
3055}
3056
3057
3058WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
3059{
3060 wxWindowMac *iter = (wxWindowMac*)this ;
3061
3062 while ( iter )
3063 {
3064 if ( iter->IsTopLevel() )
3065 {
3066 wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow);
3067 if ( toplevel )
3068 return toplevel->MacGetWindowRef();
3069#if wxUSE_POPUPWIN
3070 wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow);
3071 if ( popupwin )
3072 return popupwin->MacGetPopupWindowRef();
3073#endif
3074 }
3075 iter = iter->GetParent() ;
3076 }
3077
3078 return NULL ;
3079}
3080
3081bool wxWindowMac::MacHasScrollBarCorner() const
3082{
3083 /* Returns whether the scroll bars in a wxScrolledWindow should be
3084 * shortened. Scroll bars should be shortened if either:
3085 *
3086 * - both scroll bars are visible, or
3087 *
3088 * - there is a resize box in the parent frame's corner and this
3089 * window shares the bottom and right edge with the parent
3090 * frame.
3091 */
3092
3093 if ( m_hScrollBar == NULL && m_vScrollBar == NULL )
3094 return false;
3095
3096 if ( ( m_hScrollBar && m_hScrollBar->IsShown() )
3097 && ( m_vScrollBar && m_vScrollBar->IsShown() ) )
3098 {
3099 // Both scroll bars visible
3100 return true;
3101 }
3102 else
3103 {
3104 wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight();
3105
3106 for ( const wxWindow *win = this; win; win = win->GetParent() )
3107 {
3108 const wxFrame *frame = wxDynamicCast( win, wxFrame ) ;
3109 if ( frame )
3110 {
3111 if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER )
3112 {
3113 // Parent frame has resize handle
3114 wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight();
3115
3116 // Note: allow for some wiggle room here as wxMac's
3117 // window rect calculations seem to be imprecise
3118 if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2
3119 && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 )
3120 {
3121 // Parent frame has resize handle and shares
3122 // right bottom corner
3123 return true ;
3124 }
3125 else
3126 {
3127 // Parent frame has resize handle but doesn't
3128 // share right bottom corner
3129 return false ;
3130 }
3131 }
3132 else
3133 {
3134 // Parent frame doesn't have resize handle
3135 return false ;
3136 }
3137 }
3138 }
3139
3140 // No parent frame found
3141 return false ;
3142 }
3143}
3144
3145void wxWindowMac::MacCreateScrollBars( long style )
3146{
3147 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
3148
3149 if ( style & ( wxVSCROLL | wxHSCROLL ) )
3150 {
3151 int scrlsize = MAC_SCROLLBAR_SIZE ;
3152 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI )
3153 {
3154 scrlsize = MAC_SMALL_SCROLLBAR_SIZE ;
3155 }
3156
3157 int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ;
3158 int width, height ;
3159 GetClientSize( &width , &height ) ;
3160
3161 wxPoint vPoint(width - scrlsize, 0) ;
3162 wxSize vSize(scrlsize, height - adjust) ;
3163 wxPoint hPoint(0, height - scrlsize) ;
3164 wxSize hSize(width - adjust, scrlsize) ;
3165
3166 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
3167 if ( style & wxVSCROLL )
3168 {
3169 m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL);
3170 m_vScrollBar->SetMinSize( wxDefaultSize );
3171 }
3172
3173 if ( style & wxHSCROLL )
3174 {
3175 m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
3176 m_hScrollBar->SetMinSize( wxDefaultSize );
3177 }
3178 }
3179
3180 // because the create does not take into account the client area origin
3181 // we might have a real position shift
3182 MacRepositionScrollBars() ;
3183}
3184
3185bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const
3186{
3187 bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar)));
3188
3189 return result ;
3190}
3191
3192void wxWindowMac::MacRepositionScrollBars()
3193{
3194 if ( !m_hScrollBar && !m_vScrollBar )
3195 return ;
3196
3197 int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
3198 int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ;
3199
3200 // get real client area
3201 int width, height ;
3202 GetSize( &width , &height );
3203
3204 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
3205 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
3206
3207 wxPoint vPoint( width - scrlsize, 0 ) ;
3208 wxSize vSize( scrlsize, height - adjust ) ;
3209 wxPoint hPoint( 0 , height - scrlsize ) ;
3210 wxSize hSize( width - adjust, scrlsize ) ;
3211
3212#if 0
3213 int x = 0, y = 0, w, h ;
3214 GetSize( &w , &h ) ;
3215
3216 MacClientToRootWindow( &x , &y ) ;
3217 MacClientToRootWindow( &w , &h ) ;
3218
3219 wxWindowMac *iter = (wxWindowMac*)this ;
3220
3221 int totW = 10000 , totH = 10000;
3222 while ( iter )
3223 {
3224 if ( iter->IsTopLevel() )
3225 {
3226 iter->GetSize( &totW , &totH ) ;
3227 break ;
3228 }
3229
3230 iter = iter->GetParent() ;
3231 }
3232
3233 if ( x == 0 )
3234 {
3235 hPoint.x = -1 ;
3236 hSize.x += 1 ;
3237 }
3238 if ( y == 0 )
3239 {
3240 vPoint.y = -1 ;
3241 vSize.y += 1 ;
3242 }
3243
3244 if ( w - x >= totW )
3245 {
3246 hSize.x += 1 ;
3247 vPoint.x += 1 ;
3248 }
3249 if ( h - y >= totH )
3250 {
3251 vSize.y += 1 ;
3252 hPoint.y += 1 ;
3253 }
3254#endif
3255
3256 if ( m_vScrollBar )
3257 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE );
3258 if ( m_hScrollBar )
3259 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE );
3260}
3261
3262bool wxWindowMac::AcceptsFocus() const
3263{
3264 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3265}
3266
3267void wxWindowMac::MacSuperChangedPosition()
3268{
3269 // only window-absolute structures have to be moved i.e. controls
3270
3271 m_cachedClippedRectValid = false ;
3272
3273 wxWindowMac *child;
3274 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
3275 while ( node )
3276 {
3277 child = node->GetData();
3278 child->MacSuperChangedPosition() ;
3279
3280 node = node->GetNext();
3281 }
3282}
3283
3284void wxWindowMac::MacTopLevelWindowChangedPosition()
3285{
3286 // only screen-absolute structures have to be moved i.e. glcanvas
3287
3288 wxWindowMac *child;
3289 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
3290 while ( node )
3291 {
3292 child = node->GetData();
3293 child->MacTopLevelWindowChangedPosition() ;
3294
3295 node = node->GetNext();
3296 }
3297}
3298
3299long wxWindowMac::MacGetLeftBorderSize() const
3300{
3301 if ( IsTopLevel() )
3302 return 0 ;
3303
3304 SInt32 border = 0 ;
3305
3306 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER))
3307 {
3308 // this metric is only the 'outset' outside the simple frame rect
3309 GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
3310 border += 1 ;
3311 }
3312 else if (HasFlag(wxSIMPLE_BORDER))
3313 {
3314 // this metric is only the 'outset' outside the simple frame rect
3315 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
3316 border += 1 ;
3317 }
3318
3319 return border ;
3320}
3321
3322long wxWindowMac::MacGetRightBorderSize() const
3323{
3324 // they are all symmetric in mac themes
3325 return MacGetLeftBorderSize() ;
3326}
3327
3328long wxWindowMac::MacGetTopBorderSize() const
3329{
3330 // they are all symmetric in mac themes
3331 return MacGetLeftBorderSize() ;
3332}
3333
3334long wxWindowMac::MacGetBottomBorderSize() const
3335{
3336 // they are all symmetric in mac themes
3337 return MacGetLeftBorderSize() ;
3338}
3339
3340long wxWindowMac::MacRemoveBordersFromStyle( long style )
3341{
3342 return style & ~wxBORDER_MASK ;
3343}
3344
3345// Find the wxWindowMac at the current mouse position, returning the mouse
3346// position.
3347wxWindowMac * wxFindWindowAtPointer( wxPoint& pt )
3348{
3349 pt = wxGetMousePosition();
3350 wxWindowMac* found = wxFindWindowAtPoint(pt);
3351
3352 return found;
3353}
3354
3355// Get the current mouse position.
3356wxPoint wxGetMousePosition()
3357{
3358 int x, y;
3359
3360 wxGetMousePosition( &x, &y );
3361
3362 return wxPoint(x, y);
3363}
3364
3365void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
3366{
3367 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
3368 {
3369 // copied from wxGTK : CS
3370 // VZ: shouldn't we move this to base class then?
3371
3372 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3373 // except that:
3374 //
3375 // (a) it's a command event and so is propagated to the parent
3376 // (b) under MSW it can be generated from kbd too
3377 // (c) it uses screen coords (because of (a))
3378 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
3379 this->GetId(),
3380 this->ClientToScreen(event.GetPosition()));
3381 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
3382 event.Skip() ;
3383 }
3384 else
3385 {
3386 event.Skip() ;
3387 }
3388}
3389
3390void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) )
3391{
3392 if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL
3393 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT )
3394 CallNextEventHandler(
3395 (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() ,
3396 (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
3397}
3398
3399void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control),
3400 wxInt16 WXUNUSED(controlpart),
3401 bool WXUNUSED(mouseStillDown))
3402{
3403}
3404
3405Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
3406{
3407 int x, y, w, h ;
3408
3409 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
3410 Rect bounds = { y, x, y + h, x + w };
3411
3412 return bounds ;
3413}
3414
3415wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
3416{
3417 return eventNotHandledErr ;
3418}
3419
3420bool wxWindowMac::Reparent(wxWindowBase *newParentBase)
3421{
3422 wxWindowMac *newParent = (wxWindowMac *)newParentBase;
3423 if ( !wxWindowBase::Reparent(newParent) )
3424 return false;
3425
3426 // copied from MacPostControlCreate
3427 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
3428
3429 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
3430
3431 ::EmbedControl( m_peer->GetControlRef() , container ) ;
3432
3433 return true;
3434}
3435
3436bool wxWindowMac::SetTransparent(wxByte alpha)
3437{
3438 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
3439
3440 if ( alpha != m_macAlpha )
3441 {
3442 m_macAlpha = alpha ;
3443 Refresh() ;
3444 }
3445 return true ;
3446}
3447
3448
3449bool wxWindowMac::CanSetTransparent()
3450{
3451 return true ;
3452}
3453
3454wxByte wxWindowMac::GetTransparent() const
3455{
3456 return m_macAlpha ;
3457}