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 static const EventTypeSpec eventList
[] =
158 { kEventClassCommand
, kEventProcessCommand
} ,
159 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
161 { kEventClassControl
, kEventControlGetClickActivation
} ,
162 { kEventClassControl
, kEventControlHit
} ,
164 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
165 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
167 { kEventClassControl
, kEventControlDraw
} ,
168 #if TARGET_API_MAC_OSX
169 { kEventClassControl
, kEventControlVisibilityChanged
} ,
170 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
171 { kEventClassControl
, kEventControlHiliteChanged
} ,
173 { kEventClassControl
, kEventControlActivate
} ,
174 { kEventClassControl
, kEventControlDeactivate
} ,
176 { kEventClassControl
, kEventControlSetFocusPart
} ,
178 { kEventClassService
, kEventServiceGetTypes
},
179 { kEventClassService
, kEventServiceCopy
},
180 { kEventClassService
, kEventServicePaste
},
182 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
183 // { kEventClassControl , kEventControlBoundsChanged } ,
186 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
188 OSStatus result
= eventNotHandledErr
;
190 wxMacCarbonEvent
cEvent( event
) ;
192 ControlRef controlRef
;
193 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
195 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
197 switch ( GetEventKind( event
) )
199 #if TARGET_API_MAC_OSX
200 case kEventControlDraw
:
202 RgnHandle updateRgn
= NULL
;
203 RgnHandle allocatedRgn
= NULL
;
204 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
206 if ( cEvent
.GetParameter
<RgnHandle
>(kEventParamRgnHandle
, &updateRgn
) != noErr
)
208 updateRgn
= (RgnHandle
) visRegion
.GetWXHRGN() ;
212 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
214 // as this update region is in native window locals we must adapt it to wx window local
215 allocatedRgn
= NewRgn() ;
216 CopyRgn( updateRgn
, allocatedRgn
) ;
218 // hide the given region by the new region that must be shifted
219 wxMacNativeToWindow( thisWindow
, allocatedRgn
) ;
220 updateRgn
= allocatedRgn
;
225 GetRegionBounds( updateRgn
, &rgnBounds
) ;
227 #if wxMAC_DEBUG_REDRAW
228 if ( thisWindow
->MacIsUserPane() )
230 static float color
= 0.5 ;
233 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
235 HIViewGetBounds( controlRef
, &bounds
);
236 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
237 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
238 CGContextFillRect( cgContext
, bounds
);
251 #if wxMAC_USE_CORE_GRAPHICS
252 bool created
= false ;
253 CGContextRef cgContext
= NULL
;
254 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
255 wxASSERT_MSG( err
== noErr
, wxT("Unable to retrieve CGContextRef") ) ;
256 thisWindow
->MacSetCGContextRef( cgContext
) ;
259 wxMacCGContextStateSaver
sg( cgContext
) ;
262 wxWindow
* iter
= thisWindow
;
265 alpha
*= (float) iter
->GetTransparent()/255.0 ;
266 if ( iter
->IsTopLevel() )
269 iter
= iter
->GetParent() ;
272 CGContextSetAlpha( cgContext
, alpha
) ;
274 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
277 HIViewGetBounds( controlRef
, &bounds
);
278 CGContextClearRect( cgContext
, bounds
);
283 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
286 #if wxMAC_USE_CORE_GRAPHICS
287 thisWindow
->MacSetCGContextRef( NULL
) ;
291 CGContextRelease( cgContext
) ;
296 DisposeRgn( allocatedRgn
) ;
300 case kEventControlVisibilityChanged
:
301 thisWindow
->MacVisibilityChanged() ;
304 case kEventControlEnabledStateChanged
:
305 thisWindow
->MacEnabledStateChanged() ;
308 case kEventControlHiliteChanged
:
309 thisWindow
->MacHiliteChanged() ;
312 case kEventControlActivate
:
313 case kEventControlDeactivate
:
314 // FIXME: we should have a virtual function for this!
316 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
317 thisWindow
->Refresh();
320 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
321 thisWindow
->Refresh();
324 #endif // TARGET_API_MAC_OSX
326 // we emulate this event under Carbon CFM
327 case kEventControlSetFocusPart
:
329 Boolean focusEverything
= false ;
330 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
333 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
338 if ( thisWindow
->MacIsUserPane() )
341 if ( controlPart
== kControlFocusNoPart
)
344 if ( thisWindow
->GetCaret() )
345 thisWindow
->GetCaret()->OnKillFocus();
348 static bool inKillFocusEvent
= false ;
350 if ( !inKillFocusEvent
)
352 inKillFocusEvent
= true ;
353 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
354 event
.SetEventObject(thisWindow
);
355 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
356 inKillFocusEvent
= false ;
361 // panel wants to track the window which was the last to have focus in it
362 wxChildFocusEvent
eventFocus(thisWindow
);
363 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
366 if ( thisWindow
->GetCaret() )
367 thisWindow
->GetCaret()->OnSetFocus();
370 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
371 event
.SetEventObject(thisWindow
);
372 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
377 case kEventControlHit
:
378 result
= thisWindow
->MacControlHit( handler
, event
) ;
381 case kEventControlGetClickActivation
:
383 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
384 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
385 if ( !IsWindowActive(owner
) )
387 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
400 static pascal OSStatus
401 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
405 OSStatus result
= eventNotHandledErr
;
407 wxMacCarbonEvent
cEvent( event
) ;
409 ControlRef controlRef
;
410 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
411 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
412 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
414 switch ( GetEventKind( event
) )
416 case kEventServiceGetTypes
:
420 textCtrl
->GetSelection( &from
, &to
) ;
422 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
424 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
425 if ( textCtrl
->IsEditable() )
426 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
428 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
429 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
431 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
435 CFArrayAppendValue(copyTypes
, typestring
) ;
437 CFArrayAppendValue(pasteTypes
, typestring
) ;
439 CFRelease( typestring
) ;
447 case kEventServiceCopy
:
452 textCtrl
->GetSelection( &from
, &to
) ;
453 wxString val
= textCtrl
->GetValue() ;
454 val
= val
.Mid( from
, to
- from
) ;
455 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
456 verify_noerr( PasteboardClear( pasteboard
) ) ;
457 PasteboardSynchronize( pasteboard
);
458 // TODO add proper conversion
459 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
460 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
466 case kEventServicePaste
:
469 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
470 PasteboardSynchronize( pasteboard
);
472 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
473 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
475 PasteboardItemID itemID
;
476 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
478 CFDataRef flavorData
= NULL
;
479 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
481 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
482 char *content
= new char[flavorDataSize
+1] ;
483 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
484 content
[flavorDataSize
]=0;
485 CFRelease( flavorData
);
487 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
489 textCtrl
->WriteText( wxString( content
) ) ;
507 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
509 OSStatus result
= eventNotHandledErr
;
510 wxWindowMac
* focus
= (wxWindowMac
*) data
;
512 wchar_t* uniChars
= NULL
;
513 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
515 UniChar
* charBuf
= NULL
;
516 ByteCount dataSize
= 0 ;
519 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
521 numChars
= dataSize
/ sizeof( UniChar
) + 1;
524 if ( (size_t) numChars
* 2 > sizeof(buf
) )
525 charBuf
= new UniChar
[ numChars
] ;
529 uniChars
= new wchar_t[ numChars
] ;
530 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
531 charBuf
[ numChars
- 1 ] = 0;
532 #if SIZEOF_WCHAR_T == 2
533 uniChars
= (wchar_t*) charBuf
;
534 /* 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...)
536 // the resulting string will never have more chars than the utf16 version, so this is safe
537 wxMBConvUTF16 converter
;
538 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
542 switch ( GetEventKind( event
) )
544 case kEventTextInputUpdateActiveInputArea
:
546 // An IME input event may return several characters, but we need to send one char at a time to
548 for (int pos
=0 ; pos
< numChars
; pos
++)
550 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
551 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
552 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
554 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
556 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
557 multiple times to update the active range during inline input, so this handler will often receive
558 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
559 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
560 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
561 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
562 should add new event types to support advanced text input. For now, I would keep things as they are.
564 However, the code that was being used caused additional problems:
565 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
566 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
567 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
568 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
569 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
570 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
571 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
572 overlap with Unicode within the (7-bit) ASCII range.
573 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
574 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
575 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
576 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
577 I don't have time to look into that right now.
580 if ( wxTheApp
->MacSendCharEvent(
581 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
586 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
590 case kEventTextInputUnicodeForKeyEvent
:
592 UInt32 keyCode
, modifiers
;
595 unsigned char charCode
;
597 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
598 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
599 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
600 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
601 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
603 UInt32 message
= (keyCode
<< 8) + charCode
;
605 // An IME input event may return several characters, but we need to send one char at a time to
607 for (int pos
=0 ; pos
< numChars
; pos
++)
609 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
610 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
611 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
613 if ( wxTheApp
->MacSendCharEvent(
614 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
619 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
628 if ( charBuf
!= buf
)
634 static pascal OSStatus
635 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
639 OSStatus result
= eventNotHandledErr
;
640 wxWindowMac
* focus
= (wxWindowMac
*) data
;
644 wxMacCarbonEvent
cEvent( event
) ;
645 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
647 wxMenuItem
* item
= NULL
;
648 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
649 int id
= wxMacCommandToId( command
.commandID
) ;
653 wxASSERT( itemMenu
!= NULL
) ;
655 switch ( cEvent
.GetKind() )
657 case kEventProcessCommand
:
658 result
= itemMenu
->MacHandleCommandProcess( item
, id
, focus
);
661 case kEventCommandUpdateStatus
:
662 result
= itemMenu
->MacHandleCommandUpdateStatus( item
, id
, focus
);
672 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
674 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
675 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
676 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
677 OSStatus result
= eventNotHandledErr
;
679 switch ( GetEventClass( event
) )
681 case kEventClassCommand
:
682 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
685 case kEventClassControl
:
686 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
689 case kEventClassService
:
690 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
693 case kEventClassTextInput
:
694 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
701 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
706 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
708 #if !TARGET_API_MAC_OSX
710 // ---------------------------------------------------------------------------
711 // UserPane events for non OSX builds
712 // ---------------------------------------------------------------------------
714 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
716 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
718 win
->MacControlUserPaneDrawProc(part
) ;
720 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
722 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
724 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
726 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
728 return kControlNoPart
;
730 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
732 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
734 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
736 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
738 return kControlNoPart
;
740 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
742 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
744 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
746 win
->MacControlUserPaneIdleProc() ;
748 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
750 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
752 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
754 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
756 return kControlNoPart
;
758 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
760 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
762 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
764 win
->MacControlUserPaneActivateProc(activating
) ;
766 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
768 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
770 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
772 return win
->MacControlUserPaneFocusProc(action
) ;
774 return kControlNoPart
;
776 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
778 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
780 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
782 win
->MacControlUserPaneBackgroundProc(info
) ;
784 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
786 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
789 RgnHandle rgn
= NewRgn() ;
791 MacWindowToRootWindow( &x
, &y
) ;
792 OffsetRgn( rgn
, -x
, -y
) ;
793 wxMacWindowStateSaver
sv( this ) ;
794 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
795 MacDoRedraw( rgn
, 0 ) ;
799 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
801 return kControlNoPart
;
804 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
806 return kControlNoPart
;
809 void wxWindowMac::MacControlUserPaneIdleProc()
813 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
815 return kControlNoPart
;
818 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
822 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
824 if ( AcceptsFocus() )
827 return kControlNoPart
;
830 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
836 // ---------------------------------------------------------------------------
837 // Scrollbar Tracking for all
838 // ---------------------------------------------------------------------------
840 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
841 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
845 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
847 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
850 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
852 // ===========================================================================
854 // ===========================================================================
856 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
858 static MacControlMap wxWinMacControlList
;
860 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
862 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
864 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
867 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
869 // adding NULL ControlRef is (first) surely a result of an error and
870 // (secondly) breaks native event processing
871 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
873 wxWinMacControlList
[inControl
] = control
;
876 void wxRemoveMacControlAssociation(wxWindow
*control
)
878 // iterate over all the elements in the class
879 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
880 // we should go on...
886 MacControlMap::iterator it
;
887 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
889 if ( it
->second
== control
)
891 wxWinMacControlList
.erase(it
);
899 // ----------------------------------------------------------------------------
900 // constructors and such
901 // ----------------------------------------------------------------------------
903 wxWindowMac::wxWindowMac()
908 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
913 const wxString
& name
)
916 Create(parent
, id
, pos
, size
, style
, name
);
919 void wxWindowMac::Init()
925 #if wxMAC_USE_CORE_GRAPHICS
926 m_cgContextRef
= NULL
;
929 // as all windows are created with WS_VISIBLE style...
932 m_hScrollBar
= NULL
;
933 m_vScrollBar
= NULL
;
934 m_hScrollBarAlwaysShown
= false;
935 m_vScrollBarAlwaysShown
= false;
937 m_macBackgroundBrush
= wxNullBrush
;
939 m_macIsUserPane
= true;
940 m_clipChildren
= false ;
941 m_cachedClippedRectValid
= false ;
943 // we need a valid font for the encodings
944 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
947 wxWindowMac::~wxWindowMac()
951 m_isBeingDeleted
= true;
953 MacInvalidateBorders() ;
955 #ifndef __WXUNIVERSAL__
956 // VS: make sure there's no wxFrame with last focus set to us:
957 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
959 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
962 if ( frame
->GetLastFocus() == this )
963 frame
->SetLastFocus((wxWindow
*)NULL
);
969 // destroy children before destroying this window itself
972 // wxRemoveMacControlAssociation( this ) ;
973 // If we delete an item, we should initialize the parent panel,
974 // because it could now be invalid.
975 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
978 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
979 tlw
->SetDefaultItem(NULL
);
982 if ( m_peer
&& m_peer
->Ok() )
984 // in case the callback might be called during destruction
985 wxRemoveMacControlAssociation( this) ;
986 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
987 // we currently are not using this hook
988 // ::SetControlColorProc( *m_peer , NULL ) ;
992 if ( g_MacLastWindow
== this )
993 g_MacLastWindow
= NULL
;
995 #ifndef __WXUNIVERSAL__
996 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( (wxWindow
*)this ) , wxFrame
) ;
999 if ( frame
->GetLastFocus() == this )
1000 frame
->SetLastFocus( NULL
) ;
1004 // delete our drop target if we've got one
1005 #if wxUSE_DRAG_AND_DROP
1006 if ( m_dropTarget
!= NULL
)
1008 delete m_dropTarget
;
1009 m_dropTarget
= NULL
;
1016 WXWidget
wxWindowMac::GetHandle() const
1018 return (WXWidget
) m_peer
->GetControlRef() ;
1021 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1023 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1024 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1025 GetEventTypeCount(eventList
), eventList
, this,
1026 (EventHandlerRef
*)&m_macControlEventHandler
);
1028 #if !TARGET_API_MAC_OSX
1029 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1031 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1032 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1033 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1034 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1035 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1036 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1037 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1038 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1044 bool wxWindowMac::Create(wxWindowMac
*parent
,
1049 const wxString
& name
)
1051 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1053 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1056 m_windowVariant
= parent
->GetWindowVariant() ;
1058 if ( m_macIsUserPane
)
1060 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1063 | kControlSupportsEmbedding
1064 | kControlSupportsLiveFeedback
1065 | kControlGetsFocusOnClick
1066 // | kControlHasSpecialBackground
1067 // | kControlSupportsCalcBestRect
1068 | kControlHandlesTracking
1069 | kControlSupportsFocus
1070 | kControlWantsActivate
1071 | kControlWantsIdle
;
1073 m_peer
= new wxMacControl(this) ;
1074 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1075 verify_noerr( err
);
1077 MacPostControlCreate(pos
, size
) ;
1080 #ifndef __WXUNIVERSAL__
1081 // Don't give scrollbars to wxControls unless they ask for them
1082 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1083 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1085 MacCreateScrollBars( style
) ;
1089 wxWindowCreateEvent
event(this);
1090 GetEventHandler()->AddPendingEvent(event
);
1095 void wxWindowMac::MacChildAdded()
1098 m_vScrollBar
->Raise() ;
1100 m_hScrollBar
->Raise() ;
1103 void wxWindowMac::MacPostControlCreate(const wxPoint
& WXUNUSED(pos
), const wxSize
& size
)
1105 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1107 m_peer
->SetReference( (URefCon
) this ) ;
1108 GetParent()->AddChild( this );
1110 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1112 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1113 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1114 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1115 GetParent()->MacChildAdded() ;
1117 // adjust font, controlsize etc
1118 DoSetWindowVariant( m_windowVariant
) ;
1120 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1122 if (!m_macIsUserPane
)
1123 SetInitialSize(size
);
1125 SetCursor( *wxSTANDARD_CURSOR
) ;
1128 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1130 // Don't assert, in case we set the window variant before
1131 // the window is created
1132 // wxASSERT( m_peer->Ok() ) ;
1134 m_windowVariant
= variant
;
1136 if (m_peer
== NULL
|| !m_peer
->Ok())
1140 ThemeFontID themeFont
= kThemeSystemFont
;
1142 // we will get that from the settings later
1143 // and make this NORMAL later, but first
1144 // we have a few calculations that we must fix
1148 case wxWINDOW_VARIANT_NORMAL
:
1149 size
= kControlSizeNormal
;
1150 themeFont
= kThemeSystemFont
;
1153 case wxWINDOW_VARIANT_SMALL
:
1154 size
= kControlSizeSmall
;
1155 themeFont
= kThemeSmallSystemFont
;
1158 case wxWINDOW_VARIANT_MINI
:
1159 if (UMAGetSystemVersion() >= 0x1030 )
1161 // not always defined in the headers
1167 size
= kControlSizeSmall
;
1168 themeFont
= kThemeSmallSystemFont
;
1172 case wxWINDOW_VARIANT_LARGE
:
1173 size
= kControlSizeLarge
;
1174 themeFont
= kThemeSystemFont
;
1178 wxFAIL_MSG(_T("unexpected window variant"));
1182 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1185 font
.MacCreateThemeFont( themeFont
) ;
1189 void wxWindowMac::MacUpdateControlFont()
1191 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1192 // do not trigger refreshes upon invisible and possible partly created objects
1193 if ( MacIsReallyShown() )
1197 bool wxWindowMac::SetFont(const wxFont
& font
)
1199 bool retval
= wxWindowBase::SetFont( font
);
1201 MacUpdateControlFont() ;
1206 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1208 bool retval
= wxWindowBase::SetForegroundColour( col
);
1211 MacUpdateControlFont();
1216 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1218 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1222 wxColour
newCol(GetBackgroundColour());
1224 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1225 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1226 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1227 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1229 brush
.SetColour( newCol
) ;
1231 MacSetBackgroundBrush( brush
) ;
1232 MacUpdateControlFont() ;
1237 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1239 m_macBackgroundBrush
= brush
;
1240 m_peer
->SetBackground( brush
) ;
1243 bool wxWindowMac::MacCanFocus() const
1245 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1246 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1247 // but the value range is nowhere documented
1248 Boolean keyExistsAndHasValidFormat
;
1249 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1250 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1252 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1258 UInt32 features
= 0 ;
1259 m_peer
->GetFeatures( &features
) ;
1261 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1265 void wxWindowMac::SetFocus()
1267 if ( !AcceptsFocus() )
1270 wxWindow
* former
= FindFocus() ;
1271 if ( former
== this )
1274 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1275 // we can only leave in case of an error
1276 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1277 if ( err
== errCouldntSetFocus
)
1280 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1282 #if !TARGET_API_MAC_OSX
1283 // emulate carbon events when running under CarbonLib where they are not natively available
1286 EventRef evRef
= NULL
;
1288 err
= MacCreateEvent(
1289 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1290 kEventAttributeUserEvent
, &evRef
);
1291 verify_noerr( err
);
1293 wxMacCarbonEvent
cEvent( evRef
) ;
1294 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1295 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1297 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1298 ReleaseEvent( evRef
) ;
1301 // send new focus event
1303 EventRef evRef
= NULL
;
1305 err
= MacCreateEvent(
1306 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1307 kEventAttributeUserEvent
, &evRef
);
1308 verify_noerr( err
);
1310 wxMacCarbonEvent
cEvent( evRef
) ;
1311 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1312 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1314 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1315 ReleaseEvent( evRef
) ;
1320 void wxWindowMac::DoCaptureMouse()
1322 wxApp::s_captureWindow
= this ;
1325 wxWindow
* wxWindowBase::GetCapture()
1327 return wxApp::s_captureWindow
;
1330 void wxWindowMac::DoReleaseMouse()
1332 wxApp::s_captureWindow
= NULL
;
1335 #if wxUSE_DRAG_AND_DROP
1337 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1339 if ( m_dropTarget
!= NULL
)
1340 delete m_dropTarget
;
1342 m_dropTarget
= pDropTarget
;
1343 if ( m_dropTarget
!= NULL
)
1351 // Old-style File Manager Drag & Drop
1352 void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept
))
1357 // Returns the size of the native control. In the case of the toplevel window
1358 // this is the content area root control
1360 void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x
),
1363 int& WXUNUSED(h
)) const
1365 wxFAIL_MSG( wxT("Not currently supported") ) ;
1368 // From a wx position / size calculate the appropriate size of the native control
1370 bool wxWindowMac::MacGetBoundsForControl(
1374 int& w
, int& h
, bool adjustOrigin
) const
1376 // the desired size, minus the border pixels gives the correct size of the control
1380 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1381 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1382 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1384 x
+= MacGetLeftBorderSize() ;
1385 y
+= MacGetTopBorderSize() ;
1386 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1387 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1390 AdjustForParentClientOrigin( x
, y
) ;
1392 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1393 if ( !GetParent()->IsTopLevel() )
1395 x
-= GetParent()->MacGetLeftBorderSize() ;
1396 y
-= GetParent()->MacGetTopBorderSize() ;
1402 // Get window size (not client size)
1403 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1406 m_peer
->GetRect( &bounds
) ;
1409 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1411 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1414 // get the position of the bounds of this window in client coordinates of its parent
1415 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1418 m_peer
->GetRect( &bounds
) ;
1420 int x1
= bounds
.left
;
1421 int y1
= bounds
.top
;
1423 // get the wx window position from the native one
1424 x1
-= MacGetLeftBorderSize() ;
1425 y1
-= MacGetTopBorderSize() ;
1427 if ( !IsTopLevel() )
1429 wxWindow
*parent
= GetParent();
1432 // we must first adjust it to be in window coordinates of the parent,
1433 // as otherwise it gets lost by the ClientAreaOrigin fix
1434 x1
+= parent
->MacGetLeftBorderSize() ;
1435 y1
+= parent
->MacGetTopBorderSize() ;
1437 // and now to client coordinates
1438 wxPoint
pt(parent
->GetClientAreaOrigin());
1450 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1452 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1453 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1455 Point localwhere
= { 0, 0 } ;
1462 wxMacGlobalToLocal( window
, &localwhere
) ;
1469 MacRootWindowToWindow( x
, y
) ;
1471 wxPoint origin
= GetClientAreaOrigin() ;
1478 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1480 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1481 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1483 wxPoint origin
= GetClientAreaOrigin() ;
1489 MacWindowToRootWindow( x
, y
) ;
1491 Point localwhere
= { 0, 0 };
1497 wxMacLocalToGlobal( window
, &localwhere
) ;
1505 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1507 wxPoint origin
= GetClientAreaOrigin() ;
1513 MacWindowToRootWindow( x
, y
) ;
1516 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1518 MacRootWindowToWindow( x
, y
) ;
1520 wxPoint origin
= GetClientAreaOrigin() ;
1527 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1536 if ( !IsTopLevel() )
1538 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1541 pt
.x
-= MacGetLeftBorderSize() ;
1542 pt
.y
-= MacGetTopBorderSize() ;
1543 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1553 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1562 MacWindowToRootWindow( &x1
, &y1
) ;
1570 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1579 if ( !IsTopLevel() )
1581 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1584 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1585 pt
.x
+= MacGetLeftBorderSize() ;
1586 pt
.y
+= MacGetTopBorderSize() ;
1596 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1605 MacRootWindowToWindow( &x1
, &y1
) ;
1613 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1615 RgnHandle rgn
= NewRgn() ;
1617 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1619 Rect structure
, content
;
1621 GetRegionBounds( rgn
, &content
) ;
1622 m_peer
->GetRect( &structure
) ;
1623 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1625 left
= content
.left
- structure
.left
;
1626 top
= content
.top
- structure
.top
;
1627 right
= structure
.right
- content
.right
;
1628 bottom
= structure
.bottom
- content
.bottom
;
1632 left
= top
= right
= bottom
= 0 ;
1638 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1640 wxSize sizeTotal
= size
;
1642 RgnHandle rgn
= NewRgn() ;
1643 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1645 Rect content
, structure
;
1646 GetRegionBounds( rgn
, &content
) ;
1647 m_peer
->GetRect( &structure
) ;
1649 // structure is in parent coordinates, but we only need width and height, so it's ok
1651 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1652 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1657 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1658 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1663 // Get size *available for subwindows* i.e. excluding menu bar etc.
1664 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1668 RgnHandle rgn
= NewRgn() ;
1670 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1671 GetRegionBounds( rgn
, &content
) ;
1673 m_peer
->GetRect( &content
) ;
1676 ww
= content
.right
- content
.left
;
1677 hh
= content
.bottom
- content
.top
;
1679 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1680 hh
-= m_hScrollBar
->GetSize().y
;
1682 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1683 ww
-= m_vScrollBar
->GetSize().x
;
1691 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1693 if (m_cursor
.IsSameAs(cursor
))
1698 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1703 if ( ! wxWindowBase::SetCursor( cursor
) )
1707 wxASSERT_MSG( m_cursor
.Ok(),
1708 wxT("cursor must be valid after call to the base version"));
1710 wxWindowMac
*mouseWin
= 0 ;
1712 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1713 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1715 ControlPartCode part
;
1716 ControlRef control
;
1718 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1720 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1725 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1727 // TODO: If we ever get a GetCurrentEvent... replacement
1728 // for the mouse position, use it...
1733 control
= wxMacFindControlUnderMouse( tlw
, pt
, window
, &part
) ;
1735 mouseWin
= wxFindControlFromMacControl( control
) ;
1737 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1739 QDSwapPort( savePort
, NULL
) ;
1743 if ( mouseWin
== this && !wxIsBusy() )
1744 m_cursor
.MacInstall() ;
1750 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1752 #ifndef __WXUNIVERSAL__
1753 menu
->SetInvokingWindow((wxWindow
*)this);
1756 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1758 wxPoint mouse
= wxGetMousePosition();
1764 ClientToScreen( &x
, &y
) ;
1767 menu
->MacBeforeDisplay( true ) ;
1768 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1769 if ( HiWord(menuResult
) != 0 )
1772 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1773 int id
= wxMacCommandToId( macid
);
1774 wxMenuItem
* item
= NULL
;
1776 item
= menu
->FindItem( id
, &realmenu
) ;
1779 if (item
->IsCheckable())
1780 item
->Check( !item
->IsChecked() ) ;
1782 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1786 menu
->MacAfterDisplay( true ) ;
1787 menu
->SetInvokingWindow( NULL
);
1791 // actually this shouldn't be called, because universal is having its own implementation
1797 // ----------------------------------------------------------------------------
1799 // ----------------------------------------------------------------------------
1803 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1805 wxWindowBase::DoSetToolTip(tooltip
);
1808 m_tooltip
->SetWindow(this);
1813 void wxWindowMac::MacInvalidateBorders()
1815 if ( m_peer
== NULL
)
1818 bool vis
= MacIsReallyShown() ;
1822 int outerBorder
= MacGetLeftBorderSize() ;
1823 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1826 if ( outerBorder
== 0 )
1829 // now we know that we have something to do at all
1831 // as the borders are drawn on the parent we have to properly invalidate all these areas
1832 RgnHandle updateInner
, updateOuter
;
1835 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1836 updateInner
= NewRgn() ;
1837 updateOuter
= NewRgn() ;
1839 m_peer
->GetRect( &rect
) ;
1840 RectRgn( updateInner
, &rect
) ;
1841 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1842 RectRgn( updateOuter
, &rect
) ;
1843 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1845 #ifdef __WXMAC_OSX__
1846 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1848 WindowRef tlw
= (WindowRef
) MacGetTopLevelWindowRef() ;
1850 InvalWindowRgn( tlw
, updateOuter
) ;
1853 DisposeRgn( updateOuter
) ;
1854 DisposeRgn( updateInner
) ;
1857 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1859 // this is never called for a toplevel window, so we know we have a parent
1860 int former_x
, former_y
, former_w
, former_h
;
1862 // Get true coordinates of former position
1863 DoGetPosition( &former_x
, &former_y
) ;
1864 DoGetSize( &former_w
, &former_h
) ;
1866 wxWindow
*parent
= GetParent();
1869 wxPoint
pt(parent
->GetClientAreaOrigin());
1874 int actualWidth
= width
;
1875 int actualHeight
= height
;
1879 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1880 actualWidth
= m_minWidth
;
1881 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1882 actualHeight
= m_minHeight
;
1883 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1884 actualWidth
= m_maxWidth
;
1885 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1886 actualHeight
= m_maxHeight
;
1888 bool doMove
= false, doResize
= false ;
1890 if ( actualX
!= former_x
|| actualY
!= former_y
)
1893 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1896 if ( doMove
|| doResize
)
1898 // as the borders are drawn outside the native control, we adjust now
1900 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1901 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1902 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1905 wxMacRectToNative( &bounds
, &r
) ;
1907 if ( !GetParent()->IsTopLevel() )
1908 wxMacWindowToNative( GetParent() , &r
) ;
1910 MacInvalidateBorders() ;
1912 m_cachedClippedRectValid
= false ;
1913 m_peer
->SetRect( &r
) ;
1915 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1917 MacInvalidateBorders() ;
1919 MacRepositionScrollBars() ;
1922 wxPoint
point(actualX
, actualY
);
1923 wxMoveEvent
event(point
, m_windowId
);
1924 event
.SetEventObject(this);
1925 GetEventHandler()->ProcessEvent(event
) ;
1930 MacRepositionScrollBars() ;
1931 wxSize
size(actualWidth
, actualHeight
);
1932 wxSizeEvent
event(size
, m_windowId
);
1933 event
.SetEventObject(this);
1934 GetEventHandler()->ProcessEvent(event
);
1939 wxSize
wxWindowMac::DoGetBestSize() const
1941 if ( m_macIsUserPane
|| IsTopLevel() )
1942 return wxWindowBase::DoGetBestSize() ;
1944 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1945 int bestWidth
, bestHeight
;
1947 m_peer
->GetBestRect( &bestsize
) ;
1948 if ( EmptyRect( &bestsize
) )
1953 bestsize
.bottom
= 16 ;
1955 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1957 bestsize
.bottom
= 16 ;
1960 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1962 bestsize
.bottom
= 24 ;
1967 // return wxWindowBase::DoGetBestSize() ;
1971 bestWidth
= bestsize
.right
- bestsize
.left
;
1972 bestHeight
= bestsize
.bottom
- bestsize
.top
;
1973 if ( bestHeight
< 10 )
1976 return wxSize(bestWidth
, bestHeight
);
1979 // set the size of the window: if the dimensions are positive, just use them,
1980 // but if any of them is equal to -1, it means that we must find the value for
1981 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1982 // which case -1 is a valid value for x and y)
1984 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1985 // the width/height to best suit our contents, otherwise we reuse the current
1987 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1989 // get the current size and position...
1990 int currentX
, currentY
;
1991 int currentW
, currentH
;
1993 GetPosition(¤tX
, ¤tY
);
1994 GetSize(¤tW
, ¤tH
);
1996 // ... and don't do anything (avoiding flicker) if it's already ok
1997 if ( x
== currentX
&& y
== currentY
&&
1998 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
2001 MacRepositionScrollBars() ; // we might have a real position shift
2006 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
2008 if ( x
== wxDefaultCoord
)
2010 if ( y
== wxDefaultCoord
)
2014 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2016 wxSize size
= wxDefaultSize
;
2017 if ( width
== wxDefaultCoord
)
2019 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2021 size
= DoGetBestSize();
2026 // just take the current one
2031 if ( height
== wxDefaultCoord
)
2033 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2035 if ( size
.x
== wxDefaultCoord
)
2036 size
= DoGetBestSize();
2037 // else: already called DoGetBestSize() above
2043 // just take the current one
2048 DoMoveWindow( x
, y
, width
, height
);
2051 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2053 RgnHandle rgn
= NewRgn() ;
2055 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2057 GetRegionBounds( rgn
, &content
) ;
2067 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2070 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2072 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2074 int currentclientwidth
, currentclientheight
;
2075 int currentwidth
, currentheight
;
2077 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2078 GetSize( ¤twidth
, ¤theight
) ;
2080 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2081 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2085 void wxWindowMac::SetLabel(const wxString
& title
)
2089 if ( m_peer
&& m_peer
->Ok() )
2090 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
2092 // do not trigger refreshes upon invisible and possible partly created objects
2093 if ( MacIsReallyShown() )
2097 wxString
wxWindowMac::GetLabel() const
2102 bool wxWindowMac::Show(bool show
)
2104 bool former
= MacIsReallyShown() ;
2105 if ( !wxWindowBase::Show(show
) )
2108 // TODO: use visibilityChanged Carbon Event for OSX
2110 m_peer
->SetVisibility( show
, true ) ;
2112 if ( former
!= MacIsReallyShown() )
2113 MacPropagateVisibilityChanged() ;
2118 void wxWindowMac::DoEnable(bool enable
)
2120 m_peer
->Enable( enable
) ;
2124 // status change propagations (will be not necessary for OSX later )
2127 void wxWindowMac::MacPropagateVisibilityChanged()
2129 #if !TARGET_API_MAC_OSX
2130 MacVisibilityChanged() ;
2133 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2136 child
= node
->GetData();
2137 if ( child
->IsShown() )
2138 child
->MacPropagateVisibilityChanged() ;
2140 node
= node
->GetNext();
2145 void wxWindowMac::OnEnabled(bool WXUNUSED(enabled
))
2147 #if !TARGET_API_MAC_OSX
2148 MacEnabledStateChanged() ;
2152 void wxWindowMac::MacPropagateHiliteChanged()
2154 #if !TARGET_API_MAC_OSX
2155 MacHiliteChanged() ;
2158 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2161 child
= node
->GetData();
2162 if (child
/* && child->IsEnabled() */)
2163 child
->MacPropagateHiliteChanged() ;
2165 node
= node
->GetNext();
2171 // status change notifications
2174 void wxWindowMac::MacVisibilityChanged()
2178 void wxWindowMac::MacHiliteChanged()
2182 void wxWindowMac::MacEnabledStateChanged()
2187 // status queries on the inherited window's state
2190 bool wxWindowMac::MacIsReallyShown()
2192 // only under OSX the visibility of the TLW is taken into account
2193 if ( m_isBeingDeleted
)
2196 #if TARGET_API_MAC_OSX
2197 if ( m_peer
&& m_peer
->Ok() )
2198 return m_peer
->IsVisible();
2201 wxWindow
* win
= this ;
2202 while ( win
->IsShown() )
2204 if ( win
->IsTopLevel() )
2207 win
= win
->GetParent() ;
2215 bool wxWindowMac::MacIsReallyEnabled()
2217 return m_peer
->IsEnabled() ;
2220 bool wxWindowMac::MacIsReallyHilited()
2222 return m_peer
->IsActive();
2225 void wxWindowMac::MacFlashInvalidAreas()
2227 #if TARGET_API_MAC_OSX
2228 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2232 int wxWindowMac::GetCharHeight() const
2234 wxClientDC
dc( (wxWindowMac
*)this ) ;
2236 return dc
.GetCharHeight() ;
2239 int wxWindowMac::GetCharWidth() const
2241 wxClientDC
dc( (wxWindowMac
*)this ) ;
2243 return dc
.GetCharWidth() ;
2246 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2247 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2249 const wxFont
*fontToUse
= theFont
;
2251 fontToUse
= &m_font
;
2253 wxClientDC
dc( (wxWindowMac
*) this ) ;
2254 wxCoord lx
,ly
,ld
,le
;
2255 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2256 if ( externalLeading
)
2257 *externalLeading
= le
;
2267 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2268 * we always intersect with the entire window, not only with the client area
2271 void wxWindowMac::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
2273 if ( m_peer
== NULL
)
2276 if ( !MacIsReallyShown() )
2283 wxMacRectToNative( rect
, &r
) ;
2284 m_peer
->SetNeedsDisplay( &r
) ;
2288 m_peer
->SetNeedsDisplay() ;
2292 void wxWindowMac::Freeze()
2294 #if TARGET_API_MAC_OSX
2295 if ( !m_frozenness
++ )
2297 if ( m_peer
&& m_peer
->Ok() )
2298 m_peer
->SetDrawingEnabled( false ) ;
2303 void wxWindowMac::Thaw()
2305 #if TARGET_API_MAC_OSX
2306 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2308 if ( !--m_frozenness
)
2310 if ( m_peer
&& m_peer
->Ok() )
2312 m_peer
->SetDrawingEnabled( true ) ;
2313 m_peer
->InvalidateWithChildren() ;
2319 bool wxWindowMac::IsFrozen() const
2321 return m_frozenness
!= 0;
2324 wxWindowMac
*wxGetActiveWindow()
2326 // actually this is a windows-only concept
2330 // Coordinates relative to the window
2331 void wxWindowMac::WarpPointer(int WXUNUSED(x_pos
), int WXUNUSED(y_pos
))
2333 // We really don't move the mouse programmatically under Mac.
2336 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2338 if ( MacGetTopLevelWindow() == NULL
)
2341 #if TARGET_API_MAC_OSX
2342 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
2343 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2350 event
.GetDC()->Clear() ;
2354 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2359 int wxWindowMac::GetScrollPos(int orient
) const
2361 if ( orient
== wxHORIZONTAL
)
2364 return m_hScrollBar
->GetThumbPosition() ;
2369 return m_vScrollBar
->GetThumbPosition() ;
2375 // This now returns the whole range, not just the number
2376 // of positions that we can scroll.
2377 int wxWindowMac::GetScrollRange(int orient
) const
2379 if ( orient
== wxHORIZONTAL
)
2382 return m_hScrollBar
->GetRange() ;
2387 return m_vScrollBar
->GetRange() ;
2393 int wxWindowMac::GetScrollThumb(int orient
) const
2395 if ( orient
== wxHORIZONTAL
)
2398 return m_hScrollBar
->GetThumbSize() ;
2403 return m_vScrollBar
->GetThumbSize() ;
2409 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
2411 if ( orient
== wxHORIZONTAL
)
2414 m_hScrollBar
->SetThumbPosition( pos
) ;
2419 m_vScrollBar
->SetThumbPosition( pos
) ;
2424 wxWindowMac::AlwaysShowScrollbars(bool hflag
, bool vflag
)
2426 bool needVisibilityUpdate
= false;
2428 if ( m_hScrollBarAlwaysShown
!= hflag
)
2430 m_hScrollBarAlwaysShown
= hflag
;
2431 needVisibilityUpdate
= true;
2434 if ( m_vScrollBarAlwaysShown
!= vflag
)
2436 m_vScrollBarAlwaysShown
= vflag
;
2437 needVisibilityUpdate
= true;
2440 if ( needVisibilityUpdate
)
2441 DoUpdateScrollbarVisibility();
2445 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2446 // our own window origin is at leftOrigin/rightOrigin
2449 void wxWindowMac::MacPaintGrowBox()
2454 #if wxMAC_USE_CORE_GRAPHICS
2455 if ( MacHasScrollBarCorner() )
2459 CGContextRef cgContext
= (CGContextRef
) MacGetCGContextRef() ;
2460 wxASSERT( cgContext
) ;
2462 m_peer
->GetRect( &rect
) ;
2464 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2465 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2466 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2467 CGContextSaveGState( cgContext
);
2469 if ( m_macBackgroundBrush
.Ok() && m_macBackgroundBrush
.GetStyle() != wxTRANSPARENT
)
2471 wxMacCoreGraphicsColour
bkgnd( m_macBackgroundBrush
) ;
2472 bkgnd
.Apply( cgContext
);
2476 CGContextSetRGBFillColor( cgContext
, 1.0, 1.0 , 1.0 , 1.0 );
2478 CGContextFillRect( cgContext
, cgrect
);
2479 CGContextRestoreGState( cgContext
);
2484 void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin
) , int WXUNUSED(rightOrigin
) )
2490 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2492 // back to the surrounding frame rectangle
2493 m_peer
->GetRect( &rect
) ;
2494 InsetRect( &rect
, -1 , -1 ) ;
2496 #if wxMAC_USE_CORE_GRAPHICS
2498 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2499 rect
.bottom
- rect
.top
) ;
2501 HIThemeFrameDrawInfo info
;
2502 memset( &info
, 0 , sizeof(info
) ) ;
2506 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2507 info
.isFocused
= hasFocus
;
2509 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2510 wxASSERT( cgContext
) ;
2512 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2514 info
.kind
= kHIThemeFrameTextFieldSquare
;
2515 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2517 else if ( HasFlag(wxSIMPLE_BORDER
) )
2519 info
.kind
= kHIThemeFrameListBox
;
2520 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2522 else if ( hasFocus
)
2524 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2526 #if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
2527 m_peer
->GetRect( &rect
) ;
2528 if ( MacHasScrollBarCorner() )
2530 int variant
= (m_hScrollBar
== NULL
? m_vScrollBar
: m_hScrollBar
) ->GetWindowVariant();
2531 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2532 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2533 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2534 HIThemeGrowBoxDrawInfo info
;
2535 memset( &info
, 0, sizeof(info
) ) ;
2537 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2538 info
.kind
= kHIThemeGrowBoxKindNone
;
2539 // contrary to the docs ...SizeSmall does not work
2540 info
.size
= kHIThemeGrowBoxSizeNormal
;
2541 info
.direction
= 0 ;
2542 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2548 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2552 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2553 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2556 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2557 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2558 else if ( HasFlag(wxSIMPLE_BORDER
) )
2559 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2562 DrawThemeFocusRect( &rect
, true ) ;
2565 if ( hasBothScrollbars ) // hasBothScrollbars is not declared
2567 // GetThemeStandaloneGrowBoxBounds
2568 // DrawThemeStandaloneNoGrowBox
2575 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2577 if ( child
== m_hScrollBar
)
2578 m_hScrollBar
= NULL
;
2579 if ( child
== m_vScrollBar
)
2580 m_vScrollBar
= NULL
;
2582 wxWindowBase::RemoveChild( child
) ;
2585 void wxWindowMac::DoUpdateScrollbarVisibility()
2587 bool triggerSizeEvent
= false;
2591 bool showHScrollBar
= m_hScrollBarAlwaysShown
|| m_hScrollBar
->IsNeeded();
2593 if ( m_hScrollBar
->IsShown() != showHScrollBar
)
2595 m_hScrollBar
->Show( showHScrollBar
);
2596 triggerSizeEvent
= true;
2602 bool showVScrollBar
= m_vScrollBarAlwaysShown
|| m_vScrollBar
->IsNeeded();
2604 if ( m_vScrollBar
->IsShown() != showVScrollBar
)
2606 m_vScrollBar
->Show( showVScrollBar
) ;
2607 triggerSizeEvent
= true;
2611 MacRepositionScrollBars() ;
2612 if ( triggerSizeEvent
)
2614 wxSizeEvent
event(GetSize(), m_windowId
);
2615 event
.SetEventObject(this);
2616 GetEventHandler()->ProcessEvent(event
);
2620 // New function that will replace some of the above.
2621 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumb
,
2622 int range
, bool refresh
)
2624 if ( orient
== wxHORIZONTAL
&& m_hScrollBar
)
2625 m_hScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2626 else if ( orient
== wxVERTICAL
&& m_vScrollBar
)
2627 m_vScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2629 DoUpdateScrollbarVisibility();
2632 // Does a physical scroll
2633 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2635 if ( dx
== 0 && dy
== 0 )
2638 int width
, height
;
2639 GetClientSize( &width
, &height
) ;
2642 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2643 // area is scrolled, this does not occur if width and height are 2 pixels less,
2644 // TODO: write optimal workaround
2645 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2647 scrollrect
.Intersect( *rect
) ;
2649 if ( m_peer
->GetNeedsDisplay() )
2651 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2652 // in case there is already a pending redraw on that area
2653 // either immediate redraw or full invalidate
2655 // is the better overall solution, as it does not slow down scrolling
2656 m_peer
->SetNeedsDisplay() ;
2658 // this would be the preferred version for fast drawing controls
2659 HIViewRender(m_peer
->GetControlRef()) ;
2663 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2664 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2665 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2668 // this would be the preferred version for fast drawing controls
2669 HIViewRender(m_peer
->GetControlRef()) ;
2675 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2677 child
= node
->GetData();
2680 if (child
== m_vScrollBar
)
2682 if (child
== m_hScrollBar
)
2684 if (child
->IsTopLevel())
2687 child
->GetPosition( &x
, &y
);
2688 child
->GetSize( &w
, &h
);
2691 wxRect
rc( x
, y
, w
, h
);
2692 if (rect
->Intersects( rc
))
2693 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2697 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2702 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2704 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2706 wxScrollWinEvent wevent
;
2707 wevent
.SetPosition(event
.GetPosition());
2708 wevent
.SetOrientation(event
.GetOrientation());
2709 wevent
.SetEventObject(this);
2711 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2712 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2713 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2714 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2715 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2716 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2717 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2718 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2719 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2720 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2721 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2722 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2723 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2724 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2725 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2726 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2728 GetEventHandler()->ProcessEvent(wevent
);
2732 // Get the window with the focus
2733 wxWindowMac
*wxWindowBase::DoFindFocus()
2735 ControlRef control
;
2736 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2737 return wxFindControlFromMacControl( control
) ;
2740 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2742 // panel wants to track the window which was the last to have focus in it,
2743 // so we want to set ourselves as the window which last had focus
2745 // notice that it's also important to do it upwards the tree because
2746 // otherwise when the top level panel gets focus, it won't set it back to
2747 // us, but to some other sibling
2749 // CS: don't know if this is still needed:
2750 //wxChildFocusEvent eventFocus(this);
2751 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2753 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2755 #if wxMAC_USE_CORE_GRAPHICS
2756 GetParent()->Refresh() ;
2758 wxMacWindowStateSaver
sv( this ) ;
2761 m_peer
->GetRect( &rect
) ;
2762 // auf den umgebenden Rahmen zurチᅡ゚ck
2763 InsetRect( &rect
, -1 , -1 ) ;
2765 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2769 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2771 rect
.right
+= pt
.x
;
2773 rect
.bottom
+= pt
.y
;
2776 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2777 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2778 if ( !bIsFocusEvent
)
2780 // as this erases part of the frame we have to redraw borders
2781 // and because our z-ordering is not always correct (staticboxes)
2782 // we have to invalidate things, we cannot simple redraw
2783 MacInvalidateBorders() ;
2791 void wxWindowMac::OnInternalIdle()
2793 // This calls the UI-update mechanism (querying windows for
2794 // menu/toolbar/control state information)
2795 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
2796 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2799 // Raise the window to the top of the Z order
2800 void wxWindowMac::Raise()
2802 m_peer
->SetZOrder( true , NULL
) ;
2805 // Lower the window to the bottom of the Z order
2806 void wxWindowMac::Lower()
2808 m_peer
->SetZOrder( false , NULL
) ;
2811 // static wxWindow *gs_lastWhich = NULL;
2813 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2815 // first trigger a set cursor event
2817 wxPoint clientorigin
= GetClientAreaOrigin() ;
2818 wxSize clientsize
= GetClientSize() ;
2820 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2822 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2824 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2825 if ( processedEvtSetCursor
&& event
.HasCursor() )
2827 cursor
= event
.GetCursor() ;
2831 // the test for processedEvtSetCursor is here to prevent using m_cursor
2832 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2833 // it - this is a way to say that our cursor shouldn't be used for this
2835 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2838 if ( !wxIsBusy() && !GetParent() )
2839 cursor
= *wxSTANDARD_CURSOR
;
2843 cursor
.MacInstall() ;
2846 return cursor
.Ok() ;
2849 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&WXUNUSED(pt
) )
2853 return m_tooltip
->GetTip() ;
2856 return wxEmptyString
;
2859 void wxWindowMac::ClearBackground()
2865 void wxWindowMac::Update()
2867 #if TARGET_API_MAC_OSX
2868 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2870 top
->MacPerformUpdates() ;
2872 ::Draw1Control( m_peer
->GetControlRef() ) ;
2876 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2878 wxTopLevelWindowMac
* win
= NULL
;
2879 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2881 win
= wxFindWinFromMacWindow( window
) ;
2886 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2888 MacUpdateClippedRects() ;
2890 return m_cachedClippedClientRect
;
2893 const wxRect
& wxWindowMac::MacGetClippedRect() const
2895 MacUpdateClippedRects() ;
2897 return m_cachedClippedRect
;
2900 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2902 MacUpdateClippedRects() ;
2904 return m_cachedClippedRectWithOuterStructure
;
2907 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2909 static wxRegion emptyrgn
;
2911 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2913 MacUpdateClippedRects() ;
2914 if ( includeOuterStructures
)
2915 return m_cachedClippedRegionWithOuterStructure
;
2917 return m_cachedClippedRegion
;
2925 void wxWindowMac::MacUpdateClippedRects() const
2927 if ( m_cachedClippedRectValid
)
2930 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2931 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2932 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2933 // to add focus borders everywhere
2935 Rect r
, rIncludingOuterStructures
;
2937 m_peer
->GetRect( &r
) ;
2938 r
.left
-= MacGetLeftBorderSize() ;
2939 r
.top
-= MacGetTopBorderSize() ;
2940 r
.bottom
+= MacGetBottomBorderSize() ;
2941 r
.right
+= MacGetRightBorderSize() ;
2948 rIncludingOuterStructures
= r
;
2949 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2951 wxRect cl
= GetClientRect() ;
2952 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2956 const wxWindow
* child
= this ;
2957 const wxWindow
* parent
= NULL
;
2959 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2961 if ( parent
->MacIsChildOfClientArea(child
) )
2963 size
= parent
->GetClientSize() ;
2964 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2970 // this will be true for scrollbars, toolbars etc.
2971 size
= parent
->GetSize() ;
2972 y
= parent
->MacGetTopBorderSize() ;
2973 x
= parent
->MacGetLeftBorderSize() ;
2974 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2975 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2978 parent
->MacWindowToRootWindow( &x
, &y
) ;
2979 MacRootWindowToWindow( &x
, &y
) ;
2981 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2983 // the wxwindow and client rects will always be clipped
2984 SectRect( &r
, &rparent
, &r
) ;
2985 SectRect( &rClient
, &rparent
, &rClient
) ;
2987 // the structure only at 'hard' borders
2988 if ( parent
->MacClipChildren() ||
2989 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2991 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2997 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
2998 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
2999 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
3000 m_cachedClippedRectWithOuterStructure
= wxRect(
3001 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
3002 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
3003 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
3005 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
3006 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
3007 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
3009 m_cachedClippedRectValid
= true ;
3013 This function must not change the updatergn !
3015 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
3017 bool handled
= false ;
3019 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
3020 GetRegionBounds( updatergn
, &updatebounds
) ;
3022 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3024 if ( !EmptyRgn(updatergn
) )
3026 RgnHandle newupdate
= NewRgn() ;
3027 wxSize point
= GetClientSize() ;
3028 wxPoint origin
= GetClientAreaOrigin() ;
3029 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
3030 SectRgn( newupdate
, updatergn
, newupdate
) ;
3032 // first send an erase event to the entire update area
3034 // for the toplevel window this really is the entire area
3035 // for all the others only their client area, otherwise they
3036 // might be drawing with full alpha and eg put blue into
3037 // the grow-box area of a scrolled window (scroll sample)
3038 wxDC
* dc
= new wxWindowDC(this);
3040 dc
->SetClippingRegion(wxRegion(updatergn
));
3042 dc
->SetClippingRegion(wxRegion(newupdate
));
3044 wxEraseEvent
eevent( GetId(), dc
);
3045 eevent
.SetEventObject( this );
3046 GetEventHandler()->ProcessEvent( eevent
);
3052 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3053 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3054 m_updateRegion
= newupdate
;
3055 DisposeRgn( newupdate
) ;
3057 if ( !m_updateRegion
.Empty() )
3059 // paint the window itself
3062 event
.SetTimestamp(time
);
3063 event
.SetEventObject(this);
3064 GetEventHandler()->ProcessEvent(event
);
3068 // now we cannot rely on having its borders drawn by a window itself, as it does not
3069 // get the updateRgn wide enough to always do so, so we do it from the parent
3070 // this would also be the place to draw any custom backgrounds for native controls
3071 // in Composited windowing
3072 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3076 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3078 child
= node
->GetData();
3081 if (child
== m_vScrollBar
)
3083 if (child
== m_hScrollBar
)
3085 if (child
->IsTopLevel())
3087 if (!child
->IsShown())
3090 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3092 child
->GetPosition( &x
, &y
);
3093 child
->GetSize( &w
, &h
);
3094 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3095 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3096 InsetRect( &childRect
, -10 , -10) ;
3098 if ( RectInRgn( &childRect
, updatergn
) )
3100 // paint custom borders
3101 wxNcPaintEvent
eventNc( child
->GetId() );
3102 eventNc
.SetEventObject( child
);
3103 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3105 #if wxMAC_USE_CORE_GRAPHICS
3106 child
->MacPaintBorders(0, 0) ;
3109 wxWindowDC
dc(this) ;
3110 dc
.SetClippingRegion(wxRegion(updatergn
));
3111 wxMacPortSetter
helper(&dc
) ;
3112 child
->MacPaintBorders(0, 0) ;
3124 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3126 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3130 if ( iter
->IsTopLevel() )
3132 wxTopLevelWindow
* toplevel
= wxDynamicCast(iter
,wxTopLevelWindow
);
3134 return toplevel
->MacGetWindowRef();
3136 wxPopupWindow
* popupwin
= wxDynamicCast(iter
,wxPopupWindow
);
3138 return popupwin
->MacGetPopupWindowRef();
3141 iter
= iter
->GetParent() ;
3147 bool wxWindowMac::MacHasScrollBarCorner() const
3149 /* Returns whether the scroll bars in a wxScrolledWindow should be
3150 * shortened. Scroll bars should be shortened if either:
3152 * - both scroll bars are visible, or
3154 * - there is a resize box in the parent frame's corner and this
3155 * window shares the bottom and right edge with the parent
3159 if ( m_hScrollBar
== NULL
&& m_vScrollBar
== NULL
)
3162 if ( ( m_hScrollBar
&& m_hScrollBar
->IsShown() )
3163 && ( m_vScrollBar
&& m_vScrollBar
->IsShown() ) )
3165 // Both scroll bars visible
3170 wxPoint thisWindowBottomRight
= GetScreenRect().GetBottomRight();
3172 for ( const wxWindow
*win
= this; win
; win
= win
->GetParent() )
3174 const wxFrame
*frame
= wxDynamicCast( win
, wxFrame
) ;
3177 if ( frame
->GetWindowStyleFlag() & wxRESIZE_BORDER
)
3179 // Parent frame has resize handle
3180 wxPoint frameBottomRight
= frame
->GetScreenRect().GetBottomRight();
3182 // Note: allow for some wiggle room here as wxMac's
3183 // window rect calculations seem to be imprecise
3184 if ( abs( thisWindowBottomRight
.x
- frameBottomRight
.x
) <= 2
3185 && abs( thisWindowBottomRight
.y
- frameBottomRight
.y
) <= 2 )
3187 // Parent frame has resize handle and shares
3188 // right bottom corner
3193 // Parent frame has resize handle but doesn't
3194 // share right bottom corner
3200 // Parent frame doesn't have resize handle
3206 // No parent frame found
3211 void wxWindowMac::MacCreateScrollBars( long style
)
3213 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3215 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3217 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3218 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3220 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3223 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1: 0 ;
3225 GetClientSize( &width
, &height
) ;
3227 wxPoint
vPoint(width
- scrlsize
, 0) ;
3228 wxSize
vSize(scrlsize
, height
- adjust
) ;
3229 wxPoint
hPoint(0, height
- scrlsize
) ;
3230 wxSize
hSize(width
- adjust
, scrlsize
) ;
3232 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
3233 if ( style
& wxVSCROLL
)
3235 m_vScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3236 m_vScrollBar
->SetMinSize( wxDefaultSize
);
3239 if ( style
& wxHSCROLL
)
3241 m_hScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3242 m_hScrollBar
->SetMinSize( wxDefaultSize
);
3246 // because the create does not take into account the client area origin
3247 // we might have a real position shift
3248 MacRepositionScrollBars() ;
3251 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3253 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3258 void wxWindowMac::MacRepositionScrollBars()
3260 if ( !m_hScrollBar
&& !m_vScrollBar
)
3263 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3264 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1 : 0 ;
3266 // get real client area
3268 GetSize( &width
, &height
);
3270 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3271 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3273 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3274 wxSize
vSize( scrlsize
, height
- adjust
) ;
3275 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3276 wxSize
hSize( width
- adjust
, scrlsize
) ;
3279 int x
= 0, y
= 0, w
, h
;
3280 GetSize( &w
, &h
) ;
3282 MacClientToRootWindow( &x
, &y
) ;
3283 MacClientToRootWindow( &w
, &h
) ;
3285 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3287 int totW
= 10000 , totH
= 10000;
3290 if ( iter
->IsTopLevel() )
3292 iter
->GetSize( &totW
, &totH
) ;
3296 iter
= iter
->GetParent() ;
3310 if ( w
- x
>= totW
)
3315 if ( h
- y
>= totH
)
3323 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3325 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3328 bool wxWindowMac::AcceptsFocus() const
3330 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3333 void wxWindowMac::MacSuperChangedPosition()
3335 // only window-absolute structures have to be moved i.e. controls
3337 m_cachedClippedRectValid
= false ;
3340 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3343 child
= node
->GetData();
3344 child
->MacSuperChangedPosition() ;
3346 node
= node
->GetNext();
3350 void wxWindowMac::MacTopLevelWindowChangedPosition()
3352 // only screen-absolute structures have to be moved i.e. glcanvas
3355 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3358 child
= node
->GetData();
3359 child
->MacTopLevelWindowChangedPosition() ;
3361 node
= node
->GetNext();
3365 long wxWindowMac::MacGetLeftBorderSize() const
3372 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3374 // this metric is only the 'outset' outside the simple frame rect
3375 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3378 else if (HasFlag(wxSIMPLE_BORDER
))
3380 // this metric is only the 'outset' outside the simple frame rect
3381 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3388 long wxWindowMac::MacGetRightBorderSize() const
3390 // they are all symmetric in mac themes
3391 return MacGetLeftBorderSize() ;
3394 long wxWindowMac::MacGetTopBorderSize() const
3396 // they are all symmetric in mac themes
3397 return MacGetLeftBorderSize() ;
3400 long wxWindowMac::MacGetBottomBorderSize() const
3402 // they are all symmetric in mac themes
3403 return MacGetLeftBorderSize() ;
3406 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3408 return style
& ~wxBORDER_MASK
;
3411 // Find the wxWindowMac at the current mouse position, returning the mouse
3413 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3415 pt
= wxGetMousePosition();
3416 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3421 // Get the current mouse position.
3422 wxPoint
wxGetMousePosition()
3426 wxGetMousePosition( &x
, &y
);
3428 return wxPoint(x
, y
);
3431 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3433 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3435 // copied from wxGTK : CS
3436 // VZ: shouldn't we move this to base class then?
3438 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3441 // (a) it's a command event and so is propagated to the parent
3442 // (b) under MSW it can be generated from kbd too
3443 // (c) it uses screen coords (because of (a))
3444 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3446 this->ClientToScreen(event
.GetPosition()));
3447 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3456 void wxWindowMac::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
3458 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3459 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3460 CallNextEventHandler(
3461 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3462 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3465 void wxWindowMac::MacHandleControlClick(WXWidget
WXUNUSED(control
),
3466 wxInt16
WXUNUSED(controlpart
),
3467 bool WXUNUSED(mouseStillDown
))
3471 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3475 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3476 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3481 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3483 return eventNotHandledErr
;
3486 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3488 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3489 if ( !wxWindowBase::Reparent(newParent
) )
3492 // copied from MacPostControlCreate
3493 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3495 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3497 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3502 bool wxWindowMac::SetTransparent(wxByte alpha
)
3504 #if wxMAC_USE_CORE_GRAPHICS
3505 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3507 if ( alpha
!= m_macAlpha
)
3509 m_macAlpha
= alpha
;
3519 bool wxWindowMac::CanSetTransparent()
3521 #if wxMAC_USE_CORE_GRAPHICS
3528 wxByte
wxWindowMac::GetTransparent() const