1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/window.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/window.h"
23 #include "wx/dcclient.h"
24 #include "wx/button.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"
40 #include "wx/tooltip.h"
41 #include "wx/spinctrl.h"
42 #include "wx/geometry.h"
45 #include "wx/listctrl.h"
49 #include "wx/treectrl.h"
57 #include "wx/popupwin.h"
60 #if wxUSE_DRAG_AND_DROP
64 #include "wx/mac/uma.h"
66 #define MAC_SCROLLBAR_SIZE 15
67 #define MAC_SMALL_SCROLLBAR_SIZE 11
71 #include <ToolUtils.h>
72 #include <MacTextEditor.h>
75 #if TARGET_API_MAC_OSX
77 #include <HIToolbox/HIView.h>
83 #ifdef __WXUNIVERSAL__
84 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac
, wxWindowBase
)
86 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
89 BEGIN_EVENT_TABLE(wxWindowMac
, wxWindowBase
)
90 EVT_NC_PAINT(wxWindowMac::OnNcPaint
)
91 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground
)
92 #if TARGET_API_MAC_OSX
93 EVT_PAINT(wxWindowMac::OnPaint
)
95 EVT_SET_FOCUS(wxWindowMac::OnSetFocus
)
96 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus
)
97 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent
)
100 #define wxMAC_DEBUG_REDRAW 0
101 #ifndef wxMAC_DEBUG_REDRAW
102 #define wxMAC_DEBUG_REDRAW 0
105 // ---------------------------------------------------------------------------
106 // Utility Routines to move between different coordinate systems
107 // ---------------------------------------------------------------------------
110 * Right now we have the following setup :
111 * a border that is not part of the native control is always outside the
112 * control's border (otherwise we loose all native intelligence, future ways
113 * may be to have a second embedding control responsible for drawing borders
114 * and backgrounds eventually)
115 * so all this border calculations have to be taken into account when calling
116 * native methods or getting native oriented data
117 * so we have three coordinate systems here
118 * wx client coordinates
119 * wx window coordinates (including window frames)
124 // originating from native control
128 void wxMacNativeToWindow( const wxWindow
* window
, RgnHandle handle
)
130 OffsetRgn( handle
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
133 void wxMacNativeToWindow( const wxWindow
* window
, Rect
*rect
)
135 OffsetRect( rect
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
139 // directed towards native control
142 void wxMacWindowToNative( const wxWindow
* window
, RgnHandle handle
)
144 OffsetRgn( handle
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() );
147 void wxMacWindowToNative( const wxWindow
* window
, Rect
*rect
)
149 OffsetRect( rect
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() ) ;
152 // ---------------------------------------------------------------------------
154 // ---------------------------------------------------------------------------
156 #if TARGET_API_MAC_OSX
158 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
161 kEventControlVisibilityChanged
= 157
167 static const EventTypeSpec eventList
[] =
169 { kEventClassCommand
, kEventProcessCommand
} ,
170 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
172 { kEventClassControl
, kEventControlGetClickActivation
} ,
173 { kEventClassControl
, kEventControlHit
} ,
175 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
176 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
178 { kEventClassControl
, kEventControlDraw
} ,
179 #if TARGET_API_MAC_OSX
180 { kEventClassControl
, kEventControlVisibilityChanged
} ,
181 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
182 { kEventClassControl
, kEventControlHiliteChanged
} ,
184 { kEventClassControl
, kEventControlActivate
} ,
185 { kEventClassControl
, kEventControlDeactivate
} ,
187 { kEventClassControl
, kEventControlSetFocusPart
} ,
189 { kEventClassService
, kEventServiceGetTypes
},
190 { kEventClassService
, kEventServiceCopy
},
191 { kEventClassService
, kEventServicePaste
},
193 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
194 // { kEventClassControl , kEventControlBoundsChanged } ,
197 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
199 OSStatus result
= eventNotHandledErr
;
201 wxMacCarbonEvent
cEvent( event
) ;
203 ControlRef controlRef
;
204 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
206 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
208 switch ( GetEventKind( event
) )
210 #if TARGET_API_MAC_OSX
211 case kEventControlDraw
:
213 RgnHandle updateRgn
= NULL
;
214 RgnHandle allocatedRgn
= NULL
;
215 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
217 if ( cEvent
.GetParameter
<RgnHandle
>(kEventParamRgnHandle
, &updateRgn
) != noErr
)
219 updateRgn
= (RgnHandle
) visRegion
.GetWXHRGN() ;
223 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
225 // as this update region is in native window locals we must adapt it to wx window local
226 allocatedRgn
= NewRgn() ;
227 CopyRgn( updateRgn
, allocatedRgn
) ;
229 // hide the given region by the new region that must be shifted
230 wxMacNativeToWindow( thisWindow
, allocatedRgn
) ;
231 updateRgn
= allocatedRgn
;
236 GetRegionBounds( updateRgn
, &rgnBounds
) ;
238 #if wxMAC_DEBUG_REDRAW
239 if ( thisWindow
->MacIsUserPane() )
241 static float color
= 0.5 ;
244 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
246 HIViewGetBounds( controlRef
, &bounds
);
247 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
248 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
249 CGContextFillRect( cgContext
, bounds
);
262 #if wxMAC_USE_CORE_GRAPHICS
263 bool created
= false ;
264 CGContextRef cgContext
= NULL
;
265 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
266 wxASSERT_MSG( err
== noErr
, wxT("Unable to retrieve CGContextRef") ) ;
267 thisWindow
->MacSetCGContextRef( cgContext
) ;
270 wxMacCGContextStateSaver
sg( cgContext
) ;
273 wxWindow
* iter
= thisWindow
;
276 alpha
*= (float) iter
->GetTransparent()/255.0 ;
277 if ( iter
->IsTopLevel() )
280 iter
= iter
->GetParent() ;
283 CGContextSetAlpha( cgContext
, alpha
) ;
285 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
288 HIViewGetBounds( controlRef
, &bounds
);
289 CGContextClearRect( cgContext
, bounds
);
294 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
297 #if wxMAC_USE_CORE_GRAPHICS
298 thisWindow
->MacSetCGContextRef( NULL
) ;
302 CGContextRelease( cgContext
) ;
307 DisposeRgn( allocatedRgn
) ;
311 case kEventControlVisibilityChanged
:
312 thisWindow
->MacVisibilityChanged() ;
315 case kEventControlEnabledStateChanged
:
316 thisWindow
->MacEnabledStateChanged() ;
319 case kEventControlHiliteChanged
:
320 thisWindow
->MacHiliteChanged() ;
323 case kEventControlActivate
:
324 case kEventControlDeactivate
:
325 // FIXME: we should have a virtual function for this!
327 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
328 thisWindow
->Refresh();
331 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
332 thisWindow
->Refresh();
335 #endif // TARGET_API_MAC_OSX
337 // we emulate this event under Carbon CFM
338 case kEventControlSetFocusPart
:
340 Boolean focusEverything
= false ;
341 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
344 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
349 if ( thisWindow
->MacIsUserPane() )
352 if ( controlPart
== kControlFocusNoPart
)
355 if ( thisWindow
->GetCaret() )
356 thisWindow
->GetCaret()->OnKillFocus();
359 static bool inKillFocusEvent
= false ;
361 if ( !inKillFocusEvent
)
363 inKillFocusEvent
= true ;
364 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
365 event
.SetEventObject(thisWindow
);
366 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
367 inKillFocusEvent
= false ;
372 // panel wants to track the window which was the last to have focus in it
373 wxChildFocusEvent
eventFocus(thisWindow
);
374 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
377 if ( thisWindow
->GetCaret() )
378 thisWindow
->GetCaret()->OnSetFocus();
381 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
382 event
.SetEventObject(thisWindow
);
383 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
388 case kEventControlHit
:
389 result
= thisWindow
->MacControlHit( handler
, event
) ;
392 case kEventControlGetClickActivation
:
394 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
395 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
396 if ( !IsWindowActive(owner
) )
398 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
411 static pascal OSStatus
412 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
416 OSStatus result
= eventNotHandledErr
;
418 wxMacCarbonEvent
cEvent( event
) ;
420 ControlRef controlRef
;
421 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
422 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
423 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
425 switch ( GetEventKind( event
) )
427 case kEventServiceGetTypes
:
431 textCtrl
->GetSelection( &from
, &to
) ;
433 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
435 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
436 if ( textCtrl
->IsEditable() )
437 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
439 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
440 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
442 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
446 CFArrayAppendValue(copyTypes
, typestring
) ;
448 CFArrayAppendValue(pasteTypes
, typestring
) ;
450 CFRelease( typestring
) ;
458 case kEventServiceCopy
:
463 textCtrl
->GetSelection( &from
, &to
) ;
464 wxString val
= textCtrl
->GetValue() ;
465 val
= val
.Mid( from
, to
- from
) ;
466 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
467 verify_noerr( PasteboardClear( pasteboard
) ) ;
468 PasteboardSynchronize( pasteboard
);
469 // TODO add proper conversion
470 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
471 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
477 case kEventServicePaste
:
480 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
481 PasteboardSynchronize( pasteboard
);
483 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
484 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
486 PasteboardItemID itemID
;
487 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
489 CFDataRef flavorData
= NULL
;
490 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
492 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
493 char *content
= new char[flavorDataSize
+1] ;
494 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
495 content
[flavorDataSize
]=0;
496 CFRelease( flavorData
);
498 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
500 textCtrl
->WriteText( wxString( content
) ) ;
518 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
520 OSStatus result
= eventNotHandledErr
;
521 wxWindowMac
* focus
= (wxWindowMac
*) data
;
523 wchar_t* uniChars
= NULL
;
524 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
526 UniChar
* charBuf
= NULL
;
527 ByteCount dataSize
= 0 ;
530 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
532 numChars
= dataSize
/ sizeof( UniChar
) + 1;
535 if ( (size_t) numChars
* 2 > sizeof(buf
) )
536 charBuf
= new UniChar
[ numChars
] ;
540 uniChars
= new wchar_t[ numChars
] ;
541 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
542 charBuf
[ numChars
- 1 ] = 0;
543 #if SIZEOF_WCHAR_T == 2
544 uniChars
= (wchar_t*) charBuf
;
545 /* 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...)
547 // the resulting string will never have more chars than the utf16 version, so this is safe
548 wxMBConvUTF16 converter
;
549 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
553 switch ( GetEventKind( event
) )
555 case kEventTextInputUpdateActiveInputArea
:
557 // An IME input event may return several characters, but we need to send one char at a time to
559 for (int pos
=0 ; pos
< numChars
; pos
++)
561 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
562 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
563 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
565 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
567 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
568 multiple times to update the active range during inline input, so this handler will often receive
569 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
570 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
571 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
572 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
573 should add new event types to support advanced text input. For now, I would keep things as they are.
575 However, the code that was being used caused additional problems:
576 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
577 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
578 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
579 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
580 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
581 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
582 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
583 overlap with Unicode within the (7-bit) ASCII range.
584 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
585 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
586 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
587 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
588 I don't have time to look into that right now.
591 if ( wxTheApp
->MacSendCharEvent(
592 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
597 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
601 case kEventTextInputUnicodeForKeyEvent
:
603 UInt32 keyCode
, modifiers
;
606 unsigned char charCode
;
608 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
609 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
610 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
611 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
612 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
614 UInt32 message
= (keyCode
<< 8) + charCode
;
616 // An IME input event may return several characters, but we need to send one char at a time to
618 for (int pos
=0 ; pos
< numChars
; pos
++)
620 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
621 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
622 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
624 if ( wxTheApp
->MacSendCharEvent(
625 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
630 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
639 if ( charBuf
!= buf
)
645 static pascal OSStatus
646 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
650 OSStatus result
= eventNotHandledErr
;
651 wxWindowMac
* focus
= (wxWindowMac
*) data
;
655 wxMacCarbonEvent
cEvent( event
) ;
656 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
658 wxMenuItem
* item
= NULL
;
659 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
660 int id
= wxMacCommandToId( command
.commandID
) ;
664 wxASSERT( itemMenu
!= NULL
) ;
666 switch ( cEvent
.GetKind() )
668 case kEventProcessCommand
:
669 result
= itemMenu
->MacHandleCommandProcess( item
, id
, focus
);
672 case kEventCommandUpdateStatus
:
673 result
= itemMenu
->MacHandleCommandUpdateStatus( item
, id
, focus
);
683 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
685 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
686 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
687 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
688 OSStatus result
= eventNotHandledErr
;
690 switch ( GetEventClass( event
) )
692 case kEventClassCommand
:
693 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
696 case kEventClassControl
:
697 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
700 case kEventClassService
:
701 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
704 case kEventClassTextInput
:
705 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
712 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
717 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
719 #if !TARGET_API_MAC_OSX
721 // ---------------------------------------------------------------------------
722 // UserPane events for non OSX builds
723 // ---------------------------------------------------------------------------
725 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
727 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
729 win
->MacControlUserPaneDrawProc(part
) ;
731 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
733 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
735 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
737 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
739 return kControlNoPart
;
741 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
743 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
745 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
747 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
749 return kControlNoPart
;
751 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
753 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
755 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
757 win
->MacControlUserPaneIdleProc() ;
759 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
761 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
763 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
765 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
767 return kControlNoPart
;
769 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
771 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
773 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
775 win
->MacControlUserPaneActivateProc(activating
) ;
777 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
779 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
781 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
783 return win
->MacControlUserPaneFocusProc(action
) ;
785 return kControlNoPart
;
787 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
789 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
791 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
793 win
->MacControlUserPaneBackgroundProc(info
) ;
795 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
797 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
800 RgnHandle rgn
= NewRgn() ;
802 MacWindowToRootWindow( &x
, &y
) ;
803 OffsetRgn( rgn
, -x
, -y
) ;
804 wxMacWindowStateSaver
sv( this ) ;
805 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
806 MacDoRedraw( rgn
, 0 ) ;
810 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
812 return kControlNoPart
;
815 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
817 return kControlNoPart
;
820 void wxWindowMac::MacControlUserPaneIdleProc()
824 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
826 return kControlNoPart
;
829 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
833 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
835 if ( AcceptsFocus() )
838 return kControlNoPart
;
841 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
847 // ---------------------------------------------------------------------------
848 // Scrollbar Tracking for all
849 // ---------------------------------------------------------------------------
851 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
852 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
856 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
858 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
861 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
863 // ===========================================================================
865 // ===========================================================================
867 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
869 static MacControlMap wxWinMacControlList
;
871 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
873 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
875 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
878 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
880 // adding NULL ControlRef is (first) surely a result of an error and
881 // (secondly) breaks native event processing
882 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
884 wxWinMacControlList
[inControl
] = control
;
887 void wxRemoveMacControlAssociation(wxWindow
*control
)
889 // iterate over all the elements in the class
890 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
891 // we should go on...
897 MacControlMap::iterator it
;
898 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
900 if ( it
->second
== control
)
902 wxWinMacControlList
.erase(it
);
910 // ----------------------------------------------------------------------------
911 // constructors and such
912 // ----------------------------------------------------------------------------
914 wxWindowMac::wxWindowMac()
919 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
924 const wxString
& name
)
927 Create(parent
, id
, pos
, size
, style
, name
);
930 void wxWindowMac::Init()
936 #if wxMAC_USE_CORE_GRAPHICS
937 m_cgContextRef
= NULL
;
940 // as all windows are created with WS_VISIBLE style...
943 m_hScrollBar
= NULL
;
944 m_vScrollBar
= NULL
;
945 m_hScrollBarAlwaysShown
= false;
946 m_vScrollBarAlwaysShown
= false;
948 m_macBackgroundBrush
= wxNullBrush
;
950 m_macIsUserPane
= true;
951 m_clipChildren
= false ;
952 m_cachedClippedRectValid
= false ;
954 // we need a valid font for the encodings
955 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
958 wxWindowMac::~wxWindowMac()
962 m_isBeingDeleted
= true;
964 MacInvalidateBorders() ;
966 #ifndef __WXUNIVERSAL__
967 // VS: make sure there's no wxFrame with last focus set to us:
968 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
970 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
973 if ( frame
->GetLastFocus() == this )
974 frame
->SetLastFocus((wxWindow
*)NULL
);
980 // destroy children before destroying this window itself
983 // wxRemoveMacControlAssociation( this ) ;
984 // If we delete an item, we should initialize the parent panel,
985 // because it could now be invalid.
986 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
989 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
990 tlw
->SetDefaultItem(NULL
);
993 if ( m_peer
&& m_peer
->Ok() )
995 // in case the callback might be called during destruction
996 wxRemoveMacControlAssociation( this) ;
997 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
998 // we currently are not using this hook
999 // ::SetControlColorProc( *m_peer , NULL ) ;
1003 if ( g_MacLastWindow
== this )
1004 g_MacLastWindow
= NULL
;
1006 #ifndef __WXUNIVERSAL__
1007 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( (wxWindow
*)this ) , wxFrame
) ;
1010 if ( frame
->GetLastFocus() == this )
1011 frame
->SetLastFocus( NULL
) ;
1015 // delete our drop target if we've got one
1016 #if wxUSE_DRAG_AND_DROP
1017 if ( m_dropTarget
!= NULL
)
1019 delete m_dropTarget
;
1020 m_dropTarget
= NULL
;
1027 WXWidget
wxWindowMac::GetHandle() const
1029 return (WXWidget
) m_peer
->GetControlRef() ;
1032 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1034 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1035 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1036 GetEventTypeCount(eventList
), eventList
, this,
1037 (EventHandlerRef
*)&m_macControlEventHandler
);
1039 #if !TARGET_API_MAC_OSX
1040 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1042 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1043 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1044 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1045 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1046 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1047 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1048 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1049 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1055 bool wxWindowMac::Create(wxWindowMac
*parent
,
1060 const wxString
& name
)
1062 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1064 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1067 m_windowVariant
= parent
->GetWindowVariant() ;
1069 if ( m_macIsUserPane
)
1071 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1074 | kControlSupportsEmbedding
1075 | kControlSupportsLiveFeedback
1076 | kControlGetsFocusOnClick
1077 // | kControlHasSpecialBackground
1078 // | kControlSupportsCalcBestRect
1079 | kControlHandlesTracking
1080 | kControlSupportsFocus
1081 | kControlWantsActivate
1082 | kControlWantsIdle
;
1084 m_peer
= new wxMacControl(this) ;
1085 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1086 verify_noerr( err
);
1088 MacPostControlCreate(pos
, size
) ;
1091 #ifndef __WXUNIVERSAL__
1092 // Don't give scrollbars to wxControls unless they ask for them
1093 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1094 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1096 MacCreateScrollBars( style
) ;
1100 wxWindowCreateEvent
event(this);
1101 GetEventHandler()->AddPendingEvent(event
);
1106 void wxWindowMac::MacChildAdded()
1109 m_vScrollBar
->Raise() ;
1111 m_hScrollBar
->Raise() ;
1114 void wxWindowMac::MacPostControlCreate(const wxPoint
& WXUNUSED(pos
), const wxSize
& size
)
1116 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1118 m_peer
->SetReference( (URefCon
) this ) ;
1119 GetParent()->AddChild( this );
1121 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1123 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1124 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1125 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1126 GetParent()->MacChildAdded() ;
1128 // adjust font, controlsize etc
1129 DoSetWindowVariant( m_windowVariant
) ;
1131 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1133 if (!m_macIsUserPane
)
1134 SetInitialSize(size
);
1136 SetCursor( *wxSTANDARD_CURSOR
) ;
1139 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1141 // Don't assert, in case we set the window variant before
1142 // the window is created
1143 // wxASSERT( m_peer->Ok() ) ;
1145 m_windowVariant
= variant
;
1147 if (m_peer
== NULL
|| !m_peer
->Ok())
1151 ThemeFontID themeFont
= kThemeSystemFont
;
1153 // we will get that from the settings later
1154 // and make this NORMAL later, but first
1155 // we have a few calculations that we must fix
1159 case wxWINDOW_VARIANT_NORMAL
:
1160 size
= kControlSizeNormal
;
1161 themeFont
= kThemeSystemFont
;
1164 case wxWINDOW_VARIANT_SMALL
:
1165 size
= kControlSizeSmall
;
1166 themeFont
= kThemeSmallSystemFont
;
1169 case wxWINDOW_VARIANT_MINI
:
1170 if (UMAGetSystemVersion() >= 0x1030 )
1172 // not always defined in the headers
1178 size
= kControlSizeSmall
;
1179 themeFont
= kThemeSmallSystemFont
;
1183 case wxWINDOW_VARIANT_LARGE
:
1184 size
= kControlSizeLarge
;
1185 themeFont
= kThemeSystemFont
;
1189 wxFAIL_MSG(_T("unexpected window variant"));
1193 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1196 font
.MacCreateThemeFont( themeFont
) ;
1200 void wxWindowMac::MacUpdateControlFont()
1202 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1203 // do not trigger refreshes upon invisible and possible partly created objects
1204 if ( MacIsReallyShown() )
1208 bool wxWindowMac::SetFont(const wxFont
& font
)
1210 bool retval
= wxWindowBase::SetFont( font
);
1212 MacUpdateControlFont() ;
1217 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1219 bool retval
= wxWindowBase::SetForegroundColour( col
);
1222 MacUpdateControlFont();
1227 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1229 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1233 wxColour
newCol(GetBackgroundColour());
1235 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1236 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1237 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1238 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1240 brush
.SetColour( newCol
) ;
1242 MacSetBackgroundBrush( brush
) ;
1243 MacUpdateControlFont() ;
1248 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1250 m_macBackgroundBrush
= brush
;
1251 m_peer
->SetBackground( brush
) ;
1254 bool wxWindowMac::MacCanFocus() const
1256 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1257 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1258 // but the value range is nowhere documented
1259 Boolean keyExistsAndHasValidFormat
;
1260 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1261 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1263 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1269 UInt32 features
= 0 ;
1270 m_peer
->GetFeatures( &features
) ;
1272 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1276 void wxWindowMac::SetFocus()
1278 if ( !AcceptsFocus() )
1281 wxWindow
* former
= FindFocus() ;
1282 if ( former
== this )
1285 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1286 // we can only leave in case of an error
1287 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1288 if ( err
== errCouldntSetFocus
)
1291 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1293 #if !TARGET_API_MAC_OSX
1294 // emulate carbon events when running under CarbonLib where they are not natively available
1297 EventRef evRef
= NULL
;
1299 err
= MacCreateEvent(
1300 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1301 kEventAttributeUserEvent
, &evRef
);
1302 verify_noerr( err
);
1304 wxMacCarbonEvent
cEvent( evRef
) ;
1305 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1306 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1308 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1309 ReleaseEvent( evRef
) ;
1312 // send new focus event
1314 EventRef evRef
= NULL
;
1316 err
= MacCreateEvent(
1317 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1318 kEventAttributeUserEvent
, &evRef
);
1319 verify_noerr( err
);
1321 wxMacCarbonEvent
cEvent( evRef
) ;
1322 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1323 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1325 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1326 ReleaseEvent( evRef
) ;
1331 void wxWindowMac::DoCaptureMouse()
1333 wxApp::s_captureWindow
= this ;
1336 wxWindow
* wxWindowBase::GetCapture()
1338 return wxApp::s_captureWindow
;
1341 void wxWindowMac::DoReleaseMouse()
1343 wxApp::s_captureWindow
= NULL
;
1346 #if wxUSE_DRAG_AND_DROP
1348 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1350 if ( m_dropTarget
!= NULL
)
1351 delete m_dropTarget
;
1353 m_dropTarget
= pDropTarget
;
1354 if ( m_dropTarget
!= NULL
)
1362 // Old-style File Manager Drag & Drop
1363 void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept
))
1368 // Returns the size of the native control. In the case of the toplevel window
1369 // this is the content area root control
1371 void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x
),
1374 int& WXUNUSED(h
)) const
1376 wxFAIL_MSG( wxT("Not currently supported") ) ;
1379 // From a wx position / size calculate the appropriate size of the native control
1381 bool wxWindowMac::MacGetBoundsForControl(
1385 int& w
, int& h
, bool adjustOrigin
) const
1387 // the desired size, minus the border pixels gives the correct size of the control
1391 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1392 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1393 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1395 x
+= MacGetLeftBorderSize() ;
1396 y
+= MacGetTopBorderSize() ;
1397 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1398 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1401 AdjustForParentClientOrigin( x
, y
) ;
1403 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1404 if ( !GetParent()->IsTopLevel() )
1406 x
-= GetParent()->MacGetLeftBorderSize() ;
1407 y
-= GetParent()->MacGetTopBorderSize() ;
1413 // Get window size (not client size)
1414 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1417 m_peer
->GetRect( &bounds
) ;
1420 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1422 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1425 // get the position of the bounds of this window in client coordinates of its parent
1426 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1429 m_peer
->GetRect( &bounds
) ;
1431 int x1
= bounds
.left
;
1432 int y1
= bounds
.top
;
1434 // get the wx window position from the native one
1435 x1
-= MacGetLeftBorderSize() ;
1436 y1
-= MacGetTopBorderSize() ;
1438 if ( !IsTopLevel() )
1440 wxWindow
*parent
= GetParent();
1443 // we must first adjust it to be in window coordinates of the parent,
1444 // as otherwise it gets lost by the ClientAreaOrigin fix
1445 x1
+= parent
->MacGetLeftBorderSize() ;
1446 y1
+= parent
->MacGetTopBorderSize() ;
1448 // and now to client coordinates
1449 wxPoint
pt(parent
->GetClientAreaOrigin());
1461 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1463 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1464 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1466 Point localwhere
= { 0, 0 } ;
1473 wxMacGlobalToLocal( window
, &localwhere
) ;
1480 MacRootWindowToWindow( x
, y
) ;
1482 wxPoint origin
= GetClientAreaOrigin() ;
1489 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1491 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1492 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1494 wxPoint origin
= GetClientAreaOrigin() ;
1500 MacWindowToRootWindow( x
, y
) ;
1502 Point localwhere
= { 0, 0 };
1508 wxMacLocalToGlobal( window
, &localwhere
) ;
1516 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1518 wxPoint origin
= GetClientAreaOrigin() ;
1524 MacWindowToRootWindow( x
, y
) ;
1527 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1529 MacRootWindowToWindow( x
, y
) ;
1531 wxPoint origin
= GetClientAreaOrigin() ;
1538 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1547 if ( !IsTopLevel() )
1549 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1552 pt
.x
-= MacGetLeftBorderSize() ;
1553 pt
.y
-= MacGetTopBorderSize() ;
1554 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1564 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1573 MacWindowToRootWindow( &x1
, &y1
) ;
1581 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1590 if ( !IsTopLevel() )
1592 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1595 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1596 pt
.x
+= MacGetLeftBorderSize() ;
1597 pt
.y
+= MacGetTopBorderSize() ;
1607 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1616 MacRootWindowToWindow( &x1
, &y1
) ;
1624 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1626 RgnHandle rgn
= NewRgn() ;
1628 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1630 Rect structure
, content
;
1632 GetRegionBounds( rgn
, &content
) ;
1633 m_peer
->GetRect( &structure
) ;
1634 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1636 left
= content
.left
- structure
.left
;
1637 top
= content
.top
- structure
.top
;
1638 right
= structure
.right
- content
.right
;
1639 bottom
= structure
.bottom
- content
.bottom
;
1643 left
= top
= right
= bottom
= 0 ;
1649 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1651 wxSize sizeTotal
= size
;
1653 RgnHandle rgn
= NewRgn() ;
1654 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1656 Rect content
, structure
;
1657 GetRegionBounds( rgn
, &content
) ;
1658 m_peer
->GetRect( &structure
) ;
1660 // structure is in parent coordinates, but we only need width and height, so it's ok
1662 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1663 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1668 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1669 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1674 // Get size *available for subwindows* i.e. excluding menu bar etc.
1675 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1679 RgnHandle rgn
= NewRgn() ;
1681 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1682 GetRegionBounds( rgn
, &content
) ;
1684 m_peer
->GetRect( &content
) ;
1687 ww
= content
.right
- content
.left
;
1688 hh
= content
.bottom
- content
.top
;
1690 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1691 hh
-= m_hScrollBar
->GetSize().y
;
1693 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1694 ww
-= m_vScrollBar
->GetSize().x
;
1702 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1704 if (m_cursor
.IsSameAs(cursor
))
1709 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1714 if ( ! wxWindowBase::SetCursor( cursor
) )
1718 wxASSERT_MSG( m_cursor
.Ok(),
1719 wxT("cursor must be valid after call to the base version"));
1721 wxWindowMac
*mouseWin
= 0 ;
1723 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1724 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1726 ControlPartCode part
;
1727 ControlRef control
;
1729 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1731 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1736 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1738 // TODO: If we ever get a GetCurrentEvent... replacement
1739 // for the mouse position, use it...
1744 control
= wxMacFindControlUnderMouse( tlw
, pt
, window
, &part
) ;
1746 mouseWin
= wxFindControlFromMacControl( control
) ;
1748 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1750 QDSwapPort( savePort
, NULL
) ;
1754 if ( mouseWin
== this && !wxIsBusy() )
1755 m_cursor
.MacInstall() ;
1761 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1763 #ifndef __WXUNIVERSAL__
1764 menu
->SetInvokingWindow((wxWindow
*)this);
1767 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1769 wxPoint mouse
= wxGetMousePosition();
1775 ClientToScreen( &x
, &y
) ;
1778 menu
->MacBeforeDisplay( true ) ;
1779 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1780 if ( HiWord(menuResult
) != 0 )
1783 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1784 int id
= wxMacCommandToId( macid
);
1785 wxMenuItem
* item
= NULL
;
1787 item
= menu
->FindItem( id
, &realmenu
) ;
1790 if (item
->IsCheckable())
1791 item
->Check( !item
->IsChecked() ) ;
1793 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1797 menu
->MacAfterDisplay( true ) ;
1798 menu
->SetInvokingWindow( NULL
);
1802 // actually this shouldn't be called, because universal is having its own implementation
1808 // ----------------------------------------------------------------------------
1810 // ----------------------------------------------------------------------------
1814 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1816 wxWindowBase::DoSetToolTip(tooltip
);
1819 m_tooltip
->SetWindow(this);
1824 void wxWindowMac::MacInvalidateBorders()
1826 if ( m_peer
== NULL
)
1829 bool vis
= MacIsReallyShown() ;
1833 int outerBorder
= MacGetLeftBorderSize() ;
1834 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1837 if ( outerBorder
== 0 )
1840 // now we know that we have something to do at all
1842 // as the borders are drawn on the parent we have to properly invalidate all these areas
1843 RgnHandle updateInner
, updateOuter
;
1846 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1847 updateInner
= NewRgn() ;
1848 updateOuter
= NewRgn() ;
1850 m_peer
->GetRect( &rect
) ;
1851 RectRgn( updateInner
, &rect
) ;
1852 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1853 RectRgn( updateOuter
, &rect
) ;
1854 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1856 #ifdef __WXMAC_OSX__
1857 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1859 WindowRef tlw
= (WindowRef
) MacGetTopLevelWindowRef() ;
1861 InvalWindowRgn( tlw
, updateOuter
) ;
1864 DisposeRgn( updateOuter
) ;
1865 DisposeRgn( updateInner
) ;
1868 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1870 // this is never called for a toplevel window, so we know we have a parent
1871 int former_x
, former_y
, former_w
, former_h
;
1873 // Get true coordinates of former position
1874 DoGetPosition( &former_x
, &former_y
) ;
1875 DoGetSize( &former_w
, &former_h
) ;
1877 wxWindow
*parent
= GetParent();
1880 wxPoint
pt(parent
->GetClientAreaOrigin());
1885 int actualWidth
= width
;
1886 int actualHeight
= height
;
1890 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1891 actualWidth
= m_minWidth
;
1892 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1893 actualHeight
= m_minHeight
;
1894 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1895 actualWidth
= m_maxWidth
;
1896 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1897 actualHeight
= m_maxHeight
;
1899 bool doMove
= false, doResize
= false ;
1901 if ( actualX
!= former_x
|| actualY
!= former_y
)
1904 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1907 if ( doMove
|| doResize
)
1909 // as the borders are drawn outside the native control, we adjust now
1911 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1912 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1913 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1916 wxMacRectToNative( &bounds
, &r
) ;
1918 if ( !GetParent()->IsTopLevel() )
1919 wxMacWindowToNative( GetParent() , &r
) ;
1921 MacInvalidateBorders() ;
1923 m_cachedClippedRectValid
= false ;
1924 m_peer
->SetRect( &r
) ;
1926 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1928 MacInvalidateBorders() ;
1930 MacRepositionScrollBars() ;
1933 wxPoint
point(actualX
, actualY
);
1934 wxMoveEvent
event(point
, m_windowId
);
1935 event
.SetEventObject(this);
1936 GetEventHandler()->ProcessEvent(event
) ;
1941 MacRepositionScrollBars() ;
1942 wxSize
size(actualWidth
, actualHeight
);
1943 wxSizeEvent
event(size
, m_windowId
);
1944 event
.SetEventObject(this);
1945 GetEventHandler()->ProcessEvent(event
);
1950 wxSize
wxWindowMac::DoGetBestSize() const
1952 if ( m_macIsUserPane
|| IsTopLevel() )
1953 return wxWindowBase::DoGetBestSize() ;
1955 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1956 int bestWidth
, bestHeight
;
1958 m_peer
->GetBestRect( &bestsize
) ;
1959 if ( EmptyRect( &bestsize
) )
1964 bestsize
.bottom
= 16 ;
1966 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1968 bestsize
.bottom
= 16 ;
1971 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1973 bestsize
.bottom
= 24 ;
1978 // return wxWindowBase::DoGetBestSize() ;
1982 bestWidth
= bestsize
.right
- bestsize
.left
;
1983 bestHeight
= bestsize
.bottom
- bestsize
.top
;
1984 if ( bestHeight
< 10 )
1987 return wxSize(bestWidth
, bestHeight
);
1990 // set the size of the window: if the dimensions are positive, just use them,
1991 // but if any of them is equal to -1, it means that we must find the value for
1992 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1993 // which case -1 is a valid value for x and y)
1995 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1996 // the width/height to best suit our contents, otherwise we reuse the current
1998 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
2000 // get the current size and position...
2001 int currentX
, currentY
;
2002 int currentW
, currentH
;
2004 GetPosition(¤tX
, ¤tY
);
2005 GetSize(¤tW
, ¤tH
);
2007 // ... and don't do anything (avoiding flicker) if it's already ok
2008 if ( x
== currentX
&& y
== currentY
&&
2009 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
2012 MacRepositionScrollBars() ; // we might have a real position shift
2017 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
2019 if ( x
== wxDefaultCoord
)
2021 if ( y
== wxDefaultCoord
)
2025 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2027 wxSize size
= wxDefaultSize
;
2028 if ( width
== wxDefaultCoord
)
2030 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2032 size
= DoGetBestSize();
2037 // just take the current one
2042 if ( height
== wxDefaultCoord
)
2044 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2046 if ( size
.x
== wxDefaultCoord
)
2047 size
= DoGetBestSize();
2048 // else: already called DoGetBestSize() above
2054 // just take the current one
2059 DoMoveWindow( x
, y
, width
, height
);
2062 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2064 RgnHandle rgn
= NewRgn() ;
2066 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2068 GetRegionBounds( rgn
, &content
) ;
2078 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2081 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2083 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2085 int currentclientwidth
, currentclientheight
;
2086 int currentwidth
, currentheight
;
2088 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2089 GetSize( ¤twidth
, ¤theight
) ;
2091 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2092 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2096 void wxWindowMac::SetLabel(const wxString
& title
)
2100 if ( m_peer
&& m_peer
->Ok() )
2101 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
2103 // do not trigger refreshes upon invisible and possible partly created objects
2104 if ( MacIsReallyShown() )
2108 wxString
wxWindowMac::GetLabel() const
2113 bool wxWindowMac::Show(bool show
)
2115 bool former
= MacIsReallyShown() ;
2116 if ( !wxWindowBase::Show(show
) )
2119 // TODO: use visibilityChanged Carbon Event for OSX
2121 m_peer
->SetVisibility( show
, true ) ;
2123 if ( former
!= MacIsReallyShown() )
2124 MacPropagateVisibilityChanged() ;
2129 void wxWindowMac::DoEnable(bool enable
)
2131 m_peer
->Enable( enable
) ;
2135 // status change propagations (will be not necessary for OSX later )
2138 void wxWindowMac::MacPropagateVisibilityChanged()
2140 #if !TARGET_API_MAC_OSX
2141 MacVisibilityChanged() ;
2144 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2147 child
= node
->GetData();
2148 if ( child
->IsShown() )
2149 child
->MacPropagateVisibilityChanged() ;
2151 node
= node
->GetNext();
2156 void wxWindowMac::OnEnabled(bool WXUNUSED(enabled
))
2158 #if !TARGET_API_MAC_OSX
2159 MacEnabledStateChanged() ;
2163 void wxWindowMac::MacPropagateHiliteChanged()
2165 #if !TARGET_API_MAC_OSX
2166 MacHiliteChanged() ;
2169 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2172 child
= node
->GetData();
2173 if (child
/* && child->IsEnabled() */)
2174 child
->MacPropagateHiliteChanged() ;
2176 node
= node
->GetNext();
2182 // status change notifications
2185 void wxWindowMac::MacVisibilityChanged()
2189 void wxWindowMac::MacHiliteChanged()
2193 void wxWindowMac::MacEnabledStateChanged()
2198 // status queries on the inherited window's state
2201 bool wxWindowMac::MacIsReallyShown()
2203 // only under OSX the visibility of the TLW is taken into account
2204 if ( m_isBeingDeleted
)
2207 #if TARGET_API_MAC_OSX
2208 if ( m_peer
&& m_peer
->Ok() )
2209 return m_peer
->IsVisible();
2212 wxWindow
* win
= this ;
2213 while ( win
->IsShown() )
2215 if ( win
->IsTopLevel() )
2218 win
= win
->GetParent() ;
2226 bool wxWindowMac::MacIsReallyEnabled()
2228 return m_peer
->IsEnabled() ;
2231 bool wxWindowMac::MacIsReallyHilited()
2233 return m_peer
->IsActive();
2236 void wxWindowMac::MacFlashInvalidAreas()
2238 #if TARGET_API_MAC_OSX
2239 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2243 int wxWindowMac::GetCharHeight() const
2245 wxClientDC
dc( (wxWindowMac
*)this ) ;
2247 return dc
.GetCharHeight() ;
2250 int wxWindowMac::GetCharWidth() const
2252 wxClientDC
dc( (wxWindowMac
*)this ) ;
2254 return dc
.GetCharWidth() ;
2257 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2258 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2260 const wxFont
*fontToUse
= theFont
;
2262 fontToUse
= &m_font
;
2264 wxClientDC
dc( (wxWindowMac
*) this ) ;
2265 wxCoord lx
,ly
,ld
,le
;
2266 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2267 if ( externalLeading
)
2268 *externalLeading
= le
;
2278 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2279 * we always intersect with the entire window, not only with the client area
2282 void wxWindowMac::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
2284 if ( m_peer
== NULL
)
2287 if ( !MacIsReallyShown() )
2294 wxMacRectToNative( rect
, &r
) ;
2295 m_peer
->SetNeedsDisplay( &r
) ;
2299 m_peer
->SetNeedsDisplay() ;
2303 void wxWindowMac::Freeze()
2305 #if TARGET_API_MAC_OSX
2306 if ( !m_frozenness
++ )
2308 if ( m_peer
&& m_peer
->Ok() )
2309 m_peer
->SetDrawingEnabled( false ) ;
2314 void wxWindowMac::Thaw()
2316 #if TARGET_API_MAC_OSX
2317 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2319 if ( !--m_frozenness
)
2321 if ( m_peer
&& m_peer
->Ok() )
2323 m_peer
->SetDrawingEnabled( true ) ;
2324 m_peer
->InvalidateWithChildren() ;
2330 bool wxWindowMac::IsFrozen() const
2332 return m_frozenness
!= 0;
2335 wxWindowMac
*wxGetActiveWindow()
2337 // actually this is a windows-only concept
2341 // Coordinates relative to the window
2342 void wxWindowMac::WarpPointer(int WXUNUSED(x_pos
), int WXUNUSED(y_pos
))
2344 // We really don't move the mouse programmatically under Mac.
2347 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2349 if ( MacGetTopLevelWindow() == NULL
)
2352 #if TARGET_API_MAC_OSX
2353 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
2354 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2361 event
.GetDC()->Clear() ;
2365 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2370 int wxWindowMac::GetScrollPos(int orient
) const
2372 if ( orient
== wxHORIZONTAL
)
2375 return m_hScrollBar
->GetThumbPosition() ;
2380 return m_vScrollBar
->GetThumbPosition() ;
2386 // This now returns the whole range, not just the number
2387 // of positions that we can scroll.
2388 int wxWindowMac::GetScrollRange(int orient
) const
2390 if ( orient
== wxHORIZONTAL
)
2393 return m_hScrollBar
->GetRange() ;
2398 return m_vScrollBar
->GetRange() ;
2404 int wxWindowMac::GetScrollThumb(int orient
) const
2406 if ( orient
== wxHORIZONTAL
)
2409 return m_hScrollBar
->GetThumbSize() ;
2414 return m_vScrollBar
->GetThumbSize() ;
2420 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
2422 if ( orient
== wxHORIZONTAL
)
2425 m_hScrollBar
->SetThumbPosition( pos
) ;
2430 m_vScrollBar
->SetThumbPosition( pos
) ;
2435 wxWindowMac::AlwaysShowScrollbars(bool hflag
, bool vflag
)
2437 bool needVisibilityUpdate
= false;
2439 if ( m_hScrollBarAlwaysShown
!= hflag
)
2441 m_hScrollBarAlwaysShown
= hflag
;
2442 needVisibilityUpdate
= true;
2445 if ( m_vScrollBarAlwaysShown
!= vflag
)
2447 m_vScrollBarAlwaysShown
= vflag
;
2448 needVisibilityUpdate
= true;
2451 if ( needVisibilityUpdate
)
2452 DoUpdateScrollbarVisibility();
2456 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2457 // our own window origin is at leftOrigin/rightOrigin
2460 void wxWindowMac::MacPaintGrowBox()
2465 #if wxMAC_USE_CORE_GRAPHICS
2466 if ( MacHasScrollBarCorner() )
2470 CGContextRef cgContext
= (CGContextRef
) MacGetCGContextRef() ;
2471 wxASSERT( cgContext
) ;
2473 m_peer
->GetRect( &rect
) ;
2475 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2476 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2477 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2478 CGContextSaveGState( cgContext
);
2480 if ( m_macBackgroundBrush
.Ok() && m_macBackgroundBrush
.GetStyle() != wxTRANSPARENT
)
2482 wxMacCoreGraphicsColour
bkgnd( m_macBackgroundBrush
) ;
2483 bkgnd
.Apply( cgContext
);
2487 CGContextSetRGBFillColor( cgContext
, 1.0, 1.0 , 1.0 , 1.0 );
2489 CGContextFillRect( cgContext
, cgrect
);
2490 CGContextRestoreGState( cgContext
);
2495 void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin
) , int WXUNUSED(rightOrigin
) )
2501 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2503 // back to the surrounding frame rectangle
2504 m_peer
->GetRect( &rect
) ;
2505 InsetRect( &rect
, -1 , -1 ) ;
2507 #if wxMAC_USE_CORE_GRAPHICS
2509 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2510 rect
.bottom
- rect
.top
) ;
2512 HIThemeFrameDrawInfo info
;
2513 memset( &info
, 0 , sizeof(info
) ) ;
2517 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2518 info
.isFocused
= hasFocus
;
2520 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2521 wxASSERT( cgContext
) ;
2523 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2525 info
.kind
= kHIThemeFrameTextFieldSquare
;
2526 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2528 else if ( HasFlag(wxSIMPLE_BORDER
) )
2530 info
.kind
= kHIThemeFrameListBox
;
2531 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2533 else if ( hasFocus
)
2535 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2537 #if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
2538 m_peer
->GetRect( &rect
) ;
2539 if ( MacHasScrollBarCorner() )
2541 int variant
= (m_hScrollBar
== NULL
? m_vScrollBar
: m_hScrollBar
) ->GetWindowVariant();
2542 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2543 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2544 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2545 HIThemeGrowBoxDrawInfo info
;
2546 memset( &info
, 0, sizeof(info
) ) ;
2548 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2549 info
.kind
= kHIThemeGrowBoxKindNone
;
2550 // contrary to the docs ...SizeSmall does not work
2551 info
.size
= kHIThemeGrowBoxSizeNormal
;
2552 info
.direction
= 0 ;
2553 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2559 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2563 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2564 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2567 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2568 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2569 else if ( HasFlag(wxSIMPLE_BORDER
) )
2570 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2573 DrawThemeFocusRect( &rect
, true ) ;
2576 if ( hasBothScrollbars ) // hasBothScrollbars is not declared
2578 // GetThemeStandaloneGrowBoxBounds
2579 // DrawThemeStandaloneNoGrowBox
2586 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2588 if ( child
== m_hScrollBar
)
2589 m_hScrollBar
= NULL
;
2590 if ( child
== m_vScrollBar
)
2591 m_vScrollBar
= NULL
;
2593 wxWindowBase::RemoveChild( child
) ;
2596 void wxWindowMac::DoUpdateScrollbarVisibility()
2598 bool triggerSizeEvent
= false;
2602 bool showHScrollBar
= m_hScrollBarAlwaysShown
|| m_hScrollBar
->IsNeeded();
2604 if ( m_hScrollBar
->IsShown() != showHScrollBar
)
2606 m_hScrollBar
->Show( showHScrollBar
);
2607 triggerSizeEvent
= true;
2613 bool showVScrollBar
= m_vScrollBarAlwaysShown
|| m_vScrollBar
->IsNeeded();
2615 if ( m_vScrollBar
->IsShown() != showVScrollBar
)
2617 m_vScrollBar
->Show( showVScrollBar
) ;
2618 triggerSizeEvent
= true;
2622 MacRepositionScrollBars() ;
2623 if ( triggerSizeEvent
)
2625 wxSizeEvent
event(GetSize(), m_windowId
);
2626 event
.SetEventObject(this);
2627 GetEventHandler()->ProcessEvent(event
);
2631 // New function that will replace some of the above.
2632 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumb
,
2633 int range
, bool refresh
)
2635 if ( orient
== wxHORIZONTAL
&& m_hScrollBar
)
2636 m_hScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2637 else if ( orient
== wxVERTICAL
&& m_vScrollBar
)
2638 m_vScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2640 DoUpdateScrollbarVisibility();
2643 // Does a physical scroll
2644 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2646 if ( dx
== 0 && dy
== 0 )
2649 int width
, height
;
2650 GetClientSize( &width
, &height
) ;
2653 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2654 // area is scrolled, this does not occur if width and height are 2 pixels less,
2655 // TODO: write optimal workaround
2656 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2658 scrollrect
.Intersect( *rect
) ;
2660 if ( m_peer
->GetNeedsDisplay() )
2662 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2663 // in case there is already a pending redraw on that area
2664 // either immediate redraw or full invalidate
2666 // is the better overall solution, as it does not slow down scrolling
2667 m_peer
->SetNeedsDisplay() ;
2669 // this would be the preferred version for fast drawing controls
2671 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2672 if ( UMAGetSystemVersion() >= 0x1030 )
2673 HIViewRender(m_peer
->GetControlRef()) ;
2680 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2681 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2682 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2685 // this would be the preferred version for fast drawing controls
2686 HIViewRender(m_peer
->GetControlRef()) ;
2692 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2694 child
= node
->GetData();
2697 if (child
== m_vScrollBar
)
2699 if (child
== m_hScrollBar
)
2701 if (child
->IsTopLevel())
2704 child
->GetPosition( &x
, &y
);
2705 child
->GetSize( &w
, &h
);
2708 wxRect
rc( x
, y
, w
, h
);
2709 if (rect
->Intersects( rc
))
2710 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2714 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2719 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2721 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2723 wxScrollWinEvent wevent
;
2724 wevent
.SetPosition(event
.GetPosition());
2725 wevent
.SetOrientation(event
.GetOrientation());
2726 wevent
.SetEventObject(this);
2728 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2729 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2730 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2731 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2732 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2733 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2734 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2735 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2736 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2737 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2738 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2739 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2740 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2741 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2742 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2743 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2745 GetEventHandler()->ProcessEvent(wevent
);
2749 // Get the window with the focus
2750 wxWindowMac
*wxWindowBase::DoFindFocus()
2752 ControlRef control
;
2753 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2754 return wxFindControlFromMacControl( control
) ;
2757 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2759 // panel wants to track the window which was the last to have focus in it,
2760 // so we want to set ourselves as the window which last had focus
2762 // notice that it's also important to do it upwards the tree because
2763 // otherwise when the top level panel gets focus, it won't set it back to
2764 // us, but to some other sibling
2766 // CS: don't know if this is still needed:
2767 //wxChildFocusEvent eventFocus(this);
2768 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2770 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2772 #if wxMAC_USE_CORE_GRAPHICS
2773 GetParent()->Refresh() ;
2775 wxMacWindowStateSaver
sv( this ) ;
2778 m_peer
->GetRect( &rect
) ;
2779 // auf den umgebenden Rahmen zurチᅡ゚ck
2780 InsetRect( &rect
, -1 , -1 ) ;
2782 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2786 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2788 rect
.right
+= pt
.x
;
2790 rect
.bottom
+= pt
.y
;
2793 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2794 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2795 if ( !bIsFocusEvent
)
2797 // as this erases part of the frame we have to redraw borders
2798 // and because our z-ordering is not always correct (staticboxes)
2799 // we have to invalidate things, we cannot simple redraw
2800 MacInvalidateBorders() ;
2808 void wxWindowMac::OnInternalIdle()
2810 // This calls the UI-update mechanism (querying windows for
2811 // menu/toolbar/control state information)
2812 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
2813 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2816 // Raise the window to the top of the Z order
2817 void wxWindowMac::Raise()
2819 m_peer
->SetZOrder( true , NULL
) ;
2822 // Lower the window to the bottom of the Z order
2823 void wxWindowMac::Lower()
2825 m_peer
->SetZOrder( false , NULL
) ;
2828 // static wxWindow *gs_lastWhich = NULL;
2830 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2832 // first trigger a set cursor event
2834 wxPoint clientorigin
= GetClientAreaOrigin() ;
2835 wxSize clientsize
= GetClientSize() ;
2837 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2839 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2841 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2842 if ( processedEvtSetCursor
&& event
.HasCursor() )
2844 cursor
= event
.GetCursor() ;
2848 // the test for processedEvtSetCursor is here to prevent using m_cursor
2849 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2850 // it - this is a way to say that our cursor shouldn't be used for this
2852 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2855 if ( !wxIsBusy() && !GetParent() )
2856 cursor
= *wxSTANDARD_CURSOR
;
2860 cursor
.MacInstall() ;
2863 return cursor
.Ok() ;
2866 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&WXUNUSED(pt
) )
2870 return m_tooltip
->GetTip() ;
2873 return wxEmptyString
;
2876 void wxWindowMac::ClearBackground()
2882 void wxWindowMac::Update()
2884 #if TARGET_API_MAC_OSX
2885 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2887 top
->MacPerformUpdates() ;
2889 ::Draw1Control( m_peer
->GetControlRef() ) ;
2893 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2895 wxTopLevelWindowMac
* win
= NULL
;
2896 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2898 win
= wxFindWinFromMacWindow( window
) ;
2903 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2905 MacUpdateClippedRects() ;
2907 return m_cachedClippedClientRect
;
2910 const wxRect
& wxWindowMac::MacGetClippedRect() const
2912 MacUpdateClippedRects() ;
2914 return m_cachedClippedRect
;
2917 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2919 MacUpdateClippedRects() ;
2921 return m_cachedClippedRectWithOuterStructure
;
2924 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2926 static wxRegion emptyrgn
;
2928 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2930 MacUpdateClippedRects() ;
2931 if ( includeOuterStructures
)
2932 return m_cachedClippedRegionWithOuterStructure
;
2934 return m_cachedClippedRegion
;
2942 void wxWindowMac::MacUpdateClippedRects() const
2944 if ( m_cachedClippedRectValid
)
2947 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2948 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2949 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2950 // to add focus borders everywhere
2952 Rect r
, rIncludingOuterStructures
;
2954 m_peer
->GetRect( &r
) ;
2955 r
.left
-= MacGetLeftBorderSize() ;
2956 r
.top
-= MacGetTopBorderSize() ;
2957 r
.bottom
+= MacGetBottomBorderSize() ;
2958 r
.right
+= MacGetRightBorderSize() ;
2965 rIncludingOuterStructures
= r
;
2966 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2968 wxRect cl
= GetClientRect() ;
2969 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2973 const wxWindow
* child
= this ;
2974 const wxWindow
* parent
= NULL
;
2976 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2978 if ( parent
->MacIsChildOfClientArea(child
) )
2980 size
= parent
->GetClientSize() ;
2981 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2987 // this will be true for scrollbars, toolbars etc.
2988 size
= parent
->GetSize() ;
2989 y
= parent
->MacGetTopBorderSize() ;
2990 x
= parent
->MacGetLeftBorderSize() ;
2991 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2992 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2995 parent
->MacWindowToRootWindow( &x
, &y
) ;
2996 MacRootWindowToWindow( &x
, &y
) ;
2998 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
3000 // the wxwindow and client rects will always be clipped
3001 SectRect( &r
, &rparent
, &r
) ;
3002 SectRect( &rClient
, &rparent
, &rClient
) ;
3004 // the structure only at 'hard' borders
3005 if ( parent
->MacClipChildren() ||
3006 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
3008 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
3014 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
3015 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
3016 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
3017 m_cachedClippedRectWithOuterStructure
= wxRect(
3018 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
3019 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
3020 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
3022 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
3023 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
3024 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
3026 m_cachedClippedRectValid
= true ;
3030 This function must not change the updatergn !
3032 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
3034 bool handled
= false ;
3036 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
3037 GetRegionBounds( updatergn
, &updatebounds
) ;
3039 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3041 if ( !EmptyRgn(updatergn
) )
3043 RgnHandle newupdate
= NewRgn() ;
3044 wxSize point
= GetClientSize() ;
3045 wxPoint origin
= GetClientAreaOrigin() ;
3046 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
3047 SectRgn( newupdate
, updatergn
, newupdate
) ;
3049 // first send an erase event to the entire update area
3051 // for the toplevel window this really is the entire area
3052 // for all the others only their client area, otherwise they
3053 // might be drawing with full alpha and eg put blue into
3054 // the grow-box area of a scrolled window (scroll sample)
3055 wxDC
* dc
= new wxWindowDC(this);
3057 dc
->SetClippingRegion(wxRegion(updatergn
));
3059 dc
->SetClippingRegion(wxRegion(newupdate
));
3061 wxEraseEvent
eevent( GetId(), dc
);
3062 eevent
.SetEventObject( this );
3063 GetEventHandler()->ProcessEvent( eevent
);
3069 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3070 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3071 m_updateRegion
= newupdate
;
3072 DisposeRgn( newupdate
) ;
3074 if ( !m_updateRegion
.Empty() )
3076 // paint the window itself
3079 event
.SetTimestamp(time
);
3080 event
.SetEventObject(this);
3081 GetEventHandler()->ProcessEvent(event
);
3085 // now we cannot rely on having its borders drawn by a window itself, as it does not
3086 // get the updateRgn wide enough to always do so, so we do it from the parent
3087 // this would also be the place to draw any custom backgrounds for native controls
3088 // in Composited windowing
3089 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3093 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3095 child
= node
->GetData();
3098 if (child
== m_vScrollBar
)
3100 if (child
== m_hScrollBar
)
3102 if (child
->IsTopLevel())
3104 if (!child
->IsShown())
3107 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3109 child
->GetPosition( &x
, &y
);
3110 child
->GetSize( &w
, &h
);
3111 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3112 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3113 InsetRect( &childRect
, -10 , -10) ;
3115 if ( RectInRgn( &childRect
, updatergn
) )
3117 // paint custom borders
3118 wxNcPaintEvent
eventNc( child
->GetId() );
3119 eventNc
.SetEventObject( child
);
3120 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3122 #if wxMAC_USE_CORE_GRAPHICS
3123 child
->MacPaintBorders(0, 0) ;
3126 wxWindowDC
dc(this) ;
3127 dc
.SetClippingRegion(wxRegion(updatergn
));
3128 wxMacPortSetter
helper(&dc
) ;
3129 child
->MacPaintBorders(0, 0) ;
3141 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3143 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3147 if ( iter
->IsTopLevel() )
3149 wxTopLevelWindow
* toplevel
= wxDynamicCast(iter
,wxTopLevelWindow
);
3151 return toplevel
->MacGetWindowRef();
3153 wxPopupWindow
* popupwin
= wxDynamicCast(iter
,wxPopupWindow
);
3155 return popupwin
->MacGetPopupWindowRef();
3158 iter
= iter
->GetParent() ;
3164 bool wxWindowMac::MacHasScrollBarCorner() const
3166 /* Returns whether the scroll bars in a wxScrolledWindow should be
3167 * shortened. Scroll bars should be shortened if either:
3169 * - both scroll bars are visible, or
3171 * - there is a resize box in the parent frame's corner and this
3172 * window shares the bottom and right edge with the parent
3176 if ( m_hScrollBar
== NULL
&& m_vScrollBar
== NULL
)
3179 if ( ( m_hScrollBar
&& m_hScrollBar
->IsShown() )
3180 && ( m_vScrollBar
&& m_vScrollBar
->IsShown() ) )
3182 // Both scroll bars visible
3187 wxPoint thisWindowBottomRight
= GetScreenRect().GetBottomRight();
3189 for ( const wxWindow
*win
= this; win
; win
= win
->GetParent() )
3191 const wxFrame
*frame
= wxDynamicCast( win
, wxFrame
) ;
3194 if ( frame
->GetWindowStyleFlag() & wxRESIZE_BORDER
)
3196 // Parent frame has resize handle
3197 wxPoint frameBottomRight
= frame
->GetScreenRect().GetBottomRight();
3199 // Note: allow for some wiggle room here as wxMac's
3200 // window rect calculations seem to be imprecise
3201 if ( abs( thisWindowBottomRight
.x
- frameBottomRight
.x
) <= 2
3202 && abs( thisWindowBottomRight
.y
- frameBottomRight
.y
) <= 2 )
3204 // Parent frame has resize handle and shares
3205 // right bottom corner
3210 // Parent frame has resize handle but doesn't
3211 // share right bottom corner
3217 // Parent frame doesn't have resize handle
3223 // No parent frame found
3228 void wxWindowMac::MacCreateScrollBars( long style
)
3230 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3232 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3234 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3235 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3237 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3240 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1: 0 ;
3242 GetClientSize( &width
, &height
) ;
3244 wxPoint
vPoint(width
- scrlsize
, 0) ;
3245 wxSize
vSize(scrlsize
, height
- adjust
) ;
3246 wxPoint
hPoint(0, height
- scrlsize
) ;
3247 wxSize
hSize(width
- adjust
, scrlsize
) ;
3249 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
3250 if ( style
& wxVSCROLL
)
3252 m_vScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3253 m_vScrollBar
->SetMinSize( wxDefaultSize
);
3256 if ( style
& wxHSCROLL
)
3258 m_hScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3259 m_hScrollBar
->SetMinSize( wxDefaultSize
);
3263 // because the create does not take into account the client area origin
3264 // we might have a real position shift
3265 MacRepositionScrollBars() ;
3268 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3270 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3275 void wxWindowMac::MacRepositionScrollBars()
3277 if ( !m_hScrollBar
&& !m_vScrollBar
)
3280 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3281 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1 : 0 ;
3283 // get real client area
3285 GetSize( &width
, &height
);
3287 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3288 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3290 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3291 wxSize
vSize( scrlsize
, height
- adjust
) ;
3292 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3293 wxSize
hSize( width
- adjust
, scrlsize
) ;
3296 int x
= 0, y
= 0, w
, h
;
3297 GetSize( &w
, &h
) ;
3299 MacClientToRootWindow( &x
, &y
) ;
3300 MacClientToRootWindow( &w
, &h
) ;
3302 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3304 int totW
= 10000 , totH
= 10000;
3307 if ( iter
->IsTopLevel() )
3309 iter
->GetSize( &totW
, &totH
) ;
3313 iter
= iter
->GetParent() ;
3327 if ( w
- x
>= totW
)
3332 if ( h
- y
>= totH
)
3340 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3342 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3345 bool wxWindowMac::AcceptsFocus() const
3347 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3350 void wxWindowMac::MacSuperChangedPosition()
3352 // only window-absolute structures have to be moved i.e. controls
3354 m_cachedClippedRectValid
= false ;
3357 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3360 child
= node
->GetData();
3361 child
->MacSuperChangedPosition() ;
3363 node
= node
->GetNext();
3367 void wxWindowMac::MacTopLevelWindowChangedPosition()
3369 // only screen-absolute structures have to be moved i.e. glcanvas
3372 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3375 child
= node
->GetData();
3376 child
->MacTopLevelWindowChangedPosition() ;
3378 node
= node
->GetNext();
3382 long wxWindowMac::MacGetLeftBorderSize() const
3389 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3391 // this metric is only the 'outset' outside the simple frame rect
3392 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3395 else if (HasFlag(wxSIMPLE_BORDER
))
3397 // this metric is only the 'outset' outside the simple frame rect
3398 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3405 long wxWindowMac::MacGetRightBorderSize() const
3407 // they are all symmetric in mac themes
3408 return MacGetLeftBorderSize() ;
3411 long wxWindowMac::MacGetTopBorderSize() const
3413 // they are all symmetric in mac themes
3414 return MacGetLeftBorderSize() ;
3417 long wxWindowMac::MacGetBottomBorderSize() const
3419 // they are all symmetric in mac themes
3420 return MacGetLeftBorderSize() ;
3423 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3425 return style
& ~wxBORDER_MASK
;
3428 // Find the wxWindowMac at the current mouse position, returning the mouse
3430 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3432 pt
= wxGetMousePosition();
3433 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3438 // Get the current mouse position.
3439 wxPoint
wxGetMousePosition()
3443 wxGetMousePosition( &x
, &y
);
3445 return wxPoint(x
, y
);
3448 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3450 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3452 // copied from wxGTK : CS
3453 // VZ: shouldn't we move this to base class then?
3455 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3458 // (a) it's a command event and so is propagated to the parent
3459 // (b) under MSW it can be generated from kbd too
3460 // (c) it uses screen coords (because of (a))
3461 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3463 this->ClientToScreen(event
.GetPosition()));
3464 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3473 void wxWindowMac::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
3475 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3476 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3477 CallNextEventHandler(
3478 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3479 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3482 void wxWindowMac::MacHandleControlClick(WXWidget
WXUNUSED(control
),
3483 wxInt16
WXUNUSED(controlpart
),
3484 bool WXUNUSED(mouseStillDown
))
3488 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3492 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3493 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3498 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3500 return eventNotHandledErr
;
3503 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3505 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3506 if ( !wxWindowBase::Reparent(newParent
) )
3509 // copied from MacPostControlCreate
3510 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3512 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3514 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3519 bool wxWindowMac::SetTransparent(wxByte alpha
)
3521 #if wxMAC_USE_CORE_GRAPHICS
3522 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3524 if ( alpha
!= m_macAlpha
)
3526 m_macAlpha
= alpha
;
3536 bool wxWindowMac::CanSetTransparent()
3538 #if wxMAC_USE_CORE_GRAPHICS
3545 wxByte
wxWindowMac::GetTransparent() const