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
);
332 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
336 if ( thisWindow
->MacIsUserPane() )
339 if ( controlPart
== kControlFocusNoPart
)
342 if ( thisWindow
->GetCaret() )
343 thisWindow
->GetCaret()->OnKillFocus();
346 static bool inKillFocusEvent
= false ;
348 if ( !inKillFocusEvent
)
350 inKillFocusEvent
= true ;
351 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
352 event
.SetEventObject(thisWindow
);
353 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
354 inKillFocusEvent
= false ;
359 // panel wants to track the window which was the last to have focus in it
360 wxChildFocusEvent
eventFocus(thisWindow
);
361 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
364 if ( thisWindow
->GetCaret() )
365 thisWindow
->GetCaret()->OnSetFocus();
368 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
369 event
.SetEventObject(thisWindow
);
370 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
375 case kEventControlHit
:
376 result
= thisWindow
->MacControlHit( handler
, event
) ;
379 case kEventControlGetClickActivation
:
381 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
382 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
383 if ( !IsWindowActive(owner
) )
385 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
398 static pascal OSStatus
399 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
403 OSStatus result
= eventNotHandledErr
;
405 wxMacCarbonEvent
cEvent( event
) ;
407 ControlRef controlRef
;
408 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
409 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
410 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
412 switch ( GetEventKind( event
) )
414 case kEventServiceGetTypes
:
418 textCtrl
->GetSelection( &from
, &to
) ;
420 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
422 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
423 if ( textCtrl
->IsEditable() )
424 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
426 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
427 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
429 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
433 CFArrayAppendValue(copyTypes
, typestring
) ;
435 CFArrayAppendValue(pasteTypes
, typestring
) ;
437 CFRelease( typestring
) ;
445 case kEventServiceCopy
:
450 textCtrl
->GetSelection( &from
, &to
) ;
451 wxString val
= textCtrl
->GetValue() ;
452 val
= val
.Mid( from
, to
- from
) ;
453 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
454 verify_noerr( PasteboardClear( pasteboard
) ) ;
455 PasteboardSynchronize( pasteboard
);
456 // TODO add proper conversion
457 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
458 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
464 case kEventServicePaste
:
467 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
468 PasteboardSynchronize( pasteboard
);
470 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
471 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
473 PasteboardItemID itemID
;
474 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
476 CFDataRef flavorData
= NULL
;
477 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
479 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
480 char *content
= new char[flavorDataSize
+1] ;
481 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
482 content
[flavorDataSize
]=0;
483 CFRelease( flavorData
);
485 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
487 textCtrl
->WriteText( wxString( content
) ) ;
505 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
507 OSStatus result
= eventNotHandledErr
;
508 wxWindowMac
* focus
= (wxWindowMac
*) data
;
510 wchar_t* uniChars
= NULL
;
511 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
513 UniChar
* charBuf
= NULL
;
514 ByteCount dataSize
= 0 ;
517 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
519 numChars
= dataSize
/ sizeof( UniChar
) + 1;
522 if ( (size_t) numChars
* 2 > sizeof(buf
) )
523 charBuf
= new UniChar
[ numChars
] ;
527 uniChars
= new wchar_t[ numChars
] ;
528 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
529 charBuf
[ numChars
- 1 ] = 0;
530 #if SIZEOF_WCHAR_T == 2
531 uniChars
= (wchar_t*) charBuf
;
532 /* 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...)
534 // the resulting string will never have more chars than the utf16 version, so this is safe
535 wxMBConvUTF16 converter
;
536 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
540 switch ( GetEventKind( event
) )
542 case kEventTextInputUpdateActiveInputArea
:
544 // An IME input event may return several characters, but we need to send one char at a time to
546 for (int pos
=0 ; pos
< numChars
; pos
++)
548 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
549 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
550 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
552 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
554 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
555 multiple times to update the active range during inline input, so this handler will often receive
556 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
557 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
558 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
559 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
560 should add new event types to support advanced text input. For now, I would keep things as they are.
562 However, the code that was being used caused additional problems:
563 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
564 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
565 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
566 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
567 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
568 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
569 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
570 overlap with Unicode within the (7-bit) ASCII range.
571 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
572 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
573 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
574 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
575 I don't have time to look into that right now.
578 if ( wxTheApp
->MacSendCharEvent(
579 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
584 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
588 case kEventTextInputUnicodeForKeyEvent
:
590 UInt32 keyCode
, modifiers
;
593 unsigned char charCode
;
595 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
596 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
597 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
598 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
599 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
601 UInt32 message
= (keyCode
<< 8) + charCode
;
603 // An IME input event may return several characters, but we need to send one char at a time to
605 for (int pos
=0 ; pos
< numChars
; pos
++)
607 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
608 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
609 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
611 if ( wxTheApp
->MacSendCharEvent(
612 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
617 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
626 if ( charBuf
!= buf
)
632 static pascal OSStatus
633 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
637 OSStatus result
= eventNotHandledErr
;
638 wxWindowMac
* focus
= (wxWindowMac
*) data
;
642 wxMacCarbonEvent
cEvent( event
) ;
643 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
645 wxMenuItem
* item
= NULL
;
646 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
647 int id
= wxMacCommandToId( command
.commandID
) ;
651 wxASSERT( itemMenu
!= NULL
) ;
653 switch ( cEvent
.GetKind() )
655 case kEventProcessCommand
:
656 result
= itemMenu
->MacHandleCommandProcess( item
, id
, focus
);
659 case kEventCommandUpdateStatus
:
660 result
= itemMenu
->MacHandleCommandUpdateStatus( item
, id
, focus
);
670 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
672 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
673 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
674 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
675 OSStatus result
= eventNotHandledErr
;
677 switch ( GetEventClass( event
) )
679 case kEventClassCommand
:
680 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
683 case kEventClassControl
:
684 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
687 case kEventClassService
:
688 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
691 case kEventClassTextInput
:
692 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
699 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
704 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
706 #if !TARGET_API_MAC_OSX
708 // ---------------------------------------------------------------------------
709 // UserPane events for non OSX builds
710 // ---------------------------------------------------------------------------
712 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
714 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
716 win
->MacControlUserPaneDrawProc(part
) ;
718 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
720 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
722 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
724 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
726 return kControlNoPart
;
728 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
730 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
732 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
734 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
736 return kControlNoPart
;
738 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
740 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
742 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
744 win
->MacControlUserPaneIdleProc() ;
746 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
748 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
750 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
752 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
754 return kControlNoPart
;
756 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
758 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
760 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
762 win
->MacControlUserPaneActivateProc(activating
) ;
764 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
766 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
768 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
770 return win
->MacControlUserPaneFocusProc(action
) ;
772 return kControlNoPart
;
774 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
776 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
778 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
780 win
->MacControlUserPaneBackgroundProc(info
) ;
782 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
784 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
787 RgnHandle rgn
= NewRgn() ;
789 MacWindowToRootWindow( &x
, &y
) ;
790 OffsetRgn( rgn
, -x
, -y
) ;
791 wxMacWindowStateSaver
sv( this ) ;
792 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
793 MacDoRedraw( rgn
, 0 ) ;
797 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
799 return kControlNoPart
;
802 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
804 return kControlNoPart
;
807 void wxWindowMac::MacControlUserPaneIdleProc()
811 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
813 return kControlNoPart
;
816 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
820 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
822 if ( AcceptsFocus() )
825 return kControlNoPart
;
828 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
834 // ---------------------------------------------------------------------------
835 // Scrollbar Tracking for all
836 // ---------------------------------------------------------------------------
838 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
839 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
843 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
845 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
848 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
850 // ===========================================================================
852 // ===========================================================================
854 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
856 static MacControlMap wxWinMacControlList
;
858 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
860 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
862 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
865 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
867 // adding NULL ControlRef is (first) surely a result of an error and
868 // (secondly) breaks native event processing
869 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
871 wxWinMacControlList
[inControl
] = control
;
874 void wxRemoveMacControlAssociation(wxWindow
*control
)
876 // iterate over all the elements in the class
877 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
878 // we should go on...
884 MacControlMap::iterator it
;
885 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
887 if ( it
->second
== control
)
889 wxWinMacControlList
.erase(it
);
897 // ----------------------------------------------------------------------------
898 // constructors and such
899 // ----------------------------------------------------------------------------
901 wxWindowMac::wxWindowMac()
906 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
911 const wxString
& name
)
914 Create(parent
, id
, pos
, size
, style
, name
);
917 void wxWindowMac::Init()
923 #if wxMAC_USE_CORE_GRAPHICS
924 m_cgContextRef
= NULL
;
927 // as all windows are created with WS_VISIBLE style...
930 m_hScrollBar
= NULL
;
931 m_vScrollBar
= NULL
;
932 m_hScrollBarAlwaysShown
= false;
933 m_vScrollBarAlwaysShown
= false;
935 m_macBackgroundBrush
= wxNullBrush
;
937 m_macIsUserPane
= true;
938 m_clipChildren
= false ;
939 m_cachedClippedRectValid
= false ;
941 // we need a valid font for the encodings
942 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
945 wxWindowMac::~wxWindowMac()
949 m_isBeingDeleted
= true;
951 MacInvalidateBorders() ;
953 #ifndef __WXUNIVERSAL__
954 // VS: make sure there's no wxFrame with last focus set to us:
955 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
957 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
960 if ( frame
->GetLastFocus() == this )
961 frame
->SetLastFocus((wxWindow
*)NULL
);
967 // destroy children before destroying this window itself
970 // wxRemoveMacControlAssociation( this ) ;
971 // If we delete an item, we should initialize the parent panel,
972 // because it could now be invalid.
973 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
976 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
977 tlw
->SetDefaultItem(NULL
);
980 if ( m_peer
&& m_peer
->Ok() )
982 // in case the callback might be called during destruction
983 wxRemoveMacControlAssociation( this) ;
984 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
985 // we currently are not using this hook
986 // ::SetControlColorProc( *m_peer , NULL ) ;
990 if ( g_MacLastWindow
== this )
991 g_MacLastWindow
= NULL
;
993 #ifndef __WXUNIVERSAL__
994 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( (wxWindow
*)this ) , wxFrame
) ;
997 if ( frame
->GetLastFocus() == this )
998 frame
->SetLastFocus( NULL
) ;
1002 // delete our drop target if we've got one
1003 #if wxUSE_DRAG_AND_DROP
1004 if ( m_dropTarget
!= NULL
)
1006 delete m_dropTarget
;
1007 m_dropTarget
= NULL
;
1014 WXWidget
wxWindowMac::GetHandle() const
1016 return (WXWidget
) m_peer
->GetControlRef() ;
1019 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1021 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1022 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1023 GetEventTypeCount(eventList
), eventList
, this,
1024 (EventHandlerRef
*)&m_macControlEventHandler
);
1026 #if !TARGET_API_MAC_OSX
1027 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1029 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1030 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1031 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1032 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1033 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1034 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1035 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1036 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1042 bool wxWindowMac::Create(wxWindowMac
*parent
,
1047 const wxString
& name
)
1049 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1051 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1054 m_windowVariant
= parent
->GetWindowVariant() ;
1056 if ( m_macIsUserPane
)
1058 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1061 | kControlSupportsEmbedding
1062 | kControlSupportsLiveFeedback
1063 | kControlGetsFocusOnClick
1064 // | kControlHasSpecialBackground
1065 // | kControlSupportsCalcBestRect
1066 | kControlHandlesTracking
1067 | kControlSupportsFocus
1068 | kControlWantsActivate
1069 | kControlWantsIdle
;
1071 m_peer
= new wxMacControl(this) ;
1072 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1073 verify_noerr( err
);
1075 MacPostControlCreate(pos
, size
) ;
1078 #ifndef __WXUNIVERSAL__
1079 // Don't give scrollbars to wxControls unless they ask for them
1080 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1081 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1083 MacCreateScrollBars( style
) ;
1087 wxWindowCreateEvent
event(this);
1088 GetEventHandler()->AddPendingEvent(event
);
1093 void wxWindowMac::MacChildAdded()
1096 m_vScrollBar
->Raise() ;
1098 m_hScrollBar
->Raise() ;
1101 void wxWindowMac::MacPostControlCreate(const wxPoint
& WXUNUSED(pos
), const wxSize
& size
)
1103 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1105 m_peer
->SetReference( (URefCon
) this ) ;
1106 GetParent()->AddChild( this );
1108 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1110 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1111 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1112 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1113 GetParent()->MacChildAdded() ;
1115 // adjust font, controlsize etc
1116 DoSetWindowVariant( m_windowVariant
) ;
1118 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1120 if (!m_macIsUserPane
)
1121 SetInitialSize(size
);
1123 SetCursor( *wxSTANDARD_CURSOR
) ;
1126 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1128 // Don't assert, in case we set the window variant before
1129 // the window is created
1130 // wxASSERT( m_peer->Ok() ) ;
1132 m_windowVariant
= variant
;
1134 if (m_peer
== NULL
|| !m_peer
->Ok())
1138 ThemeFontID themeFont
= kThemeSystemFont
;
1140 // we will get that from the settings later
1141 // and make this NORMAL later, but first
1142 // we have a few calculations that we must fix
1146 case wxWINDOW_VARIANT_NORMAL
:
1147 size
= kControlSizeNormal
;
1148 themeFont
= kThemeSystemFont
;
1151 case wxWINDOW_VARIANT_SMALL
:
1152 size
= kControlSizeSmall
;
1153 themeFont
= kThemeSmallSystemFont
;
1156 case wxWINDOW_VARIANT_MINI
:
1157 // not always defined in the headers
1162 case wxWINDOW_VARIANT_LARGE
:
1163 size
= kControlSizeLarge
;
1164 themeFont
= kThemeSystemFont
;
1168 wxFAIL_MSG(_T("unexpected window variant"));
1172 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1175 font
.MacCreateThemeFont( themeFont
) ;
1179 void wxWindowMac::MacUpdateControlFont()
1181 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1182 // do not trigger refreshes upon invisible and possible partly created objects
1183 if ( MacIsReallyShown() )
1187 bool wxWindowMac::SetFont(const wxFont
& font
)
1189 bool retval
= wxWindowBase::SetFont( font
);
1191 MacUpdateControlFont() ;
1196 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1198 bool retval
= wxWindowBase::SetForegroundColour( col
);
1201 MacUpdateControlFont();
1206 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1208 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1212 wxColour
newCol(GetBackgroundColour());
1214 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1215 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1216 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1217 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1219 brush
.SetColour( newCol
) ;
1221 MacSetBackgroundBrush( brush
) ;
1222 MacUpdateControlFont() ;
1227 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1229 m_macBackgroundBrush
= brush
;
1230 m_peer
->SetBackground( brush
) ;
1233 bool wxWindowMac::MacCanFocus() const
1235 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1236 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1237 // but the value range is nowhere documented
1238 Boolean keyExistsAndHasValidFormat
;
1239 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1240 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1242 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1248 UInt32 features
= 0 ;
1249 m_peer
->GetFeatures( &features
) ;
1251 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1255 void wxWindowMac::SetFocus()
1257 if ( !AcceptsFocus() )
1260 wxWindow
* former
= FindFocus() ;
1261 if ( former
== this )
1264 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1265 // we can only leave in case of an error
1266 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1267 if ( err
== errCouldntSetFocus
)
1270 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1272 #if !TARGET_API_MAC_OSX
1273 // emulate carbon events when running under CarbonLib where they are not natively available
1276 EventRef evRef
= NULL
;
1278 err
= MacCreateEvent(
1279 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1280 kEventAttributeUserEvent
, &evRef
);
1281 verify_noerr( err
);
1283 wxMacCarbonEvent
cEvent( evRef
) ;
1284 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1285 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1287 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1288 ReleaseEvent( evRef
) ;
1291 // send new focus event
1293 EventRef evRef
= NULL
;
1295 err
= MacCreateEvent(
1296 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1297 kEventAttributeUserEvent
, &evRef
);
1298 verify_noerr( err
);
1300 wxMacCarbonEvent
cEvent( evRef
) ;
1301 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1302 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1304 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1305 ReleaseEvent( evRef
) ;
1310 void wxWindowMac::DoCaptureMouse()
1312 wxApp::s_captureWindow
= this ;
1315 wxWindow
* wxWindowBase::GetCapture()
1317 return wxApp::s_captureWindow
;
1320 void wxWindowMac::DoReleaseMouse()
1322 wxApp::s_captureWindow
= NULL
;
1325 #if wxUSE_DRAG_AND_DROP
1327 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1329 if ( m_dropTarget
!= NULL
)
1330 delete m_dropTarget
;
1332 m_dropTarget
= pDropTarget
;
1333 if ( m_dropTarget
!= NULL
)
1341 // Old-style File Manager Drag & Drop
1342 void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept
))
1347 // Returns the size of the native control. In the case of the toplevel window
1348 // this is the content area root control
1350 void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x
),
1353 int& WXUNUSED(h
)) const
1355 wxFAIL_MSG( wxT("Not currently supported") ) ;
1358 // From a wx position / size calculate the appropriate size of the native control
1360 bool wxWindowMac::MacGetBoundsForControl(
1364 int& w
, int& h
, bool adjustOrigin
) const
1366 // the desired size, minus the border pixels gives the correct size of the control
1370 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1371 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1372 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1374 x
+= MacGetLeftBorderSize() ;
1375 y
+= MacGetTopBorderSize() ;
1376 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1377 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1380 AdjustForParentClientOrigin( x
, y
) ;
1382 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1383 if ( !GetParent()->IsTopLevel() )
1385 x
-= GetParent()->MacGetLeftBorderSize() ;
1386 y
-= GetParent()->MacGetTopBorderSize() ;
1392 // Get window size (not client size)
1393 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1396 m_peer
->GetRect( &bounds
) ;
1399 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1401 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1404 // get the position of the bounds of this window in client coordinates of its parent
1405 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1408 m_peer
->GetRect( &bounds
) ;
1410 int x1
= bounds
.left
;
1411 int y1
= bounds
.top
;
1413 // get the wx window position from the native one
1414 x1
-= MacGetLeftBorderSize() ;
1415 y1
-= MacGetTopBorderSize() ;
1417 if ( !IsTopLevel() )
1419 wxWindow
*parent
= GetParent();
1422 // we must first adjust it to be in window coordinates of the parent,
1423 // as otherwise it gets lost by the ClientAreaOrigin fix
1424 x1
+= parent
->MacGetLeftBorderSize() ;
1425 y1
+= parent
->MacGetTopBorderSize() ;
1427 // and now to client coordinates
1428 wxPoint
pt(parent
->GetClientAreaOrigin());
1440 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1442 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1443 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1445 Point localwhere
= { 0, 0 } ;
1452 wxMacGlobalToLocal( window
, &localwhere
) ;
1459 MacRootWindowToWindow( x
, y
) ;
1461 wxPoint origin
= GetClientAreaOrigin() ;
1468 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1470 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1471 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1473 wxPoint origin
= GetClientAreaOrigin() ;
1479 MacWindowToRootWindow( x
, y
) ;
1481 Point localwhere
= { 0, 0 };
1487 wxMacLocalToGlobal( window
, &localwhere
) ;
1495 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1497 wxPoint origin
= GetClientAreaOrigin() ;
1503 MacWindowToRootWindow( x
, y
) ;
1506 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1508 MacRootWindowToWindow( x
, y
) ;
1510 wxPoint origin
= GetClientAreaOrigin() ;
1517 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1526 if ( !IsTopLevel() )
1528 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1531 pt
.x
-= MacGetLeftBorderSize() ;
1532 pt
.y
-= MacGetTopBorderSize() ;
1533 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1543 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1552 MacWindowToRootWindow( &x1
, &y1
) ;
1560 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1569 if ( !IsTopLevel() )
1571 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1574 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1575 pt
.x
+= MacGetLeftBorderSize() ;
1576 pt
.y
+= MacGetTopBorderSize() ;
1586 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1595 MacRootWindowToWindow( &x1
, &y1
) ;
1603 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1605 RgnHandle rgn
= NewRgn() ;
1607 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1609 Rect structure
, content
;
1611 GetRegionBounds( rgn
, &content
) ;
1612 m_peer
->GetRect( &structure
) ;
1613 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1615 left
= content
.left
- structure
.left
;
1616 top
= content
.top
- structure
.top
;
1617 right
= structure
.right
- content
.right
;
1618 bottom
= structure
.bottom
- content
.bottom
;
1622 left
= top
= right
= bottom
= 0 ;
1628 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1630 wxSize sizeTotal
= size
;
1632 RgnHandle rgn
= NewRgn() ;
1633 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1635 Rect content
, structure
;
1636 GetRegionBounds( rgn
, &content
) ;
1637 m_peer
->GetRect( &structure
) ;
1639 // structure is in parent coordinates, but we only need width and height, so it's ok
1641 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1642 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1647 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1648 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1653 // Get size *available for subwindows* i.e. excluding menu bar etc.
1654 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1658 RgnHandle rgn
= NewRgn() ;
1660 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1661 GetRegionBounds( rgn
, &content
) ;
1663 m_peer
->GetRect( &content
) ;
1666 ww
= content
.right
- content
.left
;
1667 hh
= content
.bottom
- content
.top
;
1669 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1670 hh
-= m_hScrollBar
->GetSize().y
;
1672 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1673 ww
-= m_vScrollBar
->GetSize().x
;
1681 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1683 if (m_cursor
.IsSameAs(cursor
))
1688 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1693 if ( ! wxWindowBase::SetCursor( cursor
) )
1697 wxASSERT_MSG( m_cursor
.Ok(),
1698 wxT("cursor must be valid after call to the base version"));
1700 wxWindowMac
*mouseWin
= 0 ;
1702 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1703 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1705 ControlPartCode part
;
1706 ControlRef control
;
1708 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1710 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1715 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1717 // TODO: If we ever get a GetCurrentEvent... replacement
1718 // for the mouse position, use it...
1723 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1725 mouseWin
= wxFindControlFromMacControl( control
) ;
1727 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1729 QDSwapPort( savePort
, NULL
) ;
1733 if ( mouseWin
== this && !wxIsBusy() )
1734 m_cursor
.MacInstall() ;
1740 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1742 #ifndef __WXUNIVERSAL__
1743 menu
->SetInvokingWindow((wxWindow
*)this);
1746 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1748 wxPoint mouse
= wxGetMousePosition();
1754 ClientToScreen( &x
, &y
) ;
1757 menu
->MacBeforeDisplay( true ) ;
1758 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1759 if ( HiWord(menuResult
) != 0 )
1762 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1763 int id
= wxMacCommandToId( macid
);
1764 wxMenuItem
* item
= NULL
;
1766 item
= menu
->FindItem( id
, &realmenu
) ;
1769 if (item
->IsCheckable())
1770 item
->Check( !item
->IsChecked() ) ;
1772 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1776 menu
->MacAfterDisplay( true ) ;
1777 menu
->SetInvokingWindow( NULL
);
1781 // actually this shouldn't be called, because universal is having its own implementation
1787 // ----------------------------------------------------------------------------
1789 // ----------------------------------------------------------------------------
1793 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1795 wxWindowBase::DoSetToolTip(tooltip
);
1798 m_tooltip
->SetWindow(this);
1803 void wxWindowMac::MacInvalidateBorders()
1805 if ( m_peer
== NULL
)
1808 bool vis
= MacIsReallyShown() ;
1812 int outerBorder
= MacGetLeftBorderSize() ;
1813 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1816 if ( outerBorder
== 0 )
1819 // now we know that we have something to do at all
1821 // as the borders are drawn on the parent we have to properly invalidate all these areas
1822 RgnHandle updateInner
, updateOuter
;
1825 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1826 updateInner
= NewRgn() ;
1827 updateOuter
= NewRgn() ;
1829 m_peer
->GetRect( &rect
) ;
1830 RectRgn( updateInner
, &rect
) ;
1831 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1832 RectRgn( updateOuter
, &rect
) ;
1833 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1835 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1837 DisposeRgn( updateOuter
) ;
1838 DisposeRgn( updateInner
) ;
1841 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1843 // this is never called for a toplevel window, so we know we have a parent
1844 int former_x
, former_y
, former_w
, former_h
;
1846 // Get true coordinates of former position
1847 DoGetPosition( &former_x
, &former_y
) ;
1848 DoGetSize( &former_w
, &former_h
) ;
1850 wxWindow
*parent
= GetParent();
1853 wxPoint
pt(parent
->GetClientAreaOrigin());
1858 int actualWidth
= width
;
1859 int actualHeight
= height
;
1863 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1864 actualWidth
= m_minWidth
;
1865 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1866 actualHeight
= m_minHeight
;
1867 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1868 actualWidth
= m_maxWidth
;
1869 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1870 actualHeight
= m_maxHeight
;
1872 bool doMove
= false, doResize
= false ;
1874 if ( actualX
!= former_x
|| actualY
!= former_y
)
1877 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1880 if ( doMove
|| doResize
)
1882 // as the borders are drawn outside the native control, we adjust now
1884 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1885 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1886 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1889 wxMacRectToNative( &bounds
, &r
) ;
1891 if ( !GetParent()->IsTopLevel() )
1892 wxMacWindowToNative( GetParent() , &r
) ;
1894 MacInvalidateBorders() ;
1896 m_cachedClippedRectValid
= false ;
1897 m_peer
->SetRect( &r
) ;
1899 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1901 MacInvalidateBorders() ;
1903 MacRepositionScrollBars() ;
1906 wxPoint
point(actualX
, actualY
);
1907 wxMoveEvent
event(point
, m_windowId
);
1908 event
.SetEventObject(this);
1909 GetEventHandler()->ProcessEvent(event
) ;
1914 MacRepositionScrollBars() ;
1915 wxSize
size(actualWidth
, actualHeight
);
1916 wxSizeEvent
event(size
, m_windowId
);
1917 event
.SetEventObject(this);
1918 GetEventHandler()->ProcessEvent(event
);
1923 wxSize
wxWindowMac::DoGetBestSize() const
1925 if ( m_macIsUserPane
|| IsTopLevel() )
1926 return wxWindowBase::DoGetBestSize() ;
1928 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1929 int bestWidth
, bestHeight
;
1931 m_peer
->GetBestRect( &bestsize
) ;
1932 if ( EmptyRect( &bestsize
) )
1937 bestsize
.bottom
= 16 ;
1939 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1941 bestsize
.bottom
= 16 ;
1944 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1946 bestsize
.bottom
= 24 ;
1951 // return wxWindowBase::DoGetBestSize() ;
1955 bestWidth
= bestsize
.right
- bestsize
.left
;
1956 bestHeight
= bestsize
.bottom
- bestsize
.top
;
1957 if ( bestHeight
< 10 )
1960 return wxSize(bestWidth
, bestHeight
);
1963 // set the size of the window: if the dimensions are positive, just use them,
1964 // but if any of them is equal to -1, it means that we must find the value for
1965 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1966 // which case -1 is a valid value for x and y)
1968 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1969 // the width/height to best suit our contents, otherwise we reuse the current
1971 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1973 // get the current size and position...
1974 int currentX
, currentY
;
1975 int currentW
, currentH
;
1977 GetPosition(¤tX
, ¤tY
);
1978 GetSize(¤tW
, ¤tH
);
1980 // ... and don't do anything (avoiding flicker) if it's already ok
1981 if ( x
== currentX
&& y
== currentY
&&
1982 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
1985 MacRepositionScrollBars() ; // we might have a real position shift
1990 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1992 if ( x
== wxDefaultCoord
)
1994 if ( y
== wxDefaultCoord
)
1998 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2000 wxSize size
= wxDefaultSize
;
2001 if ( width
== wxDefaultCoord
)
2003 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2005 size
= DoGetBestSize();
2010 // just take the current one
2015 if ( height
== wxDefaultCoord
)
2017 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2019 if ( size
.x
== wxDefaultCoord
)
2020 size
= DoGetBestSize();
2021 // else: already called DoGetBestSize() above
2027 // just take the current one
2032 DoMoveWindow( x
, y
, width
, height
);
2035 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2037 RgnHandle rgn
= NewRgn() ;
2039 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2041 GetRegionBounds( rgn
, &content
) ;
2051 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2054 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2056 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2058 int currentclientwidth
, currentclientheight
;
2059 int currentwidth
, currentheight
;
2061 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2062 GetSize( ¤twidth
, ¤theight
) ;
2064 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2065 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2069 void wxWindowMac::SetLabel(const wxString
& title
)
2073 if ( m_peer
&& m_peer
->Ok() )
2074 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
2076 // do not trigger refreshes upon invisible and possible partly created objects
2077 if ( MacIsReallyShown() )
2081 wxString
wxWindowMac::GetLabel() const
2086 bool wxWindowMac::Show(bool show
)
2088 bool former
= MacIsReallyShown() ;
2089 if ( !wxWindowBase::Show(show
) )
2092 // TODO: use visibilityChanged Carbon Event for OSX
2094 m_peer
->SetVisibility( show
, true ) ;
2096 if ( former
!= MacIsReallyShown() )
2097 MacPropagateVisibilityChanged() ;
2102 void wxWindowMac::DoEnable(bool enable
)
2104 m_peer
->Enable( enable
) ;
2108 // status change propagations (will be not necessary for OSX later )
2111 void wxWindowMac::MacPropagateVisibilityChanged()
2113 #if !TARGET_API_MAC_OSX
2114 MacVisibilityChanged() ;
2117 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2120 child
= node
->GetData();
2121 if ( child
->IsShown() )
2122 child
->MacPropagateVisibilityChanged() ;
2124 node
= node
->GetNext();
2129 void wxWindowMac::OnEnabled(bool WXUNUSED(enabled
))
2131 #if !TARGET_API_MAC_OSX
2132 MacEnabledStateChanged() ;
2136 void wxWindowMac::MacPropagateHiliteChanged()
2138 #if !TARGET_API_MAC_OSX
2139 MacHiliteChanged() ;
2142 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2145 child
= node
->GetData();
2146 if (child
/* && child->IsEnabled() */)
2147 child
->MacPropagateHiliteChanged() ;
2149 node
= node
->GetNext();
2155 // status change notifications
2158 void wxWindowMac::MacVisibilityChanged()
2162 void wxWindowMac::MacHiliteChanged()
2166 void wxWindowMac::MacEnabledStateChanged()
2171 // status queries on the inherited window's state
2174 bool wxWindowMac::MacIsReallyShown()
2176 // only under OSX the visibility of the TLW is taken into account
2177 if ( m_isBeingDeleted
)
2180 #if TARGET_API_MAC_OSX
2181 if ( m_peer
&& m_peer
->Ok() )
2182 return m_peer
->IsVisible();
2185 wxWindow
* win
= this ;
2186 while ( win
->IsShown() )
2188 if ( win
->IsTopLevel() )
2191 win
= win
->GetParent() ;
2199 bool wxWindowMac::MacIsReallyEnabled()
2201 return m_peer
->IsEnabled() ;
2204 bool wxWindowMac::MacIsReallyHilited()
2206 return m_peer
->IsActive();
2209 void wxWindowMac::MacFlashInvalidAreas()
2211 #if TARGET_API_MAC_OSX
2212 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2216 int wxWindowMac::GetCharHeight() const
2218 wxClientDC
dc( (wxWindowMac
*)this ) ;
2220 return dc
.GetCharHeight() ;
2223 int wxWindowMac::GetCharWidth() const
2225 wxClientDC
dc( (wxWindowMac
*)this ) ;
2227 return dc
.GetCharWidth() ;
2230 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2231 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2233 const wxFont
*fontToUse
= theFont
;
2235 fontToUse
= &m_font
;
2237 wxClientDC
dc( (wxWindowMac
*) this ) ;
2238 wxCoord lx
,ly
,ld
,le
;
2239 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2240 if ( externalLeading
)
2241 *externalLeading
= le
;
2251 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2252 * we always intersect with the entire window, not only with the client area
2255 void wxWindowMac::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
2257 if ( m_peer
== NULL
)
2260 if ( !MacIsReallyShown() )
2267 wxMacRectToNative( rect
, &r
) ;
2268 m_peer
->SetNeedsDisplay( &r
) ;
2272 m_peer
->SetNeedsDisplay() ;
2276 void wxWindowMac::Freeze()
2278 #if TARGET_API_MAC_OSX
2279 if ( !m_frozenness
++ )
2281 if ( m_peer
&& m_peer
->Ok() )
2282 m_peer
->SetDrawingEnabled( false ) ;
2287 void wxWindowMac::Thaw()
2289 #if TARGET_API_MAC_OSX
2290 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2292 if ( !--m_frozenness
)
2294 if ( m_peer
&& m_peer
->Ok() )
2296 m_peer
->SetDrawingEnabled( true ) ;
2297 m_peer
->InvalidateWithChildren() ;
2303 bool wxWindowMac::IsFrozen() const
2305 return m_frozenness
!= 0;
2308 wxWindowMac
*wxGetActiveWindow()
2310 // actually this is a windows-only concept
2314 // Coordinates relative to the window
2315 void wxWindowMac::WarpPointer(int WXUNUSED(x_pos
), int WXUNUSED(y_pos
))
2317 // We really don't move the mouse programmatically under Mac.
2320 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2322 if ( MacGetTopLevelWindow() == NULL
)
2325 #if TARGET_API_MAC_OSX
2326 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
2327 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2334 event
.GetDC()->Clear() ;
2338 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2343 int wxWindowMac::GetScrollPos(int orient
) const
2345 if ( orient
== wxHORIZONTAL
)
2348 return m_hScrollBar
->GetThumbPosition() ;
2353 return m_vScrollBar
->GetThumbPosition() ;
2359 // This now returns the whole range, not just the number
2360 // of positions that we can scroll.
2361 int wxWindowMac::GetScrollRange(int orient
) const
2363 if ( orient
== wxHORIZONTAL
)
2366 return m_hScrollBar
->GetRange() ;
2371 return m_vScrollBar
->GetRange() ;
2377 int wxWindowMac::GetScrollThumb(int orient
) const
2379 if ( orient
== wxHORIZONTAL
)
2382 return m_hScrollBar
->GetThumbSize() ;
2387 return m_vScrollBar
->GetThumbSize() ;
2393 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
2395 if ( orient
== wxHORIZONTAL
)
2398 m_hScrollBar
->SetThumbPosition( pos
) ;
2403 m_vScrollBar
->SetThumbPosition( pos
) ;
2408 wxWindowMac::AlwaysShowScrollbars(bool hflag
, bool vflag
)
2410 bool needVisibilityUpdate
= false;
2412 if ( m_hScrollBarAlwaysShown
!= hflag
)
2414 m_hScrollBarAlwaysShown
= hflag
;
2415 needVisibilityUpdate
= true;
2418 if ( m_vScrollBarAlwaysShown
!= vflag
)
2420 m_vScrollBarAlwaysShown
= vflag
;
2421 needVisibilityUpdate
= true;
2424 if ( needVisibilityUpdate
)
2425 DoUpdateScrollbarVisibility();
2429 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2430 // our own window origin is at leftOrigin/rightOrigin
2433 void wxWindowMac::MacPaintGrowBox()
2438 #if wxMAC_USE_CORE_GRAPHICS
2439 if ( MacHasScrollBarCorner() )
2443 CGContextRef cgContext
= (CGContextRef
) MacGetCGContextRef() ;
2444 wxASSERT( cgContext
) ;
2446 m_peer
->GetRect( &rect
) ;
2448 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2449 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2450 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2451 CGContextSaveGState( cgContext
);
2453 if ( m_macBackgroundBrush
.Ok() && m_macBackgroundBrush
.GetStyle() != wxTRANSPARENT
)
2455 wxMacCoreGraphicsColour
bkgnd( m_macBackgroundBrush
) ;
2456 bkgnd
.Apply( cgContext
);
2460 CGContextSetRGBFillColor( cgContext
, 1.0, 1.0 , 1.0 , 1.0 );
2462 CGContextFillRect( cgContext
, cgrect
);
2463 CGContextRestoreGState( cgContext
);
2468 void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin
) , int WXUNUSED(rightOrigin
) )
2474 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2476 // back to the surrounding frame rectangle
2477 m_peer
->GetRect( &rect
) ;
2478 InsetRect( &rect
, -1 , -1 ) ;
2480 #if wxMAC_USE_CORE_GRAPHICS
2482 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2483 rect
.bottom
- rect
.top
) ;
2485 HIThemeFrameDrawInfo info
;
2486 memset( &info
, 0 , sizeof(info
) ) ;
2490 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2491 info
.isFocused
= hasFocus
;
2493 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2494 wxASSERT( cgContext
) ;
2496 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2498 info
.kind
= kHIThemeFrameTextFieldSquare
;
2499 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2501 else if ( HasFlag(wxSIMPLE_BORDER
) )
2503 info
.kind
= kHIThemeFrameListBox
;
2504 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2506 else if ( hasFocus
)
2508 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2510 #if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
2511 m_peer
->GetRect( &rect
) ;
2512 if ( MacHasScrollBarCorner() )
2514 int variant
= (m_hScrollBar
== NULL
? m_vScrollBar
: m_hScrollBar
) ->GetWindowVariant();
2515 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2516 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2517 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2518 HIThemeGrowBoxDrawInfo info
;
2519 memset( &info
, 0, sizeof(info
) ) ;
2521 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2522 info
.kind
= kHIThemeGrowBoxKindNone
;
2523 // contrary to the docs ...SizeSmall does not work
2524 info
.size
= kHIThemeGrowBoxSizeNormal
;
2525 info
.direction
= 0 ;
2526 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2532 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2536 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2537 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2540 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2541 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2542 else if ( HasFlag(wxSIMPLE_BORDER
) )
2543 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2546 DrawThemeFocusRect( &rect
, true ) ;
2549 if ( hasBothScrollbars ) // hasBothScrollbars is not declared
2551 // GetThemeStandaloneGrowBoxBounds
2552 // DrawThemeStandaloneNoGrowBox
2559 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2561 if ( child
== m_hScrollBar
)
2562 m_hScrollBar
= NULL
;
2563 if ( child
== m_vScrollBar
)
2564 m_vScrollBar
= NULL
;
2566 wxWindowBase::RemoveChild( child
) ;
2569 void wxWindowMac::DoUpdateScrollbarVisibility()
2571 bool triggerSizeEvent
= false;
2575 bool showHScrollBar
= m_hScrollBarAlwaysShown
|| m_hScrollBar
->IsNeeded();
2577 if ( m_hScrollBar
->IsShown() != showHScrollBar
)
2579 m_hScrollBar
->Show( showHScrollBar
);
2580 triggerSizeEvent
= true;
2586 bool showVScrollBar
= m_vScrollBarAlwaysShown
|| m_vScrollBar
->IsNeeded();
2588 if ( m_vScrollBar
->IsShown() != showVScrollBar
)
2590 m_vScrollBar
->Show( showVScrollBar
) ;
2591 triggerSizeEvent
= true;
2595 MacRepositionScrollBars() ;
2596 if ( triggerSizeEvent
)
2598 wxSizeEvent
event(GetSize(), m_windowId
);
2599 event
.SetEventObject(this);
2600 GetEventHandler()->ProcessEvent(event
);
2604 // New function that will replace some of the above.
2605 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumb
,
2606 int range
, bool refresh
)
2608 if ( orient
== wxHORIZONTAL
&& m_hScrollBar
)
2609 m_hScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2610 else if ( orient
== wxVERTICAL
&& m_vScrollBar
)
2611 m_vScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2613 DoUpdateScrollbarVisibility();
2616 // Does a physical scroll
2617 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2619 if ( dx
== 0 && dy
== 0 )
2622 int width
, height
;
2623 GetClientSize( &width
, &height
) ;
2626 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2627 // area is scrolled, this does not occur if width and height are 2 pixels less,
2628 // TODO: write optimal workaround
2629 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2631 scrollrect
.Intersect( *rect
) ;
2633 if ( m_peer
->GetNeedsDisplay() )
2635 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2636 // in case there is already a pending redraw on that area
2637 // either immediate redraw or full invalidate
2639 // is the better overall solution, as it does not slow down scrolling
2640 m_peer
->SetNeedsDisplay() ;
2642 // this would be the preferred version for fast drawing controls
2643 HIViewRender(m_peer
->GetControlRef()) ;
2647 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2648 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2649 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2652 // this would be the preferred version for fast drawing controls
2653 HIViewRender(m_peer
->GetControlRef()) ;
2659 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2661 child
= node
->GetData();
2664 if (child
== m_vScrollBar
)
2666 if (child
== m_hScrollBar
)
2668 if (child
->IsTopLevel())
2671 child
->GetPosition( &x
, &y
);
2672 child
->GetSize( &w
, &h
);
2675 wxRect
rc( x
, y
, w
, h
);
2676 if (rect
->Intersects( rc
))
2677 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2681 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2686 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2688 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2690 wxScrollWinEvent wevent
;
2691 wevent
.SetPosition(event
.GetPosition());
2692 wevent
.SetOrientation(event
.GetOrientation());
2693 wevent
.SetEventObject(this);
2695 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2696 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2697 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2698 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2699 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2700 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2701 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2702 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2703 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2704 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2705 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2706 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2707 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2708 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2709 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2710 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2712 GetEventHandler()->ProcessEvent(wevent
);
2716 // Get the window with the focus
2717 wxWindowMac
*wxWindowBase::DoFindFocus()
2719 ControlRef control
;
2720 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2721 return wxFindControlFromMacControl( control
) ;
2724 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2726 // panel wants to track the window which was the last to have focus in it,
2727 // so we want to set ourselves as the window which last had focus
2729 // notice that it's also important to do it upwards the tree because
2730 // otherwise when the top level panel gets focus, it won't set it back to
2731 // us, but to some other sibling
2733 // CS: don't know if this is still needed:
2734 //wxChildFocusEvent eventFocus(this);
2735 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2737 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2739 #if wxMAC_USE_CORE_GRAPHICS
2740 GetParent()->Refresh() ;
2742 wxMacWindowStateSaver
sv( this ) ;
2745 m_peer
->GetRect( &rect
) ;
2746 // auf den umgebenden Rahmen zurチᅡ゚ck
2747 InsetRect( &rect
, -1 , -1 ) ;
2749 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2753 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2755 rect
.right
+= pt
.x
;
2757 rect
.bottom
+= pt
.y
;
2760 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2761 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2762 if ( !bIsFocusEvent
)
2764 // as this erases part of the frame we have to redraw borders
2765 // and because our z-ordering is not always correct (staticboxes)
2766 // we have to invalidate things, we cannot simple redraw
2767 MacInvalidateBorders() ;
2775 void wxWindowMac::OnInternalIdle()
2777 // This calls the UI-update mechanism (querying windows for
2778 // menu/toolbar/control state information)
2779 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
2780 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2783 // Raise the window to the top of the Z order
2784 void wxWindowMac::Raise()
2786 m_peer
->SetZOrder( true , NULL
) ;
2789 // Lower the window to the bottom of the Z order
2790 void wxWindowMac::Lower()
2792 m_peer
->SetZOrder( false , NULL
) ;
2795 // static wxWindow *gs_lastWhich = NULL;
2797 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2799 // first trigger a set cursor event
2801 wxPoint clientorigin
= GetClientAreaOrigin() ;
2802 wxSize clientsize
= GetClientSize() ;
2804 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2806 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2808 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2809 if ( processedEvtSetCursor
&& event
.HasCursor() )
2811 cursor
= event
.GetCursor() ;
2815 // the test for processedEvtSetCursor is here to prevent using m_cursor
2816 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2817 // it - this is a way to say that our cursor shouldn't be used for this
2819 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2822 if ( !wxIsBusy() && !GetParent() )
2823 cursor
= *wxSTANDARD_CURSOR
;
2827 cursor
.MacInstall() ;
2830 return cursor
.Ok() ;
2833 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&WXUNUSED(pt
) )
2837 return m_tooltip
->GetTip() ;
2840 return wxEmptyString
;
2843 void wxWindowMac::ClearBackground()
2849 void wxWindowMac::Update()
2851 #if TARGET_API_MAC_OSX
2852 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2854 top
->MacPerformUpdates() ;
2856 ::Draw1Control( m_peer
->GetControlRef() ) ;
2860 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2862 wxTopLevelWindowMac
* win
= NULL
;
2863 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2865 win
= wxFindWinFromMacWindow( window
) ;
2870 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2872 MacUpdateClippedRects() ;
2874 return m_cachedClippedClientRect
;
2877 const wxRect
& wxWindowMac::MacGetClippedRect() const
2879 MacUpdateClippedRects() ;
2881 return m_cachedClippedRect
;
2884 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2886 MacUpdateClippedRects() ;
2888 return m_cachedClippedRectWithOuterStructure
;
2891 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2893 static wxRegion emptyrgn
;
2895 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2897 MacUpdateClippedRects() ;
2898 if ( includeOuterStructures
)
2899 return m_cachedClippedRegionWithOuterStructure
;
2901 return m_cachedClippedRegion
;
2909 void wxWindowMac::MacUpdateClippedRects() const
2911 if ( m_cachedClippedRectValid
)
2914 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2915 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2916 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2917 // to add focus borders everywhere
2919 Rect r
, rIncludingOuterStructures
;
2921 m_peer
->GetRect( &r
) ;
2922 r
.left
-= MacGetLeftBorderSize() ;
2923 r
.top
-= MacGetTopBorderSize() ;
2924 r
.bottom
+= MacGetBottomBorderSize() ;
2925 r
.right
+= MacGetRightBorderSize() ;
2932 rIncludingOuterStructures
= r
;
2933 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2935 wxRect cl
= GetClientRect() ;
2936 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2940 const wxWindow
* child
= this ;
2941 const wxWindow
* parent
= NULL
;
2943 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2945 if ( parent
->MacIsChildOfClientArea(child
) )
2947 size
= parent
->GetClientSize() ;
2948 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2954 // this will be true for scrollbars, toolbars etc.
2955 size
= parent
->GetSize() ;
2956 y
= parent
->MacGetTopBorderSize() ;
2957 x
= parent
->MacGetLeftBorderSize() ;
2958 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2959 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2962 parent
->MacWindowToRootWindow( &x
, &y
) ;
2963 MacRootWindowToWindow( &x
, &y
) ;
2965 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2967 // the wxwindow and client rects will always be clipped
2968 SectRect( &r
, &rparent
, &r
) ;
2969 SectRect( &rClient
, &rparent
, &rClient
) ;
2971 // the structure only at 'hard' borders
2972 if ( parent
->MacClipChildren() ||
2973 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2975 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2981 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
2982 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
2983 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
2984 m_cachedClippedRectWithOuterStructure
= wxRect(
2985 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
2986 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
2987 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
2989 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
2990 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
2991 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
2993 m_cachedClippedRectValid
= true ;
2997 This function must not change the updatergn !
2999 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
3001 bool handled
= false ;
3003 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
3004 GetRegionBounds( updatergn
, &updatebounds
) ;
3006 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3008 if ( !EmptyRgn(updatergn
) )
3010 RgnHandle newupdate
= NewRgn() ;
3011 wxSize point
= GetClientSize() ;
3012 wxPoint origin
= GetClientAreaOrigin() ;
3013 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
3014 SectRgn( newupdate
, updatergn
, newupdate
) ;
3016 // first send an erase event to the entire update area
3018 // for the toplevel window this really is the entire area
3019 // for all the others only their client area, otherwise they
3020 // might be drawing with full alpha and eg put blue into
3021 // the grow-box area of a scrolled window (scroll sample)
3022 wxDC
* dc
= new wxWindowDC(this);
3024 dc
->SetClippingRegion(wxRegion(updatergn
));
3026 dc
->SetClippingRegion(wxRegion(newupdate
));
3028 wxEraseEvent
eevent( GetId(), dc
);
3029 eevent
.SetEventObject( this );
3030 GetEventHandler()->ProcessEvent( eevent
);
3036 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3037 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3038 m_updateRegion
= newupdate
;
3039 DisposeRgn( newupdate
) ;
3041 if ( !m_updateRegion
.Empty() )
3043 // paint the window itself
3046 event
.SetTimestamp(time
);
3047 event
.SetEventObject(this);
3048 GetEventHandler()->ProcessEvent(event
);
3052 // now we cannot rely on having its borders drawn by a window itself, as it does not
3053 // get the updateRgn wide enough to always do so, so we do it from the parent
3054 // this would also be the place to draw any custom backgrounds for native controls
3055 // in Composited windowing
3056 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3060 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3062 child
= node
->GetData();
3065 if (child
== m_vScrollBar
)
3067 if (child
== m_hScrollBar
)
3069 if (child
->IsTopLevel())
3071 if (!child
->IsShown())
3074 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3076 child
->GetPosition( &x
, &y
);
3077 child
->GetSize( &w
, &h
);
3078 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3079 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3080 InsetRect( &childRect
, -10 , -10) ;
3082 if ( RectInRgn( &childRect
, updatergn
) )
3084 // paint custom borders
3085 wxNcPaintEvent
eventNc( child
->GetId() );
3086 eventNc
.SetEventObject( child
);
3087 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3089 #if wxMAC_USE_CORE_GRAPHICS
3090 child
->MacPaintBorders(0, 0) ;
3093 wxWindowDC
dc(this) ;
3094 dc
.SetClippingRegion(wxRegion(updatergn
));
3095 wxMacPortSetter
helper(&dc
) ;
3096 child
->MacPaintBorders(0, 0) ;
3108 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3110 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3114 if ( iter
->IsTopLevel() )
3116 wxTopLevelWindow
* toplevel
= wxDynamicCast(iter
,wxTopLevelWindow
);
3118 return toplevel
->MacGetWindowRef();
3120 wxPopupWindow
* popupwin
= wxDynamicCast(iter
,wxPopupWindow
);
3122 return popupwin
->MacGetPopupWindowRef();
3125 iter
= iter
->GetParent() ;
3131 bool wxWindowMac::MacHasScrollBarCorner() const
3133 /* Returns whether the scroll bars in a wxScrolledWindow should be
3134 * shortened. Scroll bars should be shortened if either:
3136 * - both scroll bars are visible, or
3138 * - there is a resize box in the parent frame's corner and this
3139 * window shares the bottom and right edge with the parent
3143 if ( m_hScrollBar
== NULL
&& m_vScrollBar
== NULL
)
3146 if ( ( m_hScrollBar
&& m_hScrollBar
->IsShown() )
3147 && ( m_vScrollBar
&& m_vScrollBar
->IsShown() ) )
3149 // Both scroll bars visible
3154 wxPoint thisWindowBottomRight
= GetScreenRect().GetBottomRight();
3156 for ( const wxWindow
*win
= this; win
; win
= win
->GetParent() )
3158 const wxFrame
*frame
= wxDynamicCast( win
, wxFrame
) ;
3161 if ( frame
->GetWindowStyleFlag() & wxRESIZE_BORDER
)
3163 // Parent frame has resize handle
3164 wxPoint frameBottomRight
= frame
->GetScreenRect().GetBottomRight();
3166 // Note: allow for some wiggle room here as wxMac's
3167 // window rect calculations seem to be imprecise
3168 if ( abs( thisWindowBottomRight
.x
- frameBottomRight
.x
) <= 2
3169 && abs( thisWindowBottomRight
.y
- frameBottomRight
.y
) <= 2 )
3171 // Parent frame has resize handle and shares
3172 // right bottom corner
3177 // Parent frame has resize handle but doesn't
3178 // share right bottom corner
3184 // Parent frame doesn't have resize handle
3190 // No parent frame found
3195 void wxWindowMac::MacCreateScrollBars( long style
)
3197 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3199 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3201 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3202 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3204 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3207 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1: 0 ;
3209 GetClientSize( &width
, &height
) ;
3211 wxPoint
vPoint(width
- scrlsize
, 0) ;
3212 wxSize
vSize(scrlsize
, height
- adjust
) ;
3213 wxPoint
hPoint(0, height
- scrlsize
) ;
3214 wxSize
hSize(width
- adjust
, scrlsize
) ;
3216 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
3217 if ( style
& wxVSCROLL
)
3219 m_vScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3220 m_vScrollBar
->SetMinSize( wxDefaultSize
);
3223 if ( style
& wxHSCROLL
)
3225 m_hScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3226 m_hScrollBar
->SetMinSize( wxDefaultSize
);
3230 // because the create does not take into account the client area origin
3231 // we might have a real position shift
3232 MacRepositionScrollBars() ;
3235 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3237 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3242 void wxWindowMac::MacRepositionScrollBars()
3244 if ( !m_hScrollBar
&& !m_vScrollBar
)
3247 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3248 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1 : 0 ;
3250 // get real client area
3252 GetSize( &width
, &height
);
3254 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3255 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3257 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3258 wxSize
vSize( scrlsize
, height
- adjust
) ;
3259 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3260 wxSize
hSize( width
- adjust
, scrlsize
) ;
3263 int x
= 0, y
= 0, w
, h
;
3264 GetSize( &w
, &h
) ;
3266 MacClientToRootWindow( &x
, &y
) ;
3267 MacClientToRootWindow( &w
, &h
) ;
3269 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3271 int totW
= 10000 , totH
= 10000;
3274 if ( iter
->IsTopLevel() )
3276 iter
->GetSize( &totW
, &totH
) ;
3280 iter
= iter
->GetParent() ;
3294 if ( w
- x
>= totW
)
3299 if ( h
- y
>= totH
)
3307 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3309 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3312 bool wxWindowMac::AcceptsFocus() const
3314 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3317 void wxWindowMac::MacSuperChangedPosition()
3319 // only window-absolute structures have to be moved i.e. controls
3321 m_cachedClippedRectValid
= false ;
3324 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3327 child
= node
->GetData();
3328 child
->MacSuperChangedPosition() ;
3330 node
= node
->GetNext();
3334 void wxWindowMac::MacTopLevelWindowChangedPosition()
3336 // only screen-absolute structures have to be moved i.e. glcanvas
3339 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3342 child
= node
->GetData();
3343 child
->MacTopLevelWindowChangedPosition() ;
3345 node
= node
->GetNext();
3349 long wxWindowMac::MacGetLeftBorderSize() const
3356 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3358 // this metric is only the 'outset' outside the simple frame rect
3359 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3362 else if (HasFlag(wxSIMPLE_BORDER
))
3364 // this metric is only the 'outset' outside the simple frame rect
3365 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3372 long wxWindowMac::MacGetRightBorderSize() const
3374 // they are all symmetric in mac themes
3375 return MacGetLeftBorderSize() ;
3378 long wxWindowMac::MacGetTopBorderSize() const
3380 // they are all symmetric in mac themes
3381 return MacGetLeftBorderSize() ;
3384 long wxWindowMac::MacGetBottomBorderSize() const
3386 // they are all symmetric in mac themes
3387 return MacGetLeftBorderSize() ;
3390 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3392 return style
& ~wxBORDER_MASK
;
3395 // Find the wxWindowMac at the current mouse position, returning the mouse
3397 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3399 pt
= wxGetMousePosition();
3400 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3405 // Get the current mouse position.
3406 wxPoint
wxGetMousePosition()
3410 wxGetMousePosition( &x
, &y
);
3412 return wxPoint(x
, y
);
3415 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3417 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3419 // copied from wxGTK : CS
3420 // VZ: shouldn't we move this to base class then?
3422 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3425 // (a) it's a command event and so is propagated to the parent
3426 // (b) under MSW it can be generated from kbd too
3427 // (c) it uses screen coords (because of (a))
3428 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3430 this->ClientToScreen(event
.GetPosition()));
3431 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3440 void wxWindowMac::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
3442 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3443 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3444 CallNextEventHandler(
3445 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3446 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3449 void wxWindowMac::MacHandleControlClick(WXWidget
WXUNUSED(control
),
3450 wxInt16
WXUNUSED(controlpart
),
3451 bool WXUNUSED(mouseStillDown
))
3455 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3459 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3460 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3465 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3467 return eventNotHandledErr
;
3470 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3472 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3473 if ( !wxWindowBase::Reparent(newParent
) )
3476 // copied from MacPostControlCreate
3477 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3479 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3481 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3486 bool wxWindowMac::SetTransparent(wxByte alpha
)
3488 #if wxMAC_USE_CORE_GRAPHICS
3489 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3491 if ( alpha
!= m_macAlpha
)
3493 m_macAlpha
= alpha
;
3503 bool wxWindowMac::CanSetTransparent()
3505 #if wxMAC_USE_CORE_GRAPHICS
3512 wxByte
wxWindowMac::GetTransparent() const