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
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
285 HIViewGetBounds( controlRef
, &bounds
);
286 CGContextClearRect( cgContext
, bounds
);
291 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
294 #if wxMAC_USE_CORE_GRAPHICS
295 thisWindow
->MacSetCGContextRef( NULL
) ;
299 CGContextRelease( cgContext
) ;
304 DisposeRgn( allocatedRgn
) ;
308 case kEventControlVisibilityChanged
:
309 thisWindow
->MacVisibilityChanged() ;
312 case kEventControlEnabledStateChanged
:
313 thisWindow
->MacEnabledStateChanged() ;
316 case kEventControlHiliteChanged
:
317 thisWindow
->MacHiliteChanged() ;
320 case kEventControlActivate
:
321 case kEventControlDeactivate
:
322 // FIXME: we should have a virtual function for this!
324 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
325 thisWindow
->Refresh();
328 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
329 thisWindow
->Refresh();
332 #endif // TARGET_API_MAC_OSX
334 // we emulate this event under Carbon CFM
335 case kEventControlSetFocusPart
:
337 Boolean focusEverything
= false ;
338 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
341 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
346 if ( thisWindow
->MacIsUserPane() )
349 if ( controlPart
== kControlFocusNoPart
)
352 if ( thisWindow
->GetCaret() )
353 thisWindow
->GetCaret()->OnKillFocus();
356 static bool inKillFocusEvent
= false ;
358 if ( !inKillFocusEvent
)
360 inKillFocusEvent
= true ;
361 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
362 event
.SetEventObject(thisWindow
);
363 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
364 inKillFocusEvent
= false ;
369 // panel wants to track the window which was the last to have focus in it
370 wxChildFocusEvent
eventFocus(thisWindow
);
371 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
374 if ( thisWindow
->GetCaret() )
375 thisWindow
->GetCaret()->OnSetFocus();
378 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
379 event
.SetEventObject(thisWindow
);
380 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
385 case kEventControlHit
:
386 result
= thisWindow
->MacControlHit( handler
, event
) ;
389 case kEventControlGetClickActivation
:
391 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
392 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
393 if ( !IsWindowActive(owner
) )
395 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
408 static pascal OSStatus
wxMacWindowServiceEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
410 OSStatus result
= eventNotHandledErr
;
412 wxMacCarbonEvent
cEvent( event
) ;
414 ControlRef controlRef
;
415 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
416 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
417 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
419 switch ( GetEventKind( event
) )
421 case kEventServiceGetTypes
:
425 textCtrl
->GetSelection( &from
, &to
) ;
427 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
429 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
430 if ( textCtrl
->IsEditable() )
431 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
433 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
434 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
436 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
440 CFArrayAppendValue(copyTypes
, typestring
) ;
442 CFArrayAppendValue(pasteTypes
, typestring
) ;
444 CFRelease( typestring
) ;
452 case kEventServiceCopy
:
457 textCtrl
->GetSelection( &from
, &to
) ;
458 wxString val
= textCtrl
->GetValue() ;
459 val
= val
.Mid( from
, to
- from
) ;
460 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
461 verify_noerr( ClearScrap( &scrapRef
) ) ;
462 verify_noerr( PutScrapFlavor( scrapRef
, kTXNTextData
, 0 , val
.length() , val
.c_str() ) ) ;
467 case kEventServicePaste
:
470 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
471 Size textSize
, pastedSize
;
472 verify_noerr( GetScrapFlavorSize(scrapRef
, kTXNTextData
, &textSize
) ) ;
474 char *content
= new char[textSize
] ;
475 GetScrapFlavorData(scrapRef
, kTXNTextData
, &pastedSize
, content
);
476 content
[textSize
- 1] = 0 ;
479 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
481 textCtrl
->WriteText( wxString( content
) ) ;
496 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
498 OSStatus result
= eventNotHandledErr
;
499 wxWindowMac
* focus
= (wxWindowMac
*) data
;
501 wchar_t* uniChars
= NULL
;
502 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
504 UniChar
* charBuf
= NULL
;
505 ByteCount dataSize
= 0 ;
508 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
510 numChars
= dataSize
/ sizeof( UniChar
) + 1;
513 if ( (size_t) numChars
* 2 > sizeof(buf
) )
514 charBuf
= new UniChar
[ numChars
] ;
518 uniChars
= new wchar_t[ numChars
] ;
519 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
520 charBuf
[ numChars
- 1 ] = 0;
521 #if SIZEOF_WCHAR_T == 2
522 uniChars
= (wchar_t*) charBuf
;
523 /* 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...)
525 // the resulting string will never have more chars than the utf16 version, so this is safe
526 wxMBConvUTF16 converter
;
527 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
531 switch ( GetEventKind( event
) )
533 case kEventTextInputUpdateActiveInputArea
:
535 // An IME input event may return several characters, but we need to send one char at a time to
537 for (int pos
=0 ; pos
< numChars
; pos
++)
539 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
540 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
541 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
543 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
545 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
546 multiple times to update the active range during inline input, so this handler will often receive
547 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
548 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
549 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
550 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
551 should add new event types to support advanced text input. For now, I would keep things as they are.
553 However, the code that was being used caused additional problems:
554 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
555 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
556 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
557 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
558 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
559 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
560 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
561 overlap with Unicode within the (7-bit) ASCII range.
562 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
563 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
564 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
565 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
566 I don't have time to look into that right now.
569 if ( wxTheApp
->MacSendCharEvent(
570 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
575 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
579 case kEventTextInputUnicodeForKeyEvent
:
581 UInt32 keyCode
, modifiers
;
584 unsigned char charCode
;
586 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
587 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
588 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
589 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
590 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
592 UInt32 message
= (keyCode
<< 8) + charCode
;
594 // An IME input event may return several characters, but we need to send one char at a time to
596 for (int pos
=0 ; pos
< numChars
; pos
++)
598 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
599 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
600 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
602 if ( wxTheApp
->MacSendCharEvent(
603 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
608 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
617 if ( charBuf
!= buf
)
623 static pascal OSStatus
wxMacWindowCommandEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
625 OSStatus result
= eventNotHandledErr
;
626 wxWindowMac
* focus
= (wxWindowMac
*) data
;
630 wxMacCarbonEvent
cEvent( event
) ;
631 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
633 wxMenuItem
* item
= NULL
;
634 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
635 int id
= wxMacCommandToId( command
.commandID
) ;
639 wxASSERT( itemMenu
!= NULL
) ;
641 switch ( cEvent
.GetKind() )
643 case kEventProcessCommand
:
645 if (item
->IsCheckable())
646 item
->Check( !item
->IsChecked() ) ;
648 if ( itemMenu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
652 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
, id
);
653 event
.SetEventObject(focus
);
654 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
656 if ( focus
->GetEventHandler()->ProcessEvent(event
) )
662 case kEventCommandUpdateStatus
:
664 wxUpdateUIEvent
event(id
);
665 event
.SetEventObject( itemMenu
);
667 bool processed
= false;
669 // Try the menu's event handler
671 wxEvtHandler
*handler
= itemMenu
->GetEventHandler();
673 processed
= handler
->ProcessEvent(event
);
676 // Try the window the menu was popped up from
677 // (and up through the hierarchy)
680 const wxMenuBase
*menu
= itemMenu
;
683 wxWindow
*win
= menu
->GetInvokingWindow();
686 processed
= win
->GetEventHandler()->ProcessEvent(event
);
690 menu
= menu
->GetParent();
696 processed
= focus
->GetEventHandler()->ProcessEvent(event
);
701 // if anything changed, update the changed attribute
702 if (event
.GetSetText())
703 itemMenu
->SetLabel(id
, event
.GetText());
704 if (event
.GetSetChecked())
705 itemMenu
->Check(id
, event
.GetChecked());
706 if (event
.GetSetEnabled())
707 itemMenu
->Enable(id
, event
.GetEnabled());
721 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
723 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
724 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
725 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
726 OSStatus result
= eventNotHandledErr
;
728 switch ( GetEventClass( event
) )
730 case kEventClassCommand
:
731 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
734 case kEventClassControl
:
735 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
738 case kEventClassService
:
739 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
742 case kEventClassTextInput
:
743 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
750 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
755 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
757 #if !TARGET_API_MAC_OSX
759 // ---------------------------------------------------------------------------
760 // UserPane events for non OSX builds
761 // ---------------------------------------------------------------------------
763 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
765 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
767 win
->MacControlUserPaneDrawProc(part
) ;
769 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
771 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
773 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
775 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
777 return kControlNoPart
;
779 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
781 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
783 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
785 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
787 return kControlNoPart
;
789 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
791 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
793 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
795 win
->MacControlUserPaneIdleProc() ;
797 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
799 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
801 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
803 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
805 return kControlNoPart
;
807 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
809 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
811 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
813 win
->MacControlUserPaneActivateProc(activating
) ;
815 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
817 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
819 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
821 return win
->MacControlUserPaneFocusProc(action
) ;
823 return kControlNoPart
;
825 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
827 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
829 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
831 win
->MacControlUserPaneBackgroundProc(info
) ;
833 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
835 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
838 RgnHandle rgn
= NewRgn() ;
840 MacWindowToRootWindow( &x
, &y
) ;
841 OffsetRgn( rgn
, -x
, -y
) ;
842 wxMacWindowStateSaver
sv( this ) ;
843 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
844 MacDoRedraw( rgn
, 0 ) ;
848 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
850 return kControlNoPart
;
853 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
855 return kControlNoPart
;
858 void wxWindowMac::MacControlUserPaneIdleProc()
862 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
864 return kControlNoPart
;
867 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
871 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
873 if ( AcceptsFocus() )
876 return kControlNoPart
;
879 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
885 // ---------------------------------------------------------------------------
886 // Scrollbar Tracking for all
887 // ---------------------------------------------------------------------------
889 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
890 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
894 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
896 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
899 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
901 // ===========================================================================
903 // ===========================================================================
905 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
907 static MacControlMap wxWinMacControlList
;
909 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
911 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
913 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
916 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
918 // adding NULL ControlRef is (first) surely a result of an error and
919 // (secondly) breaks native event processing
920 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
922 wxWinMacControlList
[inControl
] = control
;
925 void wxRemoveMacControlAssociation(wxWindow
*control
)
927 // iterate over all the elements in the class
928 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
929 // we should go on...
935 MacControlMap::iterator it
;
936 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
938 if ( it
->second
== control
)
940 wxWinMacControlList
.erase(it
);
948 // ----------------------------------------------------------------------------
949 // constructors and such
950 // ----------------------------------------------------------------------------
952 wxWindowMac::wxWindowMac()
957 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
962 const wxString
& name
)
965 Create(parent
, id
, pos
, size
, style
, name
);
968 void wxWindowMac::Init()
974 #if wxMAC_USE_CORE_GRAPHICS
975 m_cgContextRef
= NULL
;
978 // as all windows are created with WS_VISIBLE style...
981 m_hScrollBar
= NULL
;
982 m_vScrollBar
= NULL
;
983 m_macBackgroundBrush
= wxNullBrush
;
985 m_macIsUserPane
= true;
986 m_clipChildren
= false ;
987 m_cachedClippedRectValid
= false ;
989 // we need a valid font for the encodings
990 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
993 wxWindowMac::~wxWindowMac()
997 m_isBeingDeleted
= true;
999 MacInvalidateBorders() ;
1001 #ifndef __WXUNIVERSAL__
1002 // VS: make sure there's no wxFrame with last focus set to us:
1003 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
1005 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
1008 if ( frame
->GetLastFocus() == this )
1009 frame
->SetLastFocus((wxWindow
*)NULL
);
1015 // destroy children before destroying this window itself
1018 // wxRemoveMacControlAssociation( this ) ;
1019 // If we delete an item, we should initialize the parent panel,
1020 // because it could now be invalid.
1021 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
1024 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
1025 tlw
->SetDefaultItem(NULL
);
1028 if ( m_peer
&& m_peer
->Ok() )
1030 // in case the callback might be called during destruction
1031 wxRemoveMacControlAssociation( this) ;
1032 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
1033 // we currently are not using this hook
1034 // ::SetControlColorProc( *m_peer , NULL ) ;
1038 if ( g_MacLastWindow
== this )
1039 g_MacLastWindow
= NULL
;
1041 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame
) ;
1044 if ( frame
->GetLastFocus() == this )
1045 frame
->SetLastFocus( NULL
) ;
1048 // delete our drop target if we've got one
1049 #if wxUSE_DRAG_AND_DROP
1050 if ( m_dropTarget
!= NULL
)
1052 delete m_dropTarget
;
1053 m_dropTarget
= NULL
;
1060 WXWidget
wxWindowMac::GetHandle() const
1062 return (WXWidget
) m_peer
->GetControlRef() ;
1065 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1067 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1068 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1069 GetEventTypeCount(eventList
), eventList
, this,
1070 (EventHandlerRef
*)&m_macControlEventHandler
);
1072 #if !TARGET_API_MAC_OSX
1073 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1075 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1076 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1077 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1078 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1079 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1080 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1081 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1082 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1088 bool wxWindowMac::Create(wxWindowMac
*parent
,
1093 const wxString
& name
)
1095 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1097 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1100 m_windowVariant
= parent
->GetWindowVariant() ;
1102 if ( m_macIsUserPane
)
1104 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1107 | kControlSupportsEmbedding
1108 | kControlSupportsLiveFeedback
1109 | kControlGetsFocusOnClick
1110 // | kControlHasSpecialBackground
1111 // | kControlSupportsCalcBestRect
1112 | kControlHandlesTracking
1113 | kControlSupportsFocus
1114 | kControlWantsActivate
1115 | kControlWantsIdle
;
1117 m_peer
= new wxMacControl(this) ;
1118 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1119 verify_noerr( err
);
1121 MacPostControlCreate(pos
, size
) ;
1124 #ifndef __WXUNIVERSAL__
1125 // Don't give scrollbars to wxControls unless they ask for them
1126 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1127 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1129 MacCreateScrollBars( style
) ;
1133 wxWindowCreateEvent
event(this);
1134 GetEventHandler()->AddPendingEvent(event
);
1139 void wxWindowMac::MacChildAdded()
1142 m_vScrollBar
->Raise() ;
1144 m_hScrollBar
->Raise() ;
1147 void wxWindowMac::MacPostControlCreate(const wxPoint
& pos
, const wxSize
& size
)
1149 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1151 m_peer
->SetReference( (URefCon
) this ) ;
1152 GetParent()->AddChild( this );
1154 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1156 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1157 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1158 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1159 GetParent()->MacChildAdded() ;
1161 // adjust font, controlsize etc
1162 DoSetWindowVariant( m_windowVariant
) ;
1164 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1166 if (!m_macIsUserPane
)
1167 SetInitialSize(size
);
1169 SetCursor( *wxSTANDARD_CURSOR
) ;
1172 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1174 // Don't assert, in case we set the window variant before
1175 // the window is created
1176 // wxASSERT( m_peer->Ok() ) ;
1178 m_windowVariant
= variant
;
1180 if (m_peer
== NULL
|| !m_peer
->Ok())
1184 ThemeFontID themeFont
= kThemeSystemFont
;
1186 // we will get that from the settings later
1187 // and make this NORMAL later, but first
1188 // we have a few calculations that we must fix
1192 case wxWINDOW_VARIANT_NORMAL
:
1193 size
= kControlSizeNormal
;
1194 themeFont
= kThemeSystemFont
;
1197 case wxWINDOW_VARIANT_SMALL
:
1198 size
= kControlSizeSmall
;
1199 themeFont
= kThemeSmallSystemFont
;
1202 case wxWINDOW_VARIANT_MINI
:
1203 if (UMAGetSystemVersion() >= 0x1030 )
1205 // not always defined in the headers
1211 size
= kControlSizeSmall
;
1212 themeFont
= kThemeSmallSystemFont
;
1216 case wxWINDOW_VARIANT_LARGE
:
1217 size
= kControlSizeLarge
;
1218 themeFont
= kThemeSystemFont
;
1222 wxFAIL_MSG(_T("unexpected window variant"));
1226 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1229 font
.MacCreateThemeFont( themeFont
) ;
1233 void wxWindowMac::MacUpdateControlFont()
1235 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1239 bool wxWindowMac::SetFont(const wxFont
& font
)
1241 bool retval
= wxWindowBase::SetFont( font
);
1243 MacUpdateControlFont() ;
1248 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1250 bool retval
= wxWindowBase::SetForegroundColour( col
);
1253 MacUpdateControlFont();
1258 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1260 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1264 wxColour
newCol(GetBackgroundColour());
1266 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1267 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1268 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1269 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1271 brush
.SetColour( newCol
) ;
1273 MacSetBackgroundBrush( brush
) ;
1274 MacUpdateControlFont() ;
1279 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1281 m_macBackgroundBrush
= brush
;
1282 m_peer
->SetBackground( brush
) ;
1285 bool wxWindowMac::MacCanFocus() const
1287 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1288 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1289 // but the value range is nowhere documented
1290 Boolean keyExistsAndHasValidFormat
;
1291 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1292 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1294 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1300 UInt32 features
= 0 ;
1301 m_peer
->GetFeatures( &features
) ;
1303 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1307 void wxWindowMac::SetFocus()
1309 if ( !AcceptsFocus() )
1312 wxWindow
* former
= FindFocus() ;
1313 if ( former
== this )
1316 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1317 // we can only leave in case of an error
1318 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1319 if ( err
== errCouldntSetFocus
)
1322 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1324 #if !TARGET_API_MAC_OSX
1325 // emulate carbon events when running under CarbonLib where they are not natively available
1328 EventRef evRef
= NULL
;
1330 err
= MacCreateEvent(
1331 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1332 kEventAttributeUserEvent
, &evRef
);
1333 verify_noerr( err
);
1335 wxMacCarbonEvent
cEvent( evRef
) ;
1336 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1337 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1339 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1340 ReleaseEvent( evRef
) ;
1343 // send new focus event
1345 EventRef evRef
= NULL
;
1347 err
= MacCreateEvent(
1348 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1349 kEventAttributeUserEvent
, &evRef
);
1350 verify_noerr( err
);
1352 wxMacCarbonEvent
cEvent( evRef
) ;
1353 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1354 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1356 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1357 ReleaseEvent( evRef
) ;
1362 void wxWindowMac::DoCaptureMouse()
1364 wxApp::s_captureWindow
= this ;
1367 wxWindow
* wxWindowBase::GetCapture()
1369 return wxApp::s_captureWindow
;
1372 void wxWindowMac::DoReleaseMouse()
1374 wxApp::s_captureWindow
= NULL
;
1377 #if wxUSE_DRAG_AND_DROP
1379 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1381 if ( m_dropTarget
!= NULL
)
1382 delete m_dropTarget
;
1384 m_dropTarget
= pDropTarget
;
1385 if ( m_dropTarget
!= NULL
)
1393 // Old-style File Manager Drag & Drop
1394 void wxWindowMac::DragAcceptFiles(bool accept
)
1399 // Returns the size of the native control. In the case of the toplevel window
1400 // this is the content area root control
1402 void wxWindowMac::MacGetPositionAndSizeFromControl(int& x
, int& y
,
1403 int& w
, int& h
) const
1405 wxFAIL_MSG( wxT("Not currently supported") ) ;
1408 // From a wx position / size calculate the appropriate size of the native control
1410 bool wxWindowMac::MacGetBoundsForControl(
1414 int& w
, int& h
, bool adjustOrigin
) const
1416 // the desired size, minus the border pixels gives the correct size of the control
1420 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1421 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1422 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1424 x
+= MacGetLeftBorderSize() ;
1425 y
+= MacGetTopBorderSize() ;
1426 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1427 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1430 AdjustForParentClientOrigin( x
, y
) ;
1432 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1433 if ( !GetParent()->IsTopLevel() )
1435 x
-= GetParent()->MacGetLeftBorderSize() ;
1436 y
-= GetParent()->MacGetTopBorderSize() ;
1442 // Get window size (not client size)
1443 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1446 m_peer
->GetRect( &bounds
) ;
1449 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1451 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1454 // get the position of the bounds of this window in client coordinates of its parent
1455 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1458 m_peer
->GetRect( &bounds
) ;
1460 int x1
= bounds
.left
;
1461 int y1
= bounds
.top
;
1463 // get the wx window position from the native one
1464 x1
-= MacGetLeftBorderSize() ;
1465 y1
-= MacGetTopBorderSize() ;
1467 if ( !IsTopLevel() )
1469 wxWindow
*parent
= GetParent();
1472 // we must first adjust it to be in window coordinates of the parent,
1473 // as otherwise it gets lost by the ClientAreaOrigin fix
1474 x1
+= parent
->MacGetLeftBorderSize() ;
1475 y1
+= parent
->MacGetTopBorderSize() ;
1477 // and now to client coordinates
1478 wxPoint
pt(parent
->GetClientAreaOrigin());
1490 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1492 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1493 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1495 Point localwhere
= { 0, 0 } ;
1502 wxMacGlobalToLocal( window
, &localwhere
) ;
1509 MacRootWindowToWindow( x
, y
) ;
1511 wxPoint origin
= GetClientAreaOrigin() ;
1518 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1520 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1521 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1523 wxPoint origin
= GetClientAreaOrigin() ;
1529 MacWindowToRootWindow( x
, y
) ;
1531 Point localwhere
= { 0, 0 };
1537 wxMacLocalToGlobal( window
, &localwhere
) ;
1545 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1547 wxPoint origin
= GetClientAreaOrigin() ;
1553 MacWindowToRootWindow( x
, y
) ;
1556 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1558 MacRootWindowToWindow( x
, y
) ;
1560 wxPoint origin
= GetClientAreaOrigin() ;
1567 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1576 if ( !IsTopLevel() )
1578 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1581 pt
.x
-= MacGetLeftBorderSize() ;
1582 pt
.y
-= MacGetTopBorderSize() ;
1583 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1593 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1602 MacWindowToRootWindow( &x1
, &y1
) ;
1610 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1619 if ( !IsTopLevel() )
1621 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1624 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1625 pt
.x
+= MacGetLeftBorderSize() ;
1626 pt
.y
+= MacGetTopBorderSize() ;
1636 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1645 MacRootWindowToWindow( &x1
, &y1
) ;
1653 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1655 RgnHandle rgn
= NewRgn() ;
1657 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1659 Rect structure
, content
;
1661 GetRegionBounds( rgn
, &content
) ;
1662 m_peer
->GetRect( &structure
) ;
1663 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1665 left
= content
.left
- structure
.left
;
1666 top
= content
.top
- structure
.top
;
1667 right
= structure
.right
- content
.right
;
1668 bottom
= structure
.bottom
- content
.bottom
;
1672 left
= top
= right
= bottom
= 0 ;
1678 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1680 wxSize sizeTotal
= size
;
1682 RgnHandle rgn
= NewRgn() ;
1683 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1685 Rect content
, structure
;
1686 GetRegionBounds( rgn
, &content
) ;
1687 m_peer
->GetRect( &structure
) ;
1689 // structure is in parent coordinates, but we only need width and height, so it's ok
1691 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1692 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1697 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1698 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1703 // Get size *available for subwindows* i.e. excluding menu bar etc.
1704 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1708 RgnHandle rgn
= NewRgn() ;
1710 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1711 GetRegionBounds( rgn
, &content
) ;
1713 m_peer
->GetRect( &content
) ;
1716 ww
= content
.right
- content
.left
;
1717 hh
= content
.bottom
- content
.top
;
1719 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1720 hh
-= m_hScrollBar
->GetSize().y
;
1722 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1723 ww
-= m_vScrollBar
->GetSize().x
;
1731 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1733 if (m_cursor
.IsSameAs(cursor
))
1738 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1743 if ( ! wxWindowBase::SetCursor( cursor
) )
1747 wxASSERT_MSG( m_cursor
.Ok(),
1748 wxT("cursor must be valid after call to the base version"));
1750 wxWindowMac
*mouseWin
= 0 ;
1752 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1753 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1755 ControlPartCode part
;
1756 ControlRef control
;
1758 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1760 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1765 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1767 // TODO: If we ever get a GetCurrentEvent... replacement
1768 // for the mouse position, use it...
1773 control
= wxMacFindControlUnderMouse( tlw
, pt
, window
, &part
) ;
1775 mouseWin
= wxFindControlFromMacControl( control
) ;
1777 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1779 QDSwapPort( savePort
, NULL
) ;
1783 if ( mouseWin
== this && !wxIsBusy() )
1784 m_cursor
.MacInstall() ;
1790 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1792 menu
->SetInvokingWindow(this);
1795 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1797 wxPoint mouse
= wxGetMousePosition();
1803 ClientToScreen( &x
, &y
) ;
1806 menu
->MacBeforeDisplay( true ) ;
1807 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1808 if ( HiWord(menuResult
) != 0 )
1811 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1812 int id
= wxMacCommandToId( macid
);
1813 wxMenuItem
* item
= NULL
;
1815 item
= menu
->FindItem( id
, &realmenu
) ;
1818 if (item
->IsCheckable())
1819 item
->Check( !item
->IsChecked() ) ;
1821 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1825 menu
->MacAfterDisplay( true ) ;
1826 menu
->SetInvokingWindow( NULL
);
1832 // ----------------------------------------------------------------------------
1834 // ----------------------------------------------------------------------------
1838 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1840 wxWindowBase::DoSetToolTip(tooltip
);
1843 m_tooltip
->SetWindow(this);
1848 void wxWindowMac::MacInvalidateBorders()
1850 if ( m_peer
== NULL
)
1853 bool vis
= MacIsReallyShown() ;
1857 int outerBorder
= MacGetLeftBorderSize() ;
1858 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1861 if ( outerBorder
== 0 )
1864 // now we know that we have something to do at all
1866 // as the borders are drawn on the parent we have to properly invalidate all these areas
1867 RgnHandle updateInner
, updateOuter
;
1870 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1871 updateInner
= NewRgn() ;
1872 updateOuter
= NewRgn() ;
1874 m_peer
->GetRect( &rect
) ;
1875 RectRgn( updateInner
, &rect
) ;
1876 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1877 RectRgn( updateOuter
, &rect
) ;
1878 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1880 #ifdef __WXMAC_OSX__
1881 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1883 WindowRef tlw
= (WindowRef
) MacGetTopLevelWindowRef() ;
1885 InvalWindowRgn( tlw
, updateOuter
) ;
1888 DisposeRgn( updateOuter
) ;
1889 DisposeRgn( updateInner
) ;
1892 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1894 // this is never called for a toplevel window, so we know we have a parent
1895 int former_x
, former_y
, former_w
, former_h
;
1897 // Get true coordinates of former position
1898 DoGetPosition( &former_x
, &former_y
) ;
1899 DoGetSize( &former_w
, &former_h
) ;
1901 wxWindow
*parent
= GetParent();
1904 wxPoint
pt(parent
->GetClientAreaOrigin());
1909 int actualWidth
= width
;
1910 int actualHeight
= height
;
1914 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1915 actualWidth
= m_minWidth
;
1916 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1917 actualHeight
= m_minHeight
;
1918 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1919 actualWidth
= m_maxWidth
;
1920 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1921 actualHeight
= m_maxHeight
;
1923 bool doMove
= false, doResize
= false ;
1925 if ( actualX
!= former_x
|| actualY
!= former_y
)
1928 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1931 if ( doMove
|| doResize
)
1933 // as the borders are drawn outside the native control, we adjust now
1935 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1936 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1937 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1940 wxMacRectToNative( &bounds
, &r
) ;
1942 if ( !GetParent()->IsTopLevel() )
1943 wxMacWindowToNative( GetParent() , &r
) ;
1945 MacInvalidateBorders() ;
1947 m_cachedClippedRectValid
= false ;
1948 m_peer
->SetRect( &r
) ;
1950 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1952 MacInvalidateBorders() ;
1954 MacRepositionScrollBars() ;
1957 wxPoint
point(actualX
, actualY
);
1958 wxMoveEvent
event(point
, m_windowId
);
1959 event
.SetEventObject(this);
1960 GetEventHandler()->ProcessEvent(event
) ;
1965 MacRepositionScrollBars() ;
1966 wxSize
size(actualWidth
, actualHeight
);
1967 wxSizeEvent
event(size
, m_windowId
);
1968 event
.SetEventObject(this);
1969 GetEventHandler()->ProcessEvent(event
);
1974 wxSize
wxWindowMac::DoGetBestSize() const
1976 if ( m_macIsUserPane
|| IsTopLevel() )
1977 return wxWindowBase::DoGetBestSize() ;
1979 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1980 int bestWidth
, bestHeight
;
1982 m_peer
->GetBestRect( &bestsize
) ;
1983 if ( EmptyRect( &bestsize
) )
1988 bestsize
.bottom
= 16 ;
1990 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1992 bestsize
.bottom
= 16 ;
1995 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1997 bestsize
.bottom
= 24 ;
2002 // return wxWindowBase::DoGetBestSize() ;
2006 bestWidth
= bestsize
.right
- bestsize
.left
;
2007 bestHeight
= bestsize
.bottom
- bestsize
.top
;
2008 if ( bestHeight
< 10 )
2011 return wxSize(bestWidth
, bestHeight
);
2014 // set the size of the window: if the dimensions are positive, just use them,
2015 // but if any of them is equal to -1, it means that we must find the value for
2016 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
2017 // which case -1 is a valid value for x and y)
2019 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
2020 // the width/height to best suit our contents, otherwise we reuse the current
2022 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
2024 // get the current size and position...
2025 int currentX
, currentY
;
2026 int currentW
, currentH
;
2028 GetPosition(¤tX
, ¤tY
);
2029 GetSize(¤tW
, ¤tH
);
2031 // ... and don't do anything (avoiding flicker) if it's already ok
2032 if ( x
== currentX
&& y
== currentY
&&
2033 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
2036 MacRepositionScrollBars() ; // we might have a real position shift
2041 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
2043 if ( x
== wxDefaultCoord
)
2045 if ( y
== wxDefaultCoord
)
2049 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2051 wxSize size
= wxDefaultSize
;
2052 if ( width
== wxDefaultCoord
)
2054 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2056 size
= DoGetBestSize();
2061 // just take the current one
2066 if ( height
== wxDefaultCoord
)
2068 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2070 if ( size
.x
== wxDefaultCoord
)
2071 size
= DoGetBestSize();
2072 // else: already called DoGetBestSize() above
2078 // just take the current one
2083 DoMoveWindow( x
, y
, width
, height
);
2086 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2088 RgnHandle rgn
= NewRgn() ;
2090 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2092 GetRegionBounds( rgn
, &content
) ;
2102 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2105 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2107 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2109 int currentclientwidth
, currentclientheight
;
2110 int currentwidth
, currentheight
;
2112 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2113 GetSize( ¤twidth
, ¤theight
) ;
2115 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2116 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2120 void wxWindowMac::SetLabel(const wxString
& title
)
2122 m_label
= wxStripMenuCodes(title
, wxStrip_Mnemonics
) ;
2124 if ( m_peer
&& m_peer
->Ok() )
2125 m_peer
->SetLabel( m_label
) ;
2130 wxString
wxWindowMac::GetLabel() const
2135 bool wxWindowMac::Show(bool show
)
2137 bool former
= MacIsReallyShown() ;
2138 if ( !wxWindowBase::Show(show
) )
2141 // TODO: use visibilityChanged Carbon Event for OSX
2143 m_peer
->SetVisibility( show
, true ) ;
2145 if ( former
!= MacIsReallyShown() )
2146 MacPropagateVisibilityChanged() ;
2151 void wxWindowMac::DoEnable(bool enable
)
2153 m_peer
->Enable( enable
) ;
2157 // status change propagations (will be not necessary for OSX later )
2160 void wxWindowMac::MacPropagateVisibilityChanged()
2162 #if !TARGET_API_MAC_OSX
2163 MacVisibilityChanged() ;
2166 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2169 child
= node
->GetData();
2170 if ( child
->IsShown() )
2171 child
->MacPropagateVisibilityChanged() ;
2173 node
= node
->GetNext();
2178 void wxWindowMac::OnEnabled(bool enabled
)
2180 #if !TARGET_API_MAC_OSX
2181 MacEnabledStateChanged() ;
2185 void wxWindowMac::MacPropagateHiliteChanged()
2187 #if !TARGET_API_MAC_OSX
2188 MacHiliteChanged() ;
2191 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2194 child
= node
->GetData();
2195 if (child
/* && child->IsEnabled() */)
2196 child
->MacPropagateHiliteChanged() ;
2198 node
= node
->GetNext();
2204 // status change notifications
2207 void wxWindowMac::MacVisibilityChanged()
2211 void wxWindowMac::MacHiliteChanged()
2215 void wxWindowMac::MacEnabledStateChanged()
2220 // status queries on the inherited window's state
2223 bool wxWindowMac::MacIsReallyShown()
2225 // only under OSX the visibility of the TLW is taken into account
2226 if ( m_isBeingDeleted
)
2229 #if TARGET_API_MAC_OSX
2230 if ( m_peer
&& m_peer
->Ok() )
2231 return m_peer
->IsVisible();
2234 wxWindow
* win
= this ;
2235 while ( win
->IsShown() )
2237 if ( win
->IsTopLevel() )
2240 win
= win
->GetParent() ;
2248 bool wxWindowMac::MacIsReallyEnabled()
2250 return m_peer
->IsEnabled() ;
2253 bool wxWindowMac::MacIsReallyHilited()
2255 return m_peer
->IsActive();
2258 void wxWindowMac::MacFlashInvalidAreas()
2260 #if TARGET_API_MAC_OSX
2261 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2265 int wxWindowMac::GetCharHeight() const
2267 wxClientDC
dc( (wxWindowMac
*)this ) ;
2269 return dc
.GetCharHeight() ;
2272 int wxWindowMac::GetCharWidth() const
2274 wxClientDC
dc( (wxWindowMac
*)this ) ;
2276 return dc
.GetCharWidth() ;
2279 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2280 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2282 const wxFont
*fontToUse
= theFont
;
2284 fontToUse
= &m_font
;
2286 wxClientDC
dc( (wxWindowMac
*) this ) ;
2287 wxCoord lx
,ly
,ld
,le
;
2288 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2289 if ( externalLeading
)
2290 *externalLeading
= le
;
2300 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2301 * we always intersect with the entire window, not only with the client area
2304 void wxWindowMac::Refresh(bool eraseBack
, const wxRect
*rect
)
2306 if ( m_peer
== NULL
)
2309 if ( !MacIsReallyShown() )
2316 wxMacRectToNative( rect
, &r
) ;
2317 m_peer
->SetNeedsDisplay( &r
) ;
2321 m_peer
->SetNeedsDisplay() ;
2325 void wxWindowMac::Freeze()
2327 #if TARGET_API_MAC_OSX
2328 if ( !m_frozenness
++ )
2330 if ( m_peer
&& m_peer
->Ok() )
2331 m_peer
->SetDrawingEnabled( false ) ;
2336 void wxWindowMac::Thaw()
2338 #if TARGET_API_MAC_OSX
2339 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2341 if ( !--m_frozenness
)
2343 if ( m_peer
&& m_peer
->Ok() )
2345 m_peer
->SetDrawingEnabled( true ) ;
2346 m_peer
->InvalidateWithChildren() ;
2352 bool wxWindowMac::IsFrozen() const
2354 return m_frozenness
!= 0;
2357 wxWindowMac
*wxGetActiveWindow()
2359 // actually this is a windows-only concept
2363 // Coordinates relative to the window
2364 void wxWindowMac::WarpPointer(int x_pos
, int y_pos
)
2366 // We really don't move the mouse programmatically under Mac.
2369 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2371 if ( MacGetTopLevelWindow() == NULL
)
2374 #if TARGET_API_MAC_OSX
2375 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
2376 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2383 event
.GetDC()->Clear() ;
2387 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2392 int wxWindowMac::GetScrollPos(int orient
) const
2394 if ( orient
== wxHORIZONTAL
)
2397 return m_hScrollBar
->GetThumbPosition() ;
2402 return m_vScrollBar
->GetThumbPosition() ;
2408 // This now returns the whole range, not just the number
2409 // of positions that we can scroll.
2410 int wxWindowMac::GetScrollRange(int orient
) const
2412 if ( orient
== wxHORIZONTAL
)
2415 return m_hScrollBar
->GetRange() ;
2420 return m_vScrollBar
->GetRange() ;
2426 int wxWindowMac::GetScrollThumb(int orient
) const
2428 if ( orient
== wxHORIZONTAL
)
2431 return m_hScrollBar
->GetThumbSize() ;
2436 return m_vScrollBar
->GetThumbSize() ;
2442 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool refresh
)
2444 if ( orient
== wxHORIZONTAL
)
2447 m_hScrollBar
->SetThumbPosition( pos
) ;
2452 m_vScrollBar
->SetThumbPosition( pos
) ;
2457 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2458 // our own window origin is at leftOrigin/rightOrigin
2461 void wxWindowMac::MacPaintBorders( int leftOrigin
, int rightOrigin
)
2467 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2468 bool hasBothScrollbars
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && (m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
2470 // back to the surrounding frame rectangle
2471 m_peer
->GetRect( &rect
) ;
2472 InsetRect( &rect
, -1 , -1 ) ;
2474 #if wxMAC_USE_CORE_GRAPHICS
2476 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2477 rect
.bottom
- rect
.top
) ;
2479 HIThemeFrameDrawInfo info
;
2480 memset( &info
, 0 , sizeof(info
) ) ;
2484 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2485 info
.isFocused
= hasFocus
;
2487 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2488 wxASSERT( cgContext
) ;
2490 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2492 info
.kind
= kHIThemeFrameTextFieldSquare
;
2493 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2495 else if ( HasFlag(wxSIMPLE_BORDER
) )
2497 info
.kind
= kHIThemeFrameListBox
;
2498 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2500 else if ( hasFocus
)
2502 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2505 m_peer
->GetRect( &rect
) ;
2506 if ( hasBothScrollbars
)
2508 int size
= m_hScrollBar
->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL
? 16 : 12 ;
2509 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2510 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2511 HIThemeGrowBoxDrawInfo info
;
2512 memset( &info
, 0, sizeof(info
) ) ;
2514 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2515 info
.kind
= kHIThemeGrowBoxKindNone
;
2516 info
.size
= kHIThemeGrowBoxSizeNormal
;
2517 info
.direction
= kThemeGrowRight
| kThemeGrowDown
;
2518 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2523 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2527 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2528 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2531 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2532 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2533 else if ( HasFlag(wxSIMPLE_BORDER
) )
2534 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2537 DrawThemeFocusRect( &rect
, true ) ;
2539 if ( hasBothScrollbars
)
2541 // GetThemeStandaloneGrowBoxBounds
2542 // DrawThemeStandaloneNoGrowBox
2548 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2550 if ( child
== m_hScrollBar
)
2551 m_hScrollBar
= NULL
;
2552 if ( child
== m_vScrollBar
)
2553 m_vScrollBar
= NULL
;
2555 wxWindowBase::RemoveChild( child
) ;
2558 // New function that will replace some of the above.
2559 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumbVisible
,
2560 int range
, bool refresh
)
2563 bool triggerSizeEvent
= false;
2565 if ( orient
== wxHORIZONTAL
)
2569 showScroller
= ((range
!= 0) && (range
> thumbVisible
));
2570 if ( m_hScrollBar
->IsShown() != showScroller
)
2572 m_hScrollBar
->Show( showScroller
);
2573 triggerSizeEvent
= true;
2576 m_hScrollBar
->SetScrollbar( pos
, thumbVisible
, range
, thumbVisible
, refresh
) ;
2583 showScroller
= ((range
!= 0) && (range
> thumbVisible
));
2584 if ( m_vScrollBar
->IsShown() != showScroller
)
2586 m_vScrollBar
->Show( showScroller
) ;
2587 triggerSizeEvent
= true;
2590 m_vScrollBar
->SetScrollbar( pos
, thumbVisible
, range
, thumbVisible
, refresh
) ;
2594 MacRepositionScrollBars() ;
2595 if ( triggerSizeEvent
)
2597 wxSizeEvent
event(GetSize(), m_windowId
);
2598 event
.SetEventObject(this);
2599 GetEventHandler()->ProcessEvent(event
);
2603 // Does a physical scroll
2604 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2606 if ( dx
== 0 && dy
== 0 )
2609 int width
, height
;
2610 GetClientSize( &width
, &height
) ;
2613 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2614 // area is scrolled, this does not occur if width and height are 2 pixels less,
2615 // TODO: write optimal workaround
2616 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2618 scrollrect
.Intersect( *rect
) ;
2620 if ( m_peer
->GetNeedsDisplay() )
2622 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2623 // in case there is already a pending redraw on that area
2624 // either immediate redraw or full invalidate
2626 // is the better overall solution, as it does not slow down scrolling
2627 m_peer
->SetNeedsDisplay() ;
2629 // this would be the preferred version for fast drawing controls
2631 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2632 if ( UMAGetSystemVersion() >= 0x1030 )
2633 HIViewRender(m_peer
->GetControlRef()) ;
2640 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2641 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2642 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2645 // this would be the preferred version for fast drawing controls
2646 HIViewRender(m_peer
->GetControlRef()) ;
2652 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2654 child
= node
->GetData();
2657 if (child
== m_vScrollBar
)
2659 if (child
== m_hScrollBar
)
2661 if (child
->IsTopLevel())
2664 child
->GetPosition( &x
, &y
);
2665 child
->GetSize( &w
, &h
);
2668 wxRect
rc( x
, y
, w
, h
);
2669 if (rect
->Intersects( rc
))
2670 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2674 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2679 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2681 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2683 wxScrollWinEvent wevent
;
2684 wevent
.SetPosition(event
.GetPosition());
2685 wevent
.SetOrientation(event
.GetOrientation());
2686 wevent
.SetEventObject(this);
2688 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2689 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2690 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2691 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2692 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2693 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2694 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2695 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2696 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2697 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2698 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2699 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2700 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2701 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2702 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2703 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2705 GetEventHandler()->ProcessEvent(wevent
);
2709 // Get the window with the focus
2710 wxWindowMac
*wxWindowBase::DoFindFocus()
2712 ControlRef control
;
2713 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2714 return wxFindControlFromMacControl( control
) ;
2717 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2719 // panel wants to track the window which was the last to have focus in it,
2720 // so we want to set ourselves as the window which last had focus
2722 // notice that it's also important to do it upwards the tree because
2723 // otherwise when the top level panel gets focus, it won't set it back to
2724 // us, but to some other sibling
2726 // CS: don't know if this is still needed:
2727 //wxChildFocusEvent eventFocus(this);
2728 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2730 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2732 #if wxMAC_USE_CORE_GRAPHICS
2733 GetParent()->Refresh() ;
2735 wxMacWindowStateSaver
sv( this ) ;
2738 m_peer
->GetRect( &rect
) ;
2739 // auf den umgebenden Rahmen zur\81Â\9fck
2740 InsetRect( &rect
, -1 , -1 ) ;
2742 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2746 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2748 rect
.right
+= pt
.x
;
2750 rect
.bottom
+= pt
.y
;
2753 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2754 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2755 if ( !bIsFocusEvent
)
2757 // as this erases part of the frame we have to redraw borders
2758 // and because our z-ordering is not always correct (staticboxes)
2759 // we have to invalidate things, we cannot simple redraw
2760 MacInvalidateBorders() ;
2768 void wxWindowMac::OnInternalIdle()
2770 // This calls the UI-update mechanism (querying windows for
2771 // menu/toolbar/control state information)
2772 if (wxUpdateUIEvent::CanUpdate(this))
2773 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2776 // Raise the window to the top of the Z order
2777 void wxWindowMac::Raise()
2779 m_peer
->SetZOrder( true , NULL
) ;
2782 // Lower the window to the bottom of the Z order
2783 void wxWindowMac::Lower()
2785 m_peer
->SetZOrder( false , NULL
) ;
2788 // static wxWindow *gs_lastWhich = NULL;
2790 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2792 // first trigger a set cursor event
2794 wxPoint clientorigin
= GetClientAreaOrigin() ;
2795 wxSize clientsize
= GetClientSize() ;
2797 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2799 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2801 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2802 if ( processedEvtSetCursor
&& event
.HasCursor() )
2804 cursor
= event
.GetCursor() ;
2808 // the test for processedEvtSetCursor is here to prevent using m_cursor
2809 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2810 // it - this is a way to say that our cursor shouldn't be used for this
2812 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2815 if ( !wxIsBusy() && !GetParent() )
2816 cursor
= *wxSTANDARD_CURSOR
;
2820 cursor
.MacInstall() ;
2823 return cursor
.Ok() ;
2826 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&pt
)
2830 return m_tooltip
->GetTip() ;
2833 return wxEmptyString
;
2836 void wxWindowMac::ClearBackground()
2842 void wxWindowMac::Update()
2844 #if TARGET_API_MAC_OSX
2845 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2847 top
->MacPerformUpdates() ;
2849 ::Draw1Control( m_peer
->GetControlRef() ) ;
2853 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2855 wxTopLevelWindowMac
* win
= NULL
;
2856 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2858 win
= wxFindWinFromMacWindow( window
) ;
2863 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2865 MacUpdateClippedRects() ;
2867 return m_cachedClippedClientRect
;
2870 const wxRect
& wxWindowMac::MacGetClippedRect() const
2872 MacUpdateClippedRects() ;
2874 return m_cachedClippedRect
;
2877 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2879 MacUpdateClippedRects() ;
2881 return m_cachedClippedRectWithOuterStructure
;
2884 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2886 static wxRegion emptyrgn
;
2888 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2890 MacUpdateClippedRects() ;
2891 if ( includeOuterStructures
)
2892 return m_cachedClippedRegionWithOuterStructure
;
2894 return m_cachedClippedRegion
;
2902 void wxWindowMac::MacUpdateClippedRects() const
2904 if ( m_cachedClippedRectValid
)
2907 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2908 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2909 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2910 // to add focus borders everywhere
2912 Rect r
, rIncludingOuterStructures
;
2914 m_peer
->GetRect( &r
) ;
2915 r
.left
-= MacGetLeftBorderSize() ;
2916 r
.top
-= MacGetTopBorderSize() ;
2917 r
.bottom
+= MacGetBottomBorderSize() ;
2918 r
.right
+= MacGetRightBorderSize() ;
2925 rIncludingOuterStructures
= r
;
2926 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2928 wxRect cl
= GetClientRect() ;
2929 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2933 const wxWindow
* child
= this ;
2934 const wxWindow
* parent
= NULL
;
2936 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2938 if ( parent
->MacIsChildOfClientArea(child
) )
2940 size
= parent
->GetClientSize() ;
2941 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2947 // this will be true for scrollbars, toolbars etc.
2948 size
= parent
->GetSize() ;
2949 y
= parent
->MacGetTopBorderSize() ;
2950 x
= parent
->MacGetLeftBorderSize() ;
2951 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2952 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2955 parent
->MacWindowToRootWindow( &x
, &y
) ;
2956 MacRootWindowToWindow( &x
, &y
) ;
2958 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2960 // the wxwindow and client rects will always be clipped
2961 SectRect( &r
, &rparent
, &r
) ;
2962 SectRect( &rClient
, &rparent
, &rClient
) ;
2964 // the structure only at 'hard' borders
2965 if ( parent
->MacClipChildren() ||
2966 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2968 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2974 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
2975 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
2976 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
2977 m_cachedClippedRectWithOuterStructure
= wxRect(
2978 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
2979 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
2980 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
2982 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
2983 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
2984 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
2986 m_cachedClippedRectValid
= true ;
2990 This function must not change the updatergn !
2992 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
2994 bool handled
= false ;
2996 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
2997 GetRegionBounds( updatergn
, &updatebounds
) ;
2999 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3001 if ( !EmptyRgn(updatergn
) )
3003 RgnHandle newupdate
= NewRgn() ;
3004 wxSize point
= GetClientSize() ;
3005 wxPoint origin
= GetClientAreaOrigin() ;
3006 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
3007 SectRgn( newupdate
, updatergn
, newupdate
) ;
3009 // first send an erase event to the entire update area
3011 // for the toplevel window this really is the entire area
3012 // for all the others only their client area, otherwise they
3013 // might be drawing with full alpha and eg put blue into
3014 // the grow-box area of a scrolled window (scroll sample)
3015 wxDC
* dc
= new wxWindowDC(this);
3017 dc
->SetClippingRegion(wxRegion(updatergn
));
3019 dc
->SetClippingRegion(wxRegion(newupdate
));
3021 wxEraseEvent
eevent( GetId(), dc
);
3022 eevent
.SetEventObject( this );
3023 GetEventHandler()->ProcessEvent( eevent
);
3027 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3028 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3029 m_updateRegion
= newupdate
;
3030 DisposeRgn( newupdate
) ;
3032 if ( !m_updateRegion
.Empty() )
3034 // paint the window itself
3037 event
.SetTimestamp(time
);
3038 event
.SetEventObject(this);
3039 GetEventHandler()->ProcessEvent(event
);
3043 // now we cannot rely on having its borders drawn by a window itself, as it does not
3044 // get the updateRgn wide enough to always do so, so we do it from the parent
3045 // this would also be the place to draw any custom backgrounds for native controls
3046 // in Composited windowing
3047 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3051 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3053 child
= node
->GetData();
3056 if (child
== m_vScrollBar
)
3058 if (child
== m_hScrollBar
)
3060 if (child
->IsTopLevel())
3062 if (!child
->IsShown())
3065 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3067 child
->GetPosition( &x
, &y
);
3068 child
->GetSize( &w
, &h
);
3069 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3070 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3071 InsetRect( &childRect
, -10 , -10) ;
3073 if ( RectInRgn( &childRect
, updatergn
) )
3075 // paint custom borders
3076 wxNcPaintEvent
eventNc( child
->GetId() );
3077 eventNc
.SetEventObject( child
);
3078 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3080 #if wxMAC_USE_CORE_GRAPHICS
3081 child
->MacPaintBorders(0, 0) ;
3084 wxWindowDC
dc(this) ;
3085 dc
.SetClippingRegion(wxRegion(updatergn
));
3086 wxMacPortSetter
helper(&dc
) ;
3087 child
->MacPaintBorders(0, 0) ;
3099 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3101 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3105 if ( iter
->IsTopLevel() )
3106 return ((wxTopLevelWindow
*)iter
)->MacGetWindowRef() ;
3108 iter
= iter
->GetParent() ;
3114 void wxWindowMac::MacCreateScrollBars( long style
)
3116 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3118 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3120 bool hasBoth
= ( style
& wxVSCROLL
) && ( style
& wxHSCROLL
) ;
3121 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3122 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3124 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3127 int adjust
= hasBoth
? scrlsize
- 1: 0 ;
3129 GetClientSize( &width
, &height
) ;
3131 wxPoint
vPoint(width
- scrlsize
, 0) ;
3132 wxSize
vSize(scrlsize
, height
- adjust
) ;
3133 wxPoint
hPoint(0, height
- scrlsize
) ;
3134 wxSize
hSize(width
- adjust
, scrlsize
) ;
3136 if ( style
& wxVSCROLL
)
3137 m_vScrollBar
= new wxScrollBar(this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3139 if ( style
& wxHSCROLL
)
3140 m_hScrollBar
= new wxScrollBar(this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3143 // because the create does not take into account the client area origin
3144 // we might have a real position shift
3145 MacRepositionScrollBars() ;
3148 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3150 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3155 void wxWindowMac::MacRepositionScrollBars()
3157 if ( !m_hScrollBar
&& !m_vScrollBar
)
3160 bool hasBoth
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && ( m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
3161 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3162 int adjust
= hasBoth
? scrlsize
- 1 : 0 ;
3164 // get real client area
3166 GetSize( &width
, &height
);
3168 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3169 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3171 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3172 wxSize
vSize( scrlsize
, height
- adjust
) ;
3173 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3174 wxSize
hSize( width
- adjust
, scrlsize
) ;
3177 int x
= 0, y
= 0, w
, h
;
3178 GetSize( &w
, &h
) ;
3180 MacClientToRootWindow( &x
, &y
) ;
3181 MacClientToRootWindow( &w
, &h
) ;
3183 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3185 int totW
= 10000 , totH
= 10000;
3188 if ( iter
->IsTopLevel() )
3190 iter
->GetSize( &totW
, &totH
) ;
3194 iter
= iter
->GetParent() ;
3208 if ( w
- x
>= totW
)
3213 if ( h
- y
>= totH
)
3221 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3223 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3226 bool wxWindowMac::AcceptsFocus() const
3228 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3231 void wxWindowMac::MacSuperChangedPosition()
3233 // only window-absolute structures have to be moved i.e. controls
3235 m_cachedClippedRectValid
= false ;
3238 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3241 child
= node
->GetData();
3242 child
->MacSuperChangedPosition() ;
3244 node
= node
->GetNext();
3248 void wxWindowMac::MacTopLevelWindowChangedPosition()
3250 // only screen-absolute structures have to be moved i.e. glcanvas
3253 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3256 child
= node
->GetData();
3257 child
->MacTopLevelWindowChangedPosition() ;
3259 node
= node
->GetNext();
3263 long wxWindowMac::MacGetLeftBorderSize() const
3270 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3272 // this metric is only the 'outset' outside the simple frame rect
3273 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3276 else if (HasFlag(wxSIMPLE_BORDER
))
3278 // this metric is only the 'outset' outside the simple frame rect
3279 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3286 long wxWindowMac::MacGetRightBorderSize() const
3288 // they are all symmetric in mac themes
3289 return MacGetLeftBorderSize() ;
3292 long wxWindowMac::MacGetTopBorderSize() const
3294 // they are all symmetric in mac themes
3295 return MacGetLeftBorderSize() ;
3298 long wxWindowMac::MacGetBottomBorderSize() const
3300 // they are all symmetric in mac themes
3301 return MacGetLeftBorderSize() ;
3304 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3306 return style
& ~wxBORDER_MASK
;
3309 // Find the wxWindowMac at the current mouse position, returning the mouse
3311 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3313 pt
= wxGetMousePosition();
3314 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3319 // Get the current mouse position.
3320 wxPoint
wxGetMousePosition()
3324 wxGetMousePosition( &x
, &y
);
3326 return wxPoint(x
, y
);
3329 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3331 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3333 // copied from wxGTK : CS
3334 // VZ: shouldn't we move this to base class then?
3336 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3339 // (a) it's a command event and so is propagated to the parent
3340 // (b) under MSW it can be generated from kbd too
3341 // (c) it uses screen coords (because of (a))
3342 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3344 this->ClientToScreen(event
.GetPosition()));
3345 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3354 void wxWindowMac::OnPaint( wxPaintEvent
& event
)
3356 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3357 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3358 CallNextEventHandler(
3359 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3360 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3363 void wxWindowMac::MacHandleControlClick( WXWidget control
, wxInt16 controlpart
, bool WXUNUSED( mouseStillDown
) )
3367 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3371 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3372 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3377 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3379 return eventNotHandledErr
;
3382 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3384 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3385 if ( !wxWindowBase::Reparent(newParent
) )
3388 // copied from MacPostControlCreate
3389 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3391 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3393 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3398 bool wxWindowMac::SetTransparent(wxByte alpha
)
3400 #if wxMAC_USE_CORE_GRAPHICS
3401 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3403 if ( alpha
!= m_macAlpha
)
3405 m_macAlpha
= alpha
;
3415 bool wxWindowMac::CanSetTransparent()
3417 #if wxMAC_USE_CORE_GRAPHICS
3424 wxByte
wxWindowMac::GetTransparent() const