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