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