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"
56 #if wxUSE_DRAG_AND_DROP
60 #include "wx/mac/uma.h"
62 #define MAC_SCROLLBAR_SIZE 15
63 #define MAC_SMALL_SCROLLBAR_SIZE 11
67 #include <ToolUtils.h>
69 #include <MacTextEditor.h>
72 #if TARGET_API_MAC_OSX
74 #include <HIToolbox/HIView.h>
80 #ifdef __WXUNIVERSAL__
81 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac
, wxWindowBase
)
83 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
86 BEGIN_EVENT_TABLE(wxWindowMac
, wxWindowBase
)
87 EVT_NC_PAINT(wxWindowMac::OnNcPaint
)
88 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground
)
89 #if TARGET_API_MAC_OSX
90 EVT_PAINT(wxWindowMac::OnPaint
)
92 EVT_SET_FOCUS(wxWindowMac::OnSetFocus
)
93 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus
)
94 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent
)
97 #define wxMAC_DEBUG_REDRAW 0
98 #ifndef wxMAC_DEBUG_REDRAW
99 #define wxMAC_DEBUG_REDRAW 0
102 // ---------------------------------------------------------------------------
103 // Utility Routines to move between different coordinate systems
104 // ---------------------------------------------------------------------------
107 * Right now we have the following setup :
108 * a border that is not part of the native control is always outside the
109 * control's border (otherwise we loose all native intelligence, future ways
110 * may be to have a second embedding control responsible for drawing borders
111 * and backgrounds eventually)
112 * so all this border calculations have to be taken into account when calling
113 * native methods or getting native oriented data
114 * so we have three coordinate systems here
115 * wx client coordinates
116 * wx window coordinates (including window frames)
121 // originating from native control
125 void wxMacNativeToWindow( const wxWindow
* window
, RgnHandle handle
)
127 OffsetRgn( handle
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
130 void wxMacNativeToWindow( const wxWindow
* window
, Rect
*rect
)
132 OffsetRect( rect
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
136 // directed towards native control
139 void wxMacWindowToNative( const wxWindow
* window
, RgnHandle handle
)
141 OffsetRgn( handle
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() );
144 void wxMacWindowToNative( const wxWindow
* window
, Rect
*rect
)
146 OffsetRect( rect
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() ) ;
149 // ---------------------------------------------------------------------------
151 // ---------------------------------------------------------------------------
153 #if TARGET_API_MAC_OSX
155 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
158 kEventControlVisibilityChanged
= 157
164 static const EventTypeSpec eventList
[] =
166 { kEventClassCommand
, kEventProcessCommand
} ,
167 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
169 { kEventClassControl
, kEventControlGetClickActivation
} ,
170 { kEventClassControl
, kEventControlHit
} ,
172 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
173 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
175 { kEventClassControl
, kEventControlDraw
} ,
176 #if TARGET_API_MAC_OSX
177 { kEventClassControl
, kEventControlVisibilityChanged
} ,
178 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
179 { kEventClassControl
, kEventControlHiliteChanged
} ,
181 { kEventClassControl
, kEventControlActivate
} ,
182 { kEventClassControl
, kEventControlDeactivate
} ,
184 { kEventClassControl
, kEventControlSetFocusPart
} ,
186 { kEventClassService
, kEventServiceGetTypes
},
187 { kEventClassService
, kEventServiceCopy
},
188 { kEventClassService
, kEventServicePaste
},
190 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
191 // { kEventClassControl , kEventControlBoundsChanged } ,
194 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
196 OSStatus result
= eventNotHandledErr
;
198 wxMacCarbonEvent
cEvent( event
) ;
200 ControlRef controlRef
;
201 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
203 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
205 switch ( GetEventKind( event
) )
207 #if TARGET_API_MAC_OSX
208 case kEventControlDraw
:
210 RgnHandle updateRgn
= NULL
;
211 RgnHandle allocatedRgn
= NULL
;
212 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
214 if ( cEvent
.GetParameter
<RgnHandle
>(kEventParamRgnHandle
, &updateRgn
) != noErr
)
216 updateRgn
= (RgnHandle
) visRegion
.GetWXHRGN() ;
220 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
222 // as this update region is in native window locals we must adapt it to wx window local
223 allocatedRgn
= NewRgn() ;
224 CopyRgn( updateRgn
, allocatedRgn
) ;
226 // hide the given region by the new region that must be shifted
227 wxMacNativeToWindow( thisWindow
, allocatedRgn
) ;
228 updateRgn
= allocatedRgn
;
233 GetRegionBounds( updateRgn
, &rgnBounds
) ;
235 #if wxMAC_DEBUG_REDRAW
236 if ( thisWindow
->MacIsUserPane() )
238 static float color
= 0.5 ;
241 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
243 HIViewGetBounds( controlRef
, &bounds
);
244 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
245 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
246 CGContextFillRect( cgContext
, bounds
);
259 #if wxMAC_USE_CORE_GRAPHICS
260 bool created
= false ;
261 CGContextRef cgContext
= NULL
;
262 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
263 wxASSERT_MSG( err
== noErr
, wxT("Unable to retrieve CGContextRef") ) ;
264 thisWindow
->MacSetCGContextRef( cgContext
) ;
267 wxMacCGContextStateSaver
sg( cgContext
) ;
270 wxWindow
* iter
= thisWindow
;
273 alpha
*= (float) iter
->GetTransparent()/255.0 ;
274 if ( iter
->IsTopLevel() )
277 iter
= iter
->GetParent() ;
280 CGContextSetAlpha( cgContext
, alpha
) ;
282 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
285 #if wxMAC_USE_CORE_GRAPHICS
286 thisWindow
->MacSetCGContextRef( NULL
) ;
290 CGContextRelease( cgContext
) ;
295 DisposeRgn( allocatedRgn
) ;
299 case kEventControlVisibilityChanged
:
300 thisWindow
->MacVisibilityChanged() ;
303 case kEventControlEnabledStateChanged
:
304 thisWindow
->MacEnabledStateChanged() ;
307 case kEventControlHiliteChanged
:
308 thisWindow
->MacHiliteChanged() ;
311 case kEventControlActivate
:
312 case kEventControlDeactivate
:
313 // FIXME: we should have a virtual function for this!
315 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
316 thisWindow
->Refresh();
319 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
320 thisWindow
->Refresh();
323 #endif // TARGET_API_MAC_OSX
325 // we emulate this event under Carbon CFM
326 case kEventControlSetFocusPart
:
328 Boolean focusEverything
= false ;
329 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
332 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
337 if ( thisWindow
->MacIsUserPane() )
340 if ( controlPart
== kControlFocusNoPart
)
343 if ( thisWindow
->GetCaret() )
344 thisWindow
->GetCaret()->OnKillFocus();
347 static bool inKillFocusEvent
= false ;
349 if ( !inKillFocusEvent
)
351 inKillFocusEvent
= true ;
352 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
353 event
.SetEventObject(thisWindow
);
354 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
355 inKillFocusEvent
= false ;
360 // panel wants to track the window which was the last to have focus in it
361 wxChildFocusEvent
eventFocus(thisWindow
);
362 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
365 if ( thisWindow
->GetCaret() )
366 thisWindow
->GetCaret()->OnSetFocus();
369 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
370 event
.SetEventObject(thisWindow
);
371 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
376 case kEventControlHit
:
377 result
= thisWindow
->MacControlHit( handler
, event
) ;
380 case kEventControlGetClickActivation
:
382 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
383 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
384 if ( !IsWindowActive(owner
) )
386 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
399 static pascal OSStatus
wxMacWindowServiceEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
401 OSStatus result
= eventNotHandledErr
;
403 wxMacCarbonEvent
cEvent( event
) ;
405 ControlRef controlRef
;
406 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
407 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
408 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
410 switch ( GetEventKind( event
) )
412 case kEventServiceGetTypes
:
416 textCtrl
->GetSelection( &from
, &to
) ;
418 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
420 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
421 if ( textCtrl
->IsEditable() )
422 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
424 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
425 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
427 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
431 CFArrayAppendValue(copyTypes
, typestring
) ;
433 CFArrayAppendValue(pasteTypes
, typestring
) ;
435 CFRelease( typestring
) ;
443 case kEventServiceCopy
:
448 textCtrl
->GetSelection( &from
, &to
) ;
449 wxString val
= textCtrl
->GetValue() ;
450 val
= val
.Mid( from
, to
- from
) ;
451 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
452 verify_noerr( ClearScrap( &scrapRef
) ) ;
453 verify_noerr( PutScrapFlavor( scrapRef
, kTXNTextData
, 0 , val
.length() , val
.c_str() ) ) ;
458 case kEventServicePaste
:
461 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
462 Size textSize
, pastedSize
;
463 verify_noerr( GetScrapFlavorSize(scrapRef
, kTXNTextData
, &textSize
) ) ;
465 char *content
= new char[textSize
] ;
466 GetScrapFlavorData(scrapRef
, kTXNTextData
, &pastedSize
, content
);
467 content
[textSize
- 1] = 0 ;
470 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
472 textCtrl
->WriteText( wxString( content
) ) ;
487 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
489 OSStatus result
= eventNotHandledErr
;
490 wxWindowMac
* focus
= (wxWindowMac
*) data
;
492 wchar_t* uniChars
= NULL
;
493 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
495 UniChar
* charBuf
= NULL
;
496 ByteCount dataSize
= 0 ;
499 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
501 numChars
= dataSize
/ sizeof( UniChar
) + 1;
504 if ( (size_t) numChars
* 2 > sizeof(buf
) )
505 charBuf
= new UniChar
[ numChars
] ;
509 uniChars
= new wchar_t[ numChars
] ;
510 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
511 charBuf
[ numChars
- 1 ] = 0;
512 #if SIZEOF_WCHAR_T == 2
513 uniChars
= (wchar_t*) charBuf
;
514 /* 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...)
516 // the resulting string will never have more chars than the utf16 version, so this is safe
517 wxMBConvUTF16 converter
;
518 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
522 switch ( GetEventKind( event
) )
524 case kEventTextInputUpdateActiveInputArea
:
526 // An IME input event may return several characters, but we need to send one char at a time to
528 for (int pos
=0 ; pos
< numChars
; pos
++)
530 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
531 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
532 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
534 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
536 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
537 multiple times to update the active range during inline input, so this handler will often receive
538 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
539 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
540 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
541 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
542 should add new event types to support advanced text input. For now, I would keep things as they are.
544 However, the code that was being used caused additional problems:
545 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
546 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
547 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
548 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
549 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
550 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
551 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
552 overlap with Unicode within the (7-bit) ASCII range.
553 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
554 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
555 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
556 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
557 I don't have time to look into that right now.
560 if ( wxTheApp
->MacSendCharEvent(
561 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
566 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
570 case kEventTextInputUnicodeForKeyEvent
:
572 UInt32 keyCode
, modifiers
;
575 unsigned char charCode
;
577 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
578 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
579 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
580 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
581 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
583 UInt32 message
= (keyCode
<< 8) + charCode
;
585 // An IME input event may return several characters, but we need to send one char at a time to
587 for (int pos
=0 ; pos
< numChars
; pos
++)
589 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
590 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
591 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
593 if ( wxTheApp
->MacSendCharEvent(
594 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
599 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
608 if ( charBuf
!= buf
)
614 static pascal OSStatus
wxMacWindowCommandEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
616 OSStatus result
= eventNotHandledErr
;
617 wxWindowMac
* focus
= (wxWindowMac
*) data
;
621 wxMacCarbonEvent
cEvent( event
) ;
622 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
624 wxMenuItem
* item
= NULL
;
625 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
626 int id
= wxMacCommandToId( command
.commandID
) ;
630 wxASSERT( itemMenu
!= NULL
) ;
632 switch ( cEvent
.GetKind() )
634 case kEventProcessCommand
:
636 if (item
->IsCheckable())
637 item
->Check( !item
->IsChecked() ) ;
639 if ( itemMenu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
643 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
, id
);
644 event
.SetEventObject(focus
);
645 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
647 if ( focus
->GetEventHandler()->ProcessEvent(event
) )
653 case kEventCommandUpdateStatus
:
655 wxUpdateUIEvent
event(id
);
656 event
.SetEventObject( itemMenu
);
658 bool processed
= false;
660 // Try the menu's event handler
662 wxEvtHandler
*handler
= itemMenu
->GetEventHandler();
664 processed
= handler
->ProcessEvent(event
);
667 // Try the window the menu was popped up from
668 // (and up through the hierarchy)
671 const wxMenuBase
*menu
= itemMenu
;
674 wxWindow
*win
= menu
->GetInvokingWindow();
677 processed
= win
->GetEventHandler()->ProcessEvent(event
);
681 menu
= menu
->GetParent();
687 processed
= focus
->GetEventHandler()->ProcessEvent(event
);
692 // if anything changed, update the changed attribute
693 if (event
.GetSetText())
694 itemMenu
->SetLabel(id
, event
.GetText());
695 if (event
.GetSetChecked())
696 itemMenu
->Check(id
, event
.GetChecked());
697 if (event
.GetSetEnabled())
698 itemMenu
->Enable(id
, event
.GetEnabled());
712 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
714 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
715 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
716 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
717 OSStatus result
= eventNotHandledErr
;
719 switch ( GetEventClass( event
) )
721 case kEventClassCommand
:
722 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
725 case kEventClassControl
:
726 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
729 case kEventClassService
:
730 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
733 case kEventClassTextInput
:
734 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
741 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
746 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
748 #if !TARGET_API_MAC_OSX
750 // ---------------------------------------------------------------------------
751 // UserPane events for non OSX builds
752 // ---------------------------------------------------------------------------
754 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
756 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
758 win
->MacControlUserPaneDrawProc(part
) ;
760 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
762 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
764 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
766 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
768 return kControlNoPart
;
770 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
772 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
774 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
776 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
778 return kControlNoPart
;
780 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
782 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
784 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
786 win
->MacControlUserPaneIdleProc() ;
788 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
790 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
792 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
794 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
796 return kControlNoPart
;
798 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
800 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
802 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
804 win
->MacControlUserPaneActivateProc(activating
) ;
806 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
808 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
810 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
812 return win
->MacControlUserPaneFocusProc(action
) ;
814 return kControlNoPart
;
816 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
818 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
820 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
822 win
->MacControlUserPaneBackgroundProc(info
) ;
824 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
826 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
829 RgnHandle rgn
= NewRgn() ;
831 MacWindowToRootWindow( &x
, &y
) ;
832 OffsetRgn( rgn
, -x
, -y
) ;
833 wxMacWindowStateSaver
sv( this ) ;
834 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
835 MacDoRedraw( rgn
, 0 ) ;
839 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
841 return kControlNoPart
;
844 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
846 return kControlNoPart
;
849 void wxWindowMac::MacControlUserPaneIdleProc()
853 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
855 return kControlNoPart
;
858 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
862 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
864 if ( AcceptsFocus() )
867 return kControlNoPart
;
870 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
876 // ---------------------------------------------------------------------------
877 // Scrollbar Tracking for all
878 // ---------------------------------------------------------------------------
880 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
881 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
885 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
887 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
890 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
892 // ===========================================================================
894 // ===========================================================================
896 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
898 static MacControlMap wxWinMacControlList
;
900 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
902 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
904 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
907 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
909 // adding NULL ControlRef is (first) surely a result of an error and
910 // (secondly) breaks native event processing
911 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
913 wxWinMacControlList
[inControl
] = control
;
916 void wxRemoveMacControlAssociation(wxWindow
*control
)
918 // iterate over all the elements in the class
919 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
920 // we should go on...
926 MacControlMap::iterator it
;
927 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
929 if ( it
->second
== control
)
931 wxWinMacControlList
.erase(it
);
939 // ----------------------------------------------------------------------------
940 // constructors and such
941 // ----------------------------------------------------------------------------
943 wxWindowMac::wxWindowMac()
948 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
953 const wxString
& name
)
956 Create(parent
, id
, pos
, size
, style
, name
);
959 void wxWindowMac::Init()
965 #if wxMAC_USE_CORE_GRAPHICS
966 m_cgContextRef
= NULL
;
969 // as all windows are created with WS_VISIBLE style...
972 m_hScrollBar
= NULL
;
973 m_vScrollBar
= NULL
;
974 m_macBackgroundBrush
= wxNullBrush
;
976 m_macIsUserPane
= true;
977 m_clipChildren
= false ;
978 m_cachedClippedRectValid
= false ;
980 // we need a valid font for the encodings
981 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
984 wxWindowMac::~wxWindowMac()
988 m_isBeingDeleted
= true;
990 MacInvalidateBorders() ;
992 #ifndef __WXUNIVERSAL__
993 // VS: make sure there's no wxFrame with last focus set to us:
994 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
996 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
999 if ( frame
->GetLastFocus() == this )
1000 frame
->SetLastFocus((wxWindow
*)NULL
);
1006 // destroy children before destroying this window itself
1009 // wxRemoveMacControlAssociation( this ) ;
1010 // If we delete an item, we should initialize the parent panel,
1011 // because it could now be invalid.
1012 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
1015 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
1016 tlw
->SetDefaultItem(NULL
);
1019 if ( m_peer
&& m_peer
->Ok() )
1021 // in case the callback might be called during destruction
1022 wxRemoveMacControlAssociation( this) ;
1023 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
1024 // we currently are not using this hook
1025 // ::SetControlColorProc( *m_peer , NULL ) ;
1029 if ( g_MacLastWindow
== this )
1030 g_MacLastWindow
= NULL
;
1032 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame
) ;
1035 if ( frame
->GetLastFocus() == this )
1036 frame
->SetLastFocus( NULL
) ;
1039 // delete our drop target if we've got one
1040 #if wxUSE_DRAG_AND_DROP
1041 if ( m_dropTarget
!= NULL
)
1043 delete m_dropTarget
;
1044 m_dropTarget
= NULL
;
1051 WXWidget
wxWindowMac::GetHandle() const
1053 return (WXWidget
) m_peer
->GetControlRef() ;
1056 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1058 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1059 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1060 GetEventTypeCount(eventList
), eventList
, this,
1061 (EventHandlerRef
*)&m_macControlEventHandler
);
1063 #if !TARGET_API_MAC_OSX
1064 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1066 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1067 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1068 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1069 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1070 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1071 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1072 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1073 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1079 bool wxWindowMac::Create(wxWindowMac
*parent
,
1084 const wxString
& name
)
1086 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1088 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1091 m_windowVariant
= parent
->GetWindowVariant() ;
1093 if ( m_macIsUserPane
)
1095 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1098 | kControlSupportsEmbedding
1099 | kControlSupportsLiveFeedback
1100 | kControlGetsFocusOnClick
1101 // | kControlHasSpecialBackground
1102 // | kControlSupportsCalcBestRect
1103 | kControlHandlesTracking
1104 | kControlSupportsFocus
1105 | kControlWantsActivate
1106 | kControlWantsIdle
;
1108 m_peer
= new wxMacControl(this) ;
1109 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1110 verify_noerr( err
);
1112 MacPostControlCreate(pos
, size
) ;
1115 #ifndef __WXUNIVERSAL__
1116 // Don't give scrollbars to wxControls unless they ask for them
1117 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1118 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1120 MacCreateScrollBars( style
) ;
1124 wxWindowCreateEvent
event(this);
1125 GetEventHandler()->AddPendingEvent(event
);
1130 void wxWindowMac::MacChildAdded()
1133 m_vScrollBar
->Raise() ;
1135 m_hScrollBar
->Raise() ;
1138 void wxWindowMac::MacPostControlCreate(const wxPoint
& pos
, const wxSize
& size
)
1140 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1142 m_peer
->SetReference( (URefCon
) this ) ;
1143 GetParent()->AddChild( this );
1145 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1147 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1148 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1149 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1150 GetParent()->MacChildAdded() ;
1152 // adjust font, controlsize etc
1153 DoSetWindowVariant( m_windowVariant
) ;
1155 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1157 if (!m_macIsUserPane
)
1158 SetInitialSize(size
);
1160 SetCursor( *wxSTANDARD_CURSOR
) ;
1163 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1165 // Don't assert, in case we set the window variant before
1166 // the window is created
1167 // wxASSERT( m_peer->Ok() ) ;
1169 m_windowVariant
= variant
;
1171 if (m_peer
== NULL
|| !m_peer
->Ok())
1175 ThemeFontID themeFont
= kThemeSystemFont
;
1177 // we will get that from the settings later
1178 // and make this NORMAL later, but first
1179 // we have a few calculations that we must fix
1183 case wxWINDOW_VARIANT_NORMAL
:
1184 size
= kControlSizeNormal
;
1185 themeFont
= kThemeSystemFont
;
1188 case wxWINDOW_VARIANT_SMALL
:
1189 size
= kControlSizeSmall
;
1190 themeFont
= kThemeSmallSystemFont
;
1193 case wxWINDOW_VARIANT_MINI
:
1194 if (UMAGetSystemVersion() >= 0x1030 )
1196 // not always defined in the headers
1202 size
= kControlSizeSmall
;
1203 themeFont
= kThemeSmallSystemFont
;
1207 case wxWINDOW_VARIANT_LARGE
:
1208 size
= kControlSizeLarge
;
1209 themeFont
= kThemeSystemFont
;
1213 wxFAIL_MSG(_T("unexpected window variant"));
1217 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1220 font
.MacCreateThemeFont( themeFont
) ;
1224 void wxWindowMac::MacUpdateControlFont()
1226 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1230 bool wxWindowMac::SetFont(const wxFont
& font
)
1232 bool retval
= wxWindowBase::SetFont( font
);
1234 MacUpdateControlFont() ;
1239 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1241 bool retval
= wxWindowBase::SetForegroundColour( col
);
1244 MacUpdateControlFont();
1249 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1251 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1255 wxColour
newCol(GetBackgroundColour());
1257 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1258 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1259 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1260 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1262 brush
.SetColour( newCol
) ;
1264 MacSetBackgroundBrush( brush
) ;
1265 MacUpdateControlFont() ;
1270 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1272 m_macBackgroundBrush
= brush
;
1273 m_peer
->SetBackground( brush
) ;
1276 bool wxWindowMac::MacCanFocus() const
1278 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1279 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1280 // but the value range is nowhere documented
1281 Boolean keyExistsAndHasValidFormat
;
1282 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1283 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1285 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1291 UInt32 features
= 0 ;
1292 m_peer
->GetFeatures( &features
) ;
1294 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1298 void wxWindowMac::SetFocus()
1300 if ( !AcceptsFocus() )
1303 wxWindow
* former
= FindFocus() ;
1304 if ( former
== this )
1307 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1308 // we can only leave in case of an error
1309 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1310 if ( err
== errCouldntSetFocus
)
1313 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1315 #if !TARGET_API_MAC_OSX
1316 // emulate carbon events when running under CarbonLib where they are not natively available
1319 EventRef evRef
= NULL
;
1321 err
= MacCreateEvent(
1322 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1323 kEventAttributeUserEvent
, &evRef
);
1324 verify_noerr( err
);
1326 wxMacCarbonEvent
cEvent( evRef
) ;
1327 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1328 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1330 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1331 ReleaseEvent( evRef
) ;
1334 // send new focus event
1336 EventRef evRef
= NULL
;
1338 err
= MacCreateEvent(
1339 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1340 kEventAttributeUserEvent
, &evRef
);
1341 verify_noerr( err
);
1343 wxMacCarbonEvent
cEvent( evRef
) ;
1344 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1345 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1347 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1348 ReleaseEvent( evRef
) ;
1353 void wxWindowMac::DoCaptureMouse()
1355 wxApp::s_captureWindow
= this ;
1358 wxWindow
* wxWindowBase::GetCapture()
1360 return wxApp::s_captureWindow
;
1363 void wxWindowMac::DoReleaseMouse()
1365 wxApp::s_captureWindow
= NULL
;
1368 #if wxUSE_DRAG_AND_DROP
1370 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1372 if ( m_dropTarget
!= NULL
)
1373 delete m_dropTarget
;
1375 m_dropTarget
= pDropTarget
;
1376 if ( m_dropTarget
!= NULL
)
1384 // Old-style File Manager Drag & Drop
1385 void wxWindowMac::DragAcceptFiles(bool accept
)
1390 // Returns the size of the native control. In the case of the toplevel window
1391 // this is the content area root control
1393 void wxWindowMac::MacGetPositionAndSizeFromControl(int& x
, int& y
,
1394 int& w
, int& h
) const
1396 wxFAIL_MSG( wxT("Not currently supported") ) ;
1399 // From a wx position / size calculate the appropriate size of the native control
1401 bool wxWindowMac::MacGetBoundsForControl(
1405 int& w
, int& h
, bool adjustOrigin
) const
1407 // the desired size, minus the border pixels gives the correct size of the control
1411 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1412 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1413 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1415 x
+= MacGetLeftBorderSize() ;
1416 y
+= MacGetTopBorderSize() ;
1417 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1418 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1421 AdjustForParentClientOrigin( x
, y
) ;
1423 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1424 if ( !GetParent()->IsTopLevel() )
1426 x
-= GetParent()->MacGetLeftBorderSize() ;
1427 y
-= GetParent()->MacGetTopBorderSize() ;
1433 // Get window size (not client size)
1434 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1437 m_peer
->GetRect( &bounds
) ;
1440 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1442 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1445 // get the position of the bounds of this window in client coordinates of its parent
1446 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1449 m_peer
->GetRect( &bounds
) ;
1451 int x1
= bounds
.left
;
1452 int y1
= bounds
.top
;
1454 // get the wx window position from the native one
1455 x1
-= MacGetLeftBorderSize() ;
1456 y1
-= MacGetTopBorderSize() ;
1458 if ( !IsTopLevel() )
1460 wxWindow
*parent
= GetParent();
1463 // we must first adjust it to be in window coordinates of the parent,
1464 // as otherwise it gets lost by the ClientAreaOrigin fix
1465 x1
+= parent
->MacGetLeftBorderSize() ;
1466 y1
+= parent
->MacGetTopBorderSize() ;
1468 // and now to client coordinates
1469 wxPoint
pt(parent
->GetClientAreaOrigin());
1481 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1483 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1484 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1486 Point localwhere
= { 0, 0 } ;
1493 wxMacGlobalToLocal( window
, &localwhere
) ;
1500 MacRootWindowToWindow( x
, y
) ;
1502 wxPoint origin
= GetClientAreaOrigin() ;
1509 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1511 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1512 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1514 wxPoint origin
= GetClientAreaOrigin() ;
1520 MacWindowToRootWindow( x
, y
) ;
1522 Point localwhere
= { 0, 0 };
1528 wxMacLocalToGlobal( window
, &localwhere
) ;
1536 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1538 wxPoint origin
= GetClientAreaOrigin() ;
1544 MacWindowToRootWindow( x
, y
) ;
1547 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1549 MacRootWindowToWindow( x
, y
) ;
1551 wxPoint origin
= GetClientAreaOrigin() ;
1558 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1567 if ( !IsTopLevel() )
1569 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1572 pt
.x
-= MacGetLeftBorderSize() ;
1573 pt
.y
-= MacGetTopBorderSize() ;
1574 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1584 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1593 MacWindowToRootWindow( &x1
, &y1
) ;
1601 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1610 if ( !IsTopLevel() )
1612 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1615 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1616 pt
.x
+= MacGetLeftBorderSize() ;
1617 pt
.y
+= MacGetTopBorderSize() ;
1627 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1636 MacRootWindowToWindow( &x1
, &y1
) ;
1644 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1646 RgnHandle rgn
= NewRgn() ;
1648 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1650 Rect structure
, content
;
1652 GetRegionBounds( rgn
, &content
) ;
1653 m_peer
->GetRect( &structure
) ;
1654 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1656 left
= content
.left
- structure
.left
;
1657 top
= content
.top
- structure
.top
;
1658 right
= structure
.right
- content
.right
;
1659 bottom
= structure
.bottom
- content
.bottom
;
1663 left
= top
= right
= bottom
= 0 ;
1669 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1671 wxSize sizeTotal
= size
;
1673 RgnHandle rgn
= NewRgn() ;
1674 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1676 Rect content
, structure
;
1677 GetRegionBounds( rgn
, &content
) ;
1678 m_peer
->GetRect( &structure
) ;
1680 // structure is in parent coordinates, but we only need width and height, so it's ok
1682 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1683 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1688 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1689 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1694 // Get size *available for subwindows* i.e. excluding menu bar etc.
1695 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1699 RgnHandle rgn
= NewRgn() ;
1701 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1702 GetRegionBounds( rgn
, &content
) ;
1704 m_peer
->GetRect( &content
) ;
1707 ww
= content
.right
- content
.left
;
1708 hh
= content
.bottom
- content
.top
;
1710 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1711 hh
-= m_hScrollBar
->GetSize().y
;
1713 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1714 ww
-= m_vScrollBar
->GetSize().x
;
1722 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1724 if (m_cursor
.IsSameAs(cursor
))
1729 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1734 if ( ! wxWindowBase::SetCursor( cursor
) )
1738 wxASSERT_MSG( m_cursor
.Ok(),
1739 wxT("cursor must be valid after call to the base version"));
1741 wxWindowMac
*mouseWin
= 0 ;
1743 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1744 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1746 ControlPartCode part
;
1747 ControlRef control
;
1749 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1751 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1756 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1758 // TODO: If we ever get a GetCurrentEvent... replacement
1759 // for the mouse position, use it...
1764 control
= wxMacFindControlUnderMouse( tlw
, pt
, window
, &part
) ;
1766 mouseWin
= wxFindControlFromMacControl( control
) ;
1768 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1770 QDSwapPort( savePort
, NULL
) ;
1774 if ( mouseWin
== this && !wxIsBusy() )
1775 m_cursor
.MacInstall() ;
1781 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1783 menu
->SetInvokingWindow(this);
1786 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1788 wxPoint mouse
= wxGetMousePosition();
1794 ClientToScreen( &x
, &y
) ;
1797 menu
->MacBeforeDisplay( true ) ;
1798 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1799 if ( HiWord(menuResult
) != 0 )
1802 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1803 int id
= wxMacCommandToId( macid
);
1804 wxMenuItem
* item
= NULL
;
1806 item
= menu
->FindItem( id
, &realmenu
) ;
1809 if (item
->IsCheckable())
1810 item
->Check( !item
->IsChecked() ) ;
1812 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1816 menu
->MacAfterDisplay( true ) ;
1817 menu
->SetInvokingWindow( NULL
);
1823 // ----------------------------------------------------------------------------
1825 // ----------------------------------------------------------------------------
1829 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1831 wxWindowBase::DoSetToolTip(tooltip
);
1834 m_tooltip
->SetWindow(this);
1839 void wxWindowMac::MacInvalidateBorders()
1841 if ( m_peer
== NULL
)
1844 bool vis
= MacIsReallyShown() ;
1848 int outerBorder
= MacGetLeftBorderSize() ;
1849 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1852 if ( outerBorder
== 0 )
1855 // now we know that we have something to do at all
1857 // as the borders are drawn on the parent we have to properly invalidate all these areas
1858 RgnHandle updateInner
, updateOuter
;
1861 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1862 updateInner
= NewRgn() ;
1863 updateOuter
= NewRgn() ;
1865 m_peer
->GetRect( &rect
) ;
1866 RectRgn( updateInner
, &rect
) ;
1867 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1868 RectRgn( updateOuter
, &rect
) ;
1869 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1871 #ifdef __WXMAC_OSX__
1872 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1874 WindowRef tlw
= (WindowRef
) MacGetTopLevelWindowRef() ;
1876 InvalWindowRgn( tlw
, updateOuter
) ;
1879 DisposeRgn( updateOuter
) ;
1880 DisposeRgn( updateInner
) ;
1883 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1885 // this is never called for a toplevel window, so we know we have a parent
1886 int former_x
, former_y
, former_w
, former_h
;
1888 // Get true coordinates of former position
1889 DoGetPosition( &former_x
, &former_y
) ;
1890 DoGetSize( &former_w
, &former_h
) ;
1892 wxWindow
*parent
= GetParent();
1895 wxPoint
pt(parent
->GetClientAreaOrigin());
1900 int actualWidth
= width
;
1901 int actualHeight
= height
;
1905 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1906 actualWidth
= m_minWidth
;
1907 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1908 actualHeight
= m_minHeight
;
1909 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1910 actualWidth
= m_maxWidth
;
1911 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1912 actualHeight
= m_maxHeight
;
1914 bool doMove
= false, doResize
= false ;
1916 if ( actualX
!= former_x
|| actualY
!= former_y
)
1919 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1922 if ( doMove
|| doResize
)
1924 // as the borders are drawn outside the native control, we adjust now
1926 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1927 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1928 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1931 wxMacRectToNative( &bounds
, &r
) ;
1933 if ( !GetParent()->IsTopLevel() )
1934 wxMacWindowToNative( GetParent() , &r
) ;
1936 MacInvalidateBorders() ;
1938 m_cachedClippedRectValid
= false ;
1939 m_peer
->SetRect( &r
) ;
1941 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1943 MacInvalidateBorders() ;
1945 MacRepositionScrollBars() ;
1948 wxPoint
point(actualX
, actualY
);
1949 wxMoveEvent
event(point
, m_windowId
);
1950 event
.SetEventObject(this);
1951 GetEventHandler()->ProcessEvent(event
) ;
1956 MacRepositionScrollBars() ;
1957 wxSize
size(actualWidth
, actualHeight
);
1958 wxSizeEvent
event(size
, m_windowId
);
1959 event
.SetEventObject(this);
1960 GetEventHandler()->ProcessEvent(event
);
1965 wxSize
wxWindowMac::DoGetBestSize() const
1967 if ( m_macIsUserPane
|| IsTopLevel() )
1968 return wxWindowBase::DoGetBestSize() ;
1970 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1971 int bestWidth
, bestHeight
;
1973 m_peer
->GetBestRect( &bestsize
) ;
1974 if ( EmptyRect( &bestsize
) )
1979 bestsize
.bottom
= 16 ;
1981 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1983 bestsize
.bottom
= 16 ;
1986 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1988 bestsize
.bottom
= 24 ;
1993 // return wxWindowBase::DoGetBestSize() ;
1997 bestWidth
= bestsize
.right
- bestsize
.left
;
1998 bestHeight
= bestsize
.bottom
- bestsize
.top
;
1999 if ( bestHeight
< 10 )
2002 return wxSize(bestWidth
, bestHeight
);
2005 // set the size of the window: if the dimensions are positive, just use them,
2006 // but if any of them is equal to -1, it means that we must find the value for
2007 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
2008 // which case -1 is a valid value for x and y)
2010 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
2011 // the width/height to best suit our contents, otherwise we reuse the current
2013 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
2015 // get the current size and position...
2016 int currentX
, currentY
;
2017 int currentW
, currentH
;
2019 GetPosition(¤tX
, ¤tY
);
2020 GetSize(¤tW
, ¤tH
);
2022 // ... and don't do anything (avoiding flicker) if it's already ok
2023 if ( x
== currentX
&& y
== currentY
&&
2024 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
2027 MacRepositionScrollBars() ; // we might have a real position shift
2032 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
2034 if ( x
== wxDefaultCoord
)
2036 if ( y
== wxDefaultCoord
)
2040 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2042 wxSize size
= wxDefaultSize
;
2043 if ( width
== wxDefaultCoord
)
2045 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2047 size
= DoGetBestSize();
2052 // just take the current one
2057 if ( height
== wxDefaultCoord
)
2059 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2061 if ( size
.x
== wxDefaultCoord
)
2062 size
= DoGetBestSize();
2063 // else: already called DoGetBestSize() above
2069 // just take the current one
2074 DoMoveWindow( x
, y
, width
, height
);
2077 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2079 RgnHandle rgn
= NewRgn() ;
2081 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2083 GetRegionBounds( rgn
, &content
) ;
2093 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2096 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2098 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2100 int currentclientwidth
, currentclientheight
;
2101 int currentwidth
, currentheight
;
2103 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2104 GetSize( ¤twidth
, ¤theight
) ;
2106 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2107 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2111 void wxWindowMac::SetLabel(const wxString
& title
)
2113 m_label
= wxStripMenuCodes(title
, wxStrip_Mnemonics
) ;
2115 if ( m_peer
&& m_peer
->Ok() )
2116 m_peer
->SetLabel( m_label
) ;
2121 wxString
wxWindowMac::GetLabel() const
2126 bool wxWindowMac::Show(bool show
)
2128 bool former
= MacIsReallyShown() ;
2129 if ( !wxWindowBase::Show(show
) )
2132 // TODO: use visibilityChanged Carbon Event for OSX
2134 m_peer
->SetVisibility( show
, true ) ;
2136 if ( former
!= MacIsReallyShown() )
2137 MacPropagateVisibilityChanged() ;
2142 void wxWindowMac::DoEnable(bool enable
)
2144 m_peer
->Enable( enable
) ;
2148 // status change propagations (will be not necessary for OSX later )
2151 void wxWindowMac::MacPropagateVisibilityChanged()
2153 #if !TARGET_API_MAC_OSX
2154 MacVisibilityChanged() ;
2157 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2160 child
= node
->GetData();
2161 if ( child
->IsShown() )
2162 child
->MacPropagateVisibilityChanged() ;
2164 node
= node
->GetNext();
2169 void wxWindowMac::OnEnabled(bool enabled
)
2171 #if !TARGET_API_MAC_OSX
2172 MacEnabledStateChanged() ;
2176 void wxWindowMac::MacPropagateHiliteChanged()
2178 #if !TARGET_API_MAC_OSX
2179 MacHiliteChanged() ;
2182 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2185 child
= node
->GetData();
2186 if (child
/* && child->IsEnabled() */)
2187 child
->MacPropagateHiliteChanged() ;
2189 node
= node
->GetNext();
2195 // status change notifications
2198 void wxWindowMac::MacVisibilityChanged()
2202 void wxWindowMac::MacHiliteChanged()
2206 void wxWindowMac::MacEnabledStateChanged()
2211 // status queries on the inherited window's state
2214 bool wxWindowMac::MacIsReallyShown()
2216 // only under OSX the visibility of the TLW is taken into account
2217 if ( m_isBeingDeleted
)
2220 #if TARGET_API_MAC_OSX
2221 if ( m_peer
&& m_peer
->Ok() )
2222 return m_peer
->IsVisible();
2225 wxWindow
* win
= this ;
2226 while ( win
->IsShown() )
2228 if ( win
->IsTopLevel() )
2231 win
= win
->GetParent() ;
2239 bool wxWindowMac::MacIsReallyEnabled()
2241 return m_peer
->IsEnabled() ;
2244 bool wxWindowMac::MacIsReallyHilited()
2246 return m_peer
->IsActive();
2249 void wxWindowMac::MacFlashInvalidAreas()
2251 #if TARGET_API_MAC_OSX
2252 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2256 int wxWindowMac::GetCharHeight() const
2258 wxClientDC
dc( (wxWindowMac
*)this ) ;
2260 return dc
.GetCharHeight() ;
2263 int wxWindowMac::GetCharWidth() const
2265 wxClientDC
dc( (wxWindowMac
*)this ) ;
2267 return dc
.GetCharWidth() ;
2270 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2271 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2273 const wxFont
*fontToUse
= theFont
;
2275 fontToUse
= &m_font
;
2277 wxClientDC
dc( (wxWindowMac
*) this ) ;
2278 wxCoord lx
,ly
,ld
,le
;
2279 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2280 if ( externalLeading
)
2281 *externalLeading
= le
;
2291 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2292 * we always intersect with the entire window, not only with the client area
2295 void wxWindowMac::Refresh(bool eraseBack
, const wxRect
*rect
)
2297 if ( m_peer
== NULL
)
2300 if ( !MacIsReallyShown() )
2307 wxMacRectToNative( rect
, &r
) ;
2308 m_peer
->SetNeedsDisplay( &r
) ;
2312 m_peer
->SetNeedsDisplay() ;
2316 void wxWindowMac::Freeze()
2318 #if TARGET_API_MAC_OSX
2319 if ( !m_frozenness
++ )
2321 if ( m_peer
&& m_peer
->Ok() )
2322 m_peer
->SetDrawingEnabled( false ) ;
2327 void wxWindowMac::Thaw()
2329 #if TARGET_API_MAC_OSX
2330 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2332 if ( !--m_frozenness
)
2334 if ( m_peer
&& m_peer
->Ok() )
2336 m_peer
->SetDrawingEnabled( true ) ;
2337 m_peer
->InvalidateWithChildren() ;
2343 bool wxWindowMac::IsFrozen() const
2345 return m_frozenness
!= 0;
2348 wxWindowMac
*wxGetActiveWindow()
2350 // actually this is a windows-only concept
2354 // Coordinates relative to the window
2355 void wxWindowMac::WarpPointer(int x_pos
, int y_pos
)
2357 // We really don't move the mouse programmatically under Mac.
2360 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2362 if ( MacGetTopLevelWindow() == NULL
)
2365 #if TARGET_API_MAC_OSX
2366 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
)
2373 event
.GetDC()->Clear() ;
2377 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2382 int wxWindowMac::GetScrollPos(int orient
) const
2384 if ( orient
== wxHORIZONTAL
)
2387 return m_hScrollBar
->GetThumbPosition() ;
2392 return m_vScrollBar
->GetThumbPosition() ;
2398 // This now returns the whole range, not just the number
2399 // of positions that we can scroll.
2400 int wxWindowMac::GetScrollRange(int orient
) const
2402 if ( orient
== wxHORIZONTAL
)
2405 return m_hScrollBar
->GetRange() ;
2410 return m_vScrollBar
->GetRange() ;
2416 int wxWindowMac::GetScrollThumb(int orient
) const
2418 if ( orient
== wxHORIZONTAL
)
2421 return m_hScrollBar
->GetThumbSize() ;
2426 return m_vScrollBar
->GetThumbSize() ;
2432 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool refresh
)
2434 if ( orient
== wxHORIZONTAL
)
2437 m_hScrollBar
->SetThumbPosition( pos
) ;
2442 m_vScrollBar
->SetThumbPosition( pos
) ;
2447 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2448 // our own window origin is at leftOrigin/rightOrigin
2451 void wxWindowMac::MacPaintBorders( int leftOrigin
, int rightOrigin
)
2457 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2458 bool hasBothScrollbars
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && (m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
2460 // back to the surrounding frame rectangle
2461 m_peer
->GetRect( &rect
) ;
2462 InsetRect( &rect
, -1 , -1 ) ;
2464 #if wxMAC_USE_CORE_GRAPHICS
2466 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2467 rect
.bottom
- rect
.top
) ;
2469 HIThemeFrameDrawInfo info
;
2470 memset( &info
, 0 , sizeof(info
) ) ;
2474 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2475 info
.isFocused
= hasFocus
;
2477 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2478 wxASSERT( cgContext
) ;
2480 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2482 info
.kind
= kHIThemeFrameTextFieldSquare
;
2483 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2485 else if ( HasFlag(wxSIMPLE_BORDER
) )
2487 info
.kind
= kHIThemeFrameListBox
;
2488 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2490 else if ( hasFocus
)
2492 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2495 m_peer
->GetRect( &rect
) ;
2496 if ( hasBothScrollbars
)
2498 int size
= m_hScrollBar
->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL
? 16 : 12 ;
2499 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2500 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2501 HIThemeGrowBoxDrawInfo info
;
2502 memset( &info
, 0, sizeof(info
) ) ;
2504 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2505 info
.kind
= kHIThemeGrowBoxKindNone
;
2506 info
.size
= kHIThemeGrowBoxSizeNormal
;
2507 info
.direction
= kThemeGrowRight
| kThemeGrowDown
;
2508 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2513 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2517 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2518 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2521 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2522 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2523 else if ( HasFlag(wxSIMPLE_BORDER
) )
2524 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2527 DrawThemeFocusRect( &rect
, true ) ;
2529 if ( hasBothScrollbars
)
2531 // GetThemeStandaloneGrowBoxBounds
2532 // DrawThemeStandaloneNoGrowBox
2538 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2540 if ( child
== m_hScrollBar
)
2541 m_hScrollBar
= NULL
;
2542 if ( child
== m_vScrollBar
)
2543 m_vScrollBar
= NULL
;
2545 wxWindowBase::RemoveChild( child
) ;
2548 // New function that will replace some of the above.
2549 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumbVisible
,
2550 int range
, bool refresh
)
2553 bool triggerSizeEvent
= false;
2555 if ( orient
== wxHORIZONTAL
)
2559 showScroller
= ((range
!= 0) && (range
> thumbVisible
));
2560 if ( m_hScrollBar
->IsShown() != showScroller
)
2562 m_hScrollBar
->Show( showScroller
);
2563 triggerSizeEvent
= true;
2566 m_hScrollBar
->SetScrollbar( pos
, thumbVisible
, range
, thumbVisible
, refresh
) ;
2573 showScroller
= ((range
!= 0) && (range
> thumbVisible
));
2574 if ( m_vScrollBar
->IsShown() != showScroller
)
2576 m_vScrollBar
->Show( showScroller
) ;
2577 triggerSizeEvent
= true;
2580 m_vScrollBar
->SetScrollbar( pos
, thumbVisible
, range
, thumbVisible
, refresh
) ;
2584 MacRepositionScrollBars() ;
2585 if ( triggerSizeEvent
)
2587 wxSizeEvent
event(GetSize(), m_windowId
);
2588 event
.SetEventObject(this);
2589 GetEventHandler()->ProcessEvent(event
);
2593 // Does a physical scroll
2594 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2596 if ( dx
== 0 && dy
== 0 )
2599 int width
, height
;
2600 GetClientSize( &width
, &height
) ;
2603 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2604 // area is scrolled, this does not occur if width and height are 2 pixels less,
2605 // TODO: write optimal workaround
2606 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2608 scrollrect
.Intersect( *rect
) ;
2610 if ( m_peer
->GetNeedsDisplay() )
2612 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2613 // in case there is already a pending redraw on that area
2614 // either immediate redraw or full invalidate
2616 // is the better overall solution, as it does not slow down scrolling
2617 m_peer
->SetNeedsDisplay() ;
2619 // this would be the preferred version for fast drawing controls
2621 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2622 if ( UMAGetSystemVersion() >= 0x1030 )
2623 HIViewRender(m_peer
->GetControlRef()) ;
2630 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2631 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2632 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2635 // this would be the preferred version for fast drawing controls
2636 HIViewRender(m_peer
->GetControlRef()) ;
2642 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2644 child
= node
->GetData();
2647 if (child
== m_vScrollBar
)
2649 if (child
== m_hScrollBar
)
2651 if (child
->IsTopLevel())
2654 child
->GetPosition( &x
, &y
);
2655 child
->GetSize( &w
, &h
);
2658 wxRect
rc( x
, y
, w
, h
);
2659 if (rect
->Intersects( rc
))
2660 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2664 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2669 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2671 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2673 wxScrollWinEvent wevent
;
2674 wevent
.SetPosition(event
.GetPosition());
2675 wevent
.SetOrientation(event
.GetOrientation());
2676 wevent
.SetEventObject(this);
2678 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2679 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2680 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2681 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2682 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2683 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2684 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2685 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2686 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2687 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2688 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2689 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2690 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2691 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2692 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2693 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2695 GetEventHandler()->ProcessEvent(wevent
);
2699 // Get the window with the focus
2700 wxWindowMac
*wxWindowBase::DoFindFocus()
2702 ControlRef control
;
2703 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2704 return wxFindControlFromMacControl( control
) ;
2707 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2709 // panel wants to track the window which was the last to have focus in it,
2710 // so we want to set ourselves as the window which last had focus
2712 // notice that it's also important to do it upwards the tree because
2713 // otherwise when the top level panel gets focus, it won't set it back to
2714 // us, but to some other sibling
2716 // CS: don't know if this is still needed:
2717 //wxChildFocusEvent eventFocus(this);
2718 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2720 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2722 #if wxMAC_USE_CORE_GRAPHICS
2723 GetParent()->Refresh() ;
2725 wxMacWindowStateSaver
sv( this ) ;
2728 m_peer
->GetRect( &rect
) ;
2729 // auf den umgebenden Rahmen zur\81Â\9fck
2730 InsetRect( &rect
, -1 , -1 ) ;
2732 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2736 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2738 rect
.right
+= pt
.x
;
2740 rect
.bottom
+= pt
.y
;
2743 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2744 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2745 if ( !bIsFocusEvent
)
2747 // as this erases part of the frame we have to redraw borders
2748 // and because our z-ordering is not always correct (staticboxes)
2749 // we have to invalidate things, we cannot simple redraw
2750 MacInvalidateBorders() ;
2758 void wxWindowMac::OnInternalIdle()
2760 // This calls the UI-update mechanism (querying windows for
2761 // menu/toolbar/control state information)
2762 if (wxUpdateUIEvent::CanUpdate(this))
2763 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2766 // Raise the window to the top of the Z order
2767 void wxWindowMac::Raise()
2769 m_peer
->SetZOrder( true , NULL
) ;
2772 // Lower the window to the bottom of the Z order
2773 void wxWindowMac::Lower()
2775 m_peer
->SetZOrder( false , NULL
) ;
2778 // static wxWindow *gs_lastWhich = NULL;
2780 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2782 // first trigger a set cursor event
2784 wxPoint clientorigin
= GetClientAreaOrigin() ;
2785 wxSize clientsize
= GetClientSize() ;
2787 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2789 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2791 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2792 if ( processedEvtSetCursor
&& event
.HasCursor() )
2794 cursor
= event
.GetCursor() ;
2798 // the test for processedEvtSetCursor is here to prevent using m_cursor
2799 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2800 // it - this is a way to say that our cursor shouldn't be used for this
2802 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2805 if ( !wxIsBusy() && !GetParent() )
2806 cursor
= *wxSTANDARD_CURSOR
;
2810 cursor
.MacInstall() ;
2813 return cursor
.Ok() ;
2816 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&pt
)
2820 return m_tooltip
->GetTip() ;
2823 return wxEmptyString
;
2826 void wxWindowMac::ClearBackground()
2832 void wxWindowMac::Update()
2834 #if TARGET_API_MAC_OSX
2835 MacGetTopLevelWindow()->MacPerformUpdates() ;
2837 ::Draw1Control( m_peer
->GetControlRef() ) ;
2841 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2843 wxTopLevelWindowMac
* win
= NULL
;
2844 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2846 win
= wxFindWinFromMacWindow( window
) ;
2851 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2853 MacUpdateClippedRects() ;
2855 return m_cachedClippedClientRect
;
2858 const wxRect
& wxWindowMac::MacGetClippedRect() const
2860 MacUpdateClippedRects() ;
2862 return m_cachedClippedRect
;
2865 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2867 MacUpdateClippedRects() ;
2869 return m_cachedClippedRectWithOuterStructure
;
2872 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2874 static wxRegion emptyrgn
;
2876 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2878 MacUpdateClippedRects() ;
2879 if ( includeOuterStructures
)
2880 return m_cachedClippedRegionWithOuterStructure
;
2882 return m_cachedClippedRegion
;
2890 void wxWindowMac::MacUpdateClippedRects() const
2892 if ( m_cachedClippedRectValid
)
2895 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2896 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2897 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2898 // to add focus borders everywhere
2900 Rect r
, rIncludingOuterStructures
;
2902 m_peer
->GetRect( &r
) ;
2903 r
.left
-= MacGetLeftBorderSize() ;
2904 r
.top
-= MacGetTopBorderSize() ;
2905 r
.bottom
+= MacGetBottomBorderSize() ;
2906 r
.right
+= MacGetRightBorderSize() ;
2913 rIncludingOuterStructures
= r
;
2914 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2916 wxRect cl
= GetClientRect() ;
2917 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2921 const wxWindow
* child
= this ;
2922 const wxWindow
* parent
= NULL
;
2924 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2926 if ( parent
->MacIsChildOfClientArea(child
) )
2928 size
= parent
->GetClientSize() ;
2929 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2935 // this will be true for scrollbars, toolbars etc.
2936 size
= parent
->GetSize() ;
2937 y
= parent
->MacGetTopBorderSize() ;
2938 x
= parent
->MacGetLeftBorderSize() ;
2939 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2940 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2943 parent
->MacWindowToRootWindow( &x
, &y
) ;
2944 MacRootWindowToWindow( &x
, &y
) ;
2946 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2948 // the wxwindow and client rects will always be clipped
2949 SectRect( &r
, &rparent
, &r
) ;
2950 SectRect( &rClient
, &rparent
, &rClient
) ;
2952 // the structure only at 'hard' borders
2953 if ( parent
->MacClipChildren() ||
2954 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2956 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2962 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
2963 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
2964 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
2965 m_cachedClippedRectWithOuterStructure
= wxRect(
2966 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
2967 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
2968 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
2970 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
2971 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
2972 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
2974 m_cachedClippedRectValid
= true ;
2978 This function must not change the updatergn !
2980 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
2982 bool handled
= false ;
2984 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
2985 GetRegionBounds( updatergn
, &updatebounds
) ;
2987 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
2989 if ( !EmptyRgn(updatergn
) )
2991 RgnHandle newupdate
= NewRgn() ;
2992 wxSize point
= GetClientSize() ;
2993 wxPoint origin
= GetClientAreaOrigin() ;
2994 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
2995 SectRgn( newupdate
, updatergn
, newupdate
) ;
2997 // first send an erase event to the entire update area
2999 // for the toplevel window this really is the entire area
3000 // for all the others only their client area, otherwise they
3001 // might be drawing with full alpha and eg put blue into
3002 // the grow-box area of a scrolled window (scroll sample)
3003 wxDC
* dc
= new wxWindowDC(this);
3005 dc
->SetClippingRegion(wxRegion(updatergn
));
3007 dc
->SetClippingRegion(wxRegion(newupdate
));
3009 wxEraseEvent
eevent( GetId(), dc
);
3010 eevent
.SetEventObject( this );
3011 GetEventHandler()->ProcessEvent( eevent
);
3015 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3016 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3017 m_updateRegion
= newupdate
;
3018 DisposeRgn( newupdate
) ;
3020 if ( !m_updateRegion
.Empty() )
3022 // paint the window itself
3025 event
.SetTimestamp(time
);
3026 event
.SetEventObject(this);
3027 GetEventHandler()->ProcessEvent(event
);
3031 // now we cannot rely on having its borders drawn by a window itself, as it does not
3032 // get the updateRgn wide enough to always do so, so we do it from the parent
3033 // this would also be the place to draw any custom backgrounds for native controls
3034 // in Composited windowing
3035 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3039 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3041 child
= node
->GetData();
3044 if (child
== m_vScrollBar
)
3046 if (child
== m_hScrollBar
)
3048 if (child
->IsTopLevel())
3050 if (!child
->IsShown())
3053 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3055 child
->GetPosition( &x
, &y
);
3056 child
->GetSize( &w
, &h
);
3057 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3058 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3059 InsetRect( &childRect
, -10 , -10) ;
3061 if ( RectInRgn( &childRect
, updatergn
) )
3063 // paint custom borders
3064 wxNcPaintEvent
eventNc( child
->GetId() );
3065 eventNc
.SetEventObject( child
);
3066 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3068 #if wxMAC_USE_CORE_GRAPHICS
3069 child
->MacPaintBorders(0, 0) ;
3072 wxWindowDC
dc(this) ;
3073 dc
.SetClippingRegion(wxRegion(updatergn
));
3074 wxMacPortSetter
helper(&dc
) ;
3075 child
->MacPaintBorders(0, 0) ;
3087 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3089 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3093 if ( iter
->IsTopLevel() )
3094 return ((wxTopLevelWindow
*)iter
)->MacGetWindowRef() ;
3096 iter
= iter
->GetParent() ;
3102 void wxWindowMac::MacCreateScrollBars( long style
)
3104 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3106 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3108 bool hasBoth
= ( style
& wxVSCROLL
) && ( style
& wxHSCROLL
) ;
3109 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3110 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3112 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3115 int adjust
= hasBoth
? scrlsize
- 1: 0 ;
3117 GetClientSize( &width
, &height
) ;
3119 wxPoint
vPoint(width
- scrlsize
, 0) ;
3120 wxSize
vSize(scrlsize
, height
- adjust
) ;
3121 wxPoint
hPoint(0, height
- scrlsize
) ;
3122 wxSize
hSize(width
- adjust
, scrlsize
) ;
3124 if ( style
& wxVSCROLL
)
3125 m_vScrollBar
= new wxScrollBar(this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3127 if ( style
& wxHSCROLL
)
3128 m_hScrollBar
= new wxScrollBar(this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3131 // because the create does not take into account the client area origin
3132 // we might have a real position shift
3133 MacRepositionScrollBars() ;
3136 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3138 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3143 void wxWindowMac::MacRepositionScrollBars()
3145 if ( !m_hScrollBar
&& !m_vScrollBar
)
3148 bool hasBoth
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && ( m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
3149 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3150 int adjust
= hasBoth
? scrlsize
- 1 : 0 ;
3152 // get real client area
3154 GetSize( &width
, &height
);
3156 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3157 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3159 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3160 wxSize
vSize( scrlsize
, height
- adjust
) ;
3161 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3162 wxSize
hSize( width
- adjust
, scrlsize
) ;
3165 int x
= 0, y
= 0, w
, h
;
3166 GetSize( &w
, &h
) ;
3168 MacClientToRootWindow( &x
, &y
) ;
3169 MacClientToRootWindow( &w
, &h
) ;
3171 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3173 int totW
= 10000 , totH
= 10000;
3176 if ( iter
->IsTopLevel() )
3178 iter
->GetSize( &totW
, &totH
) ;
3182 iter
= iter
->GetParent() ;
3196 if ( w
- x
>= totW
)
3201 if ( h
- y
>= totH
)
3209 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3211 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3214 bool wxWindowMac::AcceptsFocus() const
3216 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3219 void wxWindowMac::MacSuperChangedPosition()
3221 // only window-absolute structures have to be moved i.e. controls
3223 m_cachedClippedRectValid
= false ;
3226 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3229 child
= node
->GetData();
3230 child
->MacSuperChangedPosition() ;
3232 node
= node
->GetNext();
3236 void wxWindowMac::MacTopLevelWindowChangedPosition()
3238 // only screen-absolute structures have to be moved i.e. glcanvas
3241 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3244 child
= node
->GetData();
3245 child
->MacTopLevelWindowChangedPosition() ;
3247 node
= node
->GetNext();
3251 long wxWindowMac::MacGetLeftBorderSize() const
3258 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3260 // this metric is only the 'outset' outside the simple frame rect
3261 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3264 else if (HasFlag(wxSIMPLE_BORDER
))
3266 // this metric is only the 'outset' outside the simple frame rect
3267 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3274 long wxWindowMac::MacGetRightBorderSize() const
3276 // they are all symmetric in mac themes
3277 return MacGetLeftBorderSize() ;
3280 long wxWindowMac::MacGetTopBorderSize() const
3282 // they are all symmetric in mac themes
3283 return MacGetLeftBorderSize() ;
3286 long wxWindowMac::MacGetBottomBorderSize() const
3288 // they are all symmetric in mac themes
3289 return MacGetLeftBorderSize() ;
3292 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3294 return style
& ~wxBORDER_MASK
;
3297 // Find the wxWindowMac at the current mouse position, returning the mouse
3299 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3301 pt
= wxGetMousePosition();
3302 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3307 // Get the current mouse position.
3308 wxPoint
wxGetMousePosition()
3312 wxGetMousePosition( &x
, &y
);
3314 return wxPoint(x
, y
);
3317 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3319 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3321 // copied from wxGTK : CS
3322 // VZ: shouldn't we move this to base class then?
3324 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3327 // (a) it's a command event and so is propagated to the parent
3328 // (b) under MSW it can be generated from kbd too
3329 // (c) it uses screen coords (because of (a))
3330 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3332 this->ClientToScreen(event
.GetPosition()));
3333 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3342 void wxWindowMac::OnPaint( wxPaintEvent
& event
)
3344 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
3345 CallNextEventHandler(
3346 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3347 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3350 void wxWindowMac::MacHandleControlClick( WXWidget control
, wxInt16 controlpart
, bool WXUNUSED( mouseStillDown
) )
3354 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3358 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3359 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3364 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3366 return eventNotHandledErr
;
3369 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3371 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3372 if ( !wxWindowBase::Reparent(newParent
) )
3375 // copied from MacPostControlCreate
3376 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3378 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3380 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3385 bool wxWindowMac::SetTransparent(wxByte alpha
)
3387 #if wxMAC_USE_CORE_GRAPHICS
3388 if ( alpha
!= m_macAlpha
)
3390 m_macAlpha
= alpha
;
3400 bool wxWindowMac::CanSetTransparent()
3402 #if wxMAC_USE_CORE_GRAPHICS
3409 wxByte
wxWindowMac::GetTransparent() const