From: Stefan Csomor Date: Tue, 29 Jul 2008 20:04:11 +0000 (+0000) Subject: osx regrouping X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/b2680ced12cbbed16990007c5fa3ea7730700122 osx regrouping git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54820 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/osx/carbon/aboutdlg.cpp b/src/osx/carbon/aboutdlg.cpp index eca978068f..49dd82abfa 100644 --- a/src/osx/carbon/aboutdlg.cpp +++ b/src/osx/carbon/aboutdlg.cpp @@ -61,7 +61,7 @@ void wxAboutBox(const wxAboutDialogInfo& info) // Mac native about box currently can show only name, version, copyright // and description fields and we also shoehorn the credits text into the // description but if we have anything else we must use the generic version -#ifndef __LP64__ +#if wxOSX_USE_CARBON if ( info.IsSimple() ) { AboutBoxOptions opts; diff --git a/src/osx/carbon/app.cpp b/src/osx/carbon/app.cpp index 17fde1212d..b2559ecd71 100644 --- a/src/osx/carbon/app.cpp +++ b/src/osx/carbon/app.cpp @@ -44,14 +44,14 @@ #include // mac - +#if wxOSX_USE_CARBON #include "wx/osx/uma.h" +#else +#include "wx/osx/private.h" +#endif -#ifdef __DARWIN__ -# include -# if defined(WXMAKINGDLL_CORE) -# include -# endif +#if defined(WXMAKINGDLL_CORE) +# include #endif // Keep linker from discarding wxStockGDIMac @@ -60,8 +60,9 @@ wxFORCE_LINK_MODULE(gdiobj) // statics for implementation static bool s_inYield = false; static bool s_inReceiveEvent = false ; +#if wxOSX_USE_COCOA_OR_CARBON static EventTime sleepTime = kEventDurationNoWait ; - +#endif IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) @@ -84,15 +85,25 @@ wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ; bool wxApp::sm_isEmbedded = false; // Normally we're not a plugin +#if wxOSX_USE_COCOA_OR_CARBON + //---------------------------------------------------------------------- // Core Apple Event Support //---------------------------------------------------------------------- +AEEventHandlerUPP sODocHandler = NULL ; +AEEventHandlerUPP sGURLHandler = NULL ; +AEEventHandlerUPP sOAppHandler = NULL ; +AEEventHandlerUPP sPDocHandler = NULL ; +AEEventHandlerUPP sRAppHandler = NULL ; +AEEventHandlerUPP sQuitHandler = NULL ; + pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; +pascal OSErr AEHandleGURL( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) ) { @@ -268,6 +279,8 @@ short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU return noErr ; } +#endif + //---------------------------------------------------------------------- // Support Routines linking the Mac...File Calls to the Document Manager //---------------------------------------------------------------------- @@ -378,6 +391,8 @@ void wxApp::MacReopenApp() // if no native match they just return the passed-in id +#if wxOSX_USE_CARBON + struct IdPair { UInt32 macId ; @@ -511,10 +526,14 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) return itemMenu ; } +#endif + //---------------------------------------------------------------------- // Carbon Event Handler //---------------------------------------------------------------------- +#if wxOSX_USE_CARBON + static const EventTypeSpec eventList[] = { { kEventClassCommand, kEventProcessCommand } , @@ -595,7 +614,6 @@ wxMacAppMenuEventHandler( EventHandlerCallRef WXUNUSED(handler), return eventNotHandledErr; } -#ifndef __LP64__ static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef WXUNUSED(handler) , EventRef event , @@ -632,7 +650,6 @@ wxMacAppCommandEventHandler( EventHandlerCallRef WXUNUSED(handler) , } return result ; } -#endif static pascal OSStatus wxMacAppApplicationEventHandler( EventHandlerCallRef WXUNUSED(handler) , @@ -726,8 +743,9 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve } DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler ) +#endif -#ifdef __WXDEBUG__ +#if defined( __WXDEBUG__ ) && wxOSX_USE_COCOA_OR_CARBON pascal static void wxMacAssertOutputHandler(OSType WXUNUSED(componentSignature), @@ -784,13 +802,10 @@ bool wxApp::Initialize(int& argc, wxChar **argv) { // Mac-specific -#ifdef __WXDEBUG__ +#if defined( __WXDEBUG__ ) && wxOSX_USE_COCOA_OR_CARBON InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) ); #endif - UMAInitToolbox( 4, sm_isEmbedded ) ; -// TODO CHECK Can Be Removed SetEventMask( everyEvent ) ; - // Mac OS X passes a process serial number command line argument when // the application is launched from the Finder. This argument must be // removed from the command line arguments before being handled by the @@ -838,18 +853,11 @@ bool wxApp::Initialize(int& argc, wxChar **argv) return true; } -AEEventHandlerUPP sODocHandler = NULL ; -AEEventHandlerUPP sGURLHandler = NULL ; -AEEventHandlerUPP sOAppHandler = NULL ; -AEEventHandlerUPP sPDocHandler = NULL ; -AEEventHandlerUPP sRAppHandler = NULL ; -AEEventHandlerUPP sQuitHandler = NULL ; - bool wxApp::OnInitGui() { if ( !wxAppBase::OnInitGui() ) return false ; -#ifndef __LP64__ +#if wxOSX_USE_CARBON InstallStandardEventHandler( GetApplicationEventTarget() ) ; if (!sm_isEmbedded) { @@ -859,6 +867,7 @@ bool wxApp::OnInitGui() } #endif +#if wxOSX_USE_COCOA_OR_CARBON if (!sm_isEmbedded) { sODocHandler = NewAEEventHandlerUPP(AEHandleODoc) ; @@ -881,9 +890,11 @@ bool wxApp::OnInitGui() AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , sQuitHandler , 0 , FALSE ) ; } - +#endif +#if wxOSX_USE_CARBON if ( !wxMacInitCocoa() ) return false; +#endif return true ; } @@ -903,6 +914,8 @@ void wxApp::CleanUp() // One last chance for pending objects to be cleaned up wxTheApp->DeletePendingObjects(); +#if wxOSX_USE_COCOA_OR_CARBON + if (!sm_isEmbedded) RemoveEventHandler( (EventHandlerRef)(wxTheApp->m_macEventHandler) ); @@ -929,6 +942,8 @@ void wxApp::CleanUp() DisposeAEEventHandlerUPP( sQuitHandler ) ; } +#endif + wxAppBase::CleanUp(); } @@ -1108,6 +1123,8 @@ bool wxApp::Yield(bool onlyIfNeeded) // by definition yield should handle all non-processed events +#if wxOSX_USE_COCOA_OR_CARBON + EventRef theEvent; OSStatus status = noErr ; @@ -1134,6 +1151,10 @@ bool wxApp::Yield(bool onlyIfNeeded) ReleaseEvent(theEvent); } } + +#else + +#endif s_inYield = false; @@ -1142,6 +1163,7 @@ bool wxApp::Yield(bool onlyIfNeeded) void wxApp::MacDoOneEvent() { +#if wxOSX_USE_COCOA_OR_CARBON wxMacAutoreleasePool autoreleasepool; EventRef theEvent; @@ -1170,7 +1192,8 @@ void wxApp::MacDoOneEvent() break; } // repeaters - +#else +#endif DeletePendingObjects() ; } @@ -1188,8 +1211,18 @@ CFMutableArrayRef GetAutoReleaseArray() return array; } +// +// +// + + +// +// +// + void wxApp::MacHandleOneEvent( WXEVENTREF evr ) { +#if wxOSX_USE_COCOA_OR_CARBON EventTargetRef theTarget; theTarget = GetEventDispatcherTarget(); m_macCurrentEvent = evr ; @@ -1202,6 +1235,11 @@ void wxApp::MacHandleOneEvent( WXEVENTREF evr ) wxMutexGuiLeaveOrEnter(); #endif // wxUSE_THREADS +#else + // TODO Threads +#endif + + CFArrayRemoveAllValues( GetAutoReleaseArray() ); } @@ -1210,6 +1248,8 @@ void wxApp::MacAddToAutorelease( void* cfrefobj ) CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj ); } +#if wxOSX_USE_COCOA_OR_CARBON + long wxMacTranslateKey(unsigned char key, unsigned char code) { long retval = key ; @@ -1375,10 +1415,12 @@ int wxMacKeyCodeToModifier(wxKeyCode key) return 0; } } +#endif wxMouseState wxGetMouseState() { wxMouseState ms; +#if wxOSX_USE_COCOA_OR_CARBON wxPoint pt = wxGetMousePosition(); ms.SetX(pt.x); @@ -1395,6 +1437,7 @@ wxMouseState wxGetMouseState() ms.SetAltDown(modifiers & optionKey); ms.SetMetaDown(modifiers & cmdKey); +#endif return ms; } @@ -1465,13 +1508,13 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers { if ( !focus ) return false ; - wxKeyEvent event(wxEVT_CHAR) ; MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; long keyval = event.m_keyCode ; bool handled = false ; +#if wxOSX_USE_CARBON wxNonOwnedWindow *tlw = focus->MacGetTopLevelWindow() ; if (tlw) @@ -1512,12 +1555,12 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers } // backdoor handler for default return and command escape - if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) ) + if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->AcceptsFocus() ) ) { // if window is not having a focus still testing for default enter or cancel // TODO: add the UMA version for ActiveNonFloatingWindow #ifndef __LP64__ - wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ; + wxWindow* focus = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) FrontWindow() ) ; if ( focus ) { if ( keyval == WXK_RETURN || keyval == WXK_NUMPAD_ENTER ) @@ -1546,12 +1589,14 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers } #endif } +#endif return handled ; } // This method handles common code for SendKeyDown, SendKeyUp, and SendChar events. void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) { +#if wxOSX_USE_COCOA_OR_CARBON short keycode, keychar ; keychar = short(keymessage & charCodeMask); @@ -1634,15 +1679,18 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess event.m_y = wherey; event.SetTimestamp(when); event.SetEventObject(focus); +#endif } void wxApp::MacHideApp() { +#if wxOSX_USE_CARBON wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ); HICommand command; memset( &command, 0 , sizeof(command) ); command.commandID = kHICommandHide ; event.SetParameter(kEventParamDirectObject, command ); SendEventToApplication( event ); +#endif } diff --git a/src/osx/carbon/artmac.cpp b/src/osx/carbon/artmac.cpp index 466ba9be56..5b08841635 100644 --- a/src/osx/carbon/artmac.cpp +++ b/src/osx/carbon/artmac.cpp @@ -23,6 +23,8 @@ #include "wx/image.h" #endif +#if !defined(__WXUNIVERSAL__) + #include "wx/artprov.h" #include "wx/image.h" @@ -106,3 +108,7 @@ wxBitmap wxMacArtProvider::CreateBitmap(const wxArtID& id, return wxNullBitmap; } + +#endif // !defined(__WXUNIVERSAL__) + + diff --git a/src/osx/carbon/bitmap.cpp b/src/osx/carbon/bitmap.cpp index dfe4278bfd..98aeb234b2 100644 --- a/src/osx/carbon/bitmap.cpp +++ b/src/osx/carbon/bitmap.cpp @@ -28,7 +28,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject) IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) +#if wxOSX_USE_CARBON #include "wx/osx/uma.h" +#else +#include "wx/osx/private.h" +#endif + #ifndef __WXOSX_IPHONE__ #include #endif @@ -1688,7 +1693,9 @@ void wxBitmap::InitStandardHandlers() #if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__) AddHandler( new wxPICTResourceHandler ) ; #endif +#if wxOSX_USE_COCOA_OR_CARBON AddHandler( new wxICONResourceHandler ) ; +#endif } // ---------------------------------------------------------------------------- diff --git a/src/osx/carbon/bmpbuttn.cpp b/src/osx/carbon/bmpbuttn.cpp index 36512500e3..4421c143d7 100644 --- a/src/osx/carbon/bmpbuttn.cpp +++ b/src/osx/carbon/bmpbuttn.cpp @@ -137,7 +137,7 @@ bool wxBitmapButton::Create( wxWindow *parent, verify_noerr( err ); wxMacReleaseBitmapButton( &info ); - wxASSERT_MSG( m_peer != NULL && m_peer->Ok(), wxT("No valid native Mac control") ); + wxASSERT_MSG( m_peer != NULL && m_peer->IsOk(), wxT("No valid native Mac control") ); MacPostControlCreate( pos, size ); diff --git a/src/osx/carbon/button.cpp b/src/osx/carbon/button.cpp index 021ddac112..6c57596e6a 100644 --- a/src/osx/carbon/button.cpp +++ b/src/osx/carbon/button.cpp @@ -92,7 +92,7 @@ bool wxButton::Create(wxWindow *parent, } verify_noerr( err ); - wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid Mac control") ) ; + wxASSERT_MSG( m_peer != NULL && m_peer->IsOk() , wxT("No valid Mac control") ) ; MacPostControlCreate( pos, size ); @@ -236,7 +236,7 @@ bool wxDisclosureTriangle::Create(wxWindow *parent, wxWindowID id, const wxStrin m_peer->GetControlRefAddr() ); verify_noerr( err ); - wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid Mac control") ) ; + wxASSERT_MSG( m_peer != NULL && m_peer->IsOk() , wxT("No valid Mac control") ) ; MacPostControlCreate( pos, size ); // passing the text in the param doesn't seem to work, so lets do if again diff --git a/src/osx/carbon/checklst.cpp b/src/osx/carbon/checklst.cpp index adff768e25..218600348f 100644 --- a/src/osx/carbon/checklst.cpp +++ b/src/osx/carbon/checklst.cpp @@ -186,7 +186,7 @@ public : { OSStatus err = errDataBrowserPropertyNotSupported; - wxCheckListBox *checklist = wxDynamicCast( owner->GetPeer() , wxCheckListBox ); + wxCheckListBox *checklist = wxDynamicCast( owner->GetWXPeer() , wxCheckListBox ); wxCHECK_MSG( checklist != NULL , errDataBrowserPropertyNotSupported , wxT("wxCheckListBox expected")); if ( !changeValue ) diff --git a/src/osx/carbon/clipbrd.cpp b/src/osx/carbon/clipbrd.cpp index c05e24d120..1fa330c6d3 100644 --- a/src/osx/carbon/clipbrd.cpp +++ b/src/osx/carbon/clipbrd.cpp @@ -27,7 +27,7 @@ #include "wx/metafile.h" -#include "wx/osx/uma.h" +#include "wx/osx/private.h" #define wxUSE_DATAOBJ 1 diff --git a/src/osx/carbon/colour.cpp b/src/osx/carbon/colour.cpp index f46a19e9e7..a339b29339 100644 --- a/src/osx/carbon/colour.cpp +++ b/src/osx/carbon/colour.cpp @@ -21,7 +21,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxColour, wxObject) -#if wxMAC_USE_QUICKDRAW +#if wxOSX_USE_QUICKDRAW wxColour::wxColour(const RGBColor& col) { InitRGBColor(col); @@ -33,7 +33,7 @@ wxColour::wxColour(CGColorRef col) InitCGColorRef(col); } -#if wxMAC_USE_QUICKDRAW +#if wxOSX_USE_QUICKDRAW void wxColour::GetRGBColor( RGBColor *col ) const { col->red = (m_red << 8) + m_red; @@ -84,7 +84,7 @@ void wxColour::InitRGBA (ChannelType r, ChannelType g, ChannelType b, ChannelTyp m_cgColour.reset( col ); } -#if wxMAC_USE_QUICKDRAW +#if wxOSX_USE_QUICKDRAW void wxColour::InitRGBColor( const RGBColor& col ) { m_red = col.red >> 8; diff --git a/src/osx/carbon/control.cpp b/src/osx/carbon/control.cpp index e8874e6a8c..0389a007de 100644 --- a/src/osx/carbon/control.cpp +++ b/src/osx/carbon/control.cpp @@ -83,7 +83,7 @@ bool wxControl::ProcessCommand( wxCommandEvent &event ) void wxControl::OnKeyDown( wxKeyEvent &WXUNUSED(event) ) { - if ( m_peer == NULL || !m_peer->Ok() ) + if ( m_peer == NULL || !m_peer->IsOk() ) return; UInt32 keyCode, modifiers; diff --git a/src/osx/carbon/cursor.cpp b/src/osx/carbon/cursor.cpp index af2f32a726..b7849bc732 100644 --- a/src/osx/carbon/cursor.cpp +++ b/src/osx/carbon/cursor.cpp @@ -36,25 +36,32 @@ public: virtual bool IsOk() const { +#if wxOSX_USE_COCOA_OR_CARBON if ( m_hCursor != NULL ) return true; -#if !wxMAC_USE_COCOA +#if wxOSX_USE_CARBON if ( m_themeCursor != -1 ) return true; #endif return false; +#else + // in order to avoid asserts, always claim to have a valid cursor + return true; +#endif } protected: -#if wxMAC_USE_COCOA +#if wxOSX_USE_COCOA WX_NSCursor m_hCursor; -#else +#elif wxOSX_USE_CARBON WXHCURSOR m_hCursor; bool m_disposeHandle; bool m_releaseHandle; bool m_isColorCursor; long m_themeCursor; +#elif wxOSX_USE_IPHONE + void* m_hCursor; #endif friend class wxCursor; @@ -64,6 +71,8 @@ protected: #define M_CURSORDATA wx_static_cast(wxCursorRefData*, m_refData) +#if wxOSX_USE_COCOA_OR_CARBON + ClassicCursor gMacCursors[kwxCursorLast+1] = { @@ -189,9 +198,11 @@ ClassicCursor gMacCursors[kwxCursorLast+1] = }; +#endif + wxCursor gMacCurrentCursor ; -#if !wxMAC_USE_COCOA +#if wxOSX_USE_CARBON CursHandle wxGetStockCursor( int number ) { wxASSERT_MSG( number >= 0 && number <=kwxCursorLast , wxT("invalid stock cursor id") ) ; @@ -212,8 +223,7 @@ CursHandle wxGetStockCursor( int number ) wxCursorRefData::wxCursorRefData() { m_hCursor = NULL; -#if wxMAC_USE_COCOA -#else +#if wxOSX_USE_CARBON m_disposeHandle = false; m_releaseHandle = false; m_isColorCursor = false; @@ -226,9 +236,9 @@ wxCursorRefData::wxCursorRefData(const wxCursorRefData& cursor) // FIXME: need to copy the cursor m_hCursor = NULL; -#if wxMAC_USE_COCOA +#if wxOSX_USE_COCOA wxUnusedVar(cursor); -#else +#elif wxOSX_USE_CARBON m_disposeHandle = false; m_releaseHandle = false; m_isColorCursor = cursor.m_isColorCursor; @@ -238,10 +248,10 @@ wxCursorRefData::wxCursorRefData(const wxCursorRefData& cursor) wxCursorRefData::~wxCursorRefData() { -#if wxMAC_USE_COCOA +#if wxOSX_USE_COCOA if ( m_hCursor ) wxMacCocoaRelease(m_hCursor); -#else +#elif wxOSX_USE_CARBON if ( m_isColorCursor ) { #ifndef __LP64__ @@ -310,7 +320,7 @@ WXHCURSOR wxCursor::GetHCURSOR() const return (M_CURSORDATA ? M_CURSORDATA->m_hCursor : 0); } -#if !wxMAC_USE_COCOA +#if wxOSX_USE_CARBON short GetCTabIndex( CTabHandle colors , RGBColor *col ) { short retval = 0 ; @@ -340,7 +350,7 @@ void wxCursor::CreateFromImage(const wxImage & image) m_refData = new wxCursorRefData; int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X); int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y); -#if wxMAC_USE_COCOA +#if wxOSX_USE_COCOA wxBitmap bmp( image ); CGImageRef cgimage = wxMacCreateCGImageFromBitmap(bmp); if ( cgimage ) @@ -348,7 +358,7 @@ void wxCursor::CreateFromImage(const wxImage & image) M_CURSORDATA->m_hCursor = wxMacCocoaCreateCursorFromCGImage( cgimage, hotSpotX, hotSpotY ); CFRelease( cgimage ); } -#else +#elif wxOSX_USE_CARBON #ifndef __LP64__ int w = 16; int h = 16; @@ -489,9 +499,9 @@ wxCursor::wxCursor(const wxString& cursor_file, wxBitmapType flags, int hotSpotX m_refData = new wxCursorRefData; if ( flags == wxBITMAP_TYPE_MACCURSOR_RESOURCE ) { -#if wxMAC_USE_COCOA +#if wxOSX_USE_COCOA wxFAIL_MSG( wxT("Not implemented") ); -#else +#elif wxOSX_USE_CARBON #ifndef __LP64__ Str255 theName ; wxMacStringToPascal( cursor_file , theName ) ; @@ -549,9 +559,9 @@ wxCursor::wxCursor(const wxString& cursor_file, wxBitmapType flags, int hotSpotX wxCursor::wxCursor(int cursor_type) { m_refData = new wxCursorRefData; -#if wxMAC_USE_COCOA +#if wxOSX_USE_COCOA M_CURSORDATA->m_hCursor = wxMacCocoaCreateStockCursor( cursor_type ); -#else +#elif wxOSX_USE_CARBON switch (cursor_type) { case wxCURSOR_COPY_ARROW: @@ -660,10 +670,10 @@ wxCursor::wxCursor(int cursor_type) void wxCursor::MacInstall() const { gMacCurrentCursor = *this ; -#if wxMAC_USE_COCOA +#if wxOSX_USE_COCOA if ( IsOk() ) wxMacCocoaSetCursor( M_CURSORDATA->m_hCursor ); -#else +#elif wxOSX_USE_CARBON if ( m_refData && M_CURSORDATA->m_themeCursor != -1 ) { SetThemeCursor( M_CURSORDATA->m_themeCursor ) ; diff --git a/src/osx/carbon/databrow.cpp b/src/osx/carbon/databrow.cpp index 33a9a582ec..b8f5eef04a 100644 --- a/src/osx/carbon/databrow.cpp +++ b/src/osx/carbon/databrow.cpp @@ -615,7 +615,7 @@ Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrow DataBrowserTableViewColumnIndex modelColumnIndex; - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly.")); @@ -640,7 +640,7 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(M { wxArrayDataBrowserItemID itemIDs; - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); wxCHECK_RET(dataViewCtrlPtr != NULL,_("wxWidget control pointer is not a data view pointer")); @@ -668,7 +668,7 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( // variable definitions: wxDataViewCtrl* dataViewCtrlPtr; - dataViewCtrlPtr = dynamic_cast(this->GetPeer()); + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); if (dataViewCtrlPtr->IsDeleting()) return noErr; // if a delete process is running the data of editable fields cannot be saved because the associated model variable may already have been deleted @@ -762,7 +762,7 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( wxDataViewColumn* dataViewColumnPtr; wxDataViewCtrl* dataViewCtrlPtr; - dataViewCtrlPtr = dynamic_cast(this->GetPeer()); + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly.")); dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID); @@ -784,7 +784,7 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( case kDataBrowserContainerIsClosableProperty: { // variable definitions: - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); // initialize wxWidget event: @@ -801,7 +801,7 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( case kDataBrowserContainerIsOpenableProperty: { // variable definitions: - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); // initialize wxWidget event: @@ -818,7 +818,7 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( case kDataBrowserItemIsContainerProperty: { // variable definition: - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly.")); @@ -834,7 +834,7 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData) { - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); // check if the data view control pointer still exists because this call back function can still be called when the control has already been deleted: @@ -1006,7 +1006,7 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowse wxVariant dataToRender; - dataViewCtrlPtr = dynamic_cast(this->GetPeer()); + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly.")); wxCHECK_RET(dataViewCtrlPtr->GetModel() != NULL,_("Pointer to model not set correctly.")); wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex) == noErr,_("Could not determine column index.")); @@ -1029,7 +1029,7 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowse if (this->GetRegion(kControlContentMetaPart,rgn) == noErr) GetRegionBounds(rgn,&content); else - this->GetRect(&content); + GetControlBounds(m_controlRef, &content); ::DisposeRgn(rgn); // space for the header this->GetHeaderButtonHeight(&headerHeight); @@ -1111,7 +1111,7 @@ DataBrowserTrackingResult wxMacDataViewDataBrowserListViewControl::DataBrowserTr dataViewCustomRendererItem = reinterpret_cast(itemID); wxCHECK_MSG(dataViewCustomRendererItem.IsOk(),kDataBrowserNothingHit,_("Invalid data view item")); - dataViewCtrlPtr = dynamic_cast(this->GetPeer()); + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); wxCHECK_MSG(dataViewCtrlPtr != NULL,kDataBrowserNothingHit,_("Pointer to data view control not set correctly.")); dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID); wxCHECK_MSG(dataViewColumnPtr != NULL,kDataBrowserNothingHit,_("No column existing.")); diff --git a/src/osx/carbon/dataview.cpp b/src/osx/carbon/dataview.cpp index 2dd11a6b2e..775ef9e4cc 100644 --- a/src/osx/carbon/dataview.cpp +++ b/src/osx/carbon/dataview.cpp @@ -220,7 +220,7 @@ public: bool noFailureFlag = (!(parent.IsOk()) && (this->m_dataViewControlPtr->AddItem(kDataBrowserNoItem,&itemID) == noErr) || parent.IsOk() && (this->m_dataViewControlPtr->AddItem(reinterpret_cast(parent.GetID()),&itemID) == noErr)); - wxDataViewCtrl *dvc = (wxDataViewCtrl*) this->m_dataViewControlPtr->GetPeer(); + wxDataViewCtrl *dvc = (wxDataViewCtrl*) this->m_dataViewControlPtr->GetWXPeer(); if (dvc->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) { wxDataViewModel *model = GetOwner(); @@ -270,7 +270,7 @@ public: // give allocated array space free again: delete[] itemIDs; - wxDataViewCtrl *dvc = (wxDataViewCtrl*) this->m_dataViewControlPtr->GetPeer(); + wxDataViewCtrl *dvc = (wxDataViewCtrl*) this->m_dataViewControlPtr->GetWXPeer(); if (dvc->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) { wxDataViewModel *model = GetOwner(); @@ -321,7 +321,7 @@ public: wxCHECK_MSG(item.IsOk(),false,_("Changed item is invalid.")); if (this->m_dataViewControlPtr->UpdateItems(&itemID) == noErr) { - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetWXPeer())); // sent the equivalent wxWidget event: wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId()); // variable defintion @@ -356,7 +356,7 @@ public: noFailureFlag = (this->m_dataViewControlPtr->UpdateItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr); if (noFailureFlag) { - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetWXPeer())); // send for all changed items a wxWidget event: wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId()); // variable defintion @@ -385,7 +385,7 @@ public: // variable definition and initialization: DataBrowserItemID itemID(reinterpret_cast(item.GetID())); OSStatus errorStatus; - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetWXPeer())); // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have // not to be identical because the being edited item might be below the passed item in the hierarchy); @@ -407,7 +407,7 @@ public: DataBrowserItemID* itemIDs; - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetWXPeer())); size_t noOfEntries; @@ -439,7 +439,7 @@ public: DataBrowserPropertyID propertyID; - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetWXPeer())); wxCHECK_MSG(item.IsOk(), false,_("Passed item is invalid.")); diff --git a/src/osx/carbon/dcclient.cpp b/src/osx/carbon/dcclient.cpp index 00b970dd9a..9264e8b2d8 100644 --- a/src/osx/carbon/dcclient.cpp +++ b/src/osx/carbon/dcclient.cpp @@ -26,6 +26,7 @@ #include "wx/graphics.h" #include "wx/rawbmp.h" #include "wx/osx/private.h" +#include "wx/osx/dcclient.h" //----------------------------------------------------------------------------- // wxWindowDCImpl @@ -39,21 +40,20 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner ) m_release = false; } + wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) : wxGCDCImpl( owner ) { m_window = window; - WindowRef rootwindow = (WindowRef) window->MacGetTopLevelWindowRef() ; - if (!rootwindow) - return; - m_ok = true ; m_window->GetSize( &m_width , &m_height); if ( !m_window->IsShownOnScreen() ) m_width = m_height = 0; + CGContextRef cg = (CGContextRef) window->MacGetCGContextRef(); + m_release = false; if ( cg == NULL ) { @@ -96,6 +96,7 @@ void wxWindowDCImpl::DoGetSize( int* width, int* height ) const *height = m_height; } +#if wxOSX_USE_CARBON wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const { // wxScreenDC is derived from wxWindowDC, so a screen dc will @@ -103,9 +104,6 @@ wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const if (!m_window) return wxNullBitmap; -#ifdef __LP64__ - return wxNullBitmap; -#else ControlRef handle = (ControlRef) m_window->GetHandle(); if ( !handle ) return wxNullBitmap; @@ -139,8 +137,8 @@ wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const CGContextRestoreGState(context); return bmp; -#endif } +#endif /* * wxClientDCImpl diff --git a/src/osx/carbon/dcscreen.cpp b/src/osx/carbon/dcscreen.cpp index 521f73b3ae..6cd9b891fe 100644 --- a/src/osx/carbon/dcscreen.cpp +++ b/src/osx/carbon/dcscreen.cpp @@ -12,9 +12,9 @@ #include "wx/wxprec.h" #include "wx/dcscreen.h" -#include "wx/osx/carbon/dcscreen.h" +#include "wx/osx/dcscreen.h" -#include "wx/osx/uma.h" +#include "wx/osx/private.h" #include "wx/graphics.h" IMPLEMENT_ABSTRACT_CLASS(wxScreenDCImpl, wxWindowDCImpl) @@ -27,7 +27,7 @@ IMPLEMENT_ABSTRACT_CLASS(wxScreenDCImpl, wxWindowDCImpl) wxScreenDCImpl::wxScreenDCImpl( wxDC *owner ) : wxWindowDCImpl( owner ) { -#ifdef __LP64__ +#if wxOSX_USE_COCOA_OR_IPHONE m_graphicContext = NULL; m_ok = false ; #else @@ -52,7 +52,7 @@ wxScreenDCImpl::~wxScreenDCImpl() { delete m_graphicContext; m_graphicContext = NULL; -#ifdef __LP64__ +#if wxOSX_USE_COCOA_OR_IPHONE #else DisposeWindow((WindowRef) m_overlayWindow ); #endif diff --git a/src/osx/carbon/dialog.cpp b/src/osx/carbon/dialog.cpp index 7dffcc6db8..c97b487fb6 100644 --- a/src/osx/carbon/dialog.cpp +++ b/src/osx/carbon/dialog.cpp @@ -62,7 +62,7 @@ void wxDialog::SetModal( bool flag ) { m_isModalStyle = true; - SetWindowModality( (WindowRef)MacGetWindowRef(), kWindowModalityAppModal, NULL ) ; + SetWindowModality( (WindowRef)GetWXWindow(), kWindowModalityAppModal, NULL ) ; } else { @@ -135,7 +135,7 @@ void wxDialog::DoShowModal() SetFocus() ; - WindowRef windowRef = (WindowRef) MacGetWindowRef(); + WindowRef windowRef = (WindowRef) GetWXWindow(); WindowGroupRef windowGroup; WindowGroupRef formerParentGroup; bool resetGroupParent = false; diff --git a/src/osx/carbon/dirdlg.cpp b/src/osx/carbon/dirdlg.cpp index 6fc40059c7..e3f1a95ba6 100644 --- a/src/osx/carbon/dirdlg.cpp +++ b/src/osx/carbon/dirdlg.cpp @@ -11,7 +11,7 @@ #include "wx/wxprec.h" -#if wxUSE_DIRDLG +#if wxUSE_DIRDLG && !defined(__WXUNIVERSAL__) #include "wx/dirdlg.h" diff --git a/src/osx/carbon/display.cpp b/src/osx/carbon/display.cpp index d8159cb352..6743a09f6d 100644 --- a/src/osx/carbon/display.cpp +++ b/src/osx/carbon/display.cpp @@ -34,9 +34,10 @@ #include "wx/gdicmn.h" #endif -#include - #include "wx/display_impl.h" +#include "wx/osx/private.h" + +#if wxOSX_USE_COCOA_OR_CARBON // ---------------------------------------------------------------------------- // display classes implementation @@ -252,4 +253,13 @@ bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode& mode ) return new wxDisplayFactoryMacOSX; } +#else + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() +{ + return new wxDisplayFactorySingle; +} + +#endif + #endif // wxUSE_DISPLAY diff --git a/src/osx/carbon/dnd.cpp b/src/osx/carbon/dnd.cpp index b5d299b476..c6b659df3a 100644 --- a/src/osx/carbon/dnd.cpp +++ b/src/osx/carbon/dnd.cpp @@ -359,7 +359,7 @@ pascal OSErr wxMacWindowDragTrackingHandler( GetDragAttributes( theDrag, &attributes ); - wxNonOwnedWindow* toplevel = wxFindWinFromMacWindow( theWindow ); + wxNonOwnedWindow* toplevel = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) theWindow ); bool optionDown = GetCurrentKeyModifiers() & optionKey; wxDragResult result = optionDown ? wxDragCopy : wxDragMove; @@ -385,15 +385,18 @@ pascal OSErr wxMacWindowDragTrackingHandler( break; GetDragMouse( theDrag, &mouse, 0L ); - localMouse = mouse; - wxMacGlobalToLocal( theWindow, &localMouse ); + int x = mouse.h ; + int y = mouse.v ; + toplevel->GetNonOwnedPeer()->ScreenToWindow( &x, &y ); + localMouse.h = x; + localMouse.v = y; { wxWindow *win = NULL; ControlPartCode controlPart; ControlRef control = FindControlUnderMouse( localMouse, theWindow, &controlPart ); if ( control ) - win = wxFindControlFromMacControl( control ); + win = wxFindWindowFromWXWidget( (WXWidget) control ); else win = toplevel; @@ -534,9 +537,11 @@ pascal OSErr wxMacWindowDragReceiveHandler( trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ); GetDragMouse( theDrag, &mouse, 0L ); localMouse = mouse; - wxMacGlobalToLocal( theWindow, &localMouse ); localx = localMouse.h; localy = localMouse.v; + wxNonOwnedWindow* tlw = wxNonOwnedWindow::GetFromWXWindow((WXWindow) theWindow); + if ( tlw ) + tlw->GetNonOwnedPeer()->ScreenToWindow( &localx, &localy ); // TODO : should we use client coordinates? if ( trackingGlobals->m_currentTargetWindow ) diff --git a/src/osx/carbon/drawer.cpp b/src/osx/carbon/drawer.cpp index 9c2368fe90..36dc09de1a 100644 --- a/src/osx/carbon/drawer.cpp +++ b/src/osx/carbon/drawer.cpp @@ -69,30 +69,30 @@ bool wxDrawerWindow::Create(wxWindow *parent, const wxSize dummySize(0,0); const long style = wxFRAME_DRAWER; - bool success = wxWindow::Create(parent, id, pos, dummySize, style, name); + bool success = wxNonOwnedWindow::Create(parent, id, pos, size, style, name); if (success) { - this->MacCreateRealWindow(pos, size, style, name); - success = (m_macWindow != NULL); + // this->MacCreateRealWindow(pos, size, style, name); + success = (GetWXWindow() != NULL); } if (success) { // Use drawer brush. SetBackgroundColour( wxColour( wxMacCreateCGColorFromHITheme( kThemeBrushDrawerBackground ) ) ); - ::SetThemeWindowBackground((WindowRef)m_macWindow, kThemeBrushDrawerBackground, false); + ::SetThemeWindowBackground((WindowRef)GetWXWindow(), kThemeBrushDrawerBackground, false); // Leading and trailing offset are gaps from parent window edges // to where the drawer starts. - ::SetDrawerOffsets((WindowRef)m_macWindow, kLeadingOffset, kTrailingOffset); + ::SetDrawerOffsets((WindowRef)GetWXWindow() , kLeadingOffset, kTrailingOffset); // Set the drawers parent. // Is there a better way to get the parent's WindowRef? wxTopLevelWindow* tlwParent = wxDynamicCast(parent, wxTopLevelWindow); if (NULL != tlwParent) { - OSStatus status = ::SetDrawerParent((WindowRef)m_macWindow, - (WindowRef)tlwParent->MacGetWindowRef()); + OSStatus status = ::SetDrawerParent((WindowRef) GetWXWindow(), + (WindowRef)tlwParent->GetWXWindow()); success = (noErr == status); } else @@ -104,19 +104,19 @@ bool wxDrawerWindow::Create(wxWindow *parent, wxDirection wxDrawerWindow::GetCurrentEdge() const { - const OptionBits edge = ::GetDrawerCurrentEdge((WindowRef)m_macWindow); + const OptionBits edge = ::GetDrawerCurrentEdge((WindowRef)GetWXWindow()); return WindowEdgeToDirection(edge); } wxDirection wxDrawerWindow::GetPreferredEdge() const { - const OptionBits edge = ::GetDrawerPreferredEdge((WindowRef)m_macWindow); + const OptionBits edge = ::GetDrawerPreferredEdge((WindowRef)GetWXWindow()); return WindowEdgeToDirection(edge); } bool wxDrawerWindow::IsOpen() const { - WindowDrawerState state = ::GetDrawerState((WindowRef)m_macWindow); + WindowDrawerState state = ::GetDrawerState((WindowRef)GetWXWindow()); return (state == kWindowDrawerOpen || state == kWindowDrawerOpening); } @@ -127,18 +127,18 @@ bool wxDrawerWindow::Open(bool show) if (show) { - const OptionBits preferredEdge = ::GetDrawerPreferredEdge((WindowRef)m_macWindow); - status = ::OpenDrawer((WindowRef)m_macWindow, preferredEdge, kAsynchronous); + const OptionBits preferredEdge = ::GetDrawerPreferredEdge((WindowRef)GetWXWindow()); + status = ::OpenDrawer((WindowRef)GetWXWindow(), preferredEdge, kAsynchronous); } else - status = ::CloseDrawer((WindowRef)m_macWindow, kAsynchronous); + status = ::CloseDrawer((WindowRef)GetWXWindow(), kAsynchronous); return (noErr == status); } bool wxDrawerWindow::SetPreferredEdge(wxDirection edge) { - const OSStatus status = ::SetDrawerPreferredEdge((WindowRef)m_macWindow, + const OSStatus status = ::SetDrawerPreferredEdge((WindowRef)GetWXWindow(), DirectionToWindowEdge(edge)); return (noErr == status); } diff --git a/src/osx/carbon/evtloop.cpp b/src/osx/carbon/evtloop.cpp index 681564bffa..deee02fdce 100644 --- a/src/osx/carbon/evtloop.cpp +++ b/src/osx/carbon/evtloop.cpp @@ -30,10 +30,10 @@ #include "wx/app.h" #endif // WX_PRECOMP -#ifdef __DARWIN__ +#if wxOSX_USE_CARBON #include #else - #include + #include #endif // ============================================================================ // wxEventLoop implementation @@ -43,6 +43,8 @@ // high level functions for RunApplicationEventLoop() case // ---------------------------------------------------------------------------- + + #if wxMAC_USE_RUN_APP_EVENT_LOOP int wxGUIEventLoop::Run() @@ -84,6 +86,7 @@ void wxGUIEventLoop::WakeUp() bool wxGUIEventLoop::Pending() const { +#if wxOSX_USE_CARBON EventRef theEvent; return ReceiveNextEvent @@ -94,16 +97,23 @@ bool wxGUIEventLoop::Pending() const false, // don't remove the event from queue &theEvent ) == noErr; +#else + return true; // TODO +#endif } bool wxGUIEventLoop::Dispatch() { - // TODO: we probably should do the dispatching directly from here but for - // now it's easier to forward to wxApp which has all the code to do - // it if ( !wxTheApp ) return false; +#if wxOSX_USE_CARBON + // TODO: we probably should do the dispatching directly from here but for + // now it's easier to forward to wxApp which has all the code to do + // it wxTheApp->MacDoOneEvent(); +#else + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 0); +#endif return true; } diff --git a/src/osx/carbon/font.cpp b/src/osx/carbon/font.cpp index 53a3061271..6506760bbb 100644 --- a/src/osx/carbon/font.cpp +++ b/src/osx/carbon/font.cpp @@ -25,7 +25,11 @@ #include "wx/graphics.h" #include "wx/settings.h" +#if wxOSX_USE_CARBON #include "wx/osx/uma.h" +#else +#include "wx/osx/private.h" +#endif #ifndef __DARWIN__ #include @@ -414,7 +418,7 @@ void wxFontRefData::MacFindFont() traits |= kCTFontItalicTrait; // use font descriptor caching -#if 1 +#if 0 wxString lookupname = wxString::Format( "%s_%ld", m_faceName.c_str(), traits ); static std::map< std::wstring , wxCFRef< CTFontDescriptorRef > > fontdescriptorcache ; @@ -432,7 +436,7 @@ void wxFontRefData::MacFindFont() #endif // use font caching -#if 1 +#if 0 wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_faceName.c_str(), traits, m_pointSize ); static std::map< std::wstring , wxCFRef< CTFontRef > > fontcache ; @@ -445,6 +449,17 @@ void wxFontRefData::MacFindFont() #else m_ctFont.reset( CTFontCreateWithFontDescriptor( m_ctFontDescriptor, m_pointSize, NULL ) ); #endif + if ( /* (CTFontGetSymbolicTraits( m_ctFont ) & 0x03) !=*/ traits ) + { + CTFontRef font = CTFontCreateWithName( cf, m_pointSize, NULL ); + CTFontRef font2 = CTFontCreateCopyWithSymbolicTraits( font, m_pointSize, NULL, traits, 0x03 ); + CFRelease(font); + m_ctFont.reset( font2 ); + if ( (CTFontGetSymbolicTraits( m_ctFont ) & 0x03) != traits ) + { + wxMessageBox( wxString::Format( "expected %d but got %d traits" , traits, (CTFontGetSymbolicTraits( m_ctFont ) & 0x03) ) ); + } + } } #if wxMAC_USE_ATSU_TEXT OSStatus status = noErr; diff --git a/src/osx/carbon/frame.cpp b/src/osx/carbon/frame.cpp index fb6b170ae8..ca668dc372 100644 --- a/src/osx/carbon/frame.cpp +++ b/src/osx/carbon/frame.cpp @@ -225,7 +225,7 @@ void wxFrame::DetachMenuBar() void wxFrame::AttachMenuBar( wxMenuBar *menuBar ) { - wxFrame* tlf = wxDynamicCast( wxFindWinFromMacWindow( FrontNonFloatingWindow() ) , wxFrame ); + wxFrame* tlf = wxDynamicCast( wxNonOwnedWindow::GetFromWXWindow( (WXWindow) FrontNonFloatingWindow() ) , wxFrame ); bool makeCurrent = false; // if this is already the current menubar or we are the frontmost window diff --git a/src/osx/carbon/gauge.cpp b/src/osx/carbon/gauge.cpp index 57a83ed4f1..d0fcd56142 100644 --- a/src/osx/carbon/gauge.cpp +++ b/src/osx/carbon/gauge.cpp @@ -60,7 +60,7 @@ void wxGauge::SetRange(int r) // we are going via the base class in case there is // some change behind the values by it wxGaugeBase::SetRange( r ) ; - if ( m_peer && m_peer->Ok() ){ + if ( m_peer && m_peer->IsOk() ){ // switch back to determinate mode if not there already if ( m_peer->GetData( kControlNoPart, kControlProgressBarIndeterminateTag ) != false ) { @@ -77,7 +77,7 @@ void wxGauge::SetValue(int pos) // some change behind the values by it wxGaugeBase::SetValue( pos ) ; - if ( m_peer && m_peer->Ok() ) + if ( m_peer && m_peer->IsOk() ) { // switch back to determinate mode if not there already if ( m_peer->GetData( kControlNoPart, kControlProgressBarIndeterminateTag ) != false ) @@ -110,7 +110,7 @@ int wxGauge::GetValue() const void wxGauge::Pulse() { - if ( m_peer && m_peer->Ok() ) + if ( m_peer && m_peer->IsOk() ) { if ( m_peer->GetData( kControlNoPart, kControlProgressBarIndeterminateTag ) != true ) { diff --git a/src/osx/carbon/gdiobj.cpp b/src/osx/carbon/gdiobj.cpp index ad33a80ba9..81fb05c458 100644 --- a/src/osx/carbon/gdiobj.cpp +++ b/src/osx/carbon/gdiobj.cpp @@ -20,6 +20,7 @@ #include "wx/link.h" #include "wx/osx/private.h" +#include "wx/font.h" // Linker will discard entire object file without this wxFORCE_LINK_THIS_MODULE(gdiobj) @@ -50,6 +51,9 @@ void wxStockGDIMac::OnExit() { } +extern wxFont* CreateNormalFont(); +extern wxFont* CreateSmallFont(); + const wxFont* wxStockGDIMac::GetFont(Item item) { wxFont* font = static_cast(ms_stockObject[item]); @@ -57,6 +61,7 @@ const wxFont* wxStockGDIMac::GetFont(Item item) { switch (item) { +#if wxOSX_USE_COCOA_OR_CARBON case FONT_NORMAL: font = new wxFont; font->MacCreateFromThemeFont(kThemeSystemFont); @@ -65,6 +70,14 @@ const wxFont* wxStockGDIMac::GetFont(Item item) font = new wxFont; font->MacCreateFromThemeFont(kThemeSmallSystemFont); break; +#else + case FONT_NORMAL: + font = CreateNormalFont() ; + break; + case FONT_SMALL: + font = CreateSmallFont(); + break; +#endif default: font = const_cast(super::GetFont(item)); break; diff --git a/src/osx/carbon/graphics.cpp b/src/osx/carbon/graphics.cpp index 37596e8268..1b0eca575a 100644 --- a/src/osx/carbon/graphics.cpp +++ b/src/osx/carbon/graphics.cpp @@ -35,8 +35,16 @@ #endif #ifdef __WXMAC__ - #include "wx/osx/uma.h" + #include "wx/osx/private.h" #include "wx/osx/dcprint.h" + #include "wx/osx/dcclient.h" + #include "wx/osx/dcmemory.h" +#if wxOSX_USE_CARBON +#include "wx/osx/uma.h" +#else +#include "wx/osx/private.h" +#endif + #else #include "CoreServices/CoreServices.h" #include "ApplicationServices/ApplicationServices.h" @@ -92,12 +100,12 @@ OSStatus wxMacDrawCGImage( const CGRect * inBounds, CGImageRef inImage) { -#if defined( __LP64__ ) || defined(__WXCOCOA__) +#if wxOSX_USE_CARBON + return HIViewDrawCGImage( inContext, inBounds, inImage ); +#else // todo flip CGContextDrawImage(inContext, *inBounds, inImage ); return noErr; -#else - return HIViewDrawCGImage( inContext, inBounds, inImage ); #endif } @@ -122,7 +130,7 @@ CGColorRef wxMacCreateCGColor( const wxColour& col ) return retval; } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && defined(wxMAC_USE_CORE_TEXT) +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && wxMAC_USE_CORE_TEXT CTFontRef wxMacCreateCTFont( const wxFont& font ) { @@ -758,6 +766,14 @@ CGFunctionRef wxMacCoreGraphicsBrushData::CreateGradientFunction( const wxColour // Font // +#if wxOSX_USE_IPHONE + +extern UIFont* CreateUIFont( const wxFont& font ); +extern void DrawTextInContext( CGContextRef context, CGPoint where, UIFont *font, NSString* text ); +extern CGSize MeasureTextInContext( UIFont *font, NSString* text ); + +#endif + class wxMacCoreGraphicsFontData : public wxGraphicsObjectRefData { public: @@ -773,6 +789,9 @@ public: wxColour GetColour() const { return m_colour ; } bool GetUnderlined() const { return m_underlined ; } +#if wxOSX_USE_IPHONE + UIFont* GetUIFont() const { return m_uiFont; } +#endif private : wxColour m_colour; bool m_underlined; @@ -782,6 +801,9 @@ private : #if wxMAC_USE_CORE_TEXT wxCFRef< CTFontRef > m_ctFont; #endif +#if wxOSX_USE_IPHONE + UIFont* m_uiFont; +#endif }; wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col) : wxGraphicsObjectRefData( renderer ) @@ -792,6 +814,10 @@ wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* rendere #if wxMAC_USE_CORE_TEXT m_ctFont.reset( wxMacCreateCTFont( font ) ); #endif +#if wxOSX_USE_IPHONE + m_uiFont = CreateUIFont(font); + wxMacCocoaRetain( m_uiFont ); +#endif #if wxMAC_USE_ATSU_TEXT OSStatus status = noErr; m_macATSUIStyle = NULL; @@ -827,8 +853,6 @@ wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* rendere wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ); #endif -#if wxMAC_USE_CG_TEXT -#endif } wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData() @@ -842,7 +866,8 @@ wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData() m_macATSUIStyle = NULL; } #endif -#if wxMAC_USE_CG_TEXT +#if wxOSX_USE_IPHONE + wxMacCocoaRelease( m_uiFont ); #endif } @@ -1244,7 +1269,9 @@ class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext public: wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width = 0, wxDouble height = 0 ); +#if wxOSX_USE_CARBON wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window ); +#endif wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ); @@ -1353,20 +1380,23 @@ public: void SetNativeContext( CGContextRef cg ); - DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsContext) - DECLARE_DYNAMIC_CLASS(wxMacCoreGraphicsContext) + DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsContext) private: void EnsureIsValid(); CGContextRef m_cgContext; +#if wxOSX_USE_CARBON WindowRef m_windowRef; +#endif bool m_releaseContext; CGAffineTransform m_windowTransform; wxDouble m_width; wxDouble m_height; +#if wxOSX_USE_CARBON wxCFRef m_clipRgn; +#endif }; //----------------------------------------------------------------------------- @@ -1411,7 +1441,9 @@ void wxMacCoreGraphicsContext::Init() { m_cgContext = NULL; m_releaseContext = false; +#if wxOSX_USE_CARBON m_windowRef = NULL; +#endif m_width = 0; m_height = 0; } @@ -1424,11 +1456,13 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer m_height = height; } +#if wxOSX_USE_CARBON wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window ): wxGraphicsContext(renderer) { Init(); m_windowRef = window; } +#endif wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ): wxGraphicsContext(renderer) { @@ -1438,7 +1472,7 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer originX = originY = 0; Rect bounds = { 0,0,0,0 }; -#if defined( __LP64__ ) || defined(__WXCOCOA__) +#if defined(__WXCOCOA__) || !wxOSX_USE_CARBON #else m_windowRef = (WindowRef) window->MacGetTopLevelWindowRef(); window->MacWindowToRootWindow( &originX , &originY ); @@ -1499,12 +1533,10 @@ void wxMacCoreGraphicsContext::EnsureIsValid() { if ( !m_cgContext ) { - OSStatus status = -#if ! ( defined( __LP64__ ) || defined(__WXCOCOA__) ) - QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext ); +#if defined(__WXCOCOA__) || ! wxOSX_USE_CARBON + wxFAIL_MSG("Cannot create wxDCs lazily"); #else - paramErr; -#endif + OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext ); if ( status != noErr ) { wxFAIL_MSG("Cannot nest wxDCs on the same window"); @@ -1532,6 +1564,7 @@ void wxMacCoreGraphicsContext::EnsureIsValid() } } CGContextSaveGState( m_cgContext ); +#endif } } @@ -1548,8 +1581,12 @@ bool wxMacCoreGraphicsContext::SetLogicalFunction( int function ) bool shouldAntiAlias = true; CGBlendMode mode = kCGBlendModeNormal; -#if defined(__WXMAC__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 ) +#if defined(__WXMAC__) && ( wxOSX_USE_IPHONE || ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 ) ) +#if wxOSX_USE_IPHONE + if ( 1 ) +#else if ( UMAGetSystemVersion() >= 0x1050 ) +#endif { retval = true; switch ( function ) @@ -1597,7 +1634,7 @@ bool wxMacCoreGraphicsContext::SetLogicalFunction( int function ) void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion ) { -#ifdef __WXMAC__ +#if wxOSX_USE_CARBON if( m_cgContext ) { wxCFRef shape = wxCFRefFromGet(region.GetWXHRGN()); @@ -1623,6 +1660,9 @@ void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion ) HIShapeOffset( mutableShape, transformedOrigin.x, transformedOrigin.y ); m_clipRgn.reset(mutableShape); } +#else + // allow usage as measuring context + // wxASSERT_MSG( m_cgContext != NULL, "Needs a valid context for clipping" ); #endif } @@ -1636,10 +1676,15 @@ void wxMacCoreGraphicsContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDoubl } else { +#if wxOSX_USE_CARBON // the clipping itself must be stored as device coordinates, otherwise // we cannot apply it back correctly r.origin= CGPointApplyAffineTransform( r.origin, m_windowTransform ); m_clipRgn.reset(HIShapeCreateWithRect(&r)); +#else + // allow usage as measuring context + // wxFAIL_MSG( "Needs a valid context for clipping" ); +#endif } } @@ -1660,7 +1705,12 @@ void wxMacCoreGraphicsContext::ResetClip() } else { +#if wxOSX_USE_CARBON m_clipRgn.reset(); +#else + // allow usage as measuring context + // wxFAIL_MSG( "Needs a valid context for clipping" ); +#endif } } @@ -1765,7 +1815,7 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg ) CGContextRestoreGState( m_cgContext ); if ( m_releaseContext ) { -#if ! ( defined( __LP64__ ) || defined(__WXCOCOA__) ) +#if wxOSX_USE_CARBON QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext); #endif } @@ -1868,7 +1918,7 @@ void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDoubl CGContextSaveGState( m_cgContext ); CGContextTranslateCTM( m_cgContext,(CGFloat) x ,(CGFloat) (y + h) ); CGContextScaleCTM( m_cgContext, 1, -1 ); -#ifdef __WXMAC__ +#if wxOSX_USE_CARBON PlotIconRefInContext( m_cgContext , &r , kAlignNone , kTransformNone , NULL , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ); #endif @@ -1930,7 +1980,19 @@ void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDoub } #endif #if wxMAC_USE_CG_TEXT - // TODO core graphics text implementation here + wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData(); + + CGContextSaveGState(m_cgContext); + + CGColorRef col = wxMacCreateCGColor( fref->GetColour() ); + CGContextSetTextDrawingMode (m_cgContext, kCGTextFill); + CGContextSetFillColorWithColor( m_cgContext, col ); + + wxCFStringRef text(str, wxLocale::GetSystemEncoding() ); + DrawTextInContext( m_cgContext, CGPointMake( x, y ), fref->GetUIFont() , text.AsNSString() ); + + CGContextRestoreGState(m_cgContext); + CFRelease( col ); #endif } @@ -2122,7 +2184,21 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid } #endif #if wxMAC_USE_CG_TEXT - // TODO core graphics text implementation here + wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData(); + + wxCFStringRef text(str, wxLocale::GetSystemEncoding() ); + CGSize sz = MeasureTextInContext( fref->GetUIFont() , text.AsNSString() ); + + if ( height ) + *height = sz.height; + /* + if ( descent ) + *descent = FixedToInt(textDescent); + if ( externalLeading ) + *externalLeading = 0; + */ + if ( width ) + *width = sz.width; #endif } @@ -2338,7 +2414,7 @@ wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer() return &gs_MacCoreGraphicsRenderer; } -#ifdef __WXCOCOA__ +#if defined( __WXCOCOA__ ) || wxOSX_USE_COCOA extern CGContextRef wxMacGetContextFromCurrentNSContext() ; #endif @@ -2379,6 +2455,7 @@ wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC& wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxPrinterDC& dc ) { +#if wxUSE_PRINTING_ARCHITECTURE #ifdef __WXMAC__ const wxDCImpl* impl = dc.GetImpl(); wxPrinterDCImpl *print_impl = wxDynamicCast( impl, wxPrinterDCImpl ); @@ -2389,6 +2466,7 @@ wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxPrinterDC& return new wxMacCoreGraphicsContext( this, (CGContextRef)(print_impl->GetGraphicsContext()->GetNativeContext()), (wxDouble) w, (wxDouble) h ); } +#endif #endif return NULL; } @@ -2398,10 +2476,13 @@ wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeContext( v return new wxMacCoreGraphicsContext(this,(CGContextRef)context); } - wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeWindow( void * window ) { +#if wxOSX_USE_CARBON return new wxMacCoreGraphicsContext(this,(WindowRef)window); +#else + return NULL; +#endif } wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( wxWindow* window ) diff --git a/src/osx/carbon/listbox.cpp b/src/osx/carbon/listbox.cpp index edd9f96e0f..5e63f1cf8a 100644 --- a/src/osx/carbon/listbox.cpp +++ b/src/osx/carbon/listbox.cpp @@ -426,7 +426,7 @@ void wxMacListBoxItem::Notification(wxMacDataItemBrowserControl *owner , return; } - wxListBox *list = wxDynamicCast( owner->GetPeer() , wxListBox ); + wxListBox *list = wxDynamicCast( owner->GetWXPeer() , wxListBox ); wxCHECK_RET( list != NULL , wxT("Listbox expected")); if (message == kDataBrowserItemDoubleClicked) @@ -535,7 +535,7 @@ void wxMacDataBrowserListControl::ItemNotification( DataBrowserItemNotification message, DataBrowserItemDataRef itemData) { - wxListBox *list = wxDynamicCast( GetPeer() , wxListBox ); + wxListBox *list = wxDynamicCast( GetWXPeer() , wxListBox ); wxCHECK_RET( list != NULL , wxT("Listbox expected")); if (list->HasMultipleSelection() && (message == kDataBrowserSelectionSetChanged) && (!list->MacGetBlockEvents())) @@ -549,7 +549,7 @@ void wxMacDataBrowserListControl::ItemNotification( wxCommandEvent event( wxEVT_COMMAND_LISTBOX_SELECTED, list->GetId() ); int sel = list->GetSelection(); - if ((sel < 0) || (sel > list->GetCount())) // OS X can select an item below the last item (why?) + if ((sel < 0) || (sel > (int) list->GetCount())) // OS X can select an item below the last item (why?) return; event.SetEventObject( list ); if ( list->HasClientObjectData() ) @@ -566,12 +566,12 @@ void wxMacDataBrowserListControl::ItemNotification( // call super for item level(wxMacDataItem->Notification) callback processing wxMacDataItemBrowserControl::ItemNotification( itemID, message, itemData); } - +/* wxWindow * wxMacDataBrowserListControl::GetPeer() const { - return wxDynamicCast( wxMacControl::GetPeer() , wxWindow ); + return wxDynamicCast( wxMacControl::GetWX() , wxWindow ); } - +*/ wxMacDataItem* wxMacDataBrowserListControl::CreateItem() { return new wxMacListBoxItem(); diff --git a/src/osx/carbon/listctrl_mac.cpp b/src/osx/carbon/listctrl_mac.cpp index 64641fae9c..8ad2a0cd52 100644 --- a/src/osx/carbon/listctrl_mac.cpp +++ b/src/osx/carbon/listctrl_mac.cpp @@ -2448,7 +2448,7 @@ void wxMacListCtrlItem::Notification(wxMacDataItemBrowserControl *owner , return ; } - wxListCtrl *list = wxDynamicCast( owner->GetPeer() , wxListCtrl ); + wxListCtrl *list = wxDynamicCast( owner->GetWXPeer() , wxListCtrl ); if ( list && lb ) { bool trigger = false; @@ -2669,7 +2669,7 @@ void wxMacDataBrowserListCtrlControl::DrawItem( int imgIndex = -1; short listColumn = property - kMinColumnId; - wxListCtrl* list = wxDynamicCast( GetPeer() , wxListCtrl ); + wxListCtrl* list = wxDynamicCast( GetWXPeer() , wxListCtrl ); wxMacListCtrlItem* lcItem; wxColour color = *wxBLACK; wxColour bgColor = wxNullColour; @@ -2905,7 +2905,7 @@ OSStatus wxMacDataBrowserListCtrlControl::GetSetItemData(DataBrowserItemID itemI short listColumn = property - kMinColumnId; OSStatus err = errDataBrowserPropertyNotSupported; - wxListCtrl* list = wxDynamicCast( GetPeer() , wxListCtrl ); + wxListCtrl* list = wxDynamicCast( GetWXPeer() , wxListCtrl ); wxMacListCtrlItem* lcItem = NULL; if (listColumn >= 0) @@ -3024,7 +3024,7 @@ void wxMacDataBrowserListCtrlControl::ItemNotification(DataBrowserItemID itemID, return ; } - wxListCtrl *list = wxDynamicCast( GetPeer() , wxListCtrl ); + wxListCtrl *list = wxDynamicCast( GetWXPeer() , wxListCtrl ); if ( list ) { bool trigger = false; @@ -3102,7 +3102,7 @@ Boolean wxMacDataBrowserListCtrlControl::CompareItems(DataBrowserItemID itemOneI int colId = sortProperty - kMinColumnId; - wxListCtrl* list = wxDynamicCast( GetPeer() , wxListCtrl ); + wxListCtrl* list = wxDynamicCast( GetWXPeer() , wxListCtrl ); DataBrowserSortOrder sort; verify_noerr(GetSortOrder(&sort)); @@ -3175,7 +3175,7 @@ void wxMacDataBrowserListCtrlControl::MacSetColumnInfo( unsigned int row, unsign listItem->SetOrder(row); UpdateState(dataItem, item); - wxListCtrl* list = wxDynamicCast( GetPeer() , wxListCtrl ); + wxListCtrl* list = wxDynamicCast( GetWXPeer() , wxListCtrl ); // NB: When this call was made before a control was completely shown, it would // update the item prematurely (i.e. no text would be listed) and, on show, diff --git a/src/osx/carbon/mdi.cpp b/src/osx/carbon/mdi.cpp index 02b33e5cf6..6134f5267b 100644 --- a/src/osx/carbon/mdi.cpp +++ b/src/osx/carbon/mdi.cpp @@ -218,7 +218,7 @@ void wxMDIParentFrame::MacActivate(long timestamp, bool activating) { wxLogTrace(TRACE_MDI, wxT("child had been scheduled for deactivation, rehighlighting")); - UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true); + UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->GetWXWindow(), true); wxLogTrace(TRACE_MDI, wxT("finished highliting child")); @@ -382,14 +382,10 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, SetName(name); if ( id == wxID_ANY ) - m_windowId = (int)NewControlId(); - else - m_windowId = id; - - if (parent) - parent->AddChild(this); + id = (int)NewControlId(); - MacCreateRealWindow( pos , size , MacRemoveBordersFromStyle(style) , name ) ; + wxNonOwnedWindow::Create( parent, id, pos , size , MacRemoveBordersFromStyle(style) , name ) ; + SetTitle( title ); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE)); @@ -420,7 +416,7 @@ void wxMDIChildFrame::MacActivate(long timestamp, bool activating) { wxLogTrace(TRACE_MDI, wxT("parent had been scheduled for deactivation, rehighlighting")); - UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true); + UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->GetWXWindow(), true); wxLogTrace(TRACE_MDI, wxT("finished highliting parent")); diff --git a/src/osx/carbon/mediactrl.cpp b/src/osx/carbon/mediactrl.cpp index 475d02540a..96151b354b 100644 --- a/src/osx/carbon/mediactrl.cpp +++ b/src/osx/carbon/mediactrl.cpp @@ -57,7 +57,7 @@ #include #endif -#if !defined(__LP64__) +#if wxOSX_USE_CARBON #define USE_QUICKTIME 1 #else #define USE_QUICKTIME 0 diff --git a/src/osx/carbon/nonownedwnd.cpp b/src/osx/carbon/nonownedwnd.cpp index 6956f30700..17319a4ea5 100644 --- a/src/osx/carbon/nonownedwnd.cpp +++ b/src/osx/carbon/nonownedwnd.cpp @@ -28,15 +28,563 @@ #include "wx/sysopt.h" #endif +// +// TODO BEGIN move to nonowned_osx.cpp +// + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- -// unified title and toolbar constant - not in Tiger headers, so we duplicate it here -#define kWindowUnifiedTitleAndToolbarAttribute (1 << 7) +// trace mask for activation tracing messages +#define TRACE_ACTIVATE "activation" + +wxWindow* g_MacLastWindow = NULL ; + +// --------------------------------------------------------------------------- +// wxWindowMac utility functions +// --------------------------------------------------------------------------- + +// Find an item given the Macintosh Window Reference + +WX_DECLARE_HASH_MAP(WXWindow, wxNonOwnedWindow*, wxPointerHash, wxPointerEqual, MacWindowMap); + +static MacWindowMap wxWinMacWindowList; + +wxNonOwnedWindow *wxFindWindowFromWXWindow(WXWindow inWindowRef) +{ + MacWindowMap::iterator node = wxWinMacWindowList.find(inWindowRef); + + return (node == wxWinMacWindowList.end()) ? NULL : node->second; +} + +void wxAssociateWindowWithWXWindow(WXWindow inWindowRef, wxNonOwnedWindow *win) ; +void wxAssociateWindowWithWXWindow(WXWindow inWindowRef, wxNonOwnedWindow *win) +{ + // adding NULL WindowRef is (first) surely a result of an error and + // nothing else :-) + wxCHECK_RET( inWindowRef != (WXWindow) NULL, wxT("attempt to add a NULL WindowRef to window list") ); + + wxWinMacWindowList[inWindowRef] = win; +} + +void wxRemoveWXWindowAssociation(wxNonOwnedWindow *win) ; +void wxRemoveWXWindowAssociation(wxNonOwnedWindow *win) +{ + MacWindowMap::iterator it; + for ( it = wxWinMacWindowList.begin(); it != wxWinMacWindowList.end(); ++it ) + { + if ( it->second == win ) + { + wxWinMacWindowList.erase(it); + break; + } + } +} + +wxNonOwnedWindow* wxNonOwnedWindow::GetFromWXWindow( WXWindow win ) +{ + return wxFindWindowFromWXWindow( win ); +} + +// ---------------------------------------------------------------------------- +// wxNonOwnedWindow creation +// ---------------------------------------------------------------------------- + +IMPLEMENT_ABSTRACT_CLASS( wxNonOwnedWindowImpl , wxObject ) + +wxNonOwnedWindow *wxNonOwnedWindow::s_macDeactivateWindow = NULL; + +void wxNonOwnedWindow::Init() +{ + m_nowpeer = NULL; +} + +bool wxNonOwnedWindow::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + // init our fields + Init(); + + m_windowStyle = style; + + SetName( name ); + + m_windowId = id == -1 ? NewControlId() : id; + m_windowStyle = style; + m_isShown = false; + + // create frame. + int x = (int)pos.x; + int y = (int)pos.y; + + wxRect display = wxGetClientDisplayRect() ; + + if ( x == wxDefaultPosition.x ) + x = display.x ; + + if ( y == wxDefaultPosition.y ) + y = display.y ; + + int w = WidthDefault(size.x); + int h = HeightDefault(size.y); + + // temporary define, TODO +#if wxOSX_USE_CARBON + m_nowpeer = new wxNonOwnedWindowCarbonImpl( this ); +#elif wxOSX_USE_COCOA + m_nowpeer = new wxNonOwnedWindowCocoaImpl( this ); +#elif wxOSX_USE_IPHONE + m_nowpeer = new wxNonOwnedWindowIPhoneImpl( this ); +#endif + + m_nowpeer->Create( parent, wxPoint(x,y) , wxSize(w,h) , style , GetExtraStyle(), name ) ; + wxAssociateWindowWithWXWindow( m_nowpeer->GetWXWindow() , this ) ; +#if wxOSX_USE_CARBON + // temporary cast, TODO + m_peer = (wxMacControl*) wxWidgetImpl::CreateContentView(this); +#else + m_peer = wxWidgetImpl::CreateContentView(this); +#endif + + DoSetWindowVariant( m_windowVariant ) ; + + wxWindowCreateEvent event(this); + HandleWindowEvent(event); + + SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE )); + + if ( parent ) + parent->AddChild(this); + + return true; +} + +wxNonOwnedWindow::~wxNonOwnedWindow() +{ + wxRemoveWXWindowAssociation( this ) ; + if ( m_nowpeer ) + m_nowpeer->Destroy(); + + // avoid dangling refs + if ( s_macDeactivateWindow == this ) + s_macDeactivateWindow = NULL; +} + +// ---------------------------------------------------------------------------- +// wxNonOwnedWindow misc +// ---------------------------------------------------------------------------- + +bool wxNonOwnedWindow::ShowWithEffect(wxShowEffect effect, + unsigned timeout ) +{ + if ( !wxWindow::Show(true) ) + return false; + + // because apps expect a size event to occur at this moment + wxSizeEvent event(GetSize() , m_windowId); + event.SetEventObject(this); + HandleWindowEvent(event); + + + return m_nowpeer->ShowWithEffect(true, effect, timeout); +} + +bool wxNonOwnedWindow::HideWithEffect(wxShowEffect effect, + unsigned timeout ) +{ + if ( !wxWindow::Show(false) ) + return false; + + return m_nowpeer->ShowWithEffect(false, effect, timeout); +} + +wxPoint wxNonOwnedWindow::GetClientAreaOrigin() const +{ + int left, top, width, height; + m_nowpeer->GetContentArea(left, top, width, height); + return wxPoint(left, top); +} + +bool wxNonOwnedWindow::SetBackgroundColour(const wxColour& c ) +{ + if ( !wxWindow::SetBackgroundColour(c) && m_hasBgCol ) + return false ; + + if ( GetBackgroundStyle() != wxBG_STYLE_CUSTOM ) + { + return m_nowpeer->SetBackgroundColour(c); + } + return true; +} + +// Raise the window to the top of the Z order +void wxNonOwnedWindow::Raise() +{ + m_nowpeer->Raise(); +} + +// Lower the window to the bottom of the Z order +void wxNonOwnedWindow::Lower() +{ + m_nowpeer->Lower(); +} + +void wxNonOwnedWindow::MacDelayedDeactivation(long timestamp) +{ + if (s_macDeactivateWindow) + { + wxLogTrace(TRACE_ACTIVATE, + wxT("Doing delayed deactivation of %p"), + s_macDeactivateWindow); + + s_macDeactivateWindow->MacActivate(timestamp, false); + } +} + +void wxNonOwnedWindow::MacActivate( long timestamp , bool WXUNUSED(inIsActivating) ) +{ + wxLogTrace(TRACE_ACTIVATE, wxT("TopLevel=%p::MacActivate"), this); + + if (s_macDeactivateWindow == this) + s_macDeactivateWindow = NULL; + + MacDelayedDeactivation(timestamp); +} + +bool wxNonOwnedWindow::Show(bool show) +{ + if ( !wxWindow::Show(show) ) + return false; + + if ( m_nowpeer ) + m_nowpeer->Show(show); + + if ( show ) + { + // because apps expect a size event to occur at this moment + wxSizeEvent event(GetSize() , m_windowId); + event.SetEventObject(this); + HandleWindowEvent(event); + } + + return true ; +} + +bool wxNonOwnedWindow::SetTransparent(wxByte alpha) +{ + return m_nowpeer->SetTransparent(alpha); +} + + +bool wxNonOwnedWindow::CanSetTransparent() +{ + return m_nowpeer->CanSetTransparent(); +} + + +void wxNonOwnedWindow::SetExtraStyle(long exStyle) +{ + if ( GetExtraStyle() == exStyle ) + return ; + + wxWindow::SetExtraStyle( exStyle ) ; + + if ( m_nowpeer ) + m_nowpeer->SetExtraStyle(exStyle); +} + +bool wxNonOwnedWindow::SetBackgroundStyle(wxBackgroundStyle style) +{ + if ( !wxWindow::SetBackgroundStyle(style) ) + return false ; + + return m_nowpeer->SetBackgroundStyle(style); +} + +void wxNonOwnedWindow::DoMoveWindow(int x, int y, int width, int height) +{ + m_cachedClippedRectValid = false ; + + m_nowpeer->MoveWindow(x, y, width, height); + wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified +} + +void wxNonOwnedWindow::DoGetPosition( int *x, int *y ) const +{ + int x1,y1 ; + m_nowpeer->GetPosition(x1, y1); + + if (x) + *x = x1 ; + if (y) + *y = y1 ; +} + +void wxNonOwnedWindow::DoGetSize( int *width, int *height ) const +{ + int w,h; + + m_nowpeer->GetSize(w, h); + + if (width) + *width = w ; + if (height) + *height = h ; +} + +void wxNonOwnedWindow::DoGetClientSize( int *width, int *height ) const +{ + int left, top, w, h; + m_nowpeer->GetContentArea(left, top, w, h); + + if (width) + *width = w ; + if (height) + *height = h ; +} + + +void wxNonOwnedWindow::Update() +{ + m_nowpeer->Update(); +} + +WXWindow wxNonOwnedWindow::GetWXWindow() const +{ + return m_nowpeer ? m_nowpeer->GetWXWindow() : NULL; +} + +// --------------------------------------------------------------------------- +// Shape implementation +// --------------------------------------------------------------------------- + + +bool wxNonOwnedWindow::SetShape(const wxRegion& region) +{ + wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false, + _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); + + // The empty region signifies that the shape + // should be removed from the window. + if ( region.IsEmpty() ) + { + wxSize sz = GetClientSize(); + wxRegion rgn(0, 0, sz.x, sz.y); + if ( rgn.IsEmpty() ) + return false ; + else + return SetShape(rgn); + } + + return m_nowpeer->SetShape(region); +} + +// +// TODO END move to nonowned_osx.cpp +// + +#if wxOSX_USE_CARBON + +IMPLEMENT_DYNAMIC_CLASS( wxNonOwnedWindowCarbonImpl , wxNonOwnedWindowImpl ) + + +WXWindow wxNonOwnedWindowCarbonImpl::GetWXWindow() const +{ + return (WXWindow) m_macWindow; +} +void wxNonOwnedWindowCarbonImpl::Raise() +{ + ::SelectWindow( m_macWindow ) ; +} + +void wxNonOwnedWindowCarbonImpl::Lower() +{ + ::SendBehind( m_macWindow , NULL ) ; +} + +bool wxNonOwnedWindowCarbonImpl::Show(bool show) +{ + bool plainTransition = true; + +#if wxUSE_SYSTEM_OPTIONS + if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) + plainTransition = ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1 ) ; +#endif + + if (show) + { +#if wxOSX_USE_CARBON + if ( plainTransition ) + ::ShowWindow( (WindowRef)m_macWindow ); + else + ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL ); + + ::SelectWindow( (WindowRef)m_macWindow ) ; +#endif + } + else + { +#if wxOSX_USE_CARBON + if ( plainTransition ) + ::HideWindow( (WindowRef)m_macWindow ); + else + ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowHideTransitionAction, NULL ); +#endif + } + return true; +} + +void wxNonOwnedWindowCarbonImpl::Update() +{ + HIWindowFlush(m_macWindow) ; +} + +bool wxNonOwnedWindowCarbonImpl::SetTransparent(wxByte alpha) +{ + OSStatus result = SetWindowAlpha((WindowRef)m_macWindow, (CGFloat)((alpha)/255.0)); + return result == noErr; +} + +bool wxNonOwnedWindowCarbonImpl::SetBackgroundColour(const wxColour& col ) +{ + if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground)) ) + { + SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDocumentWindowBackground, false ) ; + SetBackgroundStyle(wxBG_STYLE_SYSTEM); + } + else if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive)) ) + { + SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDialogBackgroundActive, false ) ; + SetBackgroundStyle(wxBG_STYLE_SYSTEM); + } + return true; +} + +void wxNonOwnedWindowCarbonImpl::SetExtraStyle( long exStyle ) +{ + if ( m_macWindow != NULL ) + { + bool metal = exStyle & wxFRAME_EX_METAL ; + + if ( MacGetMetalAppearance() != metal ) + { + if ( MacGetUnifiedAppearance() ) + MacSetUnifiedAppearance( !metal ) ; + + MacSetMetalAppearance( metal ) ; + } + } +} + +bool wxNonOwnedWindowCarbonImpl::SetBackgroundStyle(wxBackgroundStyle style) +{ + if ( style == wxBG_STYLE_TRANSPARENT ) + { + OSStatus err = HIWindowChangeFeatures( m_macWindow, 0, kWindowIsOpaque ); + verify_noerr( err ); + err = ReshapeCustomWindow( m_macWindow ); + verify_noerr( err ); + } + + return true ; +} + +bool wxNonOwnedWindowCarbonImpl::CanSetTransparent() +{ + return true; +} + +void wxNonOwnedWindowCarbonImpl::GetContentArea( int &left , int &top , int &width , int &height ) const +{ + Rect content, structure ; + + GetWindowBounds( m_macWindow, kWindowStructureRgn , &structure ) ; + GetWindowBounds( m_macWindow, kWindowContentRgn , &content ) ; + + left = content.left - structure.left ; + top = content.top - structure.top ; + width = content.right - content.left ; + height = content.bottom - content.top ; +} + +void wxNonOwnedWindowCarbonImpl::MoveWindow(int x, int y, int width, int height) +{ + Rect bounds = { y , x , y + height , x + width } ; + verify_noerr(SetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; +} + +void wxNonOwnedWindowCarbonImpl::GetPosition( int &x, int &y ) const +{ + Rect bounds ; + + verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; + + x = bounds.left ; + y = bounds.top ; +} + +void wxNonOwnedWindowCarbonImpl::GetSize( int &width, int &height ) const +{ + Rect bounds ; + + verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; + + width = bounds.right - bounds.left ; + height = bounds.bottom - bounds.top ; +} + +bool wxNonOwnedWindowCarbonImpl::MacGetUnifiedAppearance() const +{ + return MacGetWindowAttributes() & kWindowUnifiedTitleAndToolbarAttribute ; +} + +void wxNonOwnedWindowCarbonImpl::MacChangeWindowAttributes( wxUint32 attributesToSet , wxUint32 attributesToClear ) +{ + ChangeWindowAttributes( m_macWindow, attributesToSet, attributesToClear ) ; +} + +wxUint32 wxNonOwnedWindowCarbonImpl::MacGetWindowAttributes() const +{ + UInt32 attr = 0 ; + GetWindowAttributes( m_macWindow, &attr ) ; + return attr ; +} + +void wxNonOwnedWindowCarbonImpl::MacSetMetalAppearance( bool set ) +{ + if ( MacGetUnifiedAppearance() ) + MacSetUnifiedAppearance( false ) ; + + MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes , + set ? kWindowNoAttributes : kWindowMetalAttribute ) ; +} + +bool wxNonOwnedWindowCarbonImpl::MacGetMetalAppearance() const +{ + return MacGetWindowAttributes() & kWindowMetalAttribute ; +} + +void wxNonOwnedWindowCarbonImpl::MacSetUnifiedAppearance( bool set ) +{ + if ( MacGetMetalAppearance() ) + MacSetMetalAppearance( false ) ; + + MacChangeWindowAttributes( set ? kWindowUnifiedTitleAndToolbarAttribute : kWindowNoAttributes , + set ? kWindowNoAttributes : kWindowUnifiedTitleAndToolbarAttribute) ; + + // For some reason, Tiger uses white as the background color for this appearance, + // while most apps using it use the typical striped background. Restore that behavior + // for wx. + // TODO: Determine if we need this on Leopard as well. (should be harmless either way, + // though) + m_wxPeer->SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ) ; +} -// trace mask for activation tracing messages -#define TRACE_ACTIVATE "activation" // ---------------------------------------------------------------------------- // globals @@ -48,6 +596,9 @@ static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 // wxNonOwnedWindow implementation // ============================================================================ +// unified title and toolbar constant - not in Tiger headers, so we duplicate it here +#define kWindowUnifiedTitleAndToolbarAttribute (1 << 7) + // --------------------------------------------------------------------------- // Carbon Events // --------------------------------------------------------------------------- @@ -89,7 +640,7 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event // FindFocus does not return the actual focus window, but the enclosing window wxWindow* focus = wxWindow::DoFindFocus(); if ( focus == NULL ) - focus = (wxNonOwnedWindow*) data ; + focus = data ? ((wxNonOwnedWindowImpl*) data)->GetWXPeer() : NULL ; unsigned char charCode ; wxChar uniChar[2] ; @@ -218,8 +769,6 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event // // This handler can also be called from app level where data (ie target window) may be null or a non wx window -wxWindow* g_MacLastWindow = NULL ; - EventMouseButton g_lastButton = 0 ; bool g_lastButtonWasFakeRight = false ; @@ -366,7 +915,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), EventRef event, void *data) { - wxNonOwnedWindow* toplevelWindow = (wxNonOwnedWindow*) data ; + wxNonOwnedWindow* toplevelWindow = data ? ((wxNonOwnedWindowImpl*) data)->GetWXPeer() : NULL ; OSStatus result = eventNotHandledErr ; @@ -391,7 +940,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), if ( window ) { - wxMacGlobalToLocal( window, &windowMouseLocation ) ; + QDGlobalToLocalPoint( GetWindowPort( window ), &windowMouseLocation ); if ( wxApp::s_captureWindow #if !NEW_CAPTURE_HANDLING @@ -408,11 +957,11 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), // if there is no control below the mouse position, send the event to the toplevel window itself if ( control == 0 ) { - currentMouseWindow = (wxWindow*) data ; + currentMouseWindow = (wxWindow*) toplevelWindow ; } else { - currentMouseWindow = (wxWindow*) wxFindControlFromMacControl( control ) ; + currentMouseWindow = (wxWindow*) wxFindWindowFromWXWidget( (WXWidget) control ) ; #ifndef __WXUNIVERSAL__ if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved ) { @@ -421,7 +970,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), // instead of its children (wxToolBarTools) ControlRef parent ; GetSuperControl(control, &parent ); - wxWindow *wxParent = (wxWindow*) wxFindControlFromMacControl( parent ) ; + wxWindow *wxParent = (wxWindow*) wxFindWindowFromWXWidget((WXWidget) parent ) ; if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) ) currentMouseWindow = wxParent ; #endif @@ -580,7 +1129,7 @@ wxNonOwnedWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), wxMacCarbonEvent cEvent( event ) ; // WindowRef windowRef = cEvent.GetParameter(kEventParamDirectObject) ; - wxNonOwnedWindow* toplevelWindow = (wxNonOwnedWindow*) data ; + wxNonOwnedWindow* toplevelWindow = data ? ((wxNonOwnedWindowImpl*) data)->GetWXPeer() : NULL; switch ( GetEventKind( event ) ) { @@ -659,7 +1208,8 @@ wxNonOwnedWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), { // all (Mac) rects are in content area coordinates, all wxRects in structure coordinates int left , top , right , bottom ; - toplevelWindow->MacGetContentAreaInset( left , top , right , bottom ) ; + + toplevelWindow->GetNonOwnedPeer()->GetContentArea(left, top, right, bottom); wxRect r( newRect.left - left, @@ -764,106 +1314,167 @@ pascal OSStatus wxNonOwnedEventHandler( EventHandlerCallRef handler , EventRef e DEFINE_ONE_SHOT_HANDLER_GETTER( wxNonOwnedEventHandler ) // --------------------------------------------------------------------------- -// wxWindowMac utility functions +// Support functions for shaped windows, based on Apple's CustomWindow sample at +// http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm // --------------------------------------------------------------------------- -// Find an item given the Macintosh Window Reference +static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect) +{ + GetWindowPortBounds(window, inRect); + Point pt = { inRect->top ,inRect->left }; + QDLocalToGlobalPoint( GetWindowPort( window ), &pt ); + inRect->bottom += pt.v - inRect->top; + inRect->right += pt.h - inRect->left; + inRect->top = pt.v; + inRect->left = pt.h; +} -WX_DECLARE_HASH_MAP(WindowRef, wxNonOwnedWindow*, wxPointerHash, wxPointerEqual, MacWindowMap); +static SInt32 wxShapedMacWindowGetFeatures(WindowRef WXUNUSED(window), SInt32 param) +{ + /*------------------------------------------------------ + Define which options your custom window supports. + --------------------------------------------------------*/ + //just enable everything for our demo + *(OptionBits*)param = + //kWindowCanGrow | + //kWindowCanZoom | + kWindowCanCollapse | + //kWindowCanGetWindowRegion | + //kWindowHasTitleBar | + //kWindowSupportsDragHilite | + kWindowCanDrawInCurrentPort | + //kWindowCanMeasureTitle | + kWindowWantsDisposeAtProcessDeath | + kWindowSupportsGetGrowImageRegion | + kWindowDefSupportsColorGrafPort; -static MacWindowMap wxWinMacWindowList; + return 1; +} -wxNonOwnedWindow *wxFindWinFromMacWindow(WindowRef inWindowRef) +// The content region is left as a rectangle matching the window size, this is +// so the origin in the paint event, and etc. still matches what the +// programmer expects. +static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn) { - MacWindowMap::iterator node = wxWinMacWindowList.find(inWindowRef); - - return (node == wxWinMacWindowList.end()) ? NULL : node->second; + SetEmptyRgn(rgn); + wxNonOwnedWindow* win = wxNonOwnedWindow::GetFromWXWindow((WXWindow)window); + if (win) + { + Rect r ; + wxShapedMacWindowGetPos( window, &r ) ; + RectRgn( rgn , &r ) ; + } } -void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxNonOwnedWindow *win) ; -void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxNonOwnedWindow *win) +// The structure region is set to the shape given to the SetShape method. +static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn) { - // adding NULL WindowRef is (first) surely a result of an error and - // nothing else :-) - wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") ); + RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window); - wxWinMacWindowList[inWindowRef] = win; + SetEmptyRgn(rgn); + if (cachedRegion) + { + Rect windowRect; + wxShapedMacWindowGetPos(window, &windowRect); // how big is the window + CopyRgn(cachedRegion, rgn); // make a copy of our cached region + OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window + //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size + } } -void wxRemoveMacWindowAssociation(wxNonOwnedWindow *win) ; -void wxRemoveMacWindowAssociation(wxNonOwnedWindow *win) +static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param) { - MacWindowMap::iterator it; - for ( it = wxWinMacWindowList.begin(); it != wxWinMacWindowList.end(); ++it ) + GetWindowRegionPtr rgnRec = (GetWindowRegionPtr)param; + + if (rgnRec == NULL) + return paramErr; + + switch (rgnRec->regionCode) { - if ( it->second == win ) - { - wxWinMacWindowList.erase(it); + case kWindowStructureRgn: + wxShapedMacWindowStructureRegion(window, rgnRec->winRgn); break; - } - } -} -// ---------------------------------------------------------------------------- -// wxNonOwnedWindow creation -// ---------------------------------------------------------------------------- + case kWindowContentRgn: + wxShapedMacWindowContentRegion(window, rgnRec->winRgn); + break; -wxNonOwnedWindow *wxNonOwnedWindow::s_macDeactivateWindow = NULL; + default: + SetEmptyRgn(rgnRec->winRgn); + break; + } -void wxNonOwnedWindow::Init() -{ - m_macWindow = NULL ; - m_macEventHandler = NULL ; + return noErr; } -wxMacDeferredWindowDeleter::wxMacDeferredWindowDeleter( WindowRef windowRef ) +// Determine the region of the window which was hit +// +static SInt32 wxShapedMacWindowHitTest(WindowRef window, SInt32 param) { - m_macWindow = windowRef ; -} + Point hitPoint; + static RgnHandle tempRgn = NULL; -wxMacDeferredWindowDeleter::~wxMacDeferredWindowDeleter() -{ - DisposeWindow( (WindowRef) m_macWindow ) ; + if (tempRgn == NULL) + tempRgn = NewRgn(); + + // get the point clicked + SetPt( &hitPoint, LoWord(param), HiWord(param) ); + + // Mac OS 8.5 or later + wxShapedMacWindowStructureRegion(window, tempRgn); + if (PtInRgn( hitPoint, tempRgn )) //in window content region? + return wInContent; + + // no significant area was hit + return wNoHit; } -bool wxNonOwnedWindow::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +static pascal long wxShapedMacWindowDef(short WXUNUSED(varCode), WindowRef window, SInt16 message, SInt32 param) { - // init our fields - Init(); + switch (message) + { + case kWindowMsgHitTest: + return wxShapedMacWindowHitTest(window, param); - m_windowStyle = style; + case kWindowMsgGetFeatures: + return wxShapedMacWindowGetFeatures(window, param); - SetName( name ); + // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow + case kWindowMsgGetRegion: + return wxShapedMacWindowGetRegion(window, param); - m_windowId = id == -1 ? NewControlId() : id; + default: + break; + } - DoMacCreateRealWindow( parent, pos , size , style , name ) ; + return 0; +} - SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE )); +// implementation - if (GetExtraStyle() & wxFRAME_EX_METAL) - MacSetMetalAppearance(true); +typedef struct +{ + wxPoint m_position ; + wxSize m_size ; + bool m_wasResizable ; +} FullScreenData ; - if ( parent ) - parent->AddChild(this); +wxNonOwnedWindowCarbonImpl::wxNonOwnedWindowCarbonImpl() +{ +} - return true; +wxNonOwnedWindowCarbonImpl::wxNonOwnedWindowCarbonImpl( wxNonOwnedWindow* nonownedwnd) : wxNonOwnedWindowImpl( nonownedwnd) +{ + m_macEventHandler = NULL; + m_macWindow = NULL; + m_macFullScreenData = NULL ; } -wxNonOwnedWindow::~wxNonOwnedWindow() +wxNonOwnedWindowCarbonImpl::~wxNonOwnedWindowCarbonImpl() { - if ( m_macWindow ) - { #if wxUSE_TOOLTIPS wxToolTip::NotifyWindowDelete(m_macWindow) ; #endif - wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ; - } if ( m_macEventHandler ) { @@ -871,48 +1482,21 @@ wxNonOwnedWindow::~wxNonOwnedWindow() m_macEventHandler = NULL ; } - wxRemoveMacWindowAssociation( this ) ; - - // avoid dangling refs - if ( s_macDeactivateWindow == this ) - s_macDeactivateWindow = NULL; -} - -// ---------------------------------------------------------------------------- -// wxNonOwnedWindow misc -// ---------------------------------------------------------------------------- - -wxPoint wxNonOwnedWindow::GetClientAreaOrigin() const -{ - return wxPoint(0, 0) ; -} + if ( m_macWindow ) + DisposeWindow( m_macWindow ); -bool wxNonOwnedWindow::SetBackgroundColour(const wxColour& c ) -{ - wxColour col = c; - if ( col == wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ) - col = wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground)); - else if ( col == wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) ) - col = wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive)); - - if ( !wxWindow::SetBackgroundColour(col) && m_hasBgCol ) - return false ; - - if ( GetBackgroundStyle() != wxBG_STYLE_CUSTOM ) - { - if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground)) ) - { - SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDocumentWindowBackground, false ) ; - SetBackgroundStyle(wxBG_STYLE_SYSTEM); - } - else if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive)) ) - { - SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDialogBackgroundActive, false ) ; - SetBackgroundStyle(wxBG_STYLE_SYSTEM); - } - } - return true; -} + FullScreenData *data = (FullScreenData *) m_macFullScreenData ; + delete data ; + m_macFullScreenData = NULL ; + + m_macWindow = NULL; + +} + +void wxNonOwnedWindowCarbonImpl::Destroy() +{ + wxPendingDelete.Append( new wxDeferredObjectDeleter( this ) ) ; +} void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window, EventHandlerRef* handler, void *ref) { @@ -920,7 +1504,28 @@ void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window, EventHa GetEventTypeCount(eventList), eventList, ref, handler ); } -void wxNonOwnedWindow::MacInstallTopLevelWindowEventHandler() +bool wxNonOwnedWindowCarbonImpl::SetShape(const wxRegion& region) +{ + // Make a copy of the region + RgnHandle shapeRegion = NewRgn(); + HIShapeGetAsQDRgn( region.GetWXHRGN(), shapeRegion ); + + // Dispose of any shape region we may already have + RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef) m_wxPeer->GetWXWindow() ); + if ( oldRgn ) + DisposeRgn(oldRgn); + + // Save the region so we can use it later + SetWRefCon((WindowRef) m_wxPeer->GetWXWindow(), (URefCon)shapeRegion); + + // inform the window manager that the window has changed shape + ReshapeCustomWindow((WindowRef) m_wxPeer->GetWXWindow()); + + return true; +} + + +void wxNonOwnedWindowCarbonImpl::MacInstallTopLevelWindowEventHandler() { if ( m_macEventHandler != NULL ) { @@ -929,42 +1534,22 @@ void wxNonOwnedWindow::MacInstallTopLevelWindowEventHandler() wxNonOwnedWindowInstallTopLevelWindowEventHandler(MAC_WXHWND(m_macWindow),(EventHandlerRef *)&m_macEventHandler,this); } -void wxNonOwnedWindow::MacCreateRealWindow( - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name ) -{ - DoMacCreateRealWindow( NULL, pos, size, style, name ); -} - -void wxNonOwnedWindow::DoMacCreateRealWindow( +void wxNonOwnedWindowCarbonImpl::Create( wxWindow* parent, const wxPoint& pos, const wxSize& size, - long style, + long style, long extraStyle, const wxString& name ) { + OSStatus err = noErr ; - SetName(name); - m_windowStyle = style; - m_isShown = false; + Rect theBoundsRect; - // create frame. int x = (int)pos.x; int y = (int)pos.y; - Rect theBoundsRect; - wxRect display = wxGetClientDisplayRect() ; - - if ( x == wxDefaultPosition.x ) - x = display.x ; - - if ( y == wxDefaultPosition.y ) - y = display.y ; - - int w = WidthDefault(size.x); - int h = HeightDefault(size.y); + int w = size.x; + int h = size.y; ::SetRect(&theBoundsRect, x, y , x + w, y + h); @@ -975,20 +1560,20 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( bool activationScopeSet = false; WindowActivationScope activationScope = kWindowActivationScopeNone; - if ( HasFlag( wxFRAME_TOOL_WINDOW) ) + if ( style & wxFRAME_TOOL_WINDOW ) { if ( - HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) || - HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) || - HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT) + ( style & wxMINIMIZE_BOX ) || ( style & wxMAXIMIZE_BOX ) || + ( style & wxSYSTEM_MENU ) || ( style & wxCAPTION ) || + ( style &wxTINY_CAPTION_HORIZ) || ( style &wxTINY_CAPTION_VERT) ) { - if ( HasFlag( wxSTAY_ON_TOP ) ) + if ( ( style & wxSTAY_ON_TOP ) ) wclass = kUtilityWindowClass; else wclass = kFloatingWindowClass ; - if ( HasFlag(wxTINY_CAPTION_VERT) ) + if ( ( style &wxTINY_CAPTION_VERT) ) attr |= kWindowSideTitlebarAttribute ; } else @@ -998,9 +1583,9 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( activationScope = kWindowActivationScopeNone; } } - else if ( HasFlag( wxPOPUP_WINDOW ) ) + else if ( ( style & wxPOPUP_WINDOW ) ) { - if ( HasFlag( wxBORDER_NONE ) ) + if ( ( style & wxBORDER_NONE ) ) { wclass = kHelpWindowClass ; // has no border attr |= kWindowNoShadowAttribute; @@ -1014,23 +1599,23 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( activationScopeSet = true; activationScope = kWindowActivationScopeNone; } - else if ( HasFlag( wxCAPTION ) ) + else if ( ( style & wxCAPTION ) ) { wclass = kDocumentWindowClass ; attr |= kWindowInWindowMenuAttribute ; } - else if ( HasFlag( wxFRAME_DRAWER ) ) + else if ( ( style & wxFRAME_DRAWER ) ) { wclass = kDrawerWindowClass; } else { - if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) || - HasFlag( wxCLOSE_BOX ) || HasFlag( wxSYSTEM_MENU ) ) + if ( ( style & wxMINIMIZE_BOX ) || ( style & wxMAXIMIZE_BOX ) || + ( style & wxCLOSE_BOX ) || ( style & wxSYSTEM_MENU ) ) { wclass = kDocumentWindowClass ; } - else if ( HasFlag( wxNO_BORDER ) ) + else if ( ( style & wxNO_BORDER ) ) { wclass = kSimpleWindowClass ; } @@ -1042,24 +1627,24 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( if ( wclass != kPlainWindowClass ) { - if ( HasFlag( wxMINIMIZE_BOX ) ) + if ( ( style & wxMINIMIZE_BOX ) ) attr |= kWindowCollapseBoxAttribute ; - if ( HasFlag( wxMAXIMIZE_BOX ) ) + if ( ( style & wxMAXIMIZE_BOX ) ) attr |= kWindowFullZoomAttribute ; - if ( HasFlag( wxRESIZE_BORDER ) ) + if ( ( style & wxRESIZE_BORDER ) ) attr |= kWindowResizableAttribute ; - if ( HasFlag( wxCLOSE_BOX) ) + if ( ( style & wxCLOSE_BOX) ) attr |= kWindowCloseBoxAttribute ; } attr |= kWindowLiveResizeAttribute; - if ( HasFlag(wxSTAY_ON_TOP) ) + if ( ( style &wxSTAY_ON_TOP) ) group = GetWindowGroupOfClass(kUtilityWindowClass) ; - if ( HasFlag( wxFRAME_FLOAT_ON_PARENT ) ) + if ( ( style & wxFRAME_FLOAT_ON_PARENT ) ) group = GetWindowGroupOfClass(kFloatingWindowClass) ; if ( group == NULL && parent != NULL ) @@ -1070,11 +1655,11 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( } attr |= kWindowCompositingAttribute; -#if 0 // wxMAC_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale) +#if 0 // wxOSX_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale) attr |= kWindowFrameworkScaledAttribute; #endif - if ( HasFlag(wxFRAME_SHAPED) ) + if ( ( style &wxFRAME_SHAPED) ) { WindowDefSpec customWindowDefSpec; customWindowDefSpec.defType = kWindowDefProcPtr; @@ -1112,23 +1697,7 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( // the create commands are only for content rect, // so we have to set the size again as structure bounds - SetWindowBounds( (WindowRef) m_macWindow , kWindowStructureRgn , &theBoundsRect ) ; - - wxAssociateWinWithMacWindow( (WindowRef) m_macWindow , this ) ; - m_peer = new wxMacControl(this , true /*isRootControl*/) ; - - // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of - // the content view, so we have to retrieve it explicitly - HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID , - m_peer->GetControlRefAddr() ) ; - if ( !m_peer->Ok() ) - { - // compatibility mode fallback - GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ; - } - - // the root control level handler - MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ; + SetWindowBounds( m_macWindow , kWindowStructureRgn , &theBoundsRect ) ; // Causes the inner part of the window not to be metal // if the style is used before window creation. @@ -1146,107 +1715,29 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( } HIViewRef growBoxRef = 0 ; - err = HIViewFindByID( HIViewGetRoot( (WindowRef)m_macWindow ), kHIViewWindowGrowBoxID, &growBoxRef ); + err = HIViewFindByID( HIViewGetRoot( m_macWindow ), kHIViewWindowGrowBoxID, &growBoxRef ); if ( err == noErr && growBoxRef != 0 ) HIGrowBoxViewSetTransparent( growBoxRef, true ) ; // the frame window event handler - InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ; + InstallStandardEventHandler( GetWindowEventTarget(m_macWindow) ) ; MacInstallTopLevelWindowEventHandler() ; - DoSetWindowVariant( m_windowVariant ) ; - - m_macFocus = NULL ; + if ( extraStyle & wxFRAME_EX_METAL) + MacSetMetalAppearance(true); - if ( HasFlag(wxFRAME_SHAPED) ) + if ( ( style &wxFRAME_SHAPED) ) { // default shape matches the window size wxRegion rgn( 0, 0, w, h ); SetShape( rgn ); } - - wxWindowCreateEvent event(this); - HandleWindowEvent(event); -} - -// Raise the window to the top of the Z order -void wxNonOwnedWindow::Raise() -{ - ::SelectWindow( (WindowRef)m_macWindow ) ; -} - -// Lower the window to the bottom of the Z order -void wxNonOwnedWindow::Lower() -{ - ::SendBehind( (WindowRef)m_macWindow , NULL ) ; -} - -void wxNonOwnedWindow::MacDelayedDeactivation(long timestamp) -{ - if (s_macDeactivateWindow) - { - wxLogTrace(TRACE_ACTIVATE, - wxT("Doing delayed deactivation of %p"), - s_macDeactivateWindow); - - s_macDeactivateWindow->MacActivate(timestamp, false); - } -} - -void wxNonOwnedWindow::MacActivate( long timestamp , bool WXUNUSED(inIsActivating) ) -{ - wxLogTrace(TRACE_ACTIVATE, wxT("TopLevel=%p::MacActivate"), this); - - if (s_macDeactivateWindow == this) - s_macDeactivateWindow = NULL; - - MacDelayedDeactivation(timestamp); -} - -bool wxNonOwnedWindow::Show(bool show) -{ - if ( !wxWindow::Show(show) ) - return false; - - bool plainTransition = true; - -#if wxUSE_SYSTEM_OPTIONS - if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) - plainTransition = ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1 ) ; -#endif - - if (show) - { - if ( plainTransition ) - ::ShowWindow( (WindowRef)m_macWindow ); - else - ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL ); - - ::SelectWindow( (WindowRef)m_macWindow ) ; - - // because apps expect a size event to occur at this moment - wxSizeEvent event(GetSize() , m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); - } - else - { - if ( plainTransition ) - ::HideWindow( (WindowRef)m_macWindow ); - else - ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowHideTransitionAction, NULL ); - } - - return true ; } -bool wxNonOwnedWindow::MacShowWithEffect(bool show, +bool wxNonOwnedWindowCarbonImpl::ShowWithEffect(bool show, wxShowEffect effect, unsigned timeout) { - if ( !wxWindow::Show(show) ) - return false; - WindowTransitionEffect transition = 0 ; switch( effect ) { @@ -1281,409 +1772,236 @@ bool wxNonOwnedWindow::MacShowWithEffect(bool show, TransitionWindowOptions options; options.version = 0; options.duration = timeout / 1000.0; - options.window = transition == kWindowSheetTransitionEffect ? (WindowRef) GetParent()->MacGetTopLevelWindowRef() :0; + options.window = transition == kWindowSheetTransitionEffect ? (WindowRef) m_wxPeer->GetParent()->MacGetTopLevelWindowRef() :0; options.userData = 0; wxSize size = wxGetDisplaySize(); - Rect bounds; - GetWindowBounds( (WindowRef)m_macWindow, kWindowStructureRgn, &bounds ); - CGRect hiBounds = CGRectMake( bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top ); - - switch ( effect ) - { - case wxSHOW_EFFECT_ROLL_TO_RIGHT: - case wxSHOW_EFFECT_SLIDE_TO_RIGHT: - hiBounds.origin.x = 0; - hiBounds.size.width = 0; - break; - - case wxSHOW_EFFECT_ROLL_TO_LEFT: - case wxSHOW_EFFECT_SLIDE_TO_LEFT: - hiBounds.origin.x = size.x; - hiBounds.size.width = 0; - break; - - case wxSHOW_EFFECT_ROLL_TO_TOP: - case wxSHOW_EFFECT_SLIDE_TO_TOP: - hiBounds.origin.y = size.y; - hiBounds.size.height = 0; - break; - - case wxSHOW_EFFECT_ROLL_TO_BOTTOM: - case wxSHOW_EFFECT_SLIDE_TO_BOTTOM: - hiBounds.origin.y = 0; - hiBounds.size.height = 0; - break; - - default: - break; // direction doesn't make sense - } - - ::TransitionWindowWithOptions - ( - (WindowRef)m_macWindow, - transition, - show ? kWindowShowTransitionAction : kWindowHideTransitionAction, - transition == kWindowGenieTransitionEffect ? &hiBounds : NULL, - false, - &options - ); - - if ( show ) - { - ::SelectWindow( (WindowRef)m_macWindow ) ; - - // because apps expect a size event to occur at this moment - wxSizeEvent event(GetSize() , m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); - } - - return true; -} - -bool wxNonOwnedWindow::SetTransparent(wxByte alpha) -{ - OSStatus result = SetWindowAlpha((WindowRef)m_macWindow, (CGFloat)((alpha)/255.0)); - return result == noErr; -} - - -bool wxNonOwnedWindow::CanSetTransparent() -{ - return true; -} - - -void wxNonOwnedWindow::SetExtraStyle(long exStyle) -{ - if ( GetExtraStyle() == exStyle ) - return ; - - wxWindow::SetExtraStyle( exStyle ) ; - - if ( m_macWindow != NULL ) - { - bool metal = GetExtraStyle() & wxFRAME_EX_METAL ; - - if ( MacGetMetalAppearance() != metal ) - { - if ( MacGetUnifiedAppearance() ) - MacSetUnifiedAppearance( !metal ) ; - - MacSetMetalAppearance( metal ) ; - } - } -} - -bool wxNonOwnedWindow::SetBackgroundStyle(wxBackgroundStyle style) -{ - if ( !wxWindow::SetBackgroundStyle(style) ) - return false ; - - WindowRef windowRef = HIViewGetWindow( (HIViewRef)GetHandle() ); - - if ( GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) - { - OSStatus err = HIWindowChangeFeatures( windowRef, 0, kWindowIsOpaque ); - verify_noerr( err ); - err = ReshapeCustomWindow( windowRef ); - verify_noerr( err ); - } - - return true ; -} - -// TODO: switch to structure bounds - -// we are still using coordinates of the content view -// -void wxNonOwnedWindow::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom ) -{ - Rect content, structure ; - - GetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &structure ) ; - GetWindowBounds( (WindowRef) m_macWindow, kWindowContentRgn , &content ) ; - - left = content.left - structure.left ; - top = content.top - structure.top ; - right = structure.right - content.right ; - bottom = structure.bottom - content.bottom ; -} - -void wxNonOwnedWindow::DoMoveWindow(int x, int y, int width, int height) -{ - m_cachedClippedRectValid = false ; - Rect bounds = { y , x , y + height , x + width } ; - verify_noerr(SetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; - wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified -} - -void wxNonOwnedWindow::DoGetPosition( int *x, int *y ) const -{ - Rect bounds ; - - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; - - if (x) - *x = bounds.left ; - if (y) - *y = bounds.top ; -} + Rect bounds; + GetWindowBounds( (WindowRef)m_macWindow, kWindowStructureRgn, &bounds ); + CGRect hiBounds = CGRectMake( bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top ); -void wxNonOwnedWindow::DoGetSize( int *width, int *height ) const -{ - Rect bounds ; + switch ( effect ) + { + case wxSHOW_EFFECT_ROLL_TO_RIGHT: + case wxSHOW_EFFECT_SLIDE_TO_RIGHT: + hiBounds.origin.x = 0; + hiBounds.size.width = 0; + break; - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; + case wxSHOW_EFFECT_ROLL_TO_LEFT: + case wxSHOW_EFFECT_SLIDE_TO_LEFT: + hiBounds.origin.x = size.x; + hiBounds.size.width = 0; + break; - if (width) - *width = bounds.right - bounds.left ; - if (height) - *height = bounds.bottom - bounds.top ; -} + case wxSHOW_EFFECT_ROLL_TO_TOP: + case wxSHOW_EFFECT_SLIDE_TO_TOP: + hiBounds.origin.y = size.y; + hiBounds.size.height = 0; + break; -void wxNonOwnedWindow::DoGetClientSize( int *width, int *height ) const -{ - Rect bounds ; + case wxSHOW_EFFECT_ROLL_TO_BOTTOM: + case wxSHOW_EFFECT_SLIDE_TO_BOTTOM: + hiBounds.origin.y = 0; + hiBounds.size.height = 0; + break; - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowContentRgn , &bounds )) ; + default: + break; // direction doesn't make sense + } - if (width) - *width = bounds.right - bounds.left ; - if (height) - *height = bounds.bottom - bounds.top ; -} + ::TransitionWindowWithOptions + ( + (WindowRef)m_macWindow, + transition, + show ? kWindowShowTransitionAction : kWindowHideTransitionAction, + transition == kWindowGenieTransitionEffect ? &hiBounds : NULL, + false, + &options + ); -void wxNonOwnedWindow::MacSetMetalAppearance( bool set ) -{ - if ( MacGetUnifiedAppearance() ) - MacSetUnifiedAppearance( false ) ; + if ( show ) + { + ::SelectWindow( (WindowRef)m_macWindow ) ; + } - MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes , - set ? kWindowNoAttributes : kWindowMetalAttribute ) ; + return true; } -bool wxNonOwnedWindow::MacGetMetalAppearance() const +void wxNonOwnedWindowCarbonImpl::SetTitle( const wxString& title, wxFontEncoding encoding ) { - return MacGetWindowAttributes() & kWindowMetalAttribute ; + SetWindowTitleWithCFString( m_macWindow , wxCFStringRef( title , encoding ) ) ; } - -void wxNonOwnedWindow::MacSetUnifiedAppearance( bool set ) + +bool wxNonOwnedWindowCarbonImpl::IsMaximized() const { - if ( MacGetMetalAppearance() ) - MacSetMetalAppearance( false ) ; - - MacChangeWindowAttributes( set ? kWindowUnifiedTitleAndToolbarAttribute : kWindowNoAttributes , - set ? kWindowNoAttributes : kWindowUnifiedTitleAndToolbarAttribute) ; - - // For some reason, Tiger uses white as the background color for this appearance, - // while most apps using it use the typical striped background. Restore that behavior - // for wx. - // TODO: Determine if we need this on Leopard as well. (should be harmless either way, - // though) - SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ) ; + return IsWindowInStandardState( m_macWindow , NULL , NULL ) ; } - -bool wxNonOwnedWindow::MacGetUnifiedAppearance() const + +bool wxNonOwnedWindowCarbonImpl::IsIconized() const { - return MacGetWindowAttributes() & kWindowUnifiedTitleAndToolbarAttribute ; + return IsWindowCollapsed((WindowRef)GetWXWindow() ) ; } - -void wxNonOwnedWindow::MacChangeWindowAttributes( wxUint32 attributesToSet , wxUint32 attributesToClear ) + +void wxNonOwnedWindowCarbonImpl::Iconize( bool iconize ) { - ChangeWindowAttributes( (WindowRef)m_macWindow, attributesToSet, attributesToClear ) ; + if ( IsWindowCollapsable( m_macWindow ) ) + CollapseWindow( m_macWindow , iconize ) ; } - -wxUint32 wxNonOwnedWindow::MacGetWindowAttributes() const + +void wxNonOwnedWindowCarbonImpl::Maximize(bool maximize) { - UInt32 attr = 0 ; - GetWindowAttributes( (WindowRef) m_macWindow, &attr ) ; - - return attr ; + Point idealSize = { 0 , 0 } ; + if ( maximize ) + { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + HIRect bounds ; + HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal, + &bounds); + idealSize.h = bounds.size.width; + idealSize.v = bounds.size.height; +#else + Rect rect ; + GetAvailableWindowPositioningBounds(GetMainDevice(),&rect) ; + idealSize.h = rect.right - rect.left ; + idealSize.v = rect.bottom - rect.top ; +#endif + } + ZoomWindowIdeal( (WindowRef)GetWXWindow() , maximize ? inZoomOut : inZoomIn , &idealSize ) ; } - -void wxNonOwnedWindow::MacPerformUpdates() + +bool wxNonOwnedWindowCarbonImpl::IsFullScreen() const { - // for composited windows this also triggers a redraw of all - // invalid views in the window - HIWindowFlush((WindowRef) m_macWindow) ; + return m_macFullScreenData != NULL ; } - -// --------------------------------------------------------------------------- -// Shape implementation -// --------------------------------------------------------------------------- - - -bool wxNonOwnedWindow::SetShape(const wxRegion& region) + +bool wxNonOwnedWindowCarbonImpl::ShowFullScreen(bool show, long style) { - wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false, - _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); - - // The empty region signifies that the shape - // should be removed from the window. - if ( region.IsEmpty() ) + if ( show ) { - wxSize sz = GetClientSize(); - wxRegion rgn(0, 0, sz.x, sz.y); - if ( rgn.IsEmpty() ) - return false ; - else - return SetShape(rgn); - } - - // Make a copy of the region - RgnHandle shapeRegion = NewRgn(); - HIShapeGetAsQDRgn( region.GetWXHRGN(), shapeRegion ); + FullScreenData *data = (FullScreenData *)m_macFullScreenData ; + delete data ; + data = new FullScreenData() ; + + m_macFullScreenData = data ; + data->m_position = m_wxPeer->GetPosition() ; + data->m_size = m_wxPeer->GetSize() ; +#if wxOSX_USE_CARBON + WindowAttributes attr = 0; + GetWindowAttributes((WindowRef) GetWXWindow(), &attr); + data->m_wasResizable = attr & kWindowResizableAttribute; + if ( style & wxFULLSCREEN_NOMENUBAR ) + HideMenuBar() ; +#endif - // Dispose of any shape region we may already have - RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef)MacGetWindowRef() ); - if ( oldRgn ) - DisposeRgn(oldRgn); + wxRect client = wxGetClientDisplayRect() ; - // Save the region so we can use it later - SetWRefCon((WindowRef)MacGetWindowRef(), (URefCon)shapeRegion); + int left , top , right , bottom ; + int x, y, w, h ; - // inform the window manager that the window has changed shape - ReshapeCustomWindow((WindowRef)MacGetWindowRef()); + x = client.x ; + y = client.y ; + w = client.width ; + h = client.height ; - return true; -} + GetContentArea( left , top , right , bottom ) ; -// --------------------------------------------------------------------------- -// Support functions for shaped windows, based on Apple's CustomWindow sample at -// http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm -// --------------------------------------------------------------------------- + if ( style & wxFULLSCREEN_NOCAPTION ) + { + y -= top ; + h += top ; + } -static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect) -{ - GetWindowPortBounds(window, inRect); - Point pt = { inRect->top ,inRect->left }; - wxMacLocalToGlobal( window, &pt ) ; - inRect->bottom += pt.v - inRect->top; - inRect->right += pt.h - inRect->left; - inRect->top = pt.v; - inRect->left = pt.h; -} + if ( style & wxFULLSCREEN_NOBORDER ) + { + x -= left ; + w += left + right ; + h += bottom ; + } -static SInt32 wxShapedMacWindowGetFeatures(WindowRef WXUNUSED(window), SInt32 param) -{ - /*------------------------------------------------------ - Define which options your custom window supports. - --------------------------------------------------------*/ - //just enable everything for our demo - *(OptionBits*)param = - //kWindowCanGrow | - //kWindowCanZoom | - kWindowCanCollapse | - //kWindowCanGetWindowRegion | - //kWindowHasTitleBar | - //kWindowSupportsDragHilite | - kWindowCanDrawInCurrentPort | - //kWindowCanMeasureTitle | - kWindowWantsDisposeAtProcessDeath | - kWindowSupportsGetGrowImageRegion | - kWindowDefSupportsColorGrafPort; + if ( style & wxFULLSCREEN_NOTOOLBAR ) + { + // TODO + } - return 1; -} + if ( style & wxFULLSCREEN_NOSTATUSBAR ) + { + // TODO + } -// The content region is left as a rectangle matching the window size, this is -// so the origin in the paint event, and etc. still matches what the -// programmer expects. -static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn) -{ - SetEmptyRgn(rgn); - wxNonOwnedWindow* win = wxFindWinFromMacWindow(window); - if (win) + m_wxPeer->SetSize( x , y , w, h ) ; + if ( data->m_wasResizable ) + { +#if wxOSX_USE_CARBON + ChangeWindowAttributes( (WindowRef) GetWXWindow() , kWindowNoAttributes , kWindowResizableAttribute ) ; +#endif + } + } + else if ( m_macFullScreenData != NULL ) { - Rect r ; - wxShapedMacWindowGetPos( window, &r ) ; - RectRgn( rgn , &r ) ; + FullScreenData *data = (FullScreenData *) m_macFullScreenData ; +#if wxOSX_USE_CARBON + ShowMenuBar() ; + if ( data->m_wasResizable ) + ChangeWindowAttributes( (WindowRef) GetWXWindow() , kWindowResizableAttribute , kWindowNoAttributes ) ; +#endif + m_wxPeer->SetPosition( data->m_position ) ; + m_wxPeer->SetSize( data->m_size ) ; + + delete data ; + m_macFullScreenData = NULL ; } + + return true; } -// The structure region is set to the shape given to the SetShape method. -static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn) -{ - RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window); +// Attracts the users attention to this window if the application is +// inactive (should be called when a background event occurs) - SetEmptyRgn(rgn); - if (cachedRegion) - { - Rect windowRect; - wxShapedMacWindowGetPos(window, &windowRect); // how big is the window - CopyRgn(cachedRegion, rgn); // make a copy of our cached region - OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window - //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size - } +static pascal void wxMacNMResponse( NMRecPtr ptr ) +{ + NMRemove( ptr ) ; + DisposePtr( (Ptr)ptr ) ; } -static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param) +void wxNonOwnedWindowCarbonImpl::RequestUserAttention(int WXUNUSED(flags)) { - GetWindowRegionPtr rgnRec = (GetWindowRegionPtr)param; - - if (rgnRec == NULL) - return paramErr; - - switch (rgnRec->regionCode) - { - case kWindowStructureRgn: - wxShapedMacWindowStructureRegion(window, rgnRec->winRgn); - break; + NMRecPtr notificationRequest = (NMRecPtr) NewPtr( sizeof( NMRec) ) ; - case kWindowContentRgn: - wxShapedMacWindowContentRegion(window, rgnRec->winRgn); - break; - - default: - SetEmptyRgn(rgnRec->winRgn); - break; - } + memset( notificationRequest , 0 , sizeof(*notificationRequest) ) ; + notificationRequest->qType = nmType ; + notificationRequest->nmMark = 1 ; + notificationRequest->nmIcon = 0 ; + notificationRequest->nmSound = 0 ; + notificationRequest->nmStr = NULL ; + notificationRequest->nmResp = wxMacNMResponse ; - return noErr; + verify_noerr( NMInstall( notificationRequest ) ) ; } -// Determine the region of the window which was hit -// -static SInt32 wxShapedMacWindowHitTest(WindowRef window, SInt32 param) +void wxNonOwnedWindowCarbonImpl::ScreenToWindow( int *x, int *y ) { - Point hitPoint; - static RgnHandle tempRgn = NULL; - - if (tempRgn == NULL) - tempRgn = NewRgn(); - - // get the point clicked - SetPt( &hitPoint, LoWord(param), HiWord(param) ); - - // Mac OS 8.5 or later - wxShapedMacWindowStructureRegion(window, tempRgn); - if (PtInRgn( hitPoint, tempRgn )) //in window content region? - return wInContent; - - // no significant area was hit - return wNoHit; + HIPoint p = CGPointMake( (x ? *x : 0), (y ? *y : 0) ); + HIViewRef contentView ; + // TODO check toolbar offset + HIViewFindByID( HIViewGetRoot( m_macWindow ), kHIViewWindowContentID , &contentView) ; + HIPointConvert( &p, kHICoordSpace72DPIGlobal, NULL, kHICoordSpaceView, contentView ); + if ( x ) + *x = p.x; + if ( y ) + *y = p.y; } -static pascal long wxShapedMacWindowDef(short WXUNUSED(varCode), WindowRef window, SInt16 message, SInt32 param) +void wxNonOwnedWindowCarbonImpl::WindowToScreen( int *x, int *y ) { - switch (message) - { - case kWindowMsgHitTest: - return wxShapedMacWindowHitTest(window, param); - - case kWindowMsgGetFeatures: - return wxShapedMacWindowGetFeatures(window, param); - - // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow - case kWindowMsgGetRegion: - return wxShapedMacWindowGetRegion(window, param); - - default: - break; - } - - return 0; + HIPoint p = CGPointMake( (x ? *x : 0), (y ? *y : 0) ); + HIViewRef contentView ; + // TODO check toolbar offset + HIViewFindByID( HIViewGetRoot( m_macWindow ), kHIViewWindowContentID , &contentView) ; + HIPointConvert( &p, kHICoordSpaceView, contentView, kHICoordSpace72DPIGlobal, NULL ); + if ( x ) + *x = p.x; + if ( y ) + *y = p.y; } - - +#endif // wxOSX_USE_CARBON diff --git a/src/osx/carbon/overlay.cpp b/src/osx/carbon/overlay.cpp index 3ae300276a..0cdcf578df 100644 --- a/src/osx/carbon/overlay.cpp +++ b/src/osx/carbon/overlay.cpp @@ -60,15 +60,13 @@ void wxOverlayImpl::MacGetBounds( Rect *bounds ) int x, y; x=y=0; m_window->MacWindowToRootWindow( &x , &y ) ; - WindowRef window = (WindowRef) m_window->MacGetTopLevelWindowRef() ; + wxNonOwnedWindow* tlw = m_window->MacGetTopLevelWindow(); + tlw->GetNonOwnedPeer()->WindowToScreen( &x, &y ); - Point localwhere = { y, x }; - wxMacLocalToGlobal( window, &localwhere ) ; - - bounds->top = localwhere.v+m_y; - bounds->left = localwhere.h+m_x; - bounds->bottom = localwhere.v+m_y+m_height; - bounds->right = localwhere.h+m_x+m_width; + bounds->top = y+m_y; + bounds->left = x+m_x; + bounds->bottom = y+m_y+m_height; + bounds->right = x+m_x+m_width; } OSStatus wxOverlayImpl::CreateOverlayWindow() diff --git a/src/osx/carbon/printmac.cpp b/src/osx/carbon/printmac.cpp index d013871f94..af3bd2a17f 100644 --- a/src/osx/carbon/printmac.cpp +++ b/src/osx/carbon/printmac.cpp @@ -142,7 +142,7 @@ bool wxMacCarbonPrintData::TransferFrom( const wxPrintData &data ) if ( !m_printerName.empty() ) PMSessionSetCurrentPrinter( (PMPrintSession) m_macPrintSession , wxCFStringRef( m_printerName , wxFont::GetDefaultEncoding() ) ) ; #endif -#ifndef __LP64__ +#if wxOSX_USE_CARBON PMColorMode color ; PMGetColorMode( (PMPrintSettings) m_macPrintSettings, &color ) ; if ( data.GetColour() ) @@ -176,15 +176,16 @@ bool wxMacCarbonPrintData::TransferFrom( const wxPrintData &data ) PMResolution res; PMPrinter printer; PMSessionGetCurrentPrinter(m_macPrintSession, &printer); -#if 0 // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + +#if wxOSX_USE_CARBON + PMTag tag = kPMMaxSquareResolution; + PMPrinterGetPrinterResolution(printer, tag, &res); + PMSetResolution((PMPageFormat) m_macPageFormat, &res); +#else PMPrinterGetOutputResolution( printer, (PMPrintSettings) m_macPrintSettings, &res) ; // TODO transfer ? into page format ? // may fail ! -#else - PMTag tag = kPMMaxSquareResolution; - PMPrinterGetPrinterResolution(printer, tag, &res); - PMSetResolution((PMPageFormat) m_macPageFormat, &res); #endif // after setting the new resolution the format has to be updated, otherwise the page rect remains // at the 'old' scaling @@ -420,12 +421,12 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt) PMResolution res; wxMacCarbonPrintData* nativeData = (wxMacCarbonPrintData*) (m_printDialogData.GetPrintData().GetNativeData()); -#if 0 // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 +#if wxOSX_USE_CARBON + PMGetResolution((PMPageFormat) (nativeData->m_macPageFormat), &res); +#else PMPrinter printer; PMSessionGetCurrentPrinter(nativeData->m_macPrintSession, &printer); PMPrinterGetOutputResolution( printer, nativeData->m_macPrintSettings, &res) ; -#else - PMGetResolution((PMPageFormat) (nativeData->m_macPageFormat), &res); #endif printout->SetPPIPrinter(int(res.hRes), int(res.vRes)); diff --git a/src/osx/carbon/renderer.cpp b/src/osx/carbon/renderer.cpp index 8eb4e180e7..bac3e528c4 100644 --- a/src/osx/carbon/renderer.cpp +++ b/src/osx/carbon/renderer.cpp @@ -27,7 +27,7 @@ #include "wx/renderer.h" #include "wx/graphics.h" -#include "wx/osx/uma.h" +#include "wx/osx/private.h" class WXDLLEXPORT wxRendererMac : public wxDelegateRendererNative @@ -236,7 +236,7 @@ void wxRendererMac::DrawSplitterSash( wxWindow *win, wxOrientation orient, int WXUNUSED(flags) ) { - bool hasMetal = win->MacGetTopLevelWindow()->MacGetMetalAppearance(); + bool hasMetal = win->MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL; SInt32 height; GetThemeMetric( kThemeMetricSmallPaneSplitterHeight, &height ); HIRect splitterRect; diff --git a/src/osx/carbon/settings.cpp b/src/osx/carbon/settings.cpp index ae7625872c..b2ceb365f1 100644 --- a/src/osx/carbon/settings.cpp +++ b/src/osx/carbon/settings.cpp @@ -18,7 +18,7 @@ #include "wx/gdicmn.h" #endif -#include "wx/osx/uma.h" +#include "wx/osx/private.h" // ---------------------------------------------------------------------------- // wxSystemSettingsNative @@ -31,12 +31,18 @@ wxColour wxSystemSettingsNative::GetColour(wxSystemColour index) { wxColour resultColor; +#if wxOSX_USE_COCOA_OR_CARBON ThemeBrush colorBrushID; +#endif switch ( index ) { case wxSYS_COLOUR_WINDOW: - resultColor = *wxWHITE ; +#if wxOSX_USE_COCOA_OR_CARBON + resultColor = wxColour(wxMacCreateCGColorFromHITheme( kThemeBrushDocumentWindowBackground )) ; +#else + resultColor = *wxWHITE; +#endif break ; case wxSYS_COLOUR_SCROLLBAR : case wxSYS_COLOUR_BACKGROUND: @@ -48,7 +54,11 @@ wxColour wxSystemSettingsNative::GetColour(wxSystemColour index) case wxSYS_COLOUR_INACTIVEBORDER: case wxSYS_COLOUR_BTNFACE: case wxSYS_COLOUR_MENUBAR: - resultColor = wxColor( 0xDD, 0xDD, 0xDD ); +#if wxOSX_USE_COCOA_OR_CARBON + resultColor = wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive)); +#else + resultColor = wxColour( 0xBE, 0xBE, 0xBE ) ; +#endif break ; case wxSYS_COLOUR_LISTBOX : @@ -56,7 +66,7 @@ wxColour wxSystemSettingsNative::GetColour(wxSystemColour index) break ; case wxSYS_COLOUR_BTNSHADOW: - resultColor = wxColor( 0xBE, 0xBE, 0xBE ); + resultColor = wxColour( 0xBE, 0xBE, 0xBE ); break ; case wxSYS_COLOUR_BTNTEXT: @@ -70,13 +80,17 @@ wxColour wxSystemSettingsNative::GetColour(wxSystemColour index) case wxSYS_COLOUR_HIGHLIGHT: { +#if wxOSX_USE_COCOA_OR_CARBON #if 0 // NB: enable this case as desired colorBrushID = kThemeBrushAlternatePrimaryHighlightColor; #else colorBrushID = kThemeBrushPrimaryHighlightColor; #endif - resultColor = wxColor( wxMacCreateCGColorFromHITheme(colorBrushID) ); + resultColor = wxColour( wxMacCreateCGColorFromHITheme(colorBrushID) ); +#else + resultColor = wxColor( 0xCC, 0xCC, 0xFF ); +#endif } break ; @@ -94,10 +108,7 @@ wxColour wxSystemSettingsNative::GetColour(wxSystemColour index) break ; case wxSYS_COLOUR_HIGHLIGHTTEXT : -#if 0 - // NB: enable this case as desired - resultColor = *wxWHITE ; -#else +#if wxOSX_USE_COCOA_OR_CARBON { wxColour highlightcolor( wxMacCreateCGColorFromHITheme(kThemeBrushPrimaryHighlightColor) ); if ((highlightcolor.Red() + highlightcolor.Green() + highlightcolor.Blue() ) == 0) @@ -105,6 +116,8 @@ wxColour wxSystemSettingsNative::GetColour(wxSystemColour index) else resultColor = *wxBLACK ; } +#else + resultColor = *wxWHITE ; #endif break ; @@ -227,12 +240,12 @@ int wxSystemSettingsNative::GetMetric(wxSystemMetric index, wxWindow* WXUNUSED(w // TODO: case wxSYS_SHOW_SOUNDS: case wxSYS_DCLICK_MSEC: -#ifdef __LP64__ +#if wxOSX_USE_CARBON + return (int)(GetDblTime() * 1000. / 60.); +#else // default on mac is 30 ticks, we shouldn't really use wxSYS_DCLICK_MSEC anyway // but rather rely on the 'click-count' by the system delivered in a mouse event return 500; -#else - return (int)(GetDblTime() * 1000. / 60.); #endif default: // unsupported metric diff --git a/src/osx/carbon/srchctrl.cpp b/src/osx/carbon/srchctrl.cpp index 24919560de..0a7eb7a767 100644 --- a/src/osx/carbon/srchctrl.cpp +++ b/src/osx/carbon/srchctrl.cpp @@ -66,6 +66,8 @@ public : virtual void SetDescriptiveText(const wxString& text); virtual wxString GetDescriptiveText() const; + + virtual bool SetFocus(); protected : virtual void CreateControl( wxTextCtrl* peer, const Rect* bounds, CFStringRef crf ); @@ -176,6 +178,21 @@ wxString wxMacSearchFieldControl::GetDescriptiveText() const } } +bool wxMacSearchFieldControl::SetFocus() +{ + // NB: We have to implement SetFocus a little differently because kControlFocusNextPart + // leads to setting the focus on the search icon rather than the text area. + // We get around this by explicitly telling the control to set focus to the + // text area. + + OSStatus err = SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, kControlEditTextPart ); + if ( err == errCouldntSetFocus ) + return false ; + SetUserFocusWindow(GetControlOwner( m_controlRef ) ); + return true; +} + + // ============================================================================ // implementation // ============================================================================ @@ -274,27 +291,6 @@ wxSize wxSearchCtrl::DoGetBestSize() const return size; } -void wxSearchCtrl::SetFocus() -{ - // NB: We have to implement SetFocus a little differently because kControlFocusNextPart - // leads to setting the focus on the search icon rather than the text area. - // We get around this by explicitly telling the control to set focus to the - // text area. - if ( !AcceptsFocus() ) - return ; - - wxWindow* former = FindFocus() ; - if ( former == this ) - return ; - - // as we cannot rely on the control features to find out whether we are in full keyboard mode, - // we can only leave in case of an error - OSStatus err = m_peer->SetFocus( kControlEditTextPart ) ; - if ( err == errCouldntSetFocus ) - return ; - - SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() ); -} // search control specific interfaces // wxSearchCtrl owns menu after this call diff --git a/src/osx/carbon/statbrma.cpp b/src/osx/carbon/statbrma.cpp index ba190b0df3..fc136abeb2 100644 --- a/src/osx/carbon/statbrma.cpp +++ b/src/osx/carbon/statbrma.cpp @@ -58,7 +58,7 @@ bool wxStatusBarMac::Create(wxWindow *parent, wxWindowID id, if ( !wxStatusBarGeneric::Create( parent, id, style, name ) ) return false; - if ( parent->MacGetTopLevelWindow()->MacGetMetalAppearance() ) + if ( parent->MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL ) SetBackgroundStyle( wxBG_STYLE_TRANSPARENT ); // normal system font is too tall for fitting into the standard height @@ -86,7 +86,7 @@ void wxStatusBarMac::DrawFieldText(wxDC& dc, int i) int xpos = rect.x + leftMargin + 1; int ypos = 1; - if ( MacGetTopLevelWindow()->MacGetMetalAppearance() ) + if ( MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL ) ypos++; dc.SetClippingRegion(rect.x, 0, rect.width, h); @@ -136,7 +136,7 @@ void wxStatusBarMac::OnPaint(wxPaintEvent& WXUNUSED(event)) if (major >= 10) { // Finder statusbar border color: (Project Builder similar is 9B9B9B) - if ( MacGetTopLevelWindow()->MacGetMetalAppearance() ) + if ( MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL ) dc.SetPen(wxPen(wxColour(0x40, 0x40, 0x40), 1, wxSOLID)); else dc.SetPen(wxPen(wxColour(0xB1, 0xB1, 0xB1), 1, wxSOLID)); diff --git a/src/osx/carbon/textctrl.cpp b/src/osx/carbon/textctrl.cpp index 3b21030e01..ee48f1247c 100644 --- a/src/osx/carbon/textctrl.cpp +++ b/src/osx/carbon/textctrl.cpp @@ -328,7 +328,7 @@ public : return true; } - virtual void SetRect( Rect *r ) ; + virtual void Move(int x, int y, int width, int height); protected : OSStatus DoCreate(); @@ -1368,7 +1368,7 @@ bool wxMacUnicodeTextControl::Create( wxTextCtrl *wxPeer, if ( !(m_windowStyle & wxTE_MULTILINE) ) SetData( kControlEditTextPart , kControlEditTextSingleLineTag , true ) ; - InstallControlEventHandler( m_controlRef , GetwxMacUnicodeTextControlEventHandlerUPP(), + ::InstallControlEventHandler( m_controlRef , GetwxMacUnicodeTextControlEventHandlerUPP(), GetEventTypeCount(unicodeTextControlEventList), unicodeTextControlEventList, this, NULL); @@ -1664,7 +1664,7 @@ void wxMacMLTEControl::SetStringValue( const wxString &str ) { #ifndef __LP64__ - wxMacWindowClipper c( m_peer ) ; + wxMacWindowClipper c( GetWXPeer() ) ; #endif { @@ -2010,7 +2010,7 @@ void wxMacMLTEControl::Replace( long from , long to , const wxString &str ) wxMacEditHelper help( m_txn ) ; #ifndef __LP64__ - wxMacWindowClipper c( m_peer ) ; + wxMacWindowClipper c( GetWXPeer() ) ; #endif TXNSetSelection( m_txn, from, to == -1 ? kTXNEndOffset : to ) ; @@ -2021,7 +2021,7 @@ void wxMacMLTEControl::Replace( long from , long to , const wxString &str ) void wxMacMLTEControl::Remove( long from , long to ) { #ifndef __LP64__ - wxMacWindowClipper c( m_peer ) ; + wxMacWindowClipper c( GetWXPeer() ) ; #endif wxMacEditHelper help( m_txn ) ; TXNSetSelection( m_txn , from , to ) ; @@ -2039,7 +2039,7 @@ void wxMacMLTEControl::GetSelection( long* from, long* to) const void wxMacMLTEControl::SetSelection( long from , long to ) { #ifndef __LP64__ - wxMacWindowClipper c( m_peer ) ; + wxMacWindowClipper c( GetWXPeer() ) ; #endif // change the selection @@ -2060,7 +2060,7 @@ void wxMacMLTEControl::WriteText( const wxString& str ) GetSelection( &start , &dummy ) ; #ifndef __LP64__ - wxMacWindowClipper c( m_peer ) ; + wxMacWindowClipper c( GetWXPeer() ) ; #endif { @@ -2076,7 +2076,7 @@ void wxMacMLTEControl::WriteText( const wxString& str ) void wxMacMLTEControl::Clear() { #ifndef __LP64__ - wxMacWindowClipper c( m_peer ) ; + wxMacWindowClipper c( GetWXPeer() ) ; #endif wxMacEditHelper st( m_txn ) ; TXNSetSelection( m_txn , kTXNStartOffset , kTXNEndOffset ) ; @@ -2571,9 +2571,9 @@ void wxMacMLTEClassicControl::MacUpdatePosition() } } -void wxMacMLTEClassicControl::SetRect( Rect *r ) +void wxMacMLTEClassicControl::Move(int x, int y, int width, int height) { - wxMacControl::SetRect( r ) ; + wxMacControl::Move(x,y,width,height) ; MacUpdatePosition() ; } @@ -2770,7 +2770,7 @@ wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxTextCtrl *wxPeer, { wxString st = str ; wxMacConvertNewlines10To13( &st ) ; - wxMacWindowClipper clipper( m_peer ) ; + wxMacWindowClipper clipper( GetWXPeer() ) ; SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ; TXNSetSelection( m_txn, 0, 0 ) ; } @@ -2804,7 +2804,7 @@ ControlUserPaneFocusUPP gTPFocusProc = NULL; static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget( (WXWidget) control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneDrawProc( part ) ; @@ -2812,7 +2812,7 @@ static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part) static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget( (WXWidget) control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneHitTestProc( where.h , where.v ) ; @@ -2822,7 +2822,7 @@ static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget( (WXWidget) control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc ) ; @@ -2832,7 +2832,7 @@ static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef contro static pascal void wxMacControlUserPaneIdleProc(ControlRef control) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget((WXWidget) control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneIdleProc() ; @@ -2840,7 +2840,7 @@ static pascal void wxMacControlUserPaneIdleProc(ControlRef control) static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget((WXWidget) control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneKeyDownProc( keyCode, charCode, modifiers ) ; @@ -2850,7 +2850,7 @@ static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget( (WXWidget)control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneActivateProc( activating ) ; @@ -2858,7 +2858,7 @@ static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget((WXWidget) control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneFocusProc( action ) ; @@ -2869,7 +2869,7 @@ static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, #if 0 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info) { - wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; + wxTextCtrl *textCtrl = wxDynamicCast( wxFindWindowFromWXWidget(control) , wxTextCtrl ) ; wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneBackgroundProc(info) ; @@ -3080,7 +3080,7 @@ wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxTextCtrl *wxPeer, { HIViewAddSubview( m_scrollView , m_textView ) ; m_controlRef = m_scrollView ; - wxPeer->MacInstallEventHandler( (WXWidget) m_textView ) ; + wxMacControl::MacInstallEventHandler( m_textView, wxPeer ) ; } else { @@ -3090,14 +3090,14 @@ wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxTextCtrl *wxPeer, AdjustCreationAttributes( *wxWHITE , true ) ; #ifndef __LP64__ - wxMacWindowClipper c( m_peer ) ; + wxMacWindowClipper c( GetWXPeer() ) ; #endif SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ; TXNSetSelection( m_txn, 0, 0 ); TXNShowSelection( m_txn, kTXNShowStart ); - InstallControlEventHandler( m_textView , GetwxMacTextControlEventHandlerUPP(), + ::InstallControlEventHandler( m_textView , GetwxMacTextControlEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, NULL); } diff --git a/src/osx/carbon/thread.cpp b/src/osx/carbon/thread.cpp index 6d23905e80..d8bcd279da 100644 --- a/src/osx/carbon/thread.cpp +++ b/src/osx/carbon/thread.cpp @@ -25,7 +25,12 @@ #include "wx/thread.h" +#if wxOSX_USE_COCOA_OR_CARBON #include +#else +#include +#endif + #include "wx/osx/uma.h" // the possible states of the thread: diff --git a/src/osx/carbon/toolbar.cpp b/src/osx/carbon/toolbar.cpp index 9ff9f29cbf..2a3a925a68 100644 --- a/src/osx/carbon/toolbar.cpp +++ b/src/osx/carbon/toolbar.cpp @@ -664,7 +664,7 @@ static pascal OSStatus ControlToolbarItemHandler( EventHandlerCallRef inCallRef, { case kEventControlGetSizeConstraints: { - wxWindow* wxwindow = wxFindControlFromMacControl(object->viewRef ) ; + wxWindow* wxwindow = wxFindWindowFromWXWidget( (WXWidget) object->viewRef ) ; if ( wxwindow ) { // during toolbar layout the native window sometimes gets negative sizes, @@ -1051,10 +1051,9 @@ bool wxToolBar::MacInstallNativeToolbar(bool usesNative) ChangeWindowAttributes( tlw, kWindowToolbarButtonAttribute, 0 ); SetAutomaticControlDragTrackingEnabledForWindow( tlw, true ); - Rect r = { 0, 0, 0, 0 }; - m_peer->SetRect( &r ); + m_peer->Move(0,0,0,0 ); SetSize( wxSIZE_AUTO_WIDTH, 0 ); - m_peer->SetVisibility( false, true ); + m_peer->SetVisibility( false ); wxToolBarBase::Show( false ); } } @@ -1069,7 +1068,7 @@ bool wxToolBar::MacInstallNativeToolbar(bool usesNative) ChangeWindowAttributes( tlw, 0, kWindowToolbarButtonAttribute ); SetWindowToolbar( tlw, NULL ); - m_peer->SetVisibility( true, true ); + m_peer->SetVisibility( true ); } } @@ -1125,6 +1124,13 @@ bool wxToolBar::Realize() bool insertAll = false; HIToolbarRef refTB = (HIToolbarRef)m_macHIToolbarRef; + wxFont f; + wxFontEncoding enc; + f = GetFont(); + if ( f.IsOk() ) + enc = f.GetEncoding(); + else + enc = wxFont::GetDefaultEncoding(); #endif node = m_tools.GetFirst(); @@ -1169,6 +1175,12 @@ bool wxToolBar::Realize() HIToolbarItemRef hiItemRef = tool->GetToolbarItemRef(); if ( hiItemRef != NULL ) { + // since setting the help texts is non-virtual we have to update + // the strings now + HIToolbarItemSetHelpText( hiItemRef, + wxCFStringRef( tool->GetShortHelp(), enc ), + wxCFStringRef( tool->GetLongHelp(), enc ) ); + if ( insertAll || (tool->GetIndex() != currentPosition) ) { OSStatus err = noErr; @@ -1711,7 +1723,7 @@ void wxToolBar::OnPaint(wxPaintEvent& event) int w, h; GetSize( &w, &h ); - bool drawMetalTheme = MacGetTopLevelWindow()->MacGetMetalAppearance(); + bool drawMetalTheme = MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL; if ( !drawMetalTheme ) { diff --git a/src/osx/carbon/tooltip.cpp b/src/osx/carbon/tooltip.cpp index dadf0b2ef0..60fc903593 100644 --- a/src/osx/carbon/tooltip.cpp +++ b/src/osx/carbon/tooltip.cpp @@ -224,9 +224,12 @@ void wxMacToolTip::Draw() HMHelpContentRec tag ; tag.version = kMacHelpVersion; - Point p = { m_position.y , m_position.x }; - wxMacLocalToGlobal( m_window , &p ) ; - SetRect( &tag.absHotRect , p.h - 2 , p.v - 2 , p.h + 2 , p.v + 2 ); + int x = m_position.x; + int y = m_position.y; + wxNonOwnedWindow* tlw = wxNonOwnedWindow::GetFromWXWindow((WXWindow) m_window); + if ( tlw ) + tlw->GetNonOwnedPeer()->WindowToScreen( &x, &y ); + SetRect( &tag.absHotRect , x - 2 , y - 2 , x + 2 , y + 2 ); m_helpTextRef = wxCFStringRef( m_label , wxFONTENCODING_DEFAULT ) ; tag.content[kHMMinimumContentIndex].contentType = kHMCFStringContent ; diff --git a/src/osx/carbon/toplevel.cpp b/src/osx/carbon/toplevel.cpp index fff13c351c..f80a5382d6 100644 --- a/src/osx/carbon/toplevel.cpp +++ b/src/osx/carbon/toplevel.cpp @@ -37,7 +37,6 @@ #include "wx/control.h" #endif //WX_PRECOMP -#include "wx/osx/uma.h" #include "wx/tooltip.h" #include "wx/dnd.h" @@ -45,10 +44,6 @@ #include "wx/sysopt.h" #endif -#ifndef __DARWIN__ -#include -#endif - // for targeting OSX #include "wx/osx/private.h" @@ -63,18 +58,11 @@ END_EVENT_TABLE() // wxTopLevelWindowMac creation // ---------------------------------------------------------------------------- -typedef struct -{ - wxPoint m_position ; - wxSize m_size ; - bool m_wasResizable ; -} FullScreenData ; void wxTopLevelWindowMac::Init() { m_iconized = m_maximizeOnShow = false; - m_macFullScreenData = NULL ; } bool wxTopLevelWindowMac::Create(wxWindow *parent, @@ -89,7 +77,7 @@ bool wxTopLevelWindowMac::Create(wxWindow *parent, return false; wxWindow::SetLabel( title ) ; - SetWindowTitleWithCFString( (WindowRef) m_macWindow , wxCFStringRef( title , GetFont().GetEncoding() ) ); + m_nowpeer->SetTitle(title, GetFont().GetEncoding() ); wxTopLevelWindows.Append(this); return true; @@ -97,9 +85,6 @@ bool wxTopLevelWindowMac::Create(wxWindow *parent, wxTopLevelWindowMac::~wxTopLevelWindowMac() { - FullScreenData *data = (FullScreenData *) m_macFullScreenData ; - delete data ; - m_macFullScreenData = NULL ; } @@ -109,39 +94,24 @@ wxTopLevelWindowMac::~wxTopLevelWindowMac() void wxTopLevelWindowMac::Maximize(bool maximize) { - Point idealSize = { 0 , 0 } ; - if ( maximize ) - { -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - HIRect bounds ; - HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal, - &bounds); - idealSize.h = bounds.size.width; - idealSize.v = bounds.size.height; -#else - Rect rect ; - GetAvailableWindowPositioningBounds(GetMainDevice(),&rect) ; - idealSize.h = rect.right - rect.left ; - idealSize.v = rect.bottom - rect.top ; -#endif - } - ZoomWindowIdeal( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , &idealSize ) ; + if ( IsMaximized() != maximize ) + m_nowpeer->Maximize(maximize); } bool wxTopLevelWindowMac::IsMaximized() const { - return IsWindowInStandardState( (WindowRef)m_macWindow , NULL , NULL ) ; + return m_nowpeer->IsMaximized(); } void wxTopLevelWindowMac::Iconize(bool iconize) { - if ( IsWindowCollapsable( (WindowRef)m_macWindow) ) - CollapseWindow( (WindowRef)m_macWindow , iconize ) ; + if ( IsIconized() != iconize ) + m_nowpeer->Iconize(iconize); } bool wxTopLevelWindowMac::IsIconized() const { - return IsWindowCollapsed((WindowRef)m_macWindow ) ; + return m_nowpeer->IsIconized(); } void wxTopLevelWindowMac::Restore() @@ -164,7 +134,7 @@ wxPoint wxTopLevelWindowMac::GetClientAreaOrigin() const void wxTopLevelWindowMac::SetTitle(const wxString& title) { wxWindow::SetLabel( title ) ; - SetWindowTitleWithCFString( (WindowRef) m_macWindow , wxCFStringRef( title , GetFont().GetEncoding() ) ) ; + m_nowpeer->SetTitle(title, GetFont().GetEncoding() ); } wxString wxTopLevelWindowMac::GetTitle() const @@ -174,101 +144,15 @@ wxString wxTopLevelWindowMac::GetTitle() const bool wxTopLevelWindowMac::ShowFullScreen(bool show, long style) { - if ( show ) - { - FullScreenData *data = (FullScreenData *)m_macFullScreenData ; - delete data ; - data = new FullScreenData() ; - - m_macFullScreenData = data ; - data->m_position = GetPosition() ; - data->m_size = GetSize() ; - data->m_wasResizable = MacGetWindowAttributes() & kWindowResizableAttribute ; - - if ( style & wxFULLSCREEN_NOMENUBAR ) - HideMenuBar() ; - - wxRect client = wxGetClientDisplayRect() ; - - int left , top , right , bottom ; - int x, y, w, h ; - - x = client.x ; - y = client.y ; - w = client.width ; - h = client.height ; - - MacGetContentAreaInset( left , top , right , bottom ) ; - - if ( style & wxFULLSCREEN_NOCAPTION ) - { - y -= top ; - h += top ; - } - - if ( style & wxFULLSCREEN_NOBORDER ) - { - x -= left ; - w += left + right ; - h += bottom ; - } - - if ( style & wxFULLSCREEN_NOTOOLBAR ) - { - // TODO - } - - if ( style & wxFULLSCREEN_NOSTATUSBAR ) - { - // TODO - } - - SetSize( x , y , w, h ) ; - if ( data->m_wasResizable ) - MacChangeWindowAttributes( kWindowNoAttributes , kWindowResizableAttribute ) ; - } - else if ( m_macFullScreenData != NULL ) - { - ShowMenuBar() ; - FullScreenData *data = (FullScreenData *) m_macFullScreenData ; - if ( data->m_wasResizable ) - MacChangeWindowAttributes( kWindowResizableAttribute , kWindowNoAttributes ) ; - SetPosition( data->m_position ) ; - SetSize( data->m_size ) ; - - delete data ; - m_macFullScreenData = NULL ; - } - - return false; + return m_nowpeer->ShowFullScreen(show, style); } bool wxTopLevelWindowMac::IsFullScreen() const { - return m_macFullScreenData != NULL ; -} - -// Attracts the users attention to this window if the application is -// inactive (should be called when a background event occurs) - -static pascal void wxMacNMResponse( NMRecPtr ptr ) -{ - NMRemove( ptr ) ; - DisposePtr( (Ptr)ptr ) ; + return m_nowpeer->IsFullScreen(); } -void wxTopLevelWindowMac::RequestUserAttention(int WXUNUSED(flags)) +void wxTopLevelWindowMac::RequestUserAttention(int flags) { - NMRecPtr notificationRequest = (NMRecPtr) NewPtr( sizeof( NMRec) ) ; - static wxMacNMUPP nmupp( wxMacNMResponse ); - - memset( notificationRequest , 0 , sizeof(*notificationRequest) ) ; - notificationRequest->qType = nmType ; - notificationRequest->nmMark = 1 ; - notificationRequest->nmIcon = 0 ; - notificationRequest->nmSound = 0 ; - notificationRequest->nmStr = NULL ; - notificationRequest->nmResp = nmupp ; - - verify_noerr( NMInstall( notificationRequest ) ) ; + return m_nowpeer->RequestUserAttention(flags); } diff --git a/src/osx/carbon/uma.cpp b/src/osx/carbon/uma.cpp index 45610c21bf..7601f161a4 100644 --- a/src/osx/carbon/uma.cpp +++ b/src/osx/carbon/uma.cpp @@ -31,35 +31,9 @@ long UMAGetSystemVersion() return sUMASystemVersion ; } -void UMAInitToolbox( UInt16 WXUNUSED(inMoreMastersCalls), - bool WXUNUSED(isEmbedded) ) -{ -#if 0 // ndef __LP64__ - { - FontFamilyID fontId ; - Str255 fontName ; - SInt16 fontSize ; - Style fontStyle ; - - GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ; - GetFNum( fontName, &fontId ); - - TXNMacOSPreferredFontDescription fontDescriptions[] = - { - { fontId , (fontSize << 16) , kTXNDefaultFontStyle, kTXNSystemDefaultEncoding } - } ; - int noOfFontDescriptions = sizeof( fontDescriptions ) / sizeof(TXNMacOSPreferredFontDescription) ; - - OptionBits options = 0 ; - - TXNInitTextension( fontDescriptions, noOfFontDescriptions, options ); - } -#endif -} - // menu manager -#if 1 // not yet wxMAC_USE_COCOA == 0 +#if wxOSX_USE_CARBON MenuRef UMANewMenu( SInt16 id , const wxString& title , wxFontEncoding encoding ) { @@ -271,10 +245,6 @@ void UMAInsertMenuItem( MenuRef menu , const wxString& title, wxFontEncoding enc UMASetMenuItemShortcut( menu , item+1 , entry ) ; } -#endif - -#if 1 // not yet wxMAC_USE_COCOA == 0 - static OSStatus UMAGetHelpMenu( MenuRef * outHelpMenu, MenuItemIndex * outFirstCustomItemIndex, diff --git a/src/osx/carbon/utils.cpp b/src/osx/carbon/utils.cpp index 4192588d15..e996791800 100644 --- a/src/osx/carbon/utils.cpp +++ b/src/osx/carbon/utils.cpp @@ -9,6 +9,7 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// + #include "wx/wxprec.h" #include "wx/utils.h" @@ -24,10 +25,6 @@ #include "wx/apptrait.h" -#if wxUSE_GUI - #include "wx/osx/uma.h" -#endif - #include #include @@ -41,14 +38,12 @@ #include #endif +#include "wx/osx/private.h" #if wxUSE_GUI - #include - #include #include "wx/osx/private/timer.h" #endif // wxUSE_GUI #include "wx/evtloop.h" -#include "wx/osx/private.h" #if defined(__MWERKS__) && wxUSE_UNICODE #if __MWERKS__ < 0x4100 @@ -56,8 +51,20 @@ #endif #endif +// +// TODO BEGIN move to utils_osx.cpp +// + #if wxUSE_BASE +extern bool WXDLLEXPORT wxIsDebuggerRunning() +{ + // TODO : try to find out ... + return false; +} + +#if wxOSX_USE_COCOA_OR_CARBON + // our OS version is the same in non GUI and GUI cases wxOperatingSystemId wxGetOsVersion(int *majorVsn, int *minorVsn) { @@ -70,120 +77,42 @@ wxOperatingSystemId wxGetOsVersion(int *majorVsn, int *minorVsn) if ( minorVsn != NULL ) *minorVsn = (theSystem & 0xFF); -#if defined( __DARWIN__ ) return wxOS_MAC_OSX_DARWIN; -#else - return wxOS_MAC_OS; -#endif } -extern bool WXDLLEXPORT wxIsDebuggerRunning() -{ - // TODO : try to find out ... - return false; -} - -// Emit a beeeeeep -void wxBell() -{ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - if ( AudioServicesPlayAlertSound ) - AudioServicesPlayAlertSound(kUserPreferredAlert); - else -#endif -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - SysBeep(30); -#else - { - } -#endif -} - - -#endif // wxUSE_BASE - -#if wxUSE_GUI - -wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const -{ - // We suppose that toolkit version is the same as OS version under Mac - wxGetOsVersion(verMaj, verMin); - - return wxPORT_MAC; -} - -wxEventLoopBase* wxGUIAppTraits::CreateEventLoop() -{ - return new wxEventLoop; -} - -wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer) -{ - return new wxCarbonTimerImpl(timer); -} - -int gs_wxBusyCursorCount = 0; -extern wxCursor gMacCurrentCursor; -wxCursor gMacStoredActiveCursor; - -// Set the cursor to the busy cursor for all windows -void wxBeginBusyCursor(const wxCursor *cursor) -{ - if (gs_wxBusyCursorCount++ == 0) - { - gMacStoredActiveCursor = gMacCurrentCursor; - cursor->MacInstall(); - - wxSetCursor(*cursor); - } - //else: nothing to do, already set -} +#include -// Restore cursor to normal -void wxEndBusyCursor() +wxString wxGetOsDescription() { - wxCHECK_RET( gs_wxBusyCursorCount > 0, - wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") ); - - if (--gs_wxBusyCursorCount == 0) - { - gMacStoredActiveCursor.MacInstall(); - gMacStoredActiveCursor = wxNullCursor; - - wxSetCursor(wxNullCursor); - } + struct utsname name; + uname(&name); + return wxString::Format(_T("Mac OS X (%s %s %s)"), + wxString::FromAscii(name.sysname).c_str(), + wxString::FromAscii(name.release).c_str(), + wxString::FromAscii(name.machine).c_str()); } -// true if we're between the above two calls -bool wxIsBusy() -{ - return (gs_wxBusyCursorCount > 0); -} +#endif // wxOSX_USE_COCOA_OR_CARBON -#endif // wxUSE_GUI -#if wxUSE_BASE +//--------------------------------------------------------------------------- +// wxMac Specific utility functions +//--------------------------------------------------------------------------- -wxString wxMacFindFolderNoSeparator( short vol, - OSType folderType, - Boolean createFolder) +void wxMacStringToPascal( const wxString&from , StringPtr to ) { - FSRef fsRef; - wxString strDir; - - if ( FSFindFolder( vol, folderType, createFolder, &fsRef) == noErr) - { - strDir = wxMacFSRefToPath( &fsRef ); - } + wxCharBuffer buf = from.mb_str( wxConvLocal ); + int len = strlen(buf); - return strDir; + if ( len > 255 ) + len = 255; + to[0] = len; + memcpy( (char*) &to[1] , buf , len ); } -wxString wxMacFindFolder( short vol, - OSType folderType, - Boolean createFolder) +wxString wxMacMakeStringFromPascal( ConstStringPtr from ) { - return wxMacFindFolderNoSeparator(vol, folderType, createFolder) + wxFILE_SEP_PATH; + return wxString( (char*) &from[1] , wxConvLocal , from[0] ); } #endif // wxUSE_BASE @@ -198,41 +127,18 @@ bool wxCheckForInterrupt(wxWindow *WXUNUSED(wnd)) return false; } -void wxGetMousePosition( int* x, int* y ) -{ -#if wxMAC_USE_QUICKDRAW - Point pt; - GetGlobalMouse(&pt); - *x = pt.h; - *y = pt.v; -#else - // TODO -#endif -}; - // Return true if we have a colour display bool wxColourDisplay() { return true; } +#if wxOSX_USE_COCOA_OR_CARBON // Returns depth of screen int wxDisplayDepth() { -#if wxMAC_USE_QUICKDRAW int theDepth = (int) CGDisplayBitsPerPixel(CGMainDisplayID()); - Rect globRect; - SetRect(&globRect, -32760, -32760, 32760, 32760); - GDHandle theMaxDevice; - - theMaxDevice = GetMaxDevice(&globRect); - if (theMaxDevice != NULL) - theDepth = (**(**theMaxDevice).gdPMap).pixelSize; - return theDepth; -#else - return 32; // TODO -#endif } // Get size of display @@ -245,12 +151,13 @@ void wxDisplaySize(int *width, int *height) if ( height ) *height = (int)bounds.size.height; } +#endif void wxDisplaySizeMM(int *width, int *height) { wxDisplaySize(width, height); // on mac 72 is fixed (at least now;-) - float cvPt2Mm = 25.4 / 72; + double cvPt2Mm = 25.4 / 72; if (width != NULL) *width = int( *width * cvPt2Mm ); @@ -259,712 +166,340 @@ void wxDisplaySizeMM(int *width, int *height) *height = int( *height * cvPt2Mm ); } -void wxClientDisplayRect(int *x, int *y, int *width, int *height) -{ -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 -#if wxMAC_USE_QUICKDRAW - HIRect bounds ; - HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal, - &bounds); - if ( x ) - *x = bounds.origin.x; - if ( y ) - *y = bounds.origin.y; - if ( width ) - *width = bounds.size.width; - if ( height ) - *height = bounds.size.height; -#else - int w, h; - wxDisplaySize(&w,&h); - if ( x ) - *x = 0; - if ( y ) - *y = 24; - if ( width ) - *width = w; - if ( height ) - *height = h-24; -#endif -#else - Rect r; - GetAvailableWindowPositioningBounds( GetMainDevice() , &r ); - if ( x ) - *x = r.left; - if ( y ) - *y = r.top; - if ( width ) - *width = r.right - r.left; - if ( height ) - *height = r.bottom - r.top; -#endif -} - -wxWindow* wxFindWindowAtPoint(const wxPoint& pt) -{ - return wxGenericFindWindowAtPoint(pt); -} - -#endif // wxUSE_GUI - -#if wxUSE_BASE - -#include - -wxString wxGetOsDescription() +wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const { - struct utsname name; - uname(&name); - return wxString::Format(_T("Mac OS X (%s %s %s)"), - wxString::FromAscii(name.sysname).c_str(), - wxString::FromAscii(name.release).c_str(), - wxString::FromAscii(name.machine).c_str()); -} + // We suppose that toolkit version is the same as OS version under Mac + wxGetOsVersion(verMaj, verMin); -#ifndef __DARWIN__ -wxString wxGetUserHome (const wxString& user) -{ - // TODO - return wxString(); + return wxPORT_OSX; } -bool wxGetDiskSpace(const wxString& path, wxDiskspaceSize_t *pTotal, wxDiskspaceSize_t *pFree) +wxEventLoopBase* wxGUIAppTraits::CreateEventLoop() { - if ( path.empty() ) - return false; - - wxString p = path; - if (p[0u] == ':' ) - p = wxGetCwd() + p; - - int pos = p.Find(':'); - if ( pos != wxNOT_FOUND ) - p = p.Mid(1,pos); - - p = p + wxT(":"); - - OSErr err = noErr; - - FSRef fsRef; - err = wxMacPathToFSRef( p , &fsRef ); - if ( noErr == err ) - { - FSVolumeRefNum vRefNum; - err = FSGetVRefNum( &fsRef , &vRefNum ); - if ( noErr == err ) - { - UInt64 freeBytes , totalBytes; - err = FSGetVInfo( vRefNum , NULL , &freeBytes , &totalBytes ); - if ( noErr == err ) - { - if ( pTotal ) - *pTotal = wxDiskspaceSize_t( totalBytes ); - if ( pFree ) - *pFree = wxDiskspaceSize_t( freeBytes ); - } - } - } - - return err == noErr; + return new wxEventLoop; } -#endif // !__DARWIN__ -//--------------------------------------------------------------------------- -// wxMac Specific utility functions -//--------------------------------------------------------------------------- - -void wxMacStringToPascal( const wxString&from , StringPtr to ) +wxWindow* wxFindWindowAtPoint(const wxPoint& pt) { - wxCharBuffer buf = from.mb_str( wxConvLocal ); - int len = strlen(buf); - - if ( len > 255 ) - len = 255; - to[0] = len; - memcpy( (char*) &to[1] , buf , len ); + return wxGenericFindWindowAtPoint(pt); } -wxString wxMacMakeStringFromPascal( ConstStringPtr from ) -{ - return wxString( (char*) &from[1] , wxConvLocal , from[0] ); -} +/* + Return the generic RGB color space. This is a 'get' function and the caller should + not release the returned value unless the caller retains it first. Usually callers + of this routine will immediately use the returned colorspace with CoreGraphics + so they typically do not need to retain it themselves. -// ---------------------------------------------------------------------------- -// Common Event Support -// ---------------------------------------------------------------------------- + This function creates the generic RGB color space once and hangs onto it so it can + return it whenever this function is called. +*/ -void wxMacWakeUp() +CGColorSpaceRef wxMacGetGenericRGBColorSpace() { - OSStatus err = noErr; + static wxCFRef genericRGBColorSpace; -#if 0 - // lead sometimes to race conditions, although all calls used should be thread safe ... - static wxMacCarbonEvent s_wakeupEvent; - if ( !s_wakeupEvent.IsValid() ) - { - err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(), - kEventAttributeNone ); - } - if ( err == noErr ) + if (genericRGBColorSpace == NULL) { - - if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) ) - return; - s_wakeupEvent.SetCurrentTime(); - err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent, - kEventPriorityHigh ); - } +#if wxOSX_USE_IPHONE + genericRGBColorSpace.reset( CGColorSpaceCreateDeviceRGB() ); #else - wxMacCarbonEvent wakeupEvent; - wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(), - kEventAttributeNone ); - err = PostEventToQueue(GetMainEventQueue(), wakeupEvent, - kEventPriorityHigh ); -#endif -} - -#endif // wxUSE_BASE - -#if wxUSE_GUI - -// ---------------------------------------------------------------------------- -// Native Struct Conversions -// ---------------------------------------------------------------------------- - -void wxMacRectToNative( const wxRect *wx , Rect *n ) -{ - n->left = wx->x; - n->top = wx->y; - n->right = wx->x + wx->width; - n->bottom = wx->y + wx->height; -} - -void wxMacNativeToRect( const Rect *n , wxRect* wx ) -{ - wx->x = n->left; - wx->y = n->top; - wx->width = n->right - n->left; - wx->height = n->bottom - n->top; -} - -void wxMacPointToNative( const wxPoint* wx , Point *n ) -{ - n->h = wx->x; - n->v = wx->y; -} - -void wxMacNativeToPoint( const Point *n , wxPoint* wx ) -{ - wx->x = n->h; - wx->y = n->v; -} - -// ---------------------------------------------------------------------------- -// Carbon Event Support -// ---------------------------------------------------------------------------- - -OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData) -{ - return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData ); -} - -OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData) -{ - return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData ); -} - -// ---------------------------------------------------------------------------- -// Control Access Support -// ---------------------------------------------------------------------------- - -#if wxMAC_USE_QUICKDRAW - -IMPLEMENT_DYNAMIC_CLASS( wxMacControl , wxObject ) - -wxMacControl::wxMacControl() -{ - Init(); -} - -wxMacControl::wxMacControl(wxWindow* peer , bool isRootControl ) -{ - Init(); - m_peer = peer; - m_isRootControl = isRootControl; -} - -wxMacControl::wxMacControl( wxWindow* peer , ControlRef control ) -{ - Init(); - m_peer = peer; - m_controlRef = control; -} - -wxMacControl::wxMacControl( wxWindow* peer , WXWidget control ) -{ - Init(); - m_peer = peer; - m_controlRef = (ControlRef) control; -} - -wxMacControl::~wxMacControl() -{ -} - -void wxMacControl::Init() -{ - m_peer = NULL; - m_controlRef = NULL; - m_needsFocusRect = false; - m_isRootControl = false; -} - -void wxMacControl::Dispose() -{ - wxASSERT_MSG( m_controlRef != NULL , wxT("Control Handle already NULL, Dispose called twice ?") ); - wxASSERT_MSG( IsValidControlHandle(m_controlRef) , wxT("Invalid Control Handle (maybe already released) in Dispose") ); - - // we cannot check the ref count here anymore, as autorelease objects might delete their refs later - // we can have situations when being embedded, where the control gets deleted behind our back, so only - // CFRelease if we are safe - if ( IsValidControlHandle(m_controlRef) ) - CFRelease(m_controlRef); - m_controlRef = NULL; -} - -void wxMacControl::SetReference( URefCon data ) -{ - SetControlReference( m_controlRef , data ); -} - -OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const -{ - return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize ); -} - -OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const -{ - return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize ); -} - -OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData) -{ - return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData ); -} - -OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions ) -{ - return SendEventToEventTargetWithOptions( event, - HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions ); -} - -OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions ) -{ - wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ); - - event.SetParameter(kEventParamDirectObject,command); - - return SendEvent( event , inOptions ); -} - -OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions ) -{ - HICommand command; - - memset( &command, 0 , sizeof(command) ); - command.commandID = commandID; - return SendHICommand( command , inOptions ); -} - -void wxMacControl::Flash( ControlPartCode part , UInt32 ticks ) -{ - unsigned long finalTicks; - - HiliteControl( m_controlRef , part ); - Delay( ticks , &finalTicks ); - HiliteControl( m_controlRef , kControlNoPart ); -} - -SInt32 wxMacControl::GetValue() const -{ - return ::GetControl32BitValue( m_controlRef ); -} - -SInt32 wxMacControl::GetMaximum() const -{ - return ::GetControl32BitMaximum( m_controlRef ); -} - -SInt32 wxMacControl::GetMinimum() const -{ - return ::GetControl32BitMinimum( m_controlRef ); -} - -void wxMacControl::SetValue( SInt32 v ) -{ - ::SetControl32BitValue( m_controlRef , v ); -} - -void wxMacControl::SetMinimum( SInt32 v ) -{ - ::SetControl32BitMinimum( m_controlRef , v ); -} - -void wxMacControl::SetMaximum( SInt32 v ) -{ - ::SetControl32BitMaximum( m_controlRef , v ); -} - -void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum ) -{ - ::SetControl32BitMinimum( m_controlRef , minimum ); - ::SetControl32BitMaximum( m_controlRef , maximum ); - ::SetControl32BitValue( m_controlRef , value ); -} - -OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart ) -{ - return SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, focusPart ); -} - -bool wxMacControl::HasFocus() const -{ - ControlRef control; - GetKeyboardFocus( GetUserFocusWindow() , &control ); - return control == m_controlRef; -} - -void wxMacControl::SetNeedsFocusRect( bool needs ) -{ - m_needsFocusRect = needs; -} - -bool wxMacControl::NeedsFocusRect() const -{ - return m_needsFocusRect; -} - -void wxMacControl::VisibilityChanged(bool WXUNUSED(shown)) -{ -} - -void wxMacControl::SuperChangedPosition() -{ -} - -void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle ) -{ - m_font = font; -#if wxMAC_USE_CORE_TEXT - if ( UMAGetSystemVersion() >= 0x1050 ) - { - HIViewPartCode part = 0; - HIThemeTextHorizontalFlush flush = kHIThemeTextHorizontalFlushDefault; - if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL ) - flush = kHIThemeTextHorizontalFlushCenter; - else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT ) - flush = kHIThemeTextHorizontalFlushRight; - HIViewSetTextFont( m_controlRef , part , (CTFontRef) font.MacGetCTFont() ); - HIViewSetTextHorizontalFlush( m_controlRef, part, flush ); - - if ( foreground != *wxBLACK ) - { - ControlFontStyleRec fontStyle; - foreground.GetRGBColor( &fontStyle.foreColor ); - fontStyle.flags = kControlUseForeColorMask; - ::SetControlFontStyle( m_controlRef , &fontStyle ); - } - - } + genericRGBColorSpace.reset( CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ) ); #endif -#if wxMAC_USE_ATSU_TEXT - ControlFontStyleRec fontStyle; - if ( font.MacGetThemeFontID() != kThemeCurrentPortFont ) - { - switch ( font.MacGetThemeFontID() ) - { - case kThemeSmallSystemFont : - fontStyle.font = kControlFontSmallSystemFont; - break; - - case 109 : // mini font - fontStyle.font = -5; - break; - - case kThemeSystemFont : - fontStyle.font = kControlFontBigSystemFont; - break; - - default : - fontStyle.font = kControlFontBigSystemFont; - break; - } - - fontStyle.flags = kControlUseFontMask; - } - else - { - fontStyle.font = font.MacGetFontNum(); - fontStyle.style = font.MacGetFontStyle(); - fontStyle.size = font.MacGetFontSize(); - fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask; - } - - fontStyle.just = teJustLeft; - fontStyle.flags |= kControlUseJustMask; - if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL ) - fontStyle.just = teJustCenter; - else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT ) - fontStyle.just = teJustRight; - - - // we only should do this in case of a non-standard color, as otherwise 'disabled' controls - // won't get grayed out by the system anymore - - if ( foreground != *wxBLACK ) - { - foreground.GetRGBColor( &fontStyle.foreColor ); - fontStyle.flags |= kControlUseForeColorMask; } - ::SetControlFontStyle( m_controlRef , &fontStyle ); -#endif + return genericRGBColorSpace; } -void wxMacControl::SetBackgroundColour( const wxColour &WXUNUSED(col) ) -{ -// HITextViewSetBackgroundColor( m_textView , color ); -} +#if wxOSX_USE_COCOA_OR_CARBON -void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum ) +CGColorRef wxMacCreateCGColorFromHITheme( ThemeBrush brush ) { - ::SetControl32BitMinimum( m_controlRef , minimum ); - ::SetControl32BitMaximum( m_controlRef , maximum ); + CGColorRef color ; + HIThemeBrushCreateCGColor( brush, &color ); + return color; } -short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers ) -{ -#ifndef __LP64__ - return HandleControlKey( m_controlRef , keyCode , charCode , modifiers ); -#else - return 0; -#endif -} +#endif // wxOSX_USE_COCOA_OR_CARBON -void wxMacControl::SetActionProc( ControlActionUPP actionProc ) -{ - SetControlAction( m_controlRef , actionProc ); -} +IMPLEMENT_ABSTRACT_CLASS( wxWidgetImpl , wxObject ) -void wxMacControl::SetViewSize( SInt32 viewSize ) +wxWidgetImpl::wxWidgetImpl( wxWindowMac* peer , bool isRootControl ) { - SetControlViewSize(m_controlRef , viewSize ); + Init(); + m_isRootControl = isRootControl; + m_wxPeer = peer; } -SInt32 wxMacControl::GetViewSize() const +wxWidgetImpl::wxWidgetImpl() { - return GetControlViewSize( m_controlRef ); + Init(); } -bool wxMacControl::IsVisible() const +wxWidgetImpl::~wxWidgetImpl() { - return IsControlVisible( m_controlRef ); } -void wxMacControl::SetVisibility( bool visible , bool redraw ) +void wxWidgetImpl::Init() { - SetControlVisibility( m_controlRef , visible , redraw ); + m_isRootControl = false; + m_wxPeer = NULL; + m_needsFocusRect = false; } -bool wxMacControl::IsEnabled() const +void wxWidgetImpl::Destroy() { - return IsControlEnabled( m_controlRef ); } -bool wxMacControl::IsActive() const +void wxWidgetImpl::SetNeedsFocusRect( bool needs ) { - return IsControlActive( m_controlRef ); + m_needsFocusRect = needs; } -void wxMacControl::Enable( bool enable ) +bool wxWidgetImpl::NeedsFocusRect() const { - if ( enable ) - EnableControl( m_controlRef ); - else - DisableControl( m_controlRef ); + return m_needsFocusRect; } -void wxMacControl::SetDrawingEnabled( bool enable ) -{ - HIViewSetDrawingEnabled( m_controlRef , enable ); -} +#endif // wxUSE_GUI -bool wxMacControl::GetNeedsDisplay() const -{ - return HIViewGetNeedsDisplay( m_controlRef ); -} +// +// TODO END move to utils_osx.cpp +// -void wxMacControl::SetNeedsDisplay( RgnHandle where ) -{ - if ( !IsVisible() ) - return; +// +// carbon version +// - HIViewSetNeedsDisplayInRegion( m_controlRef , where , true ); -} +#if wxOSX_USE_CARBON -void wxMacControl::SetNeedsDisplay( Rect* where ) -{ - if ( !IsVisible() ) - return; +#if wxUSE_BASE - if ( where != NULL ) +// Emit a beeeeeep +void wxBell() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( AudioServicesPlayAlertSound != NULL ) + AudioServicesPlayAlertSound(kUserPreferredAlert); + else +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + SysBeep(30); +#else { - RgnHandle update = NewRgn(); - RectRgn( update , where ); - HIViewSetNeedsDisplayInRegion( m_controlRef , update , true ); - DisposeRgn( update ); } - else - HIViewSetNeedsDisplay( m_controlRef , true ); +#endif } -void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to ) -{ - HIPoint hiPoint; +#endif // wxUSE_BASE - hiPoint.x = pt->x; - hiPoint.y = pt->y; - HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef ); - pt->x = (int)hiPoint.x; - pt->y = (int)hiPoint.y; -} +#if wxUSE_GUI -void wxMacControl::SetRect( Rect *r ) +wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer) { - //A HIRect is actually a CGRect on OSX - which consists of two structures - - //CGPoint and CGSize, which have two floats each - HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } }; - HIViewSetFrame ( m_controlRef , &hir ); - // eventuall we might have to do a SetVisibility( false , true ); - // before and a SetVisibility( true , true ); after + return new wxCarbonTimerImpl(timer); } -void wxMacControl::GetRect( Rect *r ) +int gs_wxBusyCursorCount = 0; +extern wxCursor gMacCurrentCursor; +wxCursor gMacStoredActiveCursor; + +// Set the cursor to the busy cursor for all windows +void wxBeginBusyCursor(const wxCursor *cursor) { - GetControlBounds( m_controlRef , r ); + if (gs_wxBusyCursorCount++ == 0) + { + gMacStoredActiveCursor = gMacCurrentCursor; + cursor->MacInstall(); + + wxSetCursor(*cursor); + } + //else: nothing to do, already set } -void wxMacControl::GetRectInWindowCoords( Rect *r ) +// Restore cursor to normal +void wxEndBusyCursor() { - GetControlBounds( m_controlRef , r ) ; - - WindowRef tlwref = GetControlOwner( m_controlRef ) ; + wxCHECK_RET( gs_wxBusyCursorCount > 0, + wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") ); - wxNonOwnedWindow* tlwwx = wxFindWinFromMacWindow( tlwref ) ; - if ( tlwwx != NULL ) + if (--gs_wxBusyCursorCount == 0) { - ControlRef rootControl = tlwwx->GetPeer()->GetControlRef() ; - HIPoint hiPoint = CGPointMake( 0 , 0 ) ; - HIViewConvertPoint( &hiPoint , HIViewGetSuperview(m_controlRef) , rootControl ) ; - OffsetRect( r , (short) hiPoint.x , (short) hiPoint.y ) ; + gMacStoredActiveCursor.MacInstall(); + gMacStoredActiveCursor = wxNullCursor; + + wxSetCursor(wxNullCursor); } } -void wxMacControl::GetBestRect( Rect *r ) +// true if we're between the above two calls +bool wxIsBusy() { - short baselineoffset; - - GetBestControlRect( m_controlRef , r , &baselineoffset ); + return (gs_wxBusyCursorCount > 0); } -void wxMacControl::SetLabel( const wxString &title ) +#endif // wxUSE_GUI + +#if wxUSE_BASE + +wxString wxMacFindFolderNoSeparator( short vol, + OSType folderType, + Boolean createFolder) { - wxFontEncoding encoding; + FSRef fsRef; + wxString strDir; - if ( m_font.Ok() ) - encoding = m_font.GetEncoding(); - else - encoding = wxFont::GetDefaultEncoding(); + if ( FSFindFolder( vol, folderType, createFolder, &fsRef) == noErr) + { + strDir = wxMacFSRefToPath( &fsRef ); + } - SetControlTitleWithCFString( m_controlRef , wxCFStringRef( title , encoding ) ); + return strDir; } -void wxMacControl::GetFeatures( UInt32 * features ) +wxString wxMacFindFolder( short vol, + OSType folderType, + Boolean createFolder) { - GetControlFeatures( m_controlRef , features ); + return wxMacFindFolderNoSeparator(vol, folderType, createFolder) + wxFILE_SEP_PATH; } -OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region ) +#endif // wxUSE_BASE + +#if wxUSE_GUI + +void wxGetMousePosition( int* x, int* y ) { - OSStatus err = GetControlRegion( m_controlRef , partCode , region ); - return err; -} + Point pt; + GetGlobalMouse(&pt); + if ( x ) + *x = pt.h; + if ( y ) + *y = pt.v; +}; -OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other ) +void wxClientDisplayRect(int *x, int *y, int *width, int *height) { - return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow, - (other != NULL) ? other->m_controlRef : NULL); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + HIRect bounds ; + HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal, + &bounds); + if ( x ) + *x = bounds.origin.x; + if ( y ) + *y = bounds.origin.y; + if ( width ) + *width = bounds.size.width; + if ( height ) + *height = bounds.size.height; +#else + Rect r; + GetAvailableWindowPositioningBounds( GetMainDevice() , &r ); + if ( x ) + *x = r.left; + if ( y ) + *y = r.top; + if ( width ) + *width = r.right - r.left; + if ( height ) + *height = r.bottom - r.top; +#endif } -// SetNeedsDisplay would not invalidate the children -static void InvalidateControlAndChildren( HIViewRef control ) -{ - HIViewSetNeedsDisplay( control , true ); - UInt16 childrenCount = 0; - OSStatus err = CountSubControls( control , &childrenCount ); - if ( err == errControlIsNotEmbedder ) - return; +#endif // wxUSE_GUI + +#if wxUSE_BASE +// ---------------------------------------------------------------------------- +// Common Event Support +// ---------------------------------------------------------------------------- - wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ); +void wxMacWakeUp() +{ + OSStatus err = noErr; - for ( UInt16 i = childrenCount; i >=1; --i ) +#if wxOSX_USE_CARBON +#if 0 + // lead sometimes to race conditions, although all calls used should be thread safe ... + static wxMacCarbonEvent s_wakeupEvent; + if ( !s_wakeupEvent.IsValid() ) + { + err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(), + kEventAttributeNone ); + } + if ( err == noErr ) { - HIViewRef child; - err = GetIndexedSubControl( control , i , & child ); - if ( err == errControlIsNotEmbedder ) + if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) ) return; - - InvalidateControlAndChildren( child ); + s_wakeupEvent.SetCurrentTime(); + err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent, + kEventPriorityHigh ); } +#else + wxMacCarbonEvent wakeupEvent; + wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(), + kEventAttributeNone ); + err = PostEventToQueue(GetMainEventQueue(), wakeupEvent, + kEventPriorityHigh ); +#endif +#endif +} + +#endif // wxUSE_BASE + +#if wxUSE_GUI + +// ---------------------------------------------------------------------------- +// Native Struct Conversions +// ---------------------------------------------------------------------------- + +void wxMacRectToNative( const wxRect *wx , Rect *n ) +{ + n->left = wx->x; + n->top = wx->y; + n->right = wx->x + wx->width; + n->bottom = wx->y + wx->height; } -void wxMacControl::InvalidateWithChildren() +void wxMacNativeToRect( const Rect *n , wxRect* wx ) { - InvalidateControlAndChildren( m_controlRef ); + wx->x = n->left; + wx->y = n->top; + wx->width = n->right - n->left; + wx->height = n->bottom - n->top; } -void wxMacControl::ScrollRect( wxRect *r , int dx , int dy ) +void wxMacPointToNative( const wxPoint* wx , Point *n ) { - wxASSERT( r != NULL ); + n->h = wx->x; + n->v = wx->y; +} - HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height); - HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ); +void wxMacNativeToPoint( const Point *n , wxPoint* wx ) +{ + wx->x = n->h; + wx->y = n->v; } -OSType wxMacCreator = 'WXMC'; -OSType wxMacControlProperty = 'MCCT'; +// ---------------------------------------------------------------------------- +// Carbon Event Support +// ---------------------------------------------------------------------------- -void wxMacControl::SetReferenceInNativeControl() +OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData) { - void * data = this; - verify_noerr( SetControlProperty ( m_controlRef , - wxMacCreator,wxMacControlProperty, sizeof(data), &data ) ); + return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData ); } -wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control) +OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData) { - wxMacControl* ctl = NULL; - ByteCount actualSize; - if ( GetControlProperty( control ,wxMacCreator,wxMacControlProperty, sizeof(ctl) , - &actualSize , &ctl ) == noErr ) - { - return ctl; - } - return NULL; + return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData ); } +// ---------------------------------------------------------------------------- +// Control Access Support +// ---------------------------------------------------------------------------- + + // ============================================================================ // DataBrowser Wrapper // ============================================================================ @@ -1919,7 +1454,7 @@ void wxMacDataItemBrowserControl::MacScrollTo( unsigned int n ) UInt32 linetop = n * ((UInt32) height ); UInt32 linebottom = linetop + height; Rect rect ; - GetRect( &rect ); + GetControlBounds( m_controlRef, &rect ); if ( linetop < top || linebottom > (top + rect.bottom - rect.top ) ) SetScrollPosition( wxMax( n-2, 0 ) * ((UInt32)height) , left ) ; @@ -1927,84 +1462,6 @@ void wxMacDataItemBrowserControl::MacScrollTo( unsigned int n ) RevealItem( item , kDataBrowserRevealWithoutSelecting ); } - - -// -// Tab Control -// - -OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable ) -{ - return ::SetTabEnabled( m_controlRef , tabNo , enable ); -} - -#endif - -// -// Quartz Support -// - -/* - Return the generic RGB color space. This is a 'get' function and the caller should - not release the returned value unless the caller retains it first. Usually callers - of this routine will immediately use the returned colorspace with CoreGraphics - so they typically do not need to retain it themselves. - - This function creates the generic RGB color space once and hangs onto it so it can - return it whenever this function is called. -*/ - -CGColorSpaceRef wxMacGetGenericRGBColorSpace() -{ - static wxCFRef genericRGBColorSpace; - - if (genericRGBColorSpace == NULL) - { - genericRGBColorSpace.reset( CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ) ); - } - - return genericRGBColorSpace; -} - -CGColorRef wxMacCreateCGColorFromHITheme( ThemeBrush brush ) -{ - CGColorRef color ; - HIThemeBrushCreateCGColor( brush, &color ); - return color; -} - -#if wxMAC_USE_QUICKDRAW - -static inline void PointFromHIPoint(const HIPoint& p, Point *pt) -{ - pt->h = wx_static_cast(short, p.x); - pt->v = wx_static_cast(short, p.y); -} - -void wxMacGlobalToLocal( WindowRef window , Point*pt ) -{ - HIPoint p = CGPointMake( pt->h, pt->v ); - HIViewRef contentView ; - // TODO check toolbar offset - HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ; - HIPointConvert( &p, kHICoordSpace72DPIGlobal, NULL, kHICoordSpaceView, contentView ); - PointFromHIPoint(p, pt); -} - -void wxMacLocalToGlobal( WindowRef window , Point*pt ) -{ - HIPoint p = CGPointMake( pt->h, pt->v ); - HIViewRef contentView ; - // TODO check toolbar offset - HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ; - HIPointConvert( &p, kHICoordSpaceView, contentView, kHICoordSpace72DPIGlobal, NULL ); - PointFromHIPoint(p, pt); -} - -#endif // wxMAC_USE_QUICKDRAW - #endif // wxUSE_GUI -#if wxUSE_BASE - -#endif +#endif // wxOSX_USE_CARBON diff --git a/src/osx/carbon/utilscocoa.mm b/src/osx/carbon/utilscocoa.mm index 07c34d5630..4fdf07c240 100644 --- a/src/osx/carbon/utilscocoa.mm +++ b/src/osx/carbon/utilscocoa.mm @@ -11,7 +11,11 @@ #include "wx/wxprec.h" +#if wxOSX_USE_COCOA_OR_CARBON #include +#else +#import +#endif #ifdef __WXMAC__ #include "wx/osx/private.h" @@ -19,12 +23,14 @@ #ifdef __WXMAC__ +#if wxOSX_USE_CARBON bool wxMacInitCocoa() { bool cocoaLoaded = NSApplicationLoad(); wxASSERT_MSG(cocoaLoaded,wxT("Couldn't load Cocoa in Carbon Environment")) ; return cocoaLoaded; } +#endif wxMacAutoreleasePool::wxMacAutoreleasePool() { @@ -38,7 +44,7 @@ wxMacAutoreleasePool::~wxMacAutoreleasePool() #endif -#ifdef __WXCOCOCA__ +#if defined( __WXCOCOCA__ ) || wxOSX_USE_COCOA CGContextRef wxMacGetContextFromCurrentNSContext() { @@ -68,6 +74,8 @@ void wxMacCocoaRetain( void* obj ) [(NSObject*)obj retain]; } +#if wxOSX_USE_COCOA + // ---------------------------------------------------------------------------- // NSImage Utils // ---------------------------------------------------------------------------- @@ -97,8 +105,6 @@ WX_NSImage CreateNSImageFromCGImage( CGImageRef image ) // NSCursor Utils // ---------------------------------------------------------------------------- -#if wxMAC_USE_COCOA - // copied from cursor.mm static NSCursor* wxGetStockCursor( short sIndex ) @@ -302,3 +308,4 @@ void wxMacCocoaShowCursor() } #endif + diff --git a/src/osx/carbon/window.cpp b/src/osx/carbon/window.cpp index 20619b2b08..732447328b 100644 --- a/src/osx/carbon/window.cpp +++ b/src/osx/carbon/window.cpp @@ -61,7 +61,11 @@ #include "wx/dnd.h" #endif +#if wxOSX_USE_CARBON #include "wx/osx/uma.h" +#else +#include "wx/osx/private.h" +#endif #define MAC_SCROLLBAR_SIZE 15 #define MAC_SMALL_SCROLLBAR_SIZE 11 @@ -86,6 +90,168 @@ END_EVENT_TABLE() #define wxMAC_DEBUG_REDRAW 0 #endif +// +// TODO BEGIN move to window_osx.cpp +// +// =========================================================================== +// implementation +// =========================================================================== + +WX_DECLARE_HASH_MAP(WXWidget, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap); + +static MacControlMap wxWinMacControlList; + +wxWindowMac *wxFindWindowFromWXWidget(WXWidget inControl ) +{ + MacControlMap::iterator node = wxWinMacControlList.find(inControl); + + return (node == wxWinMacControlList.end()) ? NULL : node->second; +} + +void wxAssociateWindowWithWXWidget(WXWidget inControl, wxWindow *control) +{ + // adding NULL ControlRef is (first) surely a result of an error and + // (secondly) breaks native event processing + wxCHECK_RET( inControl != (WXWidget) NULL, wxT("attempt to add a NULL WindowRef to window list") ); + + wxWinMacControlList[inControl] = control; +} + +void wxRemoveWXWidgetAssociation(wxWindow *control) +{ + // iterate over all the elements in the class + // is the iterator stable ? as we might have two associations pointing to the same wxWindow + // we should go on... + + bool found = true ; + while ( found ) + { + found = false ; + MacControlMap::iterator it; + for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it ) + { + if ( it->second == control ) + { + wxWinMacControlList.erase(it); + found = true ; + break; + } + } + } +} + +// ---------------------------------------------------------------------------- + // constructors and such +// ---------------------------------------------------------------------------- + +wxWindowMac::wxWindowMac() +{ + Init(); +} + +wxWindowMac::wxWindowMac(wxWindowMac *parent, + wxWindowID id, + const wxPoint& pos , + const wxSize& size , + long style , + const wxString& name ) +{ + Init(); + Create(parent, id, pos, size, style, name); +} + +void wxWindowMac::Init() +{ + m_peer = NULL ; + m_macAlpha = 255 ; + m_cgContextRef = NULL ; + + // as all windows are created with WS_VISIBLE style... + m_isShown = true; + + m_hScrollBar = NULL ; + m_vScrollBar = NULL ; + m_hScrollBarAlwaysShown = false; + m_vScrollBarAlwaysShown = false; + + m_macIsUserPane = true; + m_clipChildren = false ; + m_cachedClippedRectValid = false ; +} + +wxWindowMac::~wxWindowMac() +{ + SendDestroyEvent(); + + m_isBeingDeleted = true; + + MacInvalidateBorders() ; + +#ifndef __WXUNIVERSAL__ + // VS: make sure there's no wxFrame with last focus set to us: + for ( wxWindow *win = GetParent(); win; win = win->GetParent() ) + { + wxFrame *frame = wxDynamicCast(win, wxFrame); + if ( frame ) + { + if ( frame->GetLastFocus() == this ) + frame->SetLastFocus((wxWindow*)NULL); + break; + } + } +#endif + + // destroy children before destroying this window itself + DestroyChildren(); + + // wxRemoveMacControlAssociation( this ) ; + // If we delete an item, we should initialize the parent panel, + // because it could now be invalid. + wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent((wxWindow*)this), wxTopLevelWindow); + if ( tlw ) + { + if ( tlw->GetDefaultItem() == (wxButton*) this) + tlw->SetDefaultItem(NULL); + } + + if ( m_peer && m_peer->IsOk() ) + { + m_peer->Destroy() ; + } + + if ( g_MacLastWindow == this ) + g_MacLastWindow = NULL ; + +#ifndef __WXUNIVERSAL__ + wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ; + if ( frame ) + { + if ( frame->GetLastFocus() == this ) + frame->SetLastFocus( NULL ) ; + } +#endif + + // delete our drop target if we've got one +#if wxUSE_DRAG_AND_DROP + if ( m_dropTarget != NULL ) + { + delete m_dropTarget; + m_dropTarget = NULL; + } +#endif + + delete m_peer ; +} + +WXWidget wxWindowMac::GetHandle() const +{ + return (WXWidget) m_peer->GetWXWidget() ; +} + +// +// TODO END move to window_osx.cpp +// + // --------------------------------------------------------------------------- // Utility Routines to move between different coordinate systems // --------------------------------------------------------------------------- @@ -105,3173 +271,3400 @@ END_EVENT_TABLE() */ // -// originating from native control // - -void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle ) +// Constructor +bool wxWindowMac::Create(wxWindowMac *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { - OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ; -} + wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") ); -void wxMacNativeToWindow( const wxWindow* window , Rect *rect ) -{ - OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ; -} + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) + return false; -// -// directed towards native control -// + m_windowVariant = parent->GetWindowVariant() ; -void wxMacWindowToNative( const wxWindow* window , RgnHandle handle ) -{ - OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ); + if ( m_macIsUserPane ) + { +#if wxOSX_USE_CARBON + m_peer = (wxMacControl*) wxWidgetImpl::CreateUserPane( this, pos, size , style, GetExtraStyle() , name ); +#else + m_peer = wxWidgetImpl::CreateUserPane( this, pos, size , style, GetExtraStyle() , name ); +#endif + MacPostControlCreate(pos, size) ; + } + +#ifndef __WXUNIVERSAL__ + // Don't give scrollbars to wxControls unless they ask for them + if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) + || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL)))) + { + MacCreateScrollBars( style ) ; + } +#endif + + wxWindowCreateEvent event((wxWindow*)this); + GetEventHandler()->AddPendingEvent(event); + + return true; } -void wxMacWindowToNative( const wxWindow* window , Rect *rect ) +void wxWindowMac::MacChildAdded() { - OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ; + if ( m_vScrollBar ) + m_vScrollBar->Raise() ; + if ( m_hScrollBar ) + m_hScrollBar->Raise() ; } -// --------------------------------------------------------------------------- -// Carbon Events -// --------------------------------------------------------------------------- - -static const EventTypeSpec eventList[] = +void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size) { - { kEventClassCommand, kEventProcessCommand } , - { kEventClassCommand, kEventCommandUpdateStatus } , - - { kEventClassControl , kEventControlGetClickActivation } , - { kEventClassControl , kEventControlHit } , - - { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } , - { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } , + wxASSERT_MSG( m_peer != NULL && m_peer->IsOk() , wxT("No valid mac control") ) ; - { kEventClassControl , kEventControlDraw } , +#if wxOSX_USE_CARBON + m_peer->SetReference( (URefCon) this ) ; +#endif - { kEventClassControl , kEventControlVisibilityChanged } , - { kEventClassControl , kEventControlEnabledStateChanged } , - { kEventClassControl , kEventControlHiliteChanged } , + GetParent()->AddChild( this ); - { kEventClassControl , kEventControlActivate } , - { kEventClassControl , kEventControlDeactivate } , +#if wxOSX_USE_CARBON + m_peer->InstallEventHandler(); - { kEventClassControl , kEventControlSetFocusPart } , - { kEventClassControl , kEventControlFocusPartChanged } , + ControlRef container = (ControlRef) GetParent()->GetHandle() ; + wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; + ::EmbedControl( m_peer->GetControlRef() , container ) ; +#endif + GetParent()->MacChildAdded() ; - { kEventClassService , kEventServiceGetTypes }, - { kEventClassService , kEventServiceCopy }, - { kEventClassService , kEventServicePaste }, + // adjust font, controlsize etc + DoSetWindowVariant( m_windowVariant ) ; +#if wxOSX_USE_CARBON + m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; +#endif + if (!m_macIsUserPane) + SetInitialSize(size); -// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only -// { kEventClassControl , kEventControlBoundsChanged } , -} ; + SetCursor( *wxSTANDARD_CURSOR ) ; +} -static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) { - OSStatus result = eventNotHandledErr ; - static wxWindowMac* targetFocusWindow = NULL; - static wxWindowMac* formerFocusWindow = NULL; + // Don't assert, in case we set the window variant before + // the window is created + // wxASSERT( m_peer->Ok() ) ; - wxMacCarbonEvent cEvent( event ) ; + m_windowVariant = variant ; - ControlRef controlRef ; - wxWindowMac* thisWindow = (wxWindowMac*) data ; + if (m_peer == NULL || !m_peer->IsOk()) + return; - cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; +#if wxOSX_USE_COCOA_OR_CARBON - switch ( GetEventKind( event ) ) - { - case kEventControlDraw : - { - RgnHandle updateRgn = NULL ; - RgnHandle allocatedRgn = NULL ; - wxRegion visRegion = thisWindow->MacGetVisibleRegion() ; + ControlSize size ; + ThemeFontID themeFont = kThemeSystemFont ; - if ( cEvent.GetParameter(kEventParamRgnHandle, &updateRgn) != noErr ) - { - HIShapeGetAsQDRgn( visRegion.GetWXHRGN(), updateRgn ); - } - else - { - if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 ) - { - // as this update region is in native window locals we must adapt it to wx window local - allocatedRgn = NewRgn() ; - CopyRgn( updateRgn , allocatedRgn ) ; + // we will get that from the settings later + // and make this NORMAL later, but first + // we have a few calculations that we must fix - // hide the given region by the new region that must be shifted - wxMacNativeToWindow( thisWindow , allocatedRgn ) ; - updateRgn = allocatedRgn ; - } - } + switch ( variant ) + { + case wxWINDOW_VARIANT_NORMAL : + size = kControlSizeNormal; + themeFont = kThemeSystemFont ; + break ; -#if wxMAC_DEBUG_REDRAW - if ( thisWindow->MacIsUserPane() ) - { - static float color = 0.5 ; - static int channel = 0 ; - HIRect bounds; - CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; + case wxWINDOW_VARIANT_SMALL : + size = kControlSizeSmall; + themeFont = kThemeSmallSystemFont ; + break ; - HIViewGetBounds( controlRef, &bounds ); - CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 , - channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 ); - CGContextFillRect( cgContext, bounds ); - color += 0.1 ; - if ( color > 0.9 ) - { - color = 0.5 ; - channel++ ; - if ( channel == 3 ) - channel = 0 ; - } - } -#endif + case wxWINDOW_VARIANT_MINI : + // not always defined in the headers + size = 3 ; + themeFont = 109 ; + break ; - { - bool created = false ; - CGContextRef cgContext = NULL ; - OSStatus err = cEvent.GetParameter(kEventParamCGContextRef, &cgContext) ; - if ( err != noErr ) - { - wxFAIL_MSG("Unable to retrieve CGContextRef"); - } + case wxWINDOW_VARIANT_LARGE : + size = kControlSizeLarge; + themeFont = kThemeSystemFont ; + break ; - thisWindow->MacSetCGContextRef( cgContext ) ; + default: + wxFAIL_MSG(_T("unexpected window variant")); + break ; + } - { - wxMacCGContextStateSaver sg( cgContext ) ; - CGFloat alpha = (CGFloat)1.0 ; - { - wxWindow* iter = thisWindow ; - while ( iter ) - { - alpha *= (CGFloat)( iter->GetTransparent()/255.0 ) ; - if ( iter->IsTopLevel() ) - iter = NULL ; - else - iter = iter->GetParent() ; - } - } - CGContextSetAlpha( cgContext , alpha ) ; +#if wxOSX_USE_CARBON + m_peer->SetData(kControlEntireControl, kControlSizeTag, &size ) ; +#endif - if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) - { - HIRect bounds; - HIViewGetBounds( controlRef, &bounds ); - CGContextClearRect( cgContext, bounds ); - } + wxFont font ; + font.MacCreateFromThemeFont( themeFont ) ; + SetFont( font ) ; +#endif +} +void wxWindowMac::MacUpdateControlFont() +{ +#if wxOSX_USE_CARBON + m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; +#endif + // do not trigger refreshes upon invisible and possible partly created objects + if ( IsShownOnScreen() ) + Refresh() ; +} +bool wxWindowMac::SetFont(const wxFont& font) +{ + bool retval = wxWindowBase::SetFont( font ); - if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) - result = noErr ; + MacUpdateControlFont() ; - thisWindow->MacSetCGContextRef( NULL ) ; - } + return retval; +} - if ( created ) - CGContextRelease( cgContext ) ; - } +bool wxWindowMac::SetForegroundColour(const wxColour& col ) +{ + bool retval = wxWindowBase::SetForegroundColour( col ); - if ( allocatedRgn ) - DisposeRgn( allocatedRgn ) ; - } - break ; + if (retval) + MacUpdateControlFont(); - case kEventControlVisibilityChanged : - // we might have two native controls attributed to the same wxWindow instance - // eg a scrollview and an embedded textview, make sure we only fire for the 'outer' - // control, as otherwise native and wx visibility are different - if ( thisWindow->GetPeer() != NULL && thisWindow->GetPeer()->GetControlRef() == controlRef ) - { - thisWindow->MacVisibilityChanged() ; - } - break ; + return retval; +} - case kEventControlEnabledStateChanged : - thisWindow->MacEnabledStateChanged(); - break ; +bool wxWindowMac::SetBackgroundColour(const wxColour& col ) +{ + if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol ) + return false ; - case kEventControlHiliteChanged : - thisWindow->MacHiliteChanged() ; - break ; + if ( m_peer ) + m_peer->SetBackgroundColour( col ) ; - case kEventControlActivate : - case kEventControlDeactivate : - // FIXME: we should have a virtual function for this! -#if wxUSE_TREECTRL - if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) ) - thisWindow->Refresh(); -#endif -#if wxUSE_LISTCTRL - if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) ) - thisWindow->Refresh(); -#endif - break ; + return true ; +} - // - // focus handling - // different handling on OS X - // +void wxWindowMac::SetFocus() +{ + if ( !AcceptsFocus() ) + return ; - case kEventControlFocusPartChanged : - // the event is emulated by wxmac for systems lower than 10.5 - { - if ( UMAGetSystemVersion() < 0x1050 ) - { - // as it is synthesized here, we have to manually avoid propagation - result = noErr; - } - ControlPartCode previousControlPart = cEvent.GetParameter(kEventParamControlPreviousPart , typeControlPartCode ); - ControlPartCode currentControlPart = cEvent.GetParameter(kEventParamControlCurrentPart , typeControlPartCode ); + wxWindow* former = FindFocus() ; + if ( former == this ) + return ; - if ( thisWindow->MacGetTopLevelWindow() && thisWindow->GetPeer()->NeedsFocusRect() ) - { - thisWindow->MacInvalidateBorders(); - } + m_peer->SetFocus() ; +} - if ( currentControlPart == 0 ) - { - // kill focus -#if wxUSE_CARET - if ( thisWindow->GetCaret() ) - thisWindow->GetCaret()->OnKillFocus(); -#endif +void wxWindowMac::DoCaptureMouse() +{ + wxApp::s_captureWindow = (wxWindow*) this ; +} - wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); +wxWindow * wxWindowBase::GetCapture() +{ + return wxApp::s_captureWindow ; +} - // remove this as soon as posting the synthesized event works properly - static bool inKillFocusEvent = false ; +void wxWindowMac::DoReleaseMouse() +{ + wxApp::s_captureWindow = NULL ; +} - if ( !inKillFocusEvent ) - { - inKillFocusEvent = true ; - wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId()); - event.SetEventObject(thisWindow); - event.SetWindow(targetFocusWindow); - thisWindow->HandleWindowEvent(event) ; - inKillFocusEvent = false ; - targetFocusWindow = NULL; - } - } - else if ( previousControlPart == 0 ) - { - // set focus - // panel wants to track the window which was the last to have focus in it - wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow)); - wxChildFocusEvent eventFocus((wxWindow*)thisWindow); - thisWindow->HandleWindowEvent(eventFocus); +#if wxUSE_DRAG_AND_DROP + +void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) +{ + if ( m_dropTarget != NULL ) + delete m_dropTarget; + + m_dropTarget = pDropTarget; + if ( m_dropTarget != NULL ) + { + // TODO: + } +} -#if wxUSE_CARET - if ( thisWindow->GetCaret() ) - thisWindow->GetCaret()->OnSetFocus(); #endif - wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); - event.SetEventObject(thisWindow); - event.SetWindow(formerFocusWindow); - thisWindow->HandleWindowEvent(event) ; - formerFocusWindow = NULL; - } - } - break; - case kEventControlSetFocusPart : - { - Boolean focusEverything = false ; - if ( cEvent.GetParameter(kEventParamControlFocusEverything , &focusEverything ) == noErr ) - { - // put a breakpoint here to catch focus everything events - } - ControlPartCode controlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); - if ( controlPart != kControlFocusNoPart ) - { - targetFocusWindow = thisWindow; - wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), wx_static_cast(void*, thisWindow)); - } - else - { - formerFocusWindow = thisWindow; - wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), wx_static_cast(void*, thisWindow)); - } - - ControlPartCode previousControlPart = 0; - verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart)); +// Old-style File Manager Drag & Drop +void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept)) +{ + // TODO: +} - if ( thisWindow->MacIsUserPane() ) - { - if ( controlPart != kControlFocusNoPart ) - cEvent.SetParameter( kEventParamControlPart, typeControlPartCode, 1 ) ; - result = noErr ; - } - else - result = CallNextEventHandler(handler, event); +// From a wx position / size calculate the appropriate size of the native control - if ( UMAGetSystemVersion() < 0x1050 ) - { -// set back to 0 if problems arise -#if 1 - if ( result == noErr ) - { - ControlPartCode currentControlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); - // synthesize the event focus changed event - EventRef evRef = NULL ; +bool wxWindowMac::MacGetBoundsForControl( + const wxPoint& pos, + const wxSize& size, + int& x, int& y, + int& w, int& h , bool adjustOrigin ) const +{ + // the desired size, minus the border pixels gives the correct size of the control + x = (int)pos.x; + y = (int)pos.y; - OSStatus err = MacCreateEvent( - NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) , - kEventAttributeUserEvent , &evRef ); - verify_noerr( err ); + // TODO: the default calls may be used as soon as PostCreateControl Is moved here + w = wxMax(size.x, 0) ; // WidthDefault( size.x ); + h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ; - wxMacCarbonEvent iEvent( evRef ) ; - iEvent.SetParameter( kEventParamDirectObject , controlRef ); - iEvent.SetParameter( kEventParamPostTarget, typeEventTargetRef, GetControlEventTarget( controlRef ) ); - iEvent.SetParameter( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ); - iEvent.SetParameter( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ); - -#if 1 - // TODO test this first, avoid double posts etc... - PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh ); -#else - wxMacWindowControlEventHandler( NULL , evRef , data ) ; -#endif - ReleaseEvent( evRef ) ; - } -#else - // old implementation, to be removed if the new one works - if ( controlPart == kControlFocusNoPart ) - { -#if wxUSE_CARET - if ( thisWindow->GetCaret() ) - thisWindow->GetCaret()->OnKillFocus(); -#endif + x += MacGetLeftBorderSize() ; + y += MacGetTopBorderSize() ; + w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ; + h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ; - wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); + if ( adjustOrigin ) + AdjustForParentClientOrigin( x , y ) ; - static bool inKillFocusEvent = false ; + // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border + if ( !GetParent()->IsTopLevel() ) + { + x -= GetParent()->MacGetLeftBorderSize() ; + y -= GetParent()->MacGetTopBorderSize() ; + } - if ( !inKillFocusEvent ) - { - inKillFocusEvent = true ; - wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId()); - event.SetEventObject(thisWindow); - thisWindow->HandleWindowEvent(event) ; - inKillFocusEvent = false ; - } - } - else - { - // panel wants to track the window which was the last to have focus in it - wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow)); - wxChildFocusEvent eventFocus((wxWindow*)thisWindow); - thisWindow->HandleWindowEvent(eventFocus); + return true ; +} - #if wxUSE_CARET - if ( thisWindow->GetCaret() ) - thisWindow->GetCaret()->OnSetFocus(); - #endif +// Get window size (not client size) +void wxWindowMac::DoGetSize(int *x, int *y) const +{ + int width, height; + m_peer->GetSize( width, height ); - wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); - event.SetEventObject(thisWindow); - thisWindow->HandleWindowEvent(event) ; - } -#endif - } - } - break ; + if (x) + *x = width + MacGetLeftBorderSize() + MacGetRightBorderSize() ; + if (y) + *y = height + MacGetTopBorderSize() + MacGetBottomBorderSize() ; +} - case kEventControlHit : - result = thisWindow->MacControlHit( handler , event ) ; - break ; +// get the position of the bounds of this window in client coordinates of its parent +void wxWindowMac::DoGetPosition(int *x, int *y) const +{ + int x1, y1; + + m_peer->GetPosition( x1, y1 ) ; - case kEventControlGetClickActivation : - { - // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise) - WindowRef owner = cEvent.GetParameter(kEventParamWindowRef); - if ( !IsWindowActive(owner) ) - { - cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ; - result = noErr ; - } - } - break ; + // get the wx window position from the native one + x1 -= MacGetLeftBorderSize() ; + y1 -= MacGetTopBorderSize() ; - default : - break ; + if ( !IsTopLevel() ) + { + wxWindow *parent = GetParent(); + if ( parent ) + { + // we must first adjust it to be in window coordinates of the parent, + // as otherwise it gets lost by the ClientAreaOrigin fix + x1 += parent->MacGetLeftBorderSize() ; + y1 += parent->MacGetTopBorderSize() ; + + // and now to client coordinates + wxPoint pt(parent->GetClientAreaOrigin()); + x1 -= pt.x ; + y1 -= pt.y ; + } } - return result ; + if (x) + *x = x1 ; + if (y) + *y = y1 ; } -static pascal OSStatus -wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler), - EventRef event, - void *data) +void wxWindowMac::DoScreenToClient(int *x, int *y) const { - OSStatus result = eventNotHandledErr ; + wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ; + wxCHECK_RET( tlw , wxT("TopLevel Window missing") ) ; + tlw->GetNonOwnedPeer()->ScreenToWindow( x, y); + MacRootWindowToWindow( x , y ) ; - wxMacCarbonEvent cEvent( event ) ; + wxPoint origin = GetClientAreaOrigin() ; + if (x) + *x -= origin.x ; + if (y) + *y -= origin.y ; +} - ControlRef controlRef ; - wxWindowMac* thisWindow = (wxWindowMac*) data ; - wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ; - cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; +void wxWindowMac::DoClientToScreen(int *x, int *y) const +{ + wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ; + wxCHECK_RET( tlw , wxT("TopLevel window missing") ) ; - switch ( GetEventKind( event ) ) - { - case kEventServiceGetTypes : - if ( textCtrl ) - { - long from, to ; - textCtrl->GetSelection( &from , &to ) ; + wxPoint origin = GetClientAreaOrigin() ; + if (x) + *x += origin.x ; + if (y) + *y += origin.y ; - CFMutableArrayRef copyTypes = 0 , pasteTypes = 0; - if ( from != to ) - copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ; - if ( textCtrl->IsEditable() ) - pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ; + MacWindowToRootWindow( x , y ) ; + tlw->GetNonOwnedPeer()->WindowToScreen( x , y ); +} - static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt', 'PICT', 'MooV', 'AIFF' */ }; - for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i ) - { - CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]); - if ( typestring ) - { - if ( copyTypes ) - CFArrayAppendValue(copyTypes, typestring) ; - if ( pasteTypes ) - CFArrayAppendValue(pasteTypes, typestring) ; +void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const +{ + wxPoint origin = GetClientAreaOrigin() ; + if (x) + *x += origin.x ; + if (y) + *y += origin.y ; - CFRelease( typestring ) ; - } - } + MacWindowToRootWindow( x , y ) ; +} - result = noErr ; - } - break ; +void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const +{ + wxPoint pt ; - case kEventServiceCopy : - if ( textCtrl ) - { - long from, to ; + if (x) + pt.x = *x ; + if (y) + pt.y = *y ; - textCtrl->GetSelection( &from , &to ) ; - wxString val = textCtrl->GetValue() ; - val = val.Mid( from , to - from ) ; - PasteboardRef pasteboard = cEvent.GetParameter( kEventParamPasteboardRef, typePasteboardRef ); - verify_noerr( PasteboardClear( pasteboard ) ) ; - PasteboardSynchronize( pasteboard ); - // TODO add proper conversion - CFDataRef data = CFDataCreate( kCFAllocatorDefault, (const UInt8*)val.c_str(), val.length() ); - PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0); - CFRelease( data ); - result = noErr ; - } - break ; + if ( !IsTopLevel() ) + { + wxNonOwnedWindow* top = MacGetTopLevelWindow(); + if (top) + { + pt.x -= MacGetLeftBorderSize() ; + pt.y -= MacGetTopBorderSize() ; + wxWidgetImpl::Convert( &pt , m_peer , top->m_peer ) ; + } + } - case kEventServicePaste : - if ( textCtrl ) - { - PasteboardRef pasteboard = cEvent.GetParameter( kEventParamPasteboardRef, typePasteboardRef ); - PasteboardSynchronize( pasteboard ); - ItemCount itemCount; - verify_noerr( PasteboardGetItemCount( pasteboard, &itemCount ) ); - for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ ) - { - PasteboardItemID itemID; - if ( PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ) == noErr ) - { - CFDataRef flavorData = NULL; - if ( PasteboardCopyItemFlavorData( pasteboard, itemID, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData ) == noErr ) - { - CFIndex flavorDataSize = CFDataGetLength( flavorData ); - char *content = new char[flavorDataSize+1] ; - memcpy( content, CFDataGetBytePtr( flavorData ), flavorDataSize ); - content[flavorDataSize]=0; - CFRelease( flavorData ); -#if wxUSE_UNICODE - textCtrl->WriteText( wxString( content , wxConvLocal ) ); -#else - textCtrl->WriteText( wxString( content ) ) ; -#endif + if (x) + *x = (int) pt.x ; + if (y) + *y = (int) pt.y ; +} - delete[] content ; - result = noErr ; - } - } - } - } - break ; +void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const +{ + wxPoint pt ; - default: - break ; + if (x) + pt.x = *x ; + if (y) + pt.y = *y ; + + if ( !IsTopLevel() ) + { + wxNonOwnedWindow* top = MacGetTopLevelWindow(); + if (top) + { + wxWidgetImpl::Convert( &pt , top->m_peer , m_peer ) ; + pt.x += MacGetLeftBorderSize() ; + pt.y += MacGetTopBorderSize() ; + } } - return result ; + if (x) + *x = (int) pt.x ; + if (y) + *y = (int) pt.y ; } -pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const { - OSStatus result = eventNotHandledErr ; - wxWindowMac* focus = (wxWindowMac*) data ; + wxSize sizeTotal = size; - wchar_t* uniChars = NULL ; - UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ; + int innerwidth, innerheight; + int left, top; + int outerwidth, outerheight; + + m_peer->GetContentArea( left, top, innerwidth, innerheight ); + m_peer->GetSize( outerwidth, outerheight ); + + sizeTotal.x += left + (outerwidth-innerwidth); + sizeTotal.y += top + (outerheight-innerheight); + + sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ; + sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ; - UniChar* charBuf = NULL; - ByteCount dataSize = 0 ; - int numChars = 0 ; - UniChar buf[2] ; - if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr ) - { - numChars = dataSize / sizeof( UniChar) + 1; - charBuf = buf ; + return sizeTotal; +} - if ( (size_t) numChars * 2 > sizeof(buf) ) - charBuf = new UniChar[ numChars ] ; - else - charBuf = buf ; +// Get size *available for subwindows* i.e. excluding menu bar etc. +void wxWindowMac::DoGetClientSize( int *x, int *y ) const +{ + int ww, hh; - uniChars = new wchar_t[ numChars ] ; - GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ; - charBuf[ numChars - 1 ] = 0; -#if SIZEOF_WCHAR_T == 2 - uniChars = (wchar_t*) charBuf ; -/* 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...) -#else - // the resulting string will never have more chars than the utf16 version, so this is safe - wxMBConvUTF16 converter ; - numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ; -#endif - } + int left, top; + + m_peer->GetContentArea( left, top, ww, hh ); - switch ( GetEventKind( event ) ) - { - case kEventTextInputUpdateActiveInputArea : - { - // An IME input event may return several characters, but we need to send one char at a time to - // EVT_CHAR - for (int pos=0 ; pos < numChars ; pos++) - { - WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ; - WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; - wxTheApp->MacSetCurrentEvent( event , handler ) ; + if (m_hScrollBar && m_hScrollBar->IsShown() ) + hh -= m_hScrollBar->GetSize().y ; - UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?'; -/* - NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent - multiple times to update the active range during inline input, so this handler will often receive - uncommited text, which should usually not trigger side effects. It might be a good idea to check the - kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h). - On the other hand, it can be useful for some applications to react to uncommitted text (for example, - to update a status display), as long as it does not disrupt the inline input session. Ideally, wx - should add new event types to support advanced text input. For now, I would keep things as they are. + if (m_vScrollBar && m_vScrollBar->IsShown() ) + ww -= m_vScrollBar->GetSize().x ; - However, the code that was being used caused additional problems: - UInt32 message = (0 << 8) + ((char)uniChars[pos] ); - Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline - input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji - for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB - (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D - (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress. - Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only - overlap with Unicode within the (7-bit) ASCII range. - But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks - for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII - characters as they are and replaces the rest with '?', ensuring that update events are triggered. - It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but - I don't have time to look into that right now. - -- CL -*/ - if ( wxTheApp->MacSendCharEvent( - focus , message , 0 , when , 0 , 0 , uniChars[pos] ) ) - { - result = noErr ; - } + if (x) + *x = ww; + if (y) + *y = hh; +} - wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ; - } - } - break ; - case kEventTextInputUnicodeForKeyEvent : - { - UInt32 keyCode, modifiers ; - Point point ; - EventRef rawEvent ; - unsigned char charCode ; +bool wxWindowMac::SetCursor(const wxCursor& cursor) +{ + if (m_cursor.IsSameAs(cursor)) + return false; - GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ; - GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode ); - GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode ); - GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers ); - GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point ); + if (!cursor.IsOk()) + { + if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) ) + return false ; + } + else + { + if ( ! wxWindowBase::SetCursor( cursor ) ) + return false ; + } - UInt32 message = (keyCode << 8) + charCode; + wxASSERT_MSG( m_cursor.Ok(), + wxT("cursor must be valid after call to the base version")); - // An IME input event may return several characters, but we need to send one char at a time to - // EVT_CHAR - for (int pos=0 ; pos < numChars ; pos++) - { - WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ; - WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; - wxTheApp->MacSetCurrentEvent( event , handler ) ; + wxWindowMac *mouseWin = 0 ; +#if wxOSX_USE_CARBON + { + wxNonOwnedWindow *tlw = MacGetTopLevelWindow() ; + WindowRef window = (WindowRef) ( tlw ? tlw->GetWXWindow() : 0 ) ; - if ( wxTheApp->MacSendCharEvent( - focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) ) - { - result = noErr ; - } + ControlPartCode part ; + ControlRef control ; + Point pt ; + #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + HIPoint hiPoint ; + HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint); + pt.h = hiPoint.x; + pt.v = hiPoint.y; + #else + GetGlobalMouse( &pt ); + int x = pt.h; + int y = pt.v; + ScreenToClient(&x, &y); + pt.h = x; + pt.v = y; +#endif + control = FindControlUnderMouse( pt , window , &part ) ; + if ( control ) + mouseWin = wxFindWindowFromWXWidget( (WXWidget) control ) ; - wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ; - } - } - break; - default: - break ; } +#endif - delete [] uniChars ; - if ( charBuf != buf ) - delete [] charBuf ; + if ( mouseWin == this && !wxIsBusy() ) + m_cursor.MacInstall() ; - return result ; + return true ; } -static pascal OSStatus -wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), - EventRef event, - void *data) +#if wxUSE_MENUS +bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { - OSStatus result = eventNotHandledErr ; - wxWindowMac* focus = (wxWindowMac*) data ; - - HICommand command ; - - wxMacCarbonEvent cEvent( event ) ; - cEvent.GetParameter(kEventParamDirectObject,typeHICommand,&command) ; - - wxMenuItem* item = NULL ; - wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ; - int id = wxMacCommandToId( command.commandID ) ; +#ifndef __WXUNIVERSAL__ + menu->SetInvokingWindow((wxWindow*)this); + menu->UpdateUI(); - if ( item ) + if ( x == wxDefaultCoord && y == wxDefaultCoord ) { - wxASSERT( itemMenu != NULL ) ; + wxPoint mouse = wxGetMousePosition(); + x = mouse.x; + y = mouse.y; + } + else + { + ClientToScreen( &x , &y ) ; + } - switch ( cEvent.GetKind() ) + menu->MacBeforeDisplay( true ) ; + long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ; + if ( HiWord(menuResult) != 0 ) + { + MenuCommand macid; + GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid ); + int id = wxMacCommandToId( macid ); + wxMenuItem* item = NULL ; + wxMenu* realmenu ; + item = menu->FindItem( id, &realmenu ) ; + if ( item ) { - case kEventProcessCommand : - result = itemMenu->MacHandleCommandProcess( item, id, focus ); - break ; - - case kEventCommandUpdateStatus: - result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus ); - break ; + if (item->IsCheckable()) + item->Check( !item->IsChecked() ) ; - default : - break ; + menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; } } - return result ; -} - -pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) -{ - EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ; - EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ; - wxTheApp->MacSetCurrentEvent( event , handler ) ; - OSStatus result = eventNotHandledErr ; - - switch ( GetEventClass( event ) ) - { - case kEventClassCommand : - result = wxMacWindowCommandEventHandler( handler , event , data ) ; - break ; - case kEventClassControl : - result = wxMacWindowControlEventHandler( handler, event, data ) ; - break ; + menu->MacAfterDisplay( true ) ; + menu->SetInvokingWindow( NULL ); - case kEventClassService : - result = wxMacWindowServiceEventHandler( handler, event , data ) ; - break ; + return true; +#else + // actually this shouldn't be called, because universal is having its own implementation + return false; +#endif +} +#endif - case kEventClassTextInput : - result = wxMacUnicodeTextEventHandler( handler , event , data ) ; - break ; +// ---------------------------------------------------------------------------- +// tooltips +// ---------------------------------------------------------------------------- - default : - break ; - } +#if wxUSE_TOOLTIPS - wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ; +void wxWindowMac::DoSetToolTip(wxToolTip *tooltip) +{ + wxWindowBase::DoSetToolTip(tooltip); - return result ; + if ( m_tooltip ) + m_tooltip->SetWindow(this); } -DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler ) - -// --------------------------------------------------------------------------- -// Scrollbar Tracking for all -// --------------------------------------------------------------------------- +#endif -pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ; -pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) +void wxWindowMac::MacInvalidateBorders() { - if ( partCode != 0) - { - wxWindow* wx = wxFindControlFromMacControl( control ) ; - if ( wx ) - wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ; - } -} -wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ; - -// =========================================================================== -// implementation -// =========================================================================== + if ( m_peer == NULL ) + return ; -WX_DECLARE_HASH_MAP(ControlRef, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap); + bool vis = IsShownOnScreen() ; + if ( !vis ) + return ; -static MacControlMap wxWinMacControlList; + int outerBorder = MacGetLeftBorderSize() ; +#if wxOSX_USE_CARBON + if ( m_peer->NeedsFocusRect() /* && m_peer->HasFocus() */ ) + outerBorder += 4 ; +#endif -wxWindow *wxFindControlFromMacControl(ControlRef inControl ) -{ - MacControlMap::iterator node = wxWinMacControlList.find(inControl); + if ( outerBorder == 0 ) + return ; - return (node == wxWinMacControlList.end()) ? NULL : node->second; -} + // now we know that we have something to do at all + -void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control) -{ - // adding NULL ControlRef is (first) surely a result of an error and - // (secondly) breaks native event processing - wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") ); + int tx,ty,tw,th; + + m_peer->GetSize( tw, th ); + m_peer->GetPosition( tx, ty ); - wxWinMacControlList[inControl] = control; + wxRect leftupdate( tx-outerBorder,ty,outerBorder,th ); + wxRect rightupdate( tx+tw, ty, outerBorder, th ); + wxRect topupdate( tx-outerBorder, ty-outerBorder, tw + 2 * outerBorder, outerBorder ); + wxRect bottomupdate( tx-outerBorder, ty + th, tw + 2 * outerBorder, outerBorder ); + + GetParent()->m_peer->SetNeedsDisplay(&leftupdate); + GetParent()->m_peer->SetNeedsDisplay(&rightupdate); + GetParent()->m_peer->SetNeedsDisplay(&topupdate); + GetParent()->m_peer->SetNeedsDisplay(&bottomupdate); } -void wxRemoveMacControlAssociation(wxWindow *control) +void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) { - // iterate over all the elements in the class - // is the iterator stable ? as we might have two associations pointing to the same wxWindow - // we should go on... + // this is never called for a toplevel window, so we know we have a parent + int former_x , former_y , former_w, former_h ; - bool found = true ; - while ( found ) + // Get true coordinates of former position + DoGetPosition( &former_x , &former_y ) ; + DoGetSize( &former_w , &former_h ) ; + + wxWindow *parent = GetParent(); + if ( parent ) { - found = false ; - MacControlMap::iterator it; - for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it ) - { - if ( it->second == control ) - { - wxWinMacControlList.erase(it); - found = true ; - break; - } - } + wxPoint pt(parent->GetClientAreaOrigin()); + former_x += pt.x ; + former_y += pt.y ; } -} - -// ---------------------------------------------------------------------------- - // constructors and such -// ---------------------------------------------------------------------------- - -wxWindowMac::wxWindowMac() -{ - Init(); -} - -wxWindowMac::wxWindowMac(wxWindowMac *parent, - wxWindowID id, - const wxPoint& pos , - const wxSize& size , - long style , - const wxString& name ) -{ - Init(); - Create(parent, id, pos, size, style, name); -} -void wxWindowMac::Init() -{ - m_peer = NULL ; - m_macAlpha = 255 ; - m_cgContextRef = NULL ; + int actualWidth = width ; + int actualHeight = height ; + int actualX = x; + int actualY = y; - // as all windows are created with WS_VISIBLE style... - m_isShown = true; + if ((m_minWidth != -1) && (actualWidth < m_minWidth)) + actualWidth = m_minWidth; + if ((m_minHeight != -1) && (actualHeight < m_minHeight)) + actualHeight = m_minHeight; + if ((m_maxWidth != -1) && (actualWidth > m_maxWidth)) + actualWidth = m_maxWidth; + if ((m_maxHeight != -1) && (actualHeight > m_maxHeight)) + actualHeight = m_maxHeight; - m_hScrollBar = NULL ; - m_vScrollBar = NULL ; - m_hScrollBarAlwaysShown = false; - m_vScrollBarAlwaysShown = false; + bool doMove = false, doResize = false ; - m_macIsUserPane = true; - m_clipChildren = false ; - m_cachedClippedRectValid = false ; -} + if ( actualX != former_x || actualY != former_y ) + doMove = true ; -wxWindowMac::~wxWindowMac() -{ - SendDestroyEvent(); + if ( actualWidth != former_w || actualHeight != former_h ) + doResize = true ; - m_isBeingDeleted = true; + if ( doMove || doResize ) + { + // as the borders are drawn outside the native control, we adjust now - MacInvalidateBorders() ; + wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ), + wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) , + actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ; -#ifndef __WXUNIVERSAL__ - // VS: make sure there's no wxFrame with last focus set to us: - for ( wxWindow *win = GetParent(); win; win = win->GetParent() ) - { - wxFrame *frame = wxDynamicCast(win, wxFrame); - if ( frame ) + if ( !GetParent()->IsTopLevel() ) { - if ( frame->GetLastFocus() == this ) - frame->SetLastFocus((wxWindow*)NULL); - break; + bounds.Offset( -GetParent()->MacGetLeftBorderSize(), -GetParent()->MacGetTopBorderSize() ); } - } -#endif - // destroy children before destroying this window itself - DestroyChildren(); + MacInvalidateBorders() ; - // wxRemoveMacControlAssociation( this ) ; - // If we delete an item, we should initialize the parent panel, - // because it could now be invalid. - wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow); - if ( tlw ) - { - if ( tlw->GetDefaultItem() == (wxButton*) this) - tlw->SetDefaultItem(NULL); - } + m_cachedClippedRectValid = false ; + + m_peer->Move( bounds.x, bounds.y, bounds.width, bounds.height); - if ( m_peer && m_peer->Ok() ) - { - // in case the callback might be called during destruction - wxRemoveMacControlAssociation( this) ; - ::RemoveEventHandler( (EventHandlerRef ) m_macControlEventHandler ) ; - // we currently are not using this hook - // ::SetControlColorProc( *m_peer , NULL ) ; - m_peer->Dispose() ; - } + wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified - if ( g_MacLastWindow == this ) - g_MacLastWindow = NULL ; + MacInvalidateBorders() ; -#ifndef __WXUNIVERSAL__ - wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ; - if ( frame ) - { - if ( frame->GetLastFocus() == this ) - frame->SetLastFocus( NULL ) ; + MacRepositionScrollBars() ; + if ( doMove ) + { + wxPoint point(actualX, actualY); + wxMoveEvent event(point, m_windowId); + event.SetEventObject(this); + HandleWindowEvent(event) ; + } + + if ( doResize ) + { + MacRepositionScrollBars() ; + wxSize size(actualWidth, actualHeight); + wxSizeEvent event(size, m_windowId); + event.SetEventObject(this); + HandleWindowEvent(event); + } } -#endif +} - // delete our drop target if we've got one -#if wxUSE_DRAG_AND_DROP - if ( m_dropTarget != NULL ) +wxSize wxWindowMac::DoGetBestSize() const +{ + if ( m_macIsUserPane || IsTopLevel() ) { - delete m_dropTarget; - m_dropTarget = NULL; + return wxWindowBase::DoGetBestSize() ; } + else + { + + Rect bestsize = { 0 , 0 , 0 , 0 } ; + int bestWidth, bestHeight ; + +#if wxOSX_USE_COCOA_OR_CARBON +#if wxOSX_USE_CARBON + m_peer->GetBestRect( &bestsize ) ; #endif + if ( EmptyRect( &bestsize ) ) + { + bestsize.left = + bestsize.top = 0 ; + bestsize.right = + bestsize.bottom = 16 ; - delete m_peer ; -} + if ( IsKindOf( CLASSINFO( wxScrollBar ) ) ) + { + bestsize.bottom = 16 ; + } + #if wxUSE_SPINBTN + else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) ) + { + bestsize.bottom = 24 ; + } + #endif + else + { + // return wxWindowBase::DoGetBestSize() ; + } + } +#endif + bestWidth = bestsize.right - bestsize.left + MacGetLeftBorderSize() + + MacGetRightBorderSize(); + bestHeight = bestsize.bottom - bestsize.top + MacGetTopBorderSize() + + MacGetBottomBorderSize(); + if ( bestHeight < 10 ) + bestHeight = 13 ; -WXWidget wxWindowMac::GetHandle() const -{ - return (WXWidget) m_peer->GetControlRef() ; + return wxSize(bestWidth, bestHeight); + } } -void wxWindowMac::MacInstallEventHandler( WXWidget control ) +// set the size of the window: if the dimensions are positive, just use them, +// but if any of them is equal to -1, it means that we must find the value for +// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in +// which case -1 is a valid value for x and y) +// +// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate +// the width/height to best suit our contents, otherwise we reuse the current +// width/height +void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - wxAssociateControlWithMacControl( (ControlRef) control , this ) ; - InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(), - GetEventTypeCount(eventList), eventList, this, - (EventHandlerRef *)&m_macControlEventHandler); -} + // get the current size and position... + int currentX, currentY; + int currentW, currentH; -// Constructor -bool wxWindowMac::Create(wxWindowMac *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) -{ - wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") ); + GetPosition(¤tX, ¤tY); + GetSize(¤tW, ¤tH); - if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) - return false; + // ... and don't do anything (avoiding flicker) if it's already ok + if ( x == currentX && y == currentY && + width == currentW && height == currentH && ( height != -1 && width != -1 ) ) + { + // TODO: REMOVE + MacRepositionScrollBars() ; // we might have a real position shift - m_windowVariant = parent->GetWindowVariant() ; + return; + } - if ( m_macIsUserPane ) + if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) { - Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ; + if ( x == wxDefaultCoord ) + x = currentX; + if ( y == wxDefaultCoord ) + y = currentY; + } - UInt32 features = 0 - | kControlSupportsEmbedding - | kControlSupportsLiveFeedback - | kControlGetsFocusOnClick -// | kControlHasSpecialBackground -// | kControlSupportsCalcBestRect - | kControlHandlesTracking - | kControlSupportsFocus - | kControlWantsActivate - | kControlWantsIdle ; + AdjustForParentClientOrigin( x, y, sizeFlags ); + + wxSize size = wxDefaultSize; + if ( width == wxDefaultCoord ) + { + if ( sizeFlags & wxSIZE_AUTO_WIDTH ) + { + size = DoGetBestSize(); + width = size.x; + } + else + { + // just take the current one + width = currentW; + } + } - m_peer = new wxMacControl(this) ; - OSStatus err =::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() ); - verify_noerr( err ); + if ( height == wxDefaultCoord ) + { + if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) + { + if ( size.x == wxDefaultCoord ) + size = DoGetBestSize(); + // else: already called DoGetBestSize() above - MacPostControlCreate(pos, size) ; + height = size.y; + } + else + { + // just take the current one + height = currentH; + } } -#ifndef __WXUNIVERSAL__ - // Don't give scrollbars to wxControls unless they ask for them - if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) - || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL)))) + DoMoveWindow( x, y, width, height ); +} + +wxPoint wxWindowMac::GetClientAreaOrigin() const +{ +#if wxOSX_USE_CARBON + RgnHandle rgn = NewRgn() ; + Rect content ; + if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) { - MacCreateScrollBars( style ) ; + GetRegionBounds( rgn , &content ) ; + } + else + { + content.left = + content.top = 0 ; } -#endif - wxWindowCreateEvent event(this); - GetEventHandler()->AddPendingEvent(event); + DisposeRgn( rgn ) ; - return true; + return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() ); +#else + return wxPoint(0,0); +#endif } -void wxWindowMac::MacChildAdded() +void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) { - if ( m_vScrollBar ) - m_vScrollBar->Raise() ; - if ( m_hScrollBar ) - m_hScrollBar->Raise() ; + if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord ) + { + int currentclientwidth , currentclientheight ; + int currentwidth , currentheight ; + + GetClientSize( ¤tclientwidth , ¤tclientheight ) ; + GetSize( ¤twidth , ¤theight ) ; + + DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth , + currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ; + } } -void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size) +void wxWindowMac::SetLabel(const wxString& title) { - wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ; - - m_peer->SetReference( (URefCon) this ) ; - GetParent()->AddChild( this ); + m_label = title ; - MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ); +#if wxOSX_USE_CARBON + if ( m_peer && m_peer->IsOk() ) + m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; +#endif - ControlRef container = (ControlRef) GetParent()->GetHandle() ; - wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - ::EmbedControl( m_peer->GetControlRef() , container ) ; - GetParent()->MacChildAdded() ; + // do not trigger refreshes upon invisible and possible partly created objects + if ( IsShownOnScreen() ) + Refresh() ; +} - // adjust font, controlsize etc - DoSetWindowVariant( m_windowVariant ) ; +wxString wxWindowMac::GetLabel() const +{ + return m_label ; +} - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; +bool wxWindowMac::Show(bool show) +{ + if ( !wxWindowBase::Show(show) ) + return false; - if (!m_macIsUserPane) - SetInitialSize(size); + if ( m_peer ) + m_peer->SetVisibility( show ) ; - SetCursor( *wxSTANDARD_CURSOR ) ; + return true; } -void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) +void wxWindowMac::DoEnable(bool enable) { - // Don't assert, in case we set the window variant before - // the window is created - // wxASSERT( m_peer->Ok() ) ; +#if wxOSX_USE_CARBON + m_peer->Enable( enable ) ; +#endif +} - m_windowVariant = variant ; +// +// status change notifications +// - if (m_peer == NULL || !m_peer->Ok()) - return; +void wxWindowMac::MacVisibilityChanged() +{ +} - ControlSize size ; - ThemeFontID themeFont = kThemeSystemFont ; +void wxWindowMac::MacHiliteChanged() +{ +} - // we will get that from the settings later - // and make this NORMAL later, but first - // we have a few calculations that we must fix +void wxWindowMac::MacEnabledStateChanged() +{ +#if wxOSX_USE_CARBON + OnEnabled( m_peer->IsEnabled() ); +#endif +} - switch ( variant ) - { - case wxWINDOW_VARIANT_NORMAL : - size = kControlSizeNormal; - themeFont = kThemeSystemFont ; - break ; - - case wxWINDOW_VARIANT_SMALL : - size = kControlSizeSmall; - themeFont = kThemeSmallSystemFont ; - break ; - - case wxWINDOW_VARIANT_MINI : - // not always defined in the headers - size = 3 ; - themeFont = 109 ; - break ; - - case wxWINDOW_VARIANT_LARGE : - size = kControlSizeLarge; - themeFont = kThemeSystemFont ; - break ; - - default: - wxFAIL_MSG(_T("unexpected window variant")); - break ; - } - - m_peer->SetData(kControlEntireControl, kControlSizeTag, &size ) ; - - wxFont font ; - font.MacCreateFromThemeFont( themeFont ) ; - SetFont( font ) ; -} +// +// status queries on the inherited window's state +// -void wxWindowMac::MacUpdateControlFont() +bool wxWindowMac::MacIsReallyEnabled() { - m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; - // do not trigger refreshes upon invisible and possible partly created objects - if ( IsShownOnScreen() ) - Refresh() ; +#if wxOSX_USE_CARBON + return m_peer->IsEnabled() ; +#endif } -bool wxWindowMac::SetFont(const wxFont& font) +bool wxWindowMac::MacIsReallyHilited() { - bool retval = wxWindowBase::SetFont( font ); - - MacUpdateControlFont() ; - - return retval; +#if wxOSX_USE_CARBON + return m_peer->IsActive(); +#endif } -bool wxWindowMac::SetForegroundColour(const wxColour& col ) +int wxWindowMac::GetCharHeight() const { - bool retval = wxWindowBase::SetForegroundColour( col ); - - if (retval) - MacUpdateControlFont(); + wxClientDC dc( (wxWindow*)this ) ; - return retval; + return dc.GetCharHeight() ; } -bool wxWindowMac::SetBackgroundColour(const wxColour& col ) +int wxWindowMac::GetCharWidth() const { - if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol ) - return false ; + wxClientDC dc( (wxWindow*)this ) ; - m_peer->SetBackgroundColour( col ) ; - - return true ; + return dc.GetCharWidth() ; } -bool wxWindowMac::MacCanFocus() const +void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, + int *descent, int *externalLeading, const wxFont *theFont ) const { - // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so - // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning, - // but the value range is nowhere documented - Boolean keyExistsAndHasValidFormat ; - CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) , - kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat ); - - if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 ) + const wxFont *fontToUse = theFont; + wxFont tempFont; + if ( !fontToUse ) { - return true ; + tempFont = GetFont(); + fontToUse = &tempFont; } - else - { - UInt32 features = 0 ; - m_peer->GetFeatures( &features ) ; - return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; - } + wxClientDC dc( (wxWindow*) this ) ; + wxCoord lx,ly,ld,le ; + dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ; + if ( externalLeading ) + *externalLeading = le ; + if ( descent ) + *descent = ld ; + if ( x ) + *x = lx ; + if ( y ) + *y = ly ; } -void wxWindowMac::SetFocus() -{ - if ( !AcceptsFocus() ) - return ; +/* + * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect + * we always intersect with the entire window, not only with the client area + */ - wxWindow* former = FindFocus() ; - if ( former == this ) +void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect) +{ + if ( m_peer == NULL ) return ; - // as we cannot rely on the control features to find out whether we are in full keyboard mode, - // we can only leave in case of an error - wxLogTrace(_T("Focus"), _T("before wxWindow::SetFocus(%p) %d"), wx_static_cast(void*, this), GetName().c_str()); - OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ; - if ( err == errCouldntSetFocus ) - { - wxLogTrace(_T("Focus"), _T("in wxWindow::SetFocus(%p) errCouldntSetFocus"), wx_static_cast(void*, this)); + if ( !IsShownOnScreen() ) return ; - } - wxLogTrace(_T("Focus"), _T("after wxWindow::SetFocus(%p)"), wx_static_cast(void*, this)); - - SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() ); + + m_peer->SetNeedsDisplay( rect ) ; } -void wxWindowMac::DoCaptureMouse() +void wxWindowMac::DoFreeze() { - wxApp::s_captureWindow = this ; +#if wxOSX_USE_CARBON + if ( m_peer && m_peer->IsOk() ) + m_peer->SetDrawingEnabled( false ) ; +#endif } -wxWindow * wxWindowBase::GetCapture() +void wxWindowMac::DoThaw() { - return wxApp::s_captureWindow ; +#if wxOSX_USE_CARBON + if ( m_peer && m_peer->IsOk() ) + { + m_peer->SetDrawingEnabled( true ) ; + m_peer->InvalidateWithChildren() ; + } +#endif } -void wxWindowMac::DoReleaseMouse() +wxWindow *wxGetActiveWindow() { - wxApp::s_captureWindow = NULL ; + // actually this is a windows-only concept + return NULL; } -#if wxUSE_DRAG_AND_DROP - -void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) +// Coordinates relative to the window +void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos)) { - if ( m_dropTarget != NULL ) - delete m_dropTarget; + // We really don't move the mouse programmatically under Mac. +} - m_dropTarget = pDropTarget; - if ( m_dropTarget != NULL ) +void wxWindowMac::OnEraseBackground(wxEraseEvent& event) +{ + if ( MacGetTopLevelWindow() == NULL ) + return ; +/* +#if TARGET_API_MAC_OSX + if ( !m_backgroundColour.Ok() || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) { - // TODO: } -} - + else #endif - -// Old-style File Manager Drag & Drop -void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept)) -{ - // TODO: +*/ + if ( GetBackgroundStyle() == wxBG_STYLE_COLOUR ) + { + event.GetDC()->Clear() ; + } + else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) + { + // don't skip the event here, custom background means that the app + // is drawing it itself in its OnPaint(), so don't draw it at all + // now to avoid flicker + } + else + { + event.Skip() ; + } } -// Returns the size of the native control. In the case of the toplevel window -// this is the content area root control - -void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x), - int& WXUNUSED(y), - int& WXUNUSED(w), - int& WXUNUSED(h)) const +void wxWindowMac::OnNcPaint( wxNcPaintEvent& event ) { - wxFAIL_MSG( wxT("Not currently supported") ) ; + event.Skip() ; } -// From a wx position / size calculate the appropriate size of the native control - -bool wxWindowMac::MacGetBoundsForControl( - const wxPoint& pos, - const wxSize& size, - int& x, int& y, - int& w, int& h , bool adjustOrigin ) const +int wxWindowMac::GetScrollPos(int orient) const { - // the desired size, minus the border pixels gives the correct size of the control - x = (int)pos.x; - y = (int)pos.y; - - // TODO: the default calls may be used as soon as PostCreateControl Is moved here - w = wxMax(size.x, 0) ; // WidthDefault( size.x ); - h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ; - - x += MacGetLeftBorderSize() ; - y += MacGetTopBorderSize() ; - w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ; - h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ; - - if ( adjustOrigin ) - AdjustForParentClientOrigin( x , y ) ; - - // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border - if ( !GetParent()->IsTopLevel() ) + if ( orient == wxHORIZONTAL ) { - x -= GetParent()->MacGetLeftBorderSize() ; - y -= GetParent()->MacGetTopBorderSize() ; + if ( m_hScrollBar ) + return m_hScrollBar->GetThumbPosition() ; + } + else + { + if ( m_vScrollBar ) + return m_vScrollBar->GetThumbPosition() ; } - return true ; + return 0; } -// Get window size (not client size) -void wxWindowMac::DoGetSize(int *x, int *y) const +// This now returns the whole range, not just the number +// of positions that we can scroll. +int wxWindowMac::GetScrollRange(int orient) const { - Rect bounds ; - m_peer->GetRect( &bounds ) ; + if ( orient == wxHORIZONTAL ) + { + if ( m_hScrollBar ) + return m_hScrollBar->GetRange() ; + } + else + { + if ( m_vScrollBar ) + return m_vScrollBar->GetRange() ; + } - if (x) - *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ; - if (y) - *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ; + return 0; } -// get the position of the bounds of this window in client coordinates of its parent -void wxWindowMac::DoGetPosition(int *x, int *y) const +int wxWindowMac::GetScrollThumb(int orient) const { - Rect bounds ; - m_peer->GetRect( &bounds ) ; - - int x1 = bounds.left ; - int y1 = bounds.top ; + if ( orient == wxHORIZONTAL ) + { + if ( m_hScrollBar ) + return m_hScrollBar->GetThumbSize() ; + } + else + { + if ( m_vScrollBar ) + return m_vScrollBar->GetThumbSize() ; + } - // get the wx window position from the native one - x1 -= MacGetLeftBorderSize() ; - y1 -= MacGetTopBorderSize() ; + return 0; +} - if ( !IsTopLevel() ) +void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) +{ + if ( orient == wxHORIZONTAL ) { - wxWindow *parent = GetParent(); - if ( parent ) - { - // we must first adjust it to be in window coordinates of the parent, - // as otherwise it gets lost by the ClientAreaOrigin fix - x1 += parent->MacGetLeftBorderSize() ; - y1 += parent->MacGetTopBorderSize() ; - - // and now to client coordinates - wxPoint pt(parent->GetClientAreaOrigin()); - x1 -= pt.x ; - y1 -= pt.y ; - } + if ( m_hScrollBar ) + m_hScrollBar->SetThumbPosition( pos ) ; + } + else + { + if ( m_vScrollBar ) + m_vScrollBar->SetThumbPosition( pos ) ; } - - if (x) - *x = x1 ; - if (y) - *y = y1 ; } -void wxWindowMac::DoScreenToClient(int *x, int *y) const +void +wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag) { - WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; - wxCHECK_RET( window , wxT("TopLevel Window missing") ) ; - - Point localwhere = { 0, 0 } ; - - if (x) - localwhere.h = *x ; - if (y) - localwhere.v = *y ; - - wxMacGlobalToLocal( window , &localwhere ) ; + bool needVisibilityUpdate = false; - if (x) - *x = localwhere.h ; - if (y) - *y = localwhere.v ; + if ( m_hScrollBarAlwaysShown != hflag ) + { + m_hScrollBarAlwaysShown = hflag; + needVisibilityUpdate = true; + } - MacRootWindowToWindow( x , y ) ; + if ( m_vScrollBarAlwaysShown != vflag ) + { + m_vScrollBarAlwaysShown = vflag; + needVisibilityUpdate = true; + } - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x -= origin.x ; - if (y) - *y -= origin.y ; + if ( needVisibilityUpdate ) + DoUpdateScrollbarVisibility(); } -void wxWindowMac::DoClientToScreen(int *x, int *y) const +// +// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef +// our own window origin is at leftOrigin/rightOrigin +// + +void wxWindowMac::MacPaintGrowBox() { - WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; - wxCHECK_RET( window , wxT("TopLevel window missing") ) ; + if ( IsTopLevel() ) + return ; - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x += origin.x ; - if (y) - *y += origin.y ; + if ( MacHasScrollBarCorner() ) + { + CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ; + wxASSERT( cgContext ) ; - MacWindowToRootWindow( x , y ) ; + int tx,ty,tw,th; + + m_peer->GetSize( tw, th ); + m_peer->GetPosition( tx, ty ); - Point localwhere = { 0, 0 }; - if (x) - localwhere.h = *x ; - if (y) - localwhere.v = *y ; + Rect rect = { ty,tx, ty+th, tx+tw }; - wxMacLocalToGlobal( window, &localwhere ) ; - if (x) - *x = localwhere.h ; - if (y) - *y = localwhere.v ; + int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; + CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; + CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ; + CGContextSaveGState( cgContext ); + + if ( m_backgroundColour.Ok() ) + { + CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() ); + } + else + { + CGContextSetRGBFillColor( cgContext, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)1.0 ); + } + CGContextFillRect( cgContext, cgrect ); + CGContextRestoreGState( cgContext ); + } } -void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const +void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) ) { - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x += origin.x ; - if (y) - *y += origin.y ; + if ( IsTopLevel() ) + return ; - MacWindowToRootWindow( x , y ) ; -} + bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ; -void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const -{ - MacRootWindowToWindow( x , y ) ; + // back to the surrounding frame rectangle + int tx,ty,tw,th; + + m_peer->GetSize( tw, th ); + m_peer->GetPosition( tx, ty ); - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x -= origin.x ; - if (y) - *y -= origin.y ; -} + Rect rect = { ty,tx, ty+th, tx+tw }; -void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const -{ - wxPoint pt ; +#if wxOSX_USE_COCOA_OR_CARBON - if (x) - pt.x = *x ; - if (y) - pt.y = *y ; + InsetRect( &rect, -1 , -1 ) ; - if ( !IsTopLevel() ) { - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) + CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left , + rect.bottom - rect.top ) ; + + HIThemeFrameDrawInfo info ; + memset( &info, 0 , sizeof(info) ) ; + + info.version = 0 ; + info.kind = 0 ; + info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; + info.isFocused = hasFocus ; + + CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ; + wxASSERT( cgContext ) ; + + if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) { - pt.x -= MacGetLeftBorderSize() ; - pt.y -= MacGetTopBorderSize() ; - wxMacControl::Convert( &pt , m_peer , top->m_peer ) ; + info.kind = kHIThemeFrameTextFieldSquare ; + HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; + } + else if ( HasFlag(wxSIMPLE_BORDER) ) + { + info.kind = kHIThemeFrameListBox ; + HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; + } + else if ( hasFocus ) + { + HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ; + } +#if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself + m_peer->GetRect( &rect ) ; + if ( MacHasScrollBarCorner() ) + { + int variant = (m_hScrollBar == NULL ? m_vScrollBar : m_hScrollBar ) ->GetWindowVariant(); + int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; + CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; + CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ; + HIThemeGrowBoxDrawInfo info ; + memset( &info, 0, sizeof(info) ) ; + info.version = 0 ; + info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; + info.kind = kHIThemeGrowBoxKindNone ; + // contrary to the docs ...SizeSmall does not work + info.size = kHIThemeGrowBoxSizeNormal ; + info.direction = 0 ; + HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ; } +#endif } - - if (x) - *x = (int) pt.x ; - if (y) - *y = (int) pt.y ; +#endif // wxOSX_USE_COCOA_OR_CARBON } -void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const +void wxWindowMac::RemoveChild( wxWindowBase *child ) { - int x1 , y1 ; - - if (x) - x1 = *x ; - if (y) - y1 = *y ; - - MacWindowToRootWindow( &x1 , &y1 ) ; + if ( child == m_hScrollBar ) + m_hScrollBar = NULL ; + if ( child == m_vScrollBar ) + m_vScrollBar = NULL ; - if (x) - *x = x1 ; - if (y) - *y = y1 ; + wxWindowBase::RemoveChild( child ) ; } -void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const +void wxWindowMac::DoUpdateScrollbarVisibility() { - wxPoint pt ; + bool triggerSizeEvent = false; - if (x) - pt.x = *x ; - if (y) - pt.y = *y ; + if ( m_hScrollBar ) + { + bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded(); - if ( !IsTopLevel() ) + if ( m_hScrollBar->IsShown() != showHScrollBar ) + { + m_hScrollBar->Show( showHScrollBar ); + triggerSizeEvent = true; + } + } + + if ( m_vScrollBar) { - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) + bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded(); + + if ( m_vScrollBar->IsShown() != showVScrollBar ) { - wxMacControl::Convert( &pt , top->m_peer , m_peer ) ; - pt.x += MacGetLeftBorderSize() ; - pt.y += MacGetTopBorderSize() ; + m_vScrollBar->Show( showVScrollBar ) ; + triggerSizeEvent = true; } } - if (x) - *x = (int) pt.x ; - if (y) - *y = (int) pt.y ; + MacRepositionScrollBars() ; + if ( triggerSizeEvent ) + { + wxSizeEvent event(GetSize(), m_windowId); + event.SetEventObject(this); + HandleWindowEvent(event); + } } -void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const +// New function that will replace some of the above. +void wxWindowMac::SetScrollbar(int orient, int pos, int thumb, + int range, bool refresh) { - int x1 , y1 ; - - if (x) - x1 = *x ; - if (y) - y1 = *y ; - - MacRootWindowToWindow( &x1 , &y1 ) ; + if ( orient == wxHORIZONTAL && m_hScrollBar ) + m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); + else if ( orient == wxVERTICAL && m_vScrollBar ) + m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); - if (x) - *x = x1 ; - if (y) - *y = y1 ; + DoUpdateScrollbarVisibility(); } -void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom ) +// Does a physical scroll +void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) { - RgnHandle rgn = NewRgn() ; + if ( dx == 0 && dy == 0 ) + return ; - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) - { - Rect structure, content ; + int width , height ; + GetClientSize( &width , &height ) ; - GetRegionBounds( rgn , &content ) ; - m_peer->GetRect( &structure ) ; - OffsetRect( &structure, -structure.left , -structure.top ) ; + { + wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ; + if ( rect ) + scrollrect.Intersect( *rect ) ; + // as the native control might be not a 0/0 wx window coordinates, we have to offset + scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; - left = content.left - structure.left ; - top = content.top - structure.top ; - right = structure.right - content.right ; - bottom = structure.bottom - content.bottom ; + m_peer->ScrollRect( &scrollrect, dx, dy ); } - else + + wxWindowMac *child; + int x, y, w, h; + for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) { - left = top = right = bottom = 0 ; - } + child = node->GetData(); + if (child == NULL) + continue; + if (child == m_vScrollBar) + continue; + if (child == m_hScrollBar) + continue; + if (child->IsTopLevel()) + continue; - DisposeRgn( rgn ) ; + child->GetPosition( &x, &y ); + child->GetSize( &w, &h ); + if (rect) + { + wxRect rc( x, y, w, h ); + if (rect->Intersects( rc )) + child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); + } + else + { + child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); + } + } } -wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const +void wxWindowMac::MacOnScroll( wxScrollEvent &event ) { - wxSize sizeTotal = size; - - RgnHandle rgn = NewRgn() ; - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) + if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar ) { - Rect content, structure ; - GetRegionBounds( rgn , &content ) ; - m_peer->GetRect( &structure ) ; + wxScrollWinEvent wevent; + wevent.SetPosition(event.GetPosition()); + wevent.SetOrientation(event.GetOrientation()); + wevent.SetEventObject(this); - // structure is in parent coordinates, but we only need width and height, so it's ok + if (event.GetEventType() == wxEVT_SCROLL_TOP) + wevent.SetEventType( wxEVT_SCROLLWIN_TOP ); + else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM) + wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM ); + else if (event.GetEventType() == wxEVT_SCROLL_LINEUP) + wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP ); + else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN) + wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN ); + else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP) + wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP ); + else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN) + wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN ); + else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK) + wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK ); + else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE) + wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE ); - sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ; - sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top) ; + HandleWindowEvent(wevent); } +} - DisposeRgn( rgn ) ; +// Get the window with the focus +wxWindow *wxWindowBase::DoFindFocus() +{ +#if wxOSX_USE_CARBON + ControlRef control ; + GetKeyboardFocus( GetUserFocusWindow() , &control ) ; + return wxFindWindowFromWXWidget( (WXWidget) control ) ; +#else + return NULL; +#endif +} - sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ; - sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ; +void wxWindowMac::OnInternalIdle() +{ + // This calls the UI-update mechanism (querying windows for + // menu/toolbar/control state information) + if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) + UpdateWindowUI(wxUPDATE_UI_FROMIDLE); +} - return sizeTotal; +// Raise the window to the top of the Z order +void wxWindowMac::Raise() +{ + m_peer->Raise(); } -// Get size *available for subwindows* i.e. excluding menu bar etc. -void wxWindowMac::DoGetClientSize( int *x, int *y ) const +// Lower the window to the bottom of the Z order +void wxWindowMac::Lower() { - int ww, hh; + m_peer->Lower(); +} - RgnHandle rgn = NewRgn() ; - Rect content ; - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) - GetRegionBounds( rgn , &content ) ; - else - m_peer->GetRect( &content ) ; - DisposeRgn( rgn ) ; +// static wxWindow *gs_lastWhich = NULL; - ww = content.right - content.left ; - hh = content.bottom - content.top ; +bool wxWindowMac::MacSetupCursor( const wxPoint& pt ) +{ + // first trigger a set cursor event - if (m_hScrollBar && m_hScrollBar->IsShown() ) - hh -= m_hScrollBar->GetSize().y ; + wxPoint clientorigin = GetClientAreaOrigin() ; + wxSize clientsize = GetClientSize() ; + wxCursor cursor ; + if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) ) + { + wxSetCursorEvent event( pt.x , pt.y ); - if (m_vScrollBar && m_vScrollBar->IsShown() ) - ww -= m_vScrollBar->GetSize().x ; + bool processedEvtSetCursor = HandleWindowEvent(event); + if ( processedEvtSetCursor && event.HasCursor() ) + { + cursor = event.GetCursor() ; + } + else + { + // the test for processedEvtSetCursor is here to prevent using m_cursor + // if the user code caught EVT_SET_CURSOR() and returned nothing from + // it - this is a way to say that our cursor shouldn't be used for this + // point + if ( !processedEvtSetCursor && m_cursor.Ok() ) + cursor = m_cursor ; - if (x) - *x = ww; - if (y) - *y = hh; + if ( !wxIsBusy() && !GetParent() ) + cursor = *wxSTANDARD_CURSOR ; + } + + if ( cursor.Ok() ) + cursor.MacInstall() ; + } + + return cursor.Ok() ; } -bool wxWindowMac::SetCursor(const wxCursor& cursor) +wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) ) { - if (m_cursor.IsSameAs(cursor)) - return false; +#if wxUSE_TOOLTIPS + if ( m_tooltip ) + return m_tooltip->GetTip() ; +#endif - if (!cursor.IsOk()) - { - if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) ) - return false ; - } - else + return wxEmptyString ; +} + +void wxWindowMac::ClearBackground() +{ + Refresh() ; + Update() ; +} + +void wxWindowMac::Update() +{ + wxNonOwnedWindow* top = MacGetTopLevelWindow(); + if (top) + top->Update() ; +} + +wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const +{ + wxWindowMac *iter = (wxWindowMac*)this ; + + while ( iter ) { - if ( ! wxWindowBase::SetCursor( cursor ) ) - return false ; + if ( iter->IsTopLevel() ) + { + wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow); + if ( toplevel ) + return toplevel; +#if wxUSE_POPUPWIN + wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow); + if ( popupwin ) + return popupwin; +#endif + } + iter = iter->GetParent() ; } - wxASSERT_MSG( m_cursor.Ok(), - wxT("cursor must be valid after call to the base version")); + return NULL ; +} - wxWindowMac *mouseWin = 0 ; - { - wxNonOwnedWindow *tlw = MacGetTopLevelWindow() ; - WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ; +const wxRect& wxWindowMac::MacGetClippedClientRect() const +{ + MacUpdateClippedRects() ; - ControlPartCode part ; - ControlRef control ; - Point pt ; - #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - HIPoint hiPoint ; - HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint); - pt.h = hiPoint.x; - pt.v = hiPoint.y; - #else - GetGlobalMouse( &pt ); - int x = pt.h; - int y = pt.v; - ScreenToClient(&x, &y); - pt.h = x; - pt.v = y; -#endif - control = FindControlUnderMouse( pt , window , &part ) ; - if ( control ) - mouseWin = wxFindControlFromMacControl( control ) ; + return m_cachedClippedClientRect ; +} - } +const wxRect& wxWindowMac::MacGetClippedRect() const +{ + MacUpdateClippedRects() ; - if ( mouseWin == this && !wxIsBusy() ) - m_cursor.MacInstall() ; + return m_cachedClippedRect ; +} - return true ; +const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const +{ + MacUpdateClippedRects() ; + + return m_cachedClippedRectWithOuterStructure ; } -#if wxUSE_MENUS -bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) +const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) { -#ifndef __WXUNIVERSAL__ - menu->SetInvokingWindow((wxWindow*)this); - menu->UpdateUI(); + static wxRegion emptyrgn ; - if ( x == wxDefaultCoord && y == wxDefaultCoord ) + if ( !m_isBeingDeleted && IsShownOnScreen() ) { - wxPoint mouse = wxGetMousePosition(); - x = mouse.x; - y = mouse.y; + MacUpdateClippedRects() ; + if ( includeOuterStructures ) + return m_cachedClippedRegionWithOuterStructure ; + else + return m_cachedClippedRegion ; } else { - ClientToScreen( &x , &y ) ; + return emptyrgn ; } +} - menu->MacBeforeDisplay( true ) ; - long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ; - if ( HiWord(menuResult) != 0 ) - { - MenuCommand macid; - GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid ); - int id = wxMacCommandToId( macid ); - wxMenuItem* item = NULL ; - wxMenu* realmenu ; - item = menu->FindItem( id, &realmenu ) ; - if ( item ) - { - if (item->IsCheckable()) - item->Check( !item->IsChecked() ) ; +void wxWindowMac::MacUpdateClippedRects() const +{ +#if wxOSX_USE_CARBON + if ( m_cachedClippedRectValid ) + return ; - menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; - } - } + // includeOuterStructures is true if we try to draw somthing like a focus ring etc. + // also a window dc uses this, in this case we only clip in the hierarchy for hard + // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having + // to add focus borders everywhere - menu->MacAfterDisplay( true ) ; - menu->SetInvokingWindow( NULL ); + Rect rIncludingOuterStructures ; - return true; -#else - // actually this shouldn't be called, because universal is having its own implementation - return false; -#endif -} -#endif + int tx,ty,tw,th; + + m_peer->GetSize( tw, th ); + m_peer->GetPosition( tx, ty ); -// ---------------------------------------------------------------------------- -// tooltips -// ---------------------------------------------------------------------------- + Rect r = { ty,tx, ty+th, tx+tw }; -#if wxUSE_TOOLTIPS + r.left -= MacGetLeftBorderSize() ; + r.top -= MacGetTopBorderSize() ; + r.bottom += MacGetBottomBorderSize() ; + r.right += MacGetRightBorderSize() ; -void wxWindowMac::DoSetToolTip(wxToolTip *tooltip) -{ - wxWindowBase::DoSetToolTip(tooltip); + r.right -= r.left ; + r.bottom -= r.top ; + r.left = 0 ; + r.top = 0 ; - if ( m_tooltip ) - m_tooltip->SetWindow(this); -} + rIncludingOuterStructures = r ; + InsetRect( &rIncludingOuterStructures , -4 , -4 ) ; -#endif + wxRect cl = GetClientRect() ; + Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ; -void wxWindowMac::MacInvalidateBorders() -{ - if ( m_peer == NULL ) - return ; + int x , y ; + wxSize size ; + const wxWindow* child = (wxWindow*) this ; + const wxWindow* parent = NULL ; - bool vis = IsShownOnScreen() ; - if ( !vis ) - return ; + while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL ) + { + if ( parent->MacIsChildOfClientArea(child) ) + { + size = parent->GetClientSize() ; + wxPoint origin = parent->GetClientAreaOrigin() ; + x = origin.x ; + y = origin.y ; + } + else + { + // this will be true for scrollbars, toolbars etc. + size = parent->GetSize() ; + y = parent->MacGetTopBorderSize() ; + x = parent->MacGetLeftBorderSize() ; + size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ; + size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ; + } - int outerBorder = MacGetLeftBorderSize() ; - if ( m_peer->NeedsFocusRect() /* && m_peer->HasFocus() */ ) - outerBorder += 4 ; + parent->MacWindowToRootWindow( &x, &y ) ; + MacRootWindowToWindow( &x , &y ) ; - if ( outerBorder == 0 ) - return ; + Rect rparent = { y , x , y + size.y , x + size.x } ; - // now we know that we have something to do at all + // the wxwindow and client rects will always be clipped + SectRect( &r , &rparent , &r ) ; + SectRect( &rClient , &rparent , &rClient ) ; - // as the borders are drawn on the parent we have to properly invalidate all these areas - RgnHandle updateInner , updateOuter; - Rect rect ; + // the structure only at 'hard' borders + if ( parent->MacClipChildren() || + ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) ) + { + SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ; + } - // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon - updateInner = NewRgn() ; - updateOuter = NewRgn() ; + child = parent ; + } - m_peer->GetRect( &rect ) ; - RectRgn( updateInner, &rect ) ; - InsetRect( &rect , -outerBorder , -outerBorder ) ; - RectRgn( updateOuter, &rect ) ; - DiffRgn( updateOuter, updateInner , updateOuter ) ; + m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ; + m_cachedClippedClientRect = wxRect( rClient.left , rClient.top , + rClient.right - rClient.left , rClient.bottom - rClient.top ) ; + m_cachedClippedRectWithOuterStructure = wxRect( + rIncludingOuterStructures.left , rIncludingOuterStructures.top , + rIncludingOuterStructures.right - rIncludingOuterStructures.left , + rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ; - GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ; + m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ; + m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ; + m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ; - DisposeRgn( updateOuter ) ; - DisposeRgn( updateInner ) ; + m_cachedClippedRectValid = true ; +#endif } -void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) +/* + This function must not change the updatergn ! + */ +bool wxWindowMac::MacDoRedraw( void* updatergnr , long time ) { - // this is never called for a toplevel window, so we know we have a parent - int former_x , former_y , former_w, former_h ; + bool handled = false ; +#if wxOSX_USE_CARBON + Rect updatebounds ; + RgnHandle updatergn = (RgnHandle) updatergnr ; + GetRegionBounds( updatergn , &updatebounds ) ; - // Get true coordinates of former position - DoGetPosition( &former_x , &former_y ) ; - DoGetSize( &former_w , &former_h ) ; + // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ; - wxWindow *parent = GetParent(); - if ( parent ) + if ( !EmptyRgn(updatergn) ) { - wxPoint pt(parent->GetClientAreaOrigin()); - former_x += pt.x ; - former_y += pt.y ; - } - - int actualWidth = width ; - int actualHeight = height ; - int actualX = x; - int actualY = y; - - if ((m_minWidth != -1) && (actualWidth < m_minWidth)) - actualWidth = m_minWidth; - if ((m_minHeight != -1) && (actualHeight < m_minHeight)) - actualHeight = m_minHeight; - if ((m_maxWidth != -1) && (actualWidth > m_maxWidth)) - actualWidth = m_maxWidth; - if ((m_maxHeight != -1) && (actualHeight > m_maxHeight)) - actualHeight = m_maxHeight; - - bool doMove = false, doResize = false ; - - if ( actualX != former_x || actualY != former_y ) - doMove = true ; + RgnHandle newupdate = NewRgn() ; + wxSize point = GetClientSize() ; + wxPoint origin = GetClientAreaOrigin() ; + SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y + point.y ) ; + SectRgn( newupdate , updatergn , newupdate ) ; - if ( actualWidth != former_w || actualHeight != former_h ) - doResize = true ; + // first send an erase event to the entire update area + { + // for the toplevel window this really is the entire area + // for all the others only their client area, otherwise they + // might be drawing with full alpha and eg put blue into + // the grow-box area of a scrolled window (scroll sample) + wxDC* dc = new wxWindowDC(this); + if ( IsTopLevel() ) + dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(updatergn))); + else + dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(newupdate))); - if ( doMove || doResize ) - { - // as the borders are drawn outside the native control, we adjust now + wxEraseEvent eevent( GetId(), dc ); + eevent.SetEventObject( this ); + HandleWindowEvent( eevent ); + delete dc ; + } - wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ), - wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) , - actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ; + MacPaintGrowBox(); - Rect r ; - wxMacRectToNative( &bounds , &r ) ; + // calculate a client-origin version of the update rgn and set m_updateRegion to that + OffsetRgn( newupdate , -origin.x , -origin.y ) ; + m_updateRegion = wxRegion(HIShapeCreateWithQDRgn(newupdate)) ; + DisposeRgn( newupdate ) ; - if ( !GetParent()->IsTopLevel() ) - wxMacWindowToNative( GetParent() , &r ) ; + if ( !m_updateRegion.Empty() ) + { + // paint the window itself - MacInvalidateBorders() ; + wxPaintEvent event; + event.SetTimestamp(time); + event.SetEventObject(this); + HandleWindowEvent(event); + handled = true ; + } - m_cachedClippedRectValid = false ; - m_peer->SetRect( &r ) ; + // now we cannot rely on having its borders drawn by a window itself, as it does not + // get the updateRgn wide enough to always do so, so we do it from the parent + // this would also be the place to draw any custom backgrounds for native controls + // in Composited windowing + wxPoint clientOrigin = GetClientAreaOrigin() ; - wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified + wxWindowMac *child; + int x, y, w, h; + for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) + { + child = node->GetData(); + if (child == NULL) + continue; + if (child == m_vScrollBar) + continue; + if (child == m_hScrollBar) + continue; + if (child->IsTopLevel()) + continue; + if (!child->IsShown()) + continue; - MacInvalidateBorders() ; + // only draw those in the update region (add a safety margin of 10 pixels for shadow effects - MacRepositionScrollBars() ; - if ( doMove ) - { - wxPoint point(actualX, actualY); - wxMoveEvent event(point, m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event) ; - } + child->GetPosition( &x, &y ); + child->GetSize( &w, &h ); + Rect childRect = { y , x , y + h , x + w } ; + OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ; + InsetRect( &childRect , -10 , -10) ; - if ( doResize ) - { - MacRepositionScrollBars() ; - wxSize size(actualWidth, actualHeight); - wxSizeEvent event(size, m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); + if ( RectInRgn( &childRect , updatergn ) ) + { + // paint custom borders + wxNcPaintEvent eventNc( child->GetId() ); + eventNc.SetEventObject( child ); + if ( !child->HandleWindowEvent( eventNc ) ) + { + child->MacPaintBorders(0, 0) ; + } + } } } +#endif + return handled ; } -wxSize wxWindowMac::DoGetBestSize() const + +WXWindow wxWindowMac::MacGetTopLevelWindowRef() const { - if ( m_macIsUserPane || IsTopLevel() ) + wxNonOwnedWindow* tlw = MacGetTopLevelWindow(); + return tlw ? tlw->GetWXWindow() : NULL ; +} + +bool wxWindowMac::MacHasScrollBarCorner() const +{ + /* Returns whether the scroll bars in a wxScrolledWindow should be + * shortened. Scroll bars should be shortened if either: + * + * - both scroll bars are visible, or + * + * - there is a resize box in the parent frame's corner and this + * window shares the bottom and right edge with the parent + * frame. + */ + + if ( m_hScrollBar == NULL && m_vScrollBar == NULL ) + return false; + + if ( ( m_hScrollBar && m_hScrollBar->IsShown() ) + && ( m_vScrollBar && m_vScrollBar->IsShown() ) ) { - return wxWindowBase::DoGetBestSize() ; + // Both scroll bars visible + return true; } else { - Rect bestsize = { 0 , 0 , 0 , 0 } ; - int bestWidth, bestHeight ; + wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight(); - m_peer->GetBestRect( &bestsize ) ; - if ( EmptyRect( &bestsize ) ) + for ( const wxWindow *win = (wxWindow*)this; win; win = win->GetParent() ) { - bestsize.left = - bestsize.top = 0 ; - bestsize.right = - bestsize.bottom = 16 ; - - if ( IsKindOf( CLASSINFO( wxScrollBar ) ) ) - { - bestsize.bottom = 16 ; - } - #if wxUSE_SPINBTN - else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) ) - { - bestsize.bottom = 24 ; - } - #endif - else + const wxFrame *frame = wxDynamicCast( win, wxFrame ) ; + if ( frame ) { - // return wxWindowBase::DoGetBestSize() ; + if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER ) + { + // Parent frame has resize handle + wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight(); + + // Note: allow for some wiggle room here as wxMac's + // window rect calculations seem to be imprecise + if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2 + && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 ) + { + // Parent frame has resize handle and shares + // right bottom corner + return true ; + } + else + { + // Parent frame has resize handle but doesn't + // share right bottom corner + return false ; + } + } + else + { + // Parent frame doesn't have resize handle + return false ; + } } } - bestWidth = bestsize.right - bestsize.left + MacGetLeftBorderSize() + - MacGetRightBorderSize(); - bestHeight = bestsize.bottom - bestsize.top + MacGetTopBorderSize() + - MacGetBottomBorderSize(); - if ( bestHeight < 10 ) - bestHeight = 13 ; - - return wxSize(bestWidth, bestHeight); + // No parent frame found + return false ; } } -// set the size of the window: if the dimensions are positive, just use them, -// but if any of them is equal to -1, it means that we must find the value for -// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in -// which case -1 is a valid value for x and y) -// -// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate -// the width/height to best suit our contents, otherwise we reuse the current -// width/height -void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) +void wxWindowMac::MacCreateScrollBars( long style ) { - // get the current size and position... - int currentX, currentY; - int currentW, currentH; - - GetPosition(¤tX, ¤tY); - GetSize(¤tW, ¤tH); + wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; - // ... and don't do anything (avoiding flicker) if it's already ok - if ( x == currentX && y == currentY && - width == currentW && height == currentH && ( height != -1 && width != -1 ) ) + if ( style & ( wxVSCROLL | wxHSCROLL ) ) { - // TODO: REMOVE - MacRepositionScrollBars() ; // we might have a real position shift - - return; - } + int scrlsize = MAC_SCROLLBAR_SIZE ; + if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI ) + { + scrlsize = MAC_SMALL_SCROLLBAR_SIZE ; + } - if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - { - if ( x == wxDefaultCoord ) - x = currentX; - if ( y == wxDefaultCoord ) - y = currentY; - } + int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ; + int width, height ; + GetClientSize( &width , &height ) ; - AdjustForParentClientOrigin( x, y, sizeFlags ); + wxPoint vPoint(width - scrlsize, 0) ; + wxSize vSize(scrlsize, height - adjust) ; + wxPoint hPoint(0, height - scrlsize) ; + wxSize hSize(width - adjust, scrlsize) ; - wxSize size = wxDefaultSize; - if ( width == wxDefaultCoord ) - { - if ( sizeFlags & wxSIZE_AUTO_WIDTH ) - { - size = DoGetBestSize(); - width = size.x; - } - else + // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize) + if ( style & wxVSCROLL ) { - // just take the current one - width = currentW; + m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL); + m_vScrollBar->SetMinSize( wxDefaultSize ); } - } - if ( height == wxDefaultCoord ) - { - if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) - { - if ( size.x == wxDefaultCoord ) - size = DoGetBestSize(); - // else: already called DoGetBestSize() above - - height = size.y; - } - else + if ( style & wxHSCROLL ) { - // just take the current one - height = currentH; + m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL); + m_hScrollBar->SetMinSize( wxDefaultSize ); } } - DoMoveWindow( x, y, width, height ); + // because the create does not take into account the client area origin + // we might have a real position shift + MacRepositionScrollBars() ; } -wxPoint wxWindowMac::GetClientAreaOrigin() const +bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const { - RgnHandle rgn = NewRgn() ; - Rect content ; - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) - { - GetRegionBounds( rgn , &content ) ; - } - else - { - content.left = - content.top = 0 ; - } - - DisposeRgn( rgn ) ; + bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar))); - return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() ); + return result ; } -void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) +void wxWindowMac::MacRepositionScrollBars() { - if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord ) - { - int currentclientwidth , currentclientheight ; - int currentwidth , currentheight ; + if ( !m_hScrollBar && !m_vScrollBar ) + return ; - GetClientSize( ¤tclientwidth , ¤tclientheight ) ; - GetSize( ¤twidth , ¤theight ) ; + int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; + int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ; - DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth , - currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ; - } -} + // get real client area + int width, height ; + GetSize( &width , &height ); -void wxWindowMac::SetLabel(const wxString& title) -{ - m_label = title ; + width -= MacGetLeftBorderSize() + MacGetRightBorderSize(); + height -= MacGetTopBorderSize() + MacGetBottomBorderSize(); - if ( m_peer && m_peer->Ok() ) - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; + wxPoint vPoint( width - scrlsize, 0 ) ; + wxSize vSize( scrlsize, height - adjust ) ; + wxPoint hPoint( 0 , height - scrlsize ) ; + wxSize hSize( width - adjust, scrlsize ) ; - // do not trigger refreshes upon invisible and possible partly created objects - if ( IsShownOnScreen() ) - Refresh() ; + if ( m_vScrollBar ) + m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE ); + if ( m_hScrollBar ) + m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE ); } -wxString wxWindowMac::GetLabel() const +bool wxWindowMac::AcceptsFocus() const { - return m_label ; + return m_peer->CanFocus() && wxWindowBase::AcceptsFocus(); } -bool wxWindowMac::Show(bool show) +void wxWindowMac::MacSuperChangedPosition() { - if ( !wxWindowBase::Show(show) ) - return false; + // only window-absolute structures have to be moved i.e. controls - if ( m_peer ) - m_peer->SetVisibility( show , true ) ; + m_cachedClippedRectValid = false ; - return true; + wxWindowMac *child; + wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); + while ( node ) + { + child = node->GetData(); + child->MacSuperChangedPosition() ; + + node = node->GetNext(); + } } -void wxWindowMac::DoEnable(bool enable) +void wxWindowMac::MacTopLevelWindowChangedPosition() { - m_peer->Enable( enable ) ; -} + // only screen-absolute structures have to be moved i.e. glcanvas -// -// status change notifications -// + wxWindowMac *child; + wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); + while ( node ) + { + child = node->GetData(); + child->MacTopLevelWindowChangedPosition() ; -void wxWindowMac::MacVisibilityChanged() -{ + node = node->GetNext(); + } } -void wxWindowMac::MacHiliteChanged() +long wxWindowMac::MacGetLeftBorderSize() const { -} + if ( IsTopLevel() ) + return 0 ; -void wxWindowMac::MacEnabledStateChanged() -{ - OnEnabled( m_peer->IsEnabled() ); -} + SInt32 border = 0 ; -// -// status queries on the inherited window's state -// + if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER)) + { +#if wxOSX_USE_COCOA_OR_CARBON + // this metric is only the 'outset' outside the simple frame rect + GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; + border += 1; +#else + border += 2; +#endif + } + else if (HasFlag(wxSIMPLE_BORDER)) + { +#if wxOSX_USE_COCOA_OR_CARBON + // this metric is only the 'outset' outside the simple frame rect + GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; + border += 1; +#else + border += 1; +#endif + } -bool wxWindowMac::MacIsReallyEnabled() -{ - return m_peer->IsEnabled() ; + return border ; } -bool wxWindowMac::MacIsReallyHilited() +long wxWindowMac::MacGetRightBorderSize() const { - return m_peer->IsActive(); + // they are all symmetric in mac themes + return MacGetLeftBorderSize() ; } -void wxWindowMac::MacFlashInvalidAreas() +long wxWindowMac::MacGetTopBorderSize() const { -#if TARGET_API_MAC_OSX - HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ; -#endif + // they are all symmetric in mac themes + return MacGetLeftBorderSize() ; } -int wxWindowMac::GetCharHeight() const +long wxWindowMac::MacGetBottomBorderSize() const { - wxClientDC dc( (wxWindowMac*)this ) ; - - return dc.GetCharHeight() ; + // they are all symmetric in mac themes + return MacGetLeftBorderSize() ; } -int wxWindowMac::GetCharWidth() const +long wxWindowMac::MacRemoveBordersFromStyle( long style ) { - wxClientDC dc( (wxWindowMac*)this ) ; - - return dc.GetCharWidth() ; + return style & ~wxBORDER_MASK ; } -void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, - int *descent, int *externalLeading, const wxFont *theFont ) const +// Find the wxWindowMac at the current mouse position, returning the mouse +// position. +wxWindow * wxFindWindowAtPointer( wxPoint& pt ) { - const wxFont *fontToUse = theFont; - wxFont tempFont; - if ( !fontToUse ) - { - tempFont = GetFont(); - fontToUse = &tempFont; - } + pt = wxGetMousePosition(); + wxWindowMac* found = wxFindWindowAtPoint(pt); - wxClientDC dc( (wxWindowMac*) this ) ; - wxCoord lx,ly,ld,le ; - dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ; - if ( externalLeading ) - *externalLeading = le ; - if ( descent ) - *descent = ld ; - if ( x ) - *x = lx ; - if ( y ) - *y = ly ; + return (wxWindow*) found; } -/* - * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect - * we always intersect with the entire window, not only with the client area - */ - -void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect) +// Get the current mouse position. +wxPoint wxGetMousePosition() { - if ( m_peer == NULL ) - return ; + int x, y; - if ( !IsShownOnScreen() ) - return ; + wxGetMousePosition( &x, &y ); + + return wxPoint(x, y); +} - if ( rect ) +void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) +{ + if ( event.GetEventType() == wxEVT_RIGHT_DOWN ) { - Rect r ; + // copied from wxGTK : CS + // VZ: shouldn't we move this to base class then? - wxMacRectToNative( rect , &r ) ; - m_peer->SetNeedsDisplay( &r ) ; + // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN + // except that: + // + // (a) it's a command event and so is propagated to the parent + // (b) under MSW it can be generated from kbd too + // (c) it uses screen coords (because of (a)) + wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, + this->GetId(), + this->ClientToScreen(event.GetPosition())); + evtCtx.SetEventObject(this); + if ( ! HandleWindowEvent(evtCtx) ) + event.Skip() ; } else { - m_peer->SetNeedsDisplay() ; + event.Skip() ; } } -void wxWindowMac::DoFreeze() -{ -#if TARGET_API_MAC_OSX - if ( m_peer && m_peer->Ok() ) - m_peer->SetDrawingEnabled( false ) ; -#endif -} - -void wxWindowMac::DoThaw() +void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) ) { -#if TARGET_API_MAC_OSX - if ( m_peer && m_peer->Ok() ) +#if wxOSX_USE_COCOA_OR_CARBON + // for native controls: call their native paint method + if ( !MacIsUserPane() || ( IsTopLevel() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM ) ) { - m_peer->SetDrawingEnabled( true ) ; - m_peer->InvalidateWithChildren() ; + if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL + && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) + CallNextEventHandler( + (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , + (EventRef) wxTheApp->MacGetCurrentEvent() ) ; } #endif } -wxWindowMac *wxGetActiveWindow() +void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control), + wxInt16 WXUNUSED(controlpart), + bool WXUNUSED(mouseStillDown)) { - // actually this is a windows-only concept - return NULL; } -// Coordinates relative to the window -void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos)) +Rect wxMacGetBoundsForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) { - // We really don't move the mouse programmatically under Mac. + int x, y, w, h ; + + window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ; + Rect bounds = { y, x, y + h, x + w }; + + return bounds ; } -void wxWindowMac::OnEraseBackground(wxEraseEvent& event) +wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) { - if ( MacGetTopLevelWindow() == NULL ) - return ; -/* -#if TARGET_API_MAC_OSX - if ( !m_backgroundColour.Ok() || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) - { - } - else +#if wxOSX_USE_COCOA_OR_CARBON + return eventNotHandledErr ; +#else + return 0; #endif -*/ - if ( GetBackgroundStyle() == wxBG_STYLE_COLOUR ) - { - event.GetDC()->Clear() ; - } - else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) - { - // don't skip the event here, custom background means that the app - // is drawing it itself in its OnPaint(), so don't draw it at all - // now to avoid flicker - } - else - { - event.Skip() ; - } } -void wxWindowMac::OnNcPaint( wxNcPaintEvent& event ) +bool wxWindowMac::Reparent(wxWindowBase *newParentBase) { - event.Skip() ; + wxWindowMac *newParent = (wxWindowMac *)newParentBase; + if ( !wxWindowBase::Reparent(newParent) ) + return false; + + m_peer->RemoveFromParent(); + m_peer->Embed( GetParent()->GetPeer() ); + return true; } -int wxWindowMac::GetScrollPos(int orient) const +bool wxWindowMac::SetTransparent(wxByte alpha) { - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - return m_hScrollBar->GetThumbPosition() ; - } - else + SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); + + if ( alpha != m_macAlpha ) { - if ( m_vScrollBar ) - return m_vScrollBar->GetThumbPosition() ; + m_macAlpha = alpha ; + Refresh() ; } - - return 0; + return true ; } -// This now returns the whole range, not just the number -// of positions that we can scroll. -int wxWindowMac::GetScrollRange(int orient) const -{ - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - return m_hScrollBar->GetRange() ; - } - else - { - if ( m_vScrollBar ) - return m_vScrollBar->GetRange() ; - } - return 0; +bool wxWindowMac::CanSetTransparent() +{ + return true ; } -int wxWindowMac::GetScrollThumb(int orient) const +wxByte wxWindowMac::GetTransparent() const { - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - return m_hScrollBar->GetThumbSize() ; - } - else - { - if ( m_vScrollBar ) - return m_vScrollBar->GetThumbSize() ; - } - - return 0; + return m_macAlpha ; } -void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) +bool wxWindowMac::IsShownOnScreen() const { - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - m_hScrollBar->SetThumbPosition( pos ) ; - } - else + if ( m_peer && m_peer->IsOk() ) { - if ( m_vScrollBar ) - m_vScrollBar->SetThumbPosition( pos ) ; + bool peerVis = m_peer->IsVisible(); + bool wxVis = wxWindowBase::IsShownOnScreen(); + if( peerVis != wxVis ) + { + // CS : put a breakpoint here to investigate differences + // between native an wx visibilities + // the only place where I've encountered them until now + // are the hiding/showing sequences where the vis-changed event is + // first sent to the innermost control, while wx does things + // from the outmost control + wxVis = wxWindowBase::IsShownOnScreen(); + return wxVis; + } + + return m_peer->IsVisible(); } + return wxWindowBase::IsShownOnScreen(); } -void -wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag) -{ - bool needVisibilityUpdate = false; +#if wxOSX_USE_CARBON +// +// impl +// - if ( m_hScrollBarAlwaysShown != hflag ) - { - m_hScrollBarAlwaysShown = hflag; - needVisibilityUpdate = true; - } - if ( m_vScrollBarAlwaysShown != vflag ) - { - m_vScrollBarAlwaysShown = vflag; - needVisibilityUpdate = true; - } +// --------------------------------------------------------------------------- +// Carbon Events +// --------------------------------------------------------------------------- - if ( needVisibilityUpdate ) - DoUpdateScrollbarVisibility(); -} +static const EventTypeSpec eventList[] = +{ + { kEventClassCommand, kEventProcessCommand } , + { kEventClassCommand, kEventCommandUpdateStatus } , -// -// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef -// our own window origin is at leftOrigin/rightOrigin -// + { kEventClassControl , kEventControlGetClickActivation } , + { kEventClassControl , kEventControlHit } , -void wxWindowMac::MacPaintGrowBox() -{ - if ( IsTopLevel() ) - return ; + { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } , + { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } , - if ( MacHasScrollBarCorner() ) - { - Rect rect ; + { kEventClassControl , kEventControlDraw } , - CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ; - wxASSERT( cgContext ) ; + { kEventClassControl , kEventControlVisibilityChanged } , + { kEventClassControl , kEventControlEnabledStateChanged } , + { kEventClassControl , kEventControlHiliteChanged } , - m_peer->GetRect( &rect ) ; + { kEventClassControl , kEventControlActivate } , + { kEventClassControl , kEventControlDeactivate } , - int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; - CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; - CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ; - CGContextSaveGState( cgContext ); + { kEventClassControl , kEventControlSetFocusPart } , + { kEventClassControl , kEventControlFocusPartChanged } , - if ( m_backgroundColour.Ok() ) - { - CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() ); - } - else - { - CGContextSetRGBFillColor( cgContext, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)1.0 ); - } - CGContextFillRect( cgContext, cgrect ); - CGContextRestoreGState( cgContext ); - } -} + { kEventClassService , kEventServiceGetTypes }, + { kEventClassService , kEventServiceCopy }, + { kEventClassService , kEventServicePaste }, -void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) ) +// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only +// { kEventClassControl , kEventControlBoundsChanged } , +} ; + +static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - if ( IsTopLevel() ) - return ; + OSStatus result = eventNotHandledErr ; + static wxWindowMac* targetFocusWindow = NULL; + static wxWindowMac* formerFocusWindow = NULL; - Rect rect ; - bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ; + wxMacCarbonEvent cEvent( event ) ; - // back to the surrounding frame rectangle - m_peer->GetRect( &rect ) ; - InsetRect( &rect, -1 , -1 ) ; + ControlRef controlRef ; + wxWindowMac* thisWindow = (wxWindowMac*) data ; + + cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; + switch ( GetEventKind( event ) ) { - CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left , - rect.bottom - rect.top ) ; + case kEventControlDraw : + { + RgnHandle updateRgn = NULL ; + RgnHandle allocatedRgn = NULL ; + wxRegion visRegion = thisWindow->MacGetVisibleRegion() ; - HIThemeFrameDrawInfo info ; - memset( &info, 0 , sizeof(info) ) ; + if ( cEvent.GetParameter(kEventParamRgnHandle, &updateRgn) != noErr ) + { + HIShapeGetAsQDRgn( visRegion.GetWXHRGN(), updateRgn ); + } + else + { + if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 ) + { + // as this update region is in native window locals we must adapt it to wx window local + allocatedRgn = NewRgn() ; + CopyRgn( updateRgn , allocatedRgn ) ; - info.version = 0 ; - info.kind = 0 ; - info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; - info.isFocused = hasFocus ; + // hide the given region by the new region that must be shifted + OffsetRgn( allocatedRgn , thisWindow->MacGetLeftBorderSize() , thisWindow->MacGetTopBorderSize() ) ; + updateRgn = allocatedRgn ; + } + } - CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ; - wxASSERT( cgContext ) ; +#if wxMAC_DEBUG_REDRAW + if ( thisWindow->MacIsUserPane() ) + { + static float color = 0.5 ; + static int channel = 0 ; + HIRect bounds; + CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; - if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) - { - info.kind = kHIThemeFrameTextFieldSquare ; - HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; - } - else if ( HasFlag(wxSIMPLE_BORDER) ) - { - info.kind = kHIThemeFrameListBox ; - HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; - } - else if ( hasFocus ) - { - HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ; - } -#if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself - m_peer->GetRect( &rect ) ; - if ( MacHasScrollBarCorner() ) - { - int variant = (m_hScrollBar == NULL ? m_vScrollBar : m_hScrollBar ) ->GetWindowVariant(); - int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; - CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; - CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ; - HIThemeGrowBoxDrawInfo info ; - memset( &info, 0, sizeof(info) ) ; - info.version = 0 ; - info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; - info.kind = kHIThemeGrowBoxKindNone ; - // contrary to the docs ...SizeSmall does not work - info.size = kHIThemeGrowBoxSizeNormal ; - info.direction = 0 ; - HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ; - } + HIViewGetBounds( controlRef, &bounds ); + CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 , + channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 ); + CGContextFillRect( cgContext, bounds ); + color += 0.1 ; + if ( color > 0.9 ) + { + color = 0.5 ; + channel++ ; + if ( channel == 3 ) + channel = 0 ; + } + } #endif - } -} -void wxWindowMac::RemoveChild( wxWindowBase *child ) -{ - if ( child == m_hScrollBar ) - m_hScrollBar = NULL ; - if ( child == m_vScrollBar ) - m_vScrollBar = NULL ; + { + bool created = false ; + CGContextRef cgContext = NULL ; + OSStatus err = cEvent.GetParameter(kEventParamCGContextRef, &cgContext) ; + if ( err != noErr ) + { + wxFAIL_MSG("Unable to retrieve CGContextRef"); + } - wxWindowBase::RemoveChild( child ) ; -} + thisWindow->MacSetCGContextRef( cgContext ) ; -void wxWindowMac::DoUpdateScrollbarVisibility() -{ - bool triggerSizeEvent = false; + { + wxMacCGContextStateSaver sg( cgContext ) ; + CGFloat alpha = (CGFloat)1.0 ; + { + wxWindow* iter = thisWindow ; + while ( iter ) + { + alpha *= (CGFloat)( iter->GetTransparent()/255.0 ) ; + if ( iter->IsTopLevel() ) + iter = NULL ; + else + iter = iter->GetParent() ; + } + } + CGContextSetAlpha( cgContext , alpha ) ; - if ( m_hScrollBar ) - { - bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded(); + if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) + { + HIRect bounds; + HIViewGetBounds( controlRef, &bounds ); + CGContextClearRect( cgContext, bounds ); + } - if ( m_hScrollBar->IsShown() != showHScrollBar ) - { - m_hScrollBar->Show( showHScrollBar ); - triggerSizeEvent = true; - } - } - if ( m_vScrollBar) - { - bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded(); - if ( m_vScrollBar->IsShown() != showVScrollBar ) - { - m_vScrollBar->Show( showVScrollBar ) ; - triggerSizeEvent = true; - } - } + if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) + result = noErr ; - MacRepositionScrollBars() ; - if ( triggerSizeEvent ) - { - wxSizeEvent event(GetSize(), m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); - } -} + thisWindow->MacSetCGContextRef( NULL ) ; + } -// New function that will replace some of the above. -void wxWindowMac::SetScrollbar(int orient, int pos, int thumb, - int range, bool refresh) -{ - if ( orient == wxHORIZONTAL && m_hScrollBar ) - m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); - else if ( orient == wxVERTICAL && m_vScrollBar ) - m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); + if ( created ) + CGContextRelease( cgContext ) ; + } - DoUpdateScrollbarVisibility(); -} + if ( allocatedRgn ) + DisposeRgn( allocatedRgn ) ; + } + break ; -// Does a physical scroll -void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) -{ - if ( dx == 0 && dy == 0 ) - return ; + case kEventControlVisibilityChanged : + // we might have two native controls attributed to the same wxWindow instance + // eg a scrollview and an embedded textview, make sure we only fire for the 'outer' + // control, as otherwise native and wx visibility are different + if ( thisWindow->GetPeer() != NULL && thisWindow->GetPeer()->GetControlRef() == controlRef ) + { + thisWindow->MacVisibilityChanged() ; + } + break ; - int width , height ; - GetClientSize( &width , &height ) ; + case kEventControlEnabledStateChanged : + thisWindow->MacEnabledStateChanged(); + break ; - { - // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control - // area is scrolled, this does not occur if width and height are 2 pixels less, - // TODO: write optimal workaround - wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ; - if ( rect ) - scrollrect.Intersect( *rect ) ; + case kEventControlHiliteChanged : + thisWindow->MacHiliteChanged() ; + break ; - if ( m_peer->GetNeedsDisplay() ) - { - // because HIViewScrollRect does not scroll the already invalidated area we have two options: - // in case there is already a pending redraw on that area - // either immediate redraw or full invalidate + case kEventControlActivate : + case kEventControlDeactivate : + // FIXME: we should have a virtual function for this! +#if wxUSE_TREECTRL + if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) ) + thisWindow->Refresh(); +#endif +#if wxUSE_LISTCTRL + if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) ) + thisWindow->Refresh(); +#endif + break ; + + // + // focus handling + // different handling on OS X + // + + case kEventControlFocusPartChanged : + // the event is emulated by wxmac for systems lower than 10.5 + { + if ( UMAGetSystemVersion() < 0x1050 ) + { + // as it is synthesized here, we have to manually avoid propagation + result = noErr; + } + ControlPartCode previousControlPart = cEvent.GetParameter(kEventParamControlPreviousPart , typeControlPartCode ); + ControlPartCode currentControlPart = cEvent.GetParameter(kEventParamControlCurrentPart , typeControlPartCode ); + + if ( thisWindow->MacGetTopLevelWindow() && thisWindow->GetPeer()->NeedsFocusRect() ) + { + thisWindow->MacInvalidateBorders(); + } + + if ( currentControlPart == 0 ) + { + // kill focus +#if wxUSE_CARET + if ( thisWindow->GetCaret() ) + thisWindow->GetCaret()->OnKillFocus(); +#endif + + wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); + + // remove this as soon as posting the synthesized event works properly + static bool inKillFocusEvent = false ; + + if ( !inKillFocusEvent ) + { + inKillFocusEvent = true ; + wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + event.SetWindow(targetFocusWindow); + thisWindow->HandleWindowEvent(event) ; + inKillFocusEvent = false ; + targetFocusWindow = NULL; + } + } + else if ( previousControlPart == 0 ) + { + // set focus + // panel wants to track the window which was the last to have focus in it + wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow)); + wxChildFocusEvent eventFocus((wxWindow*)thisWindow); + thisWindow->HandleWindowEvent(eventFocus); + +#if wxUSE_CARET + if ( thisWindow->GetCaret() ) + thisWindow->GetCaret()->OnSetFocus(); +#endif + + wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + event.SetWindow(formerFocusWindow); + thisWindow->HandleWindowEvent(event) ; + formerFocusWindow = NULL; + } + } + break; + case kEventControlSetFocusPart : + { + Boolean focusEverything = false ; + if ( cEvent.GetParameter(kEventParamControlFocusEverything , &focusEverything ) == noErr ) + { + // put a breakpoint here to catch focus everything events + } + ControlPartCode controlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); + if ( controlPart != kControlFocusNoPart ) + { + targetFocusWindow = thisWindow; + wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), wx_static_cast(void*, thisWindow)); + } + else + { + formerFocusWindow = thisWindow; + wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), wx_static_cast(void*, thisWindow)); + } + + ControlPartCode previousControlPart = 0; + verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart)); + + if ( thisWindow->MacIsUserPane() ) + { + if ( controlPart != kControlFocusNoPart ) + cEvent.SetParameter( kEventParamControlPart, typeControlPartCode, 1 ) ; + result = noErr ; + } + else + result = CallNextEventHandler(handler, event); + + if ( UMAGetSystemVersion() < 0x1050 ) + { +// set back to 0 if problems arise +#if 1 + if ( result == noErr ) + { + ControlPartCode currentControlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); + // synthesize the event focus changed event + EventRef evRef = NULL ; + + OSStatus err = MacCreateEvent( + NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) , + kEventAttributeUserEvent , &evRef ); + verify_noerr( err ); + + wxMacCarbonEvent iEvent( evRef ) ; + iEvent.SetParameter( kEventParamDirectObject , controlRef ); + iEvent.SetParameter( kEventParamPostTarget, typeEventTargetRef, GetControlEventTarget( controlRef ) ); + iEvent.SetParameter( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ); + iEvent.SetParameter( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ); + #if 1 - // is the better overall solution, as it does not slow down scrolling - m_peer->SetNeedsDisplay() ; + // TODO test this first, avoid double posts etc... + PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh ); #else - // this would be the preferred version for fast drawing controls - HIViewRender(m_peer->GetControlRef()) ; + wxMacWindowControlEventHandler( NULL , evRef , data ) ; +#endif + ReleaseEvent( evRef ) ; + } +#else + // old implementation, to be removed if the new one works + if ( controlPart == kControlFocusNoPart ) + { +#if wxUSE_CARET + if ( thisWindow->GetCaret() ) + thisWindow->GetCaret()->OnKillFocus(); #endif - } - // as the native control might be not a 0/0 wx window coordinates, we have to offset - scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; - m_peer->ScrollRect( &scrollrect , dx , dy ) ; + wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); -#if 0 - // this would be the preferred version for fast drawing controls - HIViewRender(m_peer->GetControlRef()) ; + static bool inKillFocusEvent = false ; + + if ( !inKillFocusEvent ) + { + inKillFocusEvent = true ; + wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + thisWindow->HandleWindowEvent(event) ; + inKillFocusEvent = false ; + } + } + else + { + // panel wants to track the window which was the last to have focus in it + wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow)); + wxChildFocusEvent eventFocus((wxWindow*)thisWindow); + thisWindow->HandleWindowEvent(eventFocus); + + #if wxUSE_CARET + if ( thisWindow->GetCaret() ) + thisWindow->GetCaret()->OnSetFocus(); + #endif + + wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + thisWindow->HandleWindowEvent(event) ; + } #endif + } + } + break ; + + case kEventControlHit : + result = thisWindow->MacControlHit( handler , event ) ; + break ; + + case kEventControlGetClickActivation : + { + // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise) + WindowRef owner = cEvent.GetParameter(kEventParamWindowRef); + if ( !IsWindowActive(owner) ) + { + cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ; + result = noErr ; + } + } + break ; + + default : + break ; } - wxWindowMac *child; - int x, y, w, h; - for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) + return result ; +} + +static pascal OSStatus +wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler), + EventRef event, + void *data) +{ + OSStatus result = eventNotHandledErr ; + + wxMacCarbonEvent cEvent( event ) ; + + ControlRef controlRef ; + wxWindowMac* thisWindow = (wxWindowMac*) data ; + wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ; + cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; + + switch ( GetEventKind( event ) ) { - child = node->GetData(); - if (child == NULL) - continue; - if (child == m_vScrollBar) - continue; - if (child == m_hScrollBar) - continue; - if (child->IsTopLevel()) - continue; + case kEventServiceGetTypes : + if ( textCtrl ) + { + long from, to ; + textCtrl->GetSelection( &from , &to ) ; - child->GetPosition( &x, &y ); - child->GetSize( &w, &h ); - if (rect) - { - wxRect rc( x, y, w, h ); - if (rect->Intersects( rc )) - child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); - } - else - { - child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); - } + CFMutableArrayRef copyTypes = 0 , pasteTypes = 0; + if ( from != to ) + copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ; + if ( textCtrl->IsEditable() ) + pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ; + + static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt', 'PICT', 'MooV', 'AIFF' */ }; + for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i ) + { + CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]); + if ( typestring ) + { + if ( copyTypes ) + CFArrayAppendValue(copyTypes, typestring) ; + if ( pasteTypes ) + CFArrayAppendValue(pasteTypes, typestring) ; + + CFRelease( typestring ) ; + } + } + + result = noErr ; + } + break ; + + case kEventServiceCopy : + if ( textCtrl ) + { + long from, to ; + + textCtrl->GetSelection( &from , &to ) ; + wxString val = textCtrl->GetValue() ; + val = val.Mid( from , to - from ) ; + PasteboardRef pasteboard = cEvent.GetParameter( kEventParamPasteboardRef, typePasteboardRef ); + verify_noerr( PasteboardClear( pasteboard ) ) ; + PasteboardSynchronize( pasteboard ); + // TODO add proper conversion + CFDataRef data = CFDataCreate( kCFAllocatorDefault, (const UInt8*)val.c_str(), val.length() ); + PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0); + CFRelease( data ); + result = noErr ; + } + break ; + + case kEventServicePaste : + if ( textCtrl ) + { + PasteboardRef pasteboard = cEvent.GetParameter( kEventParamPasteboardRef, typePasteboardRef ); + PasteboardSynchronize( pasteboard ); + ItemCount itemCount; + verify_noerr( PasteboardGetItemCount( pasteboard, &itemCount ) ); + for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ ) + { + PasteboardItemID itemID; + if ( PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ) == noErr ) + { + CFDataRef flavorData = NULL; + if ( PasteboardCopyItemFlavorData( pasteboard, itemID, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData ) == noErr ) + { + CFIndex flavorDataSize = CFDataGetLength( flavorData ); + char *content = new char[flavorDataSize+1] ; + memcpy( content, CFDataGetBytePtr( flavorData ), flavorDataSize ); + content[flavorDataSize]=0; + CFRelease( flavorData ); +#if wxUSE_UNICODE + textCtrl->WriteText( wxString( content , wxConvLocal ) ); +#else + textCtrl->WriteText( wxString( content ) ) ; +#endif + + delete[] content ; + result = noErr ; + } + } + } + } + break ; + + default: + break ; } + + return result ; } -void wxWindowMac::MacOnScroll( wxScrollEvent &event ) +pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar ) + OSStatus result = eventNotHandledErr ; + wxWindowMac* focus = (wxWindowMac*) data ; + + wchar_t* uniChars = NULL ; + UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ; + + UniChar* charBuf = NULL; + ByteCount dataSize = 0 ; + int numChars = 0 ; + UniChar buf[2] ; + if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr ) { - wxScrollWinEvent wevent; - wevent.SetPosition(event.GetPosition()); - wevent.SetOrientation(event.GetOrientation()); - wevent.SetEventObject(this); + numChars = dataSize / sizeof( UniChar) + 1; + charBuf = buf ; - if (event.GetEventType() == wxEVT_SCROLL_TOP) - wevent.SetEventType( wxEVT_SCROLLWIN_TOP ); - else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM) - wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM ); - else if (event.GetEventType() == wxEVT_SCROLL_LINEUP) - wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP ); - else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN) - wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN ); - else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP) - wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP ); - else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN) - wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN ); - else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK) - wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK ); - else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE) - wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE ); + if ( (size_t) numChars * 2 > sizeof(buf) ) + charBuf = new UniChar[ numChars ] ; + else + charBuf = buf ; + + uniChars = new wchar_t[ numChars ] ; + GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ; + charBuf[ numChars - 1 ] = 0; +#if SIZEOF_WCHAR_T == 2 + uniChars = (wchar_t*) charBuf ; +/* 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...) +#else + // the resulting string will never have more chars than the utf16 version, so this is safe + wxMBConvUTF16 converter ; + numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ; +#endif + } + + switch ( GetEventKind( event ) ) + { + case kEventTextInputUpdateActiveInputArea : + { + // An IME input event may return several characters, but we need to send one char at a time to + // EVT_CHAR + for (int pos=0 ; pos < numChars ; pos++) + { + WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ; + WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; + wxTheApp->MacSetCurrentEvent( event , handler ) ; + + UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?'; +/* + NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent + multiple times to update the active range during inline input, so this handler will often receive + uncommited text, which should usually not trigger side effects. It might be a good idea to check the + kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h). + On the other hand, it can be useful for some applications to react to uncommitted text (for example, + to update a status display), as long as it does not disrupt the inline input session. Ideally, wx + should add new event types to support advanced text input. For now, I would keep things as they are. + + However, the code that was being used caused additional problems: + UInt32 message = (0 << 8) + ((char)uniChars[pos] ); + Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline + input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji + for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB + (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D + (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress. + Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only + overlap with Unicode within the (7-bit) ASCII range. + But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks + for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII + characters as they are and replaces the rest with '?', ensuring that update events are triggered. + It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but + I don't have time to look into that right now. + -- CL +*/ + if ( wxTheApp->MacSendCharEvent( + focus , message , 0 , when , 0 , 0 , uniChars[pos] ) ) + { + result = noErr ; + } + + wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ; + } + } + break ; + case kEventTextInputUnicodeForKeyEvent : + { + UInt32 keyCode, modifiers ; + Point point ; + EventRef rawEvent ; + unsigned char charCode ; + + GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ; + GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode ); + GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode ); + GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers ); + GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point ); + + UInt32 message = (keyCode << 8) + charCode; - HandleWindowEvent(wevent); + // An IME input event may return several characters, but we need to send one char at a time to + // EVT_CHAR + for (int pos=0 ; pos < numChars ; pos++) + { + WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ; + WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; + wxTheApp->MacSetCurrentEvent( event , handler ) ; + + if ( wxTheApp->MacSendCharEvent( + focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) ) + { + result = noErr ; + } + + wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ; + } + } + break; + default: + break ; } -} -// Get the window with the focus -wxWindowMac *wxWindowBase::DoFindFocus() -{ - ControlRef control ; - GetKeyboardFocus( GetUserFocusWindow() , &control ) ; - return wxFindControlFromMacControl( control ) ; -} + delete [] uniChars ; + if ( charBuf != buf ) + delete [] charBuf ; -void wxWindowMac::OnInternalIdle() -{ - // This calls the UI-update mechanism (querying windows for - // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); + return result ; } -// Raise the window to the top of the Z order -void wxWindowMac::Raise() +static pascal OSStatus +wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), + EventRef event, + void *data) { - m_peer->SetZOrder( true , NULL ) ; -} + OSStatus result = eventNotHandledErr ; + wxWindowMac* focus = (wxWindowMac*) data ; -// Lower the window to the bottom of the Z order -void wxWindowMac::Lower() -{ - m_peer->SetZOrder( false , NULL ) ; -} + HICommand command ; -// static wxWindow *gs_lastWhich = NULL; + wxMacCarbonEvent cEvent( event ) ; + cEvent.GetParameter(kEventParamDirectObject,typeHICommand,&command) ; -bool wxWindowMac::MacSetupCursor( const wxPoint& pt ) -{ - // first trigger a set cursor event + wxMenuItem* item = NULL ; + wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ; + int id = wxMacCommandToId( command.commandID ) ; - wxPoint clientorigin = GetClientAreaOrigin() ; - wxSize clientsize = GetClientSize() ; - wxCursor cursor ; - if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) ) + if ( item ) { - wxSetCursorEvent event( pt.x , pt.y ); + wxASSERT( itemMenu != NULL ) ; - bool processedEvtSetCursor = HandleWindowEvent(event); - if ( processedEvtSetCursor && event.HasCursor() ) - { - cursor = event.GetCursor() ; - } - else + switch ( cEvent.GetKind() ) { - // the test for processedEvtSetCursor is here to prevent using m_cursor - // if the user code caught EVT_SET_CURSOR() and returned nothing from - // it - this is a way to say that our cursor shouldn't be used for this - // point - if ( !processedEvtSetCursor && m_cursor.Ok() ) - cursor = m_cursor ; + case kEventProcessCommand : + result = itemMenu->MacHandleCommandProcess( item, id, focus ); + break ; - if ( !wxIsBusy() && !GetParent() ) - cursor = *wxSTANDARD_CURSOR ; - } + case kEventCommandUpdateStatus: + result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus ); + break ; - if ( cursor.Ok() ) - cursor.MacInstall() ; + default : + break ; + } } - - return cursor.Ok() ; -} - -wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) ) -{ -#if wxUSE_TOOLTIPS - if ( m_tooltip ) - return m_tooltip->GetTip() ; -#endif - - return wxEmptyString ; + return result ; } -void wxWindowMac::ClearBackground() +pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - Refresh() ; - Update() ; -} + EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ; + EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ; + wxTheApp->MacSetCurrentEvent( event , handler ) ; + OSStatus result = eventNotHandledErr ; -void wxWindowMac::Update() -{ - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) - top->MacPerformUpdates() ; -} + switch ( GetEventClass( event ) ) + { + case kEventClassCommand : + result = wxMacWindowCommandEventHandler( handler , event , data ) ; + break ; -wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const -{ - wxNonOwnedWindow* win = NULL ; - WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; - if ( window ) - win = wxFindWinFromMacWindow( window ) ; + case kEventClassControl : + result = wxMacWindowControlEventHandler( handler, event, data ) ; + break ; - return win ; -} + case kEventClassService : + result = wxMacWindowServiceEventHandler( handler, event , data ) ; + break ; -const wxRect& wxWindowMac::MacGetClippedClientRect() const -{ - MacUpdateClippedRects() ; + case kEventClassTextInput : + result = wxMacUnicodeTextEventHandler( handler , event , data ) ; + break ; - return m_cachedClippedClientRect ; -} + default : + break ; + } -const wxRect& wxWindowMac::MacGetClippedRect() const -{ - MacUpdateClippedRects() ; + wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ; - return m_cachedClippedRect ; + return result ; } -const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const -{ - MacUpdateClippedRects() ; +DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler ) - return m_cachedClippedRectWithOuterStructure ; -} +// --------------------------------------------------------------------------- +// Scrollbar Tracking for all +// --------------------------------------------------------------------------- -const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) +pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ; +pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) { - static wxRegion emptyrgn ; - - if ( !m_isBeingDeleted && IsShownOnScreen() ) - { - MacUpdateClippedRects() ; - if ( includeOuterStructures ) - return m_cachedClippedRegionWithOuterStructure ; - else - return m_cachedClippedRegion ; - } - else + if ( partCode != 0) { - return emptyrgn ; + wxWindow* wx = wxFindWindowFromWXWidget( (WXWidget) control ) ; + if ( wx ) + wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ; } } +wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ; -void wxWindowMac::MacUpdateClippedRects() const +wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, const wxPoint& pos, const wxSize& size, + long style, long extraStyle, const wxString& name) { - if ( m_cachedClippedRectValid ) - return ; - - // includeOuterStructures is true if we try to draw somthing like a focus ring etc. - // also a window dc uses this, in this case we only clip in the hierarchy for hard - // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having - // to add focus borders everywhere - - Rect r, rIncludingOuterStructures ; - - m_peer->GetRect( &r ) ; - r.left -= MacGetLeftBorderSize() ; - r.top -= MacGetTopBorderSize() ; - r.bottom += MacGetBottomBorderSize() ; - r.right += MacGetRightBorderSize() ; - - r.right -= r.left ; - r.bottom -= r.top ; - r.left = 0 ; - r.top = 0 ; - - rIncludingOuterStructures = r ; - InsetRect( &rIncludingOuterStructures , -4 , -4 ) ; - - wxRect cl = GetClientRect() ; - Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ; - - int x , y ; - wxSize size ; - const wxWindow* child = this ; - const wxWindow* parent = NULL ; - - while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL ) - { - if ( parent->MacIsChildOfClientArea(child) ) - { - size = parent->GetClientSize() ; - wxPoint origin = parent->GetClientAreaOrigin() ; - x = origin.x ; - y = origin.y ; - } - else - { - // this will be true for scrollbars, toolbars etc. - size = parent->GetSize() ; - y = parent->MacGetTopBorderSize() ; - x = parent->MacGetLeftBorderSize() ; - size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ; - size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ; - } - - parent->MacWindowToRootWindow( &x, &y ) ; - MacRootWindowToWindow( &x , &y ) ; - - Rect rparent = { y , x , y + size.y , x + size.x } ; - - // the wxwindow and client rects will always be clipped - SectRect( &r , &rparent , &r ) ; - SectRect( &rClient , &rparent , &rClient ) ; - - // the structure only at 'hard' borders - if ( parent->MacClipChildren() || - ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) ) - { - SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ; - } - - child = parent ; - } + OSStatus err = noErr; + Rect bounds = wxMacGetBoundsForControl( wxpeer , pos , size ) ; + wxMacControl* c = new wxMacControl(wxpeer) ; + UInt32 features = 0 + | kControlSupportsEmbedding + | kControlSupportsLiveFeedback + | kControlGetsFocusOnClick +// | kControlHasSpecialBackground +// | kControlSupportsCalcBestRect + | kControlHandlesTracking + | kControlSupportsFocus + | kControlWantsActivate + | kControlWantsIdle ; - m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ; - m_cachedClippedClientRect = wxRect( rClient.left , rClient.top , - rClient.right - rClient.left , rClient.bottom - rClient.top ) ; - m_cachedClippedRectWithOuterStructure = wxRect( - rIncludingOuterStructures.left , rIncludingOuterStructures.top , - rIncludingOuterStructures.right - rIncludingOuterStructures.left , - rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ; + err =::CreateUserPaneControl( MAC_WXHWND(wxpeer->GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , c->GetControlRefAddr() ); + verify_noerr( err ); + return c; +} - m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ; - m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ; - m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ; - m_cachedClippedRectValid = true ; +void wxMacControl::MacInstallEventHandler( ControlRef control, wxWindowMac* wxPeer ) +{ + wxAssociateWindowWithWXWidget( (WXWidget) control , wxPeer ) ; + ::InstallControlEventHandler( control , GetwxMacWindowEventHandlerUPP(), + GetEventTypeCount(eventList), eventList, wxPeer, NULL); } -/* - This function must not change the updatergn ! - */ -bool wxWindowMac::MacDoRedraw( void* updatergnr , long time ) +IMPLEMENT_DYNAMIC_CLASS( wxMacControl , wxWidgetImpl ) + +wxMacControl::wxMacControl() { - bool handled = false ; - Rect updatebounds ; - RgnHandle updatergn = (RgnHandle) updatergnr ; - GetRegionBounds( updatergn , &updatebounds ) ; + Init(); +} - // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ; +wxMacControl::wxMacControl(wxWindowMac* peer , bool isRootControl ) : + wxWidgetImpl( peer, isRootControl ) +{ + Init(); +} - if ( !EmptyRgn(updatergn) ) - { - RgnHandle newupdate = NewRgn() ; - wxSize point = GetClientSize() ; - wxPoint origin = GetClientAreaOrigin() ; - SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y + point.y ) ; - SectRgn( newupdate , updatergn , newupdate ) ; +wxMacControl::~wxMacControl() +{ +} - // first send an erase event to the entire update area - { - // for the toplevel window this really is the entire area - // for all the others only their client area, otherwise they - // might be drawing with full alpha and eg put blue into - // the grow-box area of a scrolled window (scroll sample) - wxDC* dc = new wxWindowDC(this); - if ( IsTopLevel() ) - dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(updatergn))); - else - dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(newupdate))); +void wxMacControl::Init() +{ + m_controlRef = NULL; + m_macControlEventHandler = NULL; +} - wxEraseEvent eevent( GetId(), dc ); - eevent.SetEventObject( this ); - HandleWindowEvent( eevent ); - delete dc ; - } +void wxMacControl::Destroy() +{ + wxASSERT_MSG( m_controlRef != NULL , wxT("Control Handle already NULL, Dispose called twice ?") ); + wxASSERT_MSG( IsValidControlHandle(m_controlRef) , wxT("Invalid Control Handle (maybe already released) in Dispose") ); - MacPaintGrowBox(); + wxRemoveWXWidgetAssociation( m_wxPeer) ; + // we cannot check the ref count here anymore, as autorelease objects might delete their refs later + // we can have situations when being embedded, where the control gets deleted behind our back, so only + // CFRelease if we are safe + if ( IsValidControlHandle(m_controlRef) ) + CFRelease(m_controlRef); + m_controlRef = NULL; +} - // calculate a client-origin version of the update rgn and set m_updateRegion to that - OffsetRgn( newupdate , -origin.x , -origin.y ) ; - m_updateRegion = wxRegion(HIShapeCreateWithQDRgn(newupdate)) ; - DisposeRgn( newupdate ) ; +void wxMacControl::SetReference( URefCon data ) +{ + SetControlReference( m_controlRef , data ); +} - if ( !m_updateRegion.Empty() ) - { - // paint the window itself +void wxMacControl::RemoveFromParent() +{ + // nothing to do here for carbon +} - wxPaintEvent event; - event.SetTimestamp(time); - event.SetEventObject(this); - HandleWindowEvent(event); - handled = true ; - } +void wxMacControl::Embed( wxWidgetImpl *parent ) +{ + // copied from MacPostControlCreate + ControlRef container = (ControlRef) parent->GetWXWidget() ; + wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; + ::EmbedControl( m_controlRef , container ) ; +} - // now we cannot rely on having its borders drawn by a window itself, as it does not - // get the updateRgn wide enough to always do so, so we do it from the parent - // this would also be the place to draw any custom backgrounds for native controls - // in Composited windowing - wxPoint clientOrigin = GetClientAreaOrigin() ; +void wxMacControl::SetNeedsDisplay( const wxRect* rect ) +{ + if ( !IsVisible() ) + return; - wxWindowMac *child; - int x, y, w, h; - for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) - { - child = node->GetData(); - if (child == NULL) - continue; - if (child == m_vScrollBar) - continue; - if (child == m_hScrollBar) - continue; - if (child->IsTopLevel()) - continue; - if (!child->IsShown()) - continue; + if ( rect != NULL ) + { + HIRect updatearea = CGRectMake( rect->x , rect->y , rect->width , rect->height); + HIViewSetNeedsDisplayInRect( m_controlRef, &updatearea, true ); + } + else + HIViewSetNeedsDisplay( m_controlRef , true ); +} - // only draw those in the update region (add a safety margin of 10 pixels for shadow effects +void wxMacControl::Raise() +{ + verify_noerr( HIViewSetZOrder( m_controlRef, kHIViewZOrderAbove, NULL ) ); +} + +void wxMacControl::Lower() +{ + verify_noerr( HIViewSetZOrder( m_controlRef, kHIViewZOrderBelow, NULL ) ); +} - child->GetPosition( &x, &y ); - child->GetSize( &w, &h ); - Rect childRect = { y , x , y + h , x + w } ; - OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ; - InsetRect( &childRect , -10 , -10) ; +void wxMacControl::GetContentArea(int &left , int &top , int &width , int &height) const +{ + RgnHandle rgn = NewRgn() ; + Rect content ; + if ( GetControlRegion( m_controlRef, kControlContentMetaPart , rgn ) == noErr ) + GetRegionBounds( rgn , &content ) ; + else + GetControlBounds( m_controlRef , &content ); + DisposeRgn( rgn ) ; - if ( RectInRgn( &childRect , updatergn ) ) - { - // paint custom borders - wxNcPaintEvent eventNc( child->GetId() ); - eventNc.SetEventObject( child ); - if ( !child->HandleWindowEvent( eventNc ) ) - { - child->MacPaintBorders(0, 0) ; - } - } - } - } + left = content.left; + top = content.top; - return handled ; + width = content.right - content.left ; + height = content.bottom - content.top ; +} + +void wxMacControl::Move(int x, int y, int width, int height) +{ + HIRect hir = CGRectMake(x,y,width,height); + HIViewSetFrame ( m_controlRef , &hir ); } +void wxMacControl::GetPosition( int &x, int &y ) const +{ + Rect r; + GetControlBounds( m_controlRef , &r ); + x = r.left; + y = r.top; +} -WXWindow wxWindowMac::MacGetTopLevelWindowRef() const +void wxMacControl::GetSize( int &width, int &height ) const { - wxWindowMac *iter = (wxWindowMac*)this ; + Rect r; + GetControlBounds( m_controlRef , &r ); + width = r.right - r.left; + height = r.bottom - r.top; +} - while ( iter ) +void wxMacControl::ScrollRect( const wxRect *rect, int dx, int dy ) +{ + if (GetNeedsDisplay() ) { - if ( iter->IsTopLevel() ) - { - wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow); - if ( toplevel ) - return toplevel->MacGetWindowRef(); -#if wxUSE_POPUPWIN - wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow); - if ( popupwin ) - return popupwin->MacGetWindowRef(); + // because HIViewScrollRect does not scroll the already invalidated area we have two options: + // in case there is already a pending redraw on that area + // either immediate redraw or full invalidate +#if 1 + // is the better overall solution, as it does not slow down scrolling + SetNeedsDisplay() ; +#else + // this would be the preferred version for fast drawing controls + HIViewRender(GetControlRef()) ; #endif - } - iter = iter->GetParent() ; } - return NULL ; + // note there currently is a bug in OSX (10.3 +?) which makes inefficient refreshes in case an entire control + // area is scrolled, this does not occur if width and height are 2 pixels less, + // TODO: write optimal workaround + + HIRect scrollarea = CGRectMake( rect->x , rect->y , rect->width , rect->height); + HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ); + +#if 0 + // this would be the preferred version for fast drawing controls + HIViewRender(GetControlRef()) ; +#endif } -bool wxWindowMac::MacHasScrollBarCorner() const +bool wxMacControl::CanFocus() const { - /* Returns whether the scroll bars in a wxScrolledWindow should be - * shortened. Scroll bars should be shortened if either: - * - * - both scroll bars are visible, or - * - * - there is a resize box in the parent frame's corner and this - * window shares the bottom and right edge with the parent - * frame. - */ - - if ( m_hScrollBar == NULL && m_vScrollBar == NULL ) - return false; + // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so + // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning, + // but the value range is nowhere documented + Boolean keyExistsAndHasValidFormat ; + CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) , + kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat ); - if ( ( m_hScrollBar && m_hScrollBar->IsShown() ) - && ( m_vScrollBar && m_vScrollBar->IsShown() ) ) + if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 ) { - // Both scroll bars visible - return true; + return true ; } else { - wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight(); - - for ( const wxWindow *win = this; win; win = win->GetParent() ) - { - const wxFrame *frame = wxDynamicCast( win, wxFrame ) ; - if ( frame ) - { - if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER ) - { - // Parent frame has resize handle - wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight(); - - // Note: allow for some wiggle room here as wxMac's - // window rect calculations seem to be imprecise - if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2 - && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 ) - { - // Parent frame has resize handle and shares - // right bottom corner - return true ; - } - else - { - // Parent frame has resize handle but doesn't - // share right bottom corner - return false ; - } - } - else - { - // Parent frame doesn't have resize handle - return false ; - } - } - } + UInt32 features = 0 ; + GetControlFeatures( m_controlRef, &features ) ; - // No parent frame found - return false ; + return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; } } -void wxWindowMac::MacCreateScrollBars( long style ) +bool wxMacControl::GetNeedsDisplay() const { - wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; - - if ( style & ( wxVSCROLL | wxHSCROLL ) ) - { - int scrlsize = MAC_SCROLLBAR_SIZE ; - if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI ) - { - scrlsize = MAC_SMALL_SCROLLBAR_SIZE ; - } - - int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ; - int width, height ; - GetClientSize( &width , &height ) ; + return HIViewGetNeedsDisplay( m_controlRef ); +} - wxPoint vPoint(width - scrlsize, 0) ; - wxSize vSize(scrlsize, height - adjust) ; - wxPoint hPoint(0, height - scrlsize) ; - wxSize hSize(width - adjust, scrlsize) ; +void wxWidgetImpl::Convert( wxPoint *pt , wxWidgetImpl *from , wxWidgetImpl *to ) +{ + HIPoint hiPoint; - // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize) - if ( style & wxVSCROLL ) - { - m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL); - m_vScrollBar->SetMinSize( wxDefaultSize ); - } + hiPoint.x = pt->x; + hiPoint.y = pt->y; + HIViewConvertPoint( &hiPoint , (ControlRef) from->GetWXWidget() , (ControlRef) to->GetWXWidget() ); + pt->x = (int)hiPoint.x; + pt->y = (int)hiPoint.y; +} - if ( style & wxHSCROLL ) - { - m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL); - m_hScrollBar->SetMinSize( wxDefaultSize ); - } - } +bool wxMacControl::SetFocus() +{ + // as we cannot rely on the control features to find out whether we are in full keyboard mode, + // we can only leave in case of an error - // because the create does not take into account the client area origin - // we might have a real position shift - MacRepositionScrollBars() ; + OSStatus err = SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, kControlFocusNextPart ); + if ( err == errCouldntSetFocus ) + return false ; + SetUserFocusWindow(GetControlOwner( m_controlRef ) ); + + return true; } -bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const +bool wxMacControl::HasFocus() const { - bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar))); + ControlRef control; + GetKeyboardFocus( GetUserFocusWindow() , &control ); + return control == m_controlRef; +} - return result ; +// +// subclass specifics +// + +OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const +{ + return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize ); } -void wxWindowMac::MacRepositionScrollBars() +OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const { - if ( !m_hScrollBar && !m_vScrollBar ) - return ; + return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize ); +} - int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; - int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ; +OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData) +{ + return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData ); +} - // get real client area - int width, height ; - GetSize( &width , &height ); +OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions ) +{ + return SendEventToEventTargetWithOptions( event, + HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions ); +} - width -= MacGetLeftBorderSize() + MacGetRightBorderSize(); - height -= MacGetTopBorderSize() + MacGetBottomBorderSize(); +OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions ) +{ + wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ); - wxPoint vPoint( width - scrlsize, 0 ) ; - wxSize vSize( scrlsize, height - adjust ) ; - wxPoint hPoint( 0 , height - scrlsize ) ; - wxSize hSize( width - adjust, scrlsize ) ; + event.SetParameter(kEventParamDirectObject,command); -#if 0 - int x = 0, y = 0, w, h ; - GetSize( &w , &h ) ; + return SendEvent( event , inOptions ); +} - MacClientToRootWindow( &x , &y ) ; - MacClientToRootWindow( &w , &h ) ; +OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions ) +{ + HICommand command; - wxWindowMac *iter = (wxWindowMac*)this ; + memset( &command, 0 , sizeof(command) ); + command.commandID = commandID; + return SendHICommand( command , inOptions ); +} - int totW = 10000 , totH = 10000; - while ( iter ) - { - if ( iter->IsTopLevel() ) - { - iter->GetSize( &totW , &totH ) ; - break ; - } +void wxMacControl::Flash( ControlPartCode part , UInt32 ticks ) +{ + unsigned long finalTicks; - iter = iter->GetParent() ; - } + HiliteControl( m_controlRef , part ); + Delay( ticks , &finalTicks ); + HiliteControl( m_controlRef , kControlNoPart ); +} - if ( x == 0 ) - { - hPoint.x = -1 ; - hSize.x += 1 ; - } - if ( y == 0 ) - { - vPoint.y = -1 ; - vSize.y += 1 ; - } +SInt32 wxMacControl::GetValue() const +{ + return ::GetControl32BitValue( m_controlRef ); +} - if ( w - x >= totW ) - { - hSize.x += 1 ; - vPoint.x += 1 ; - } - if ( h - y >= totH ) - { - vSize.y += 1 ; - hPoint.y += 1 ; - } -#endif +SInt32 wxMacControl::GetMaximum() const +{ + return ::GetControl32BitMaximum( m_controlRef ); +} - if ( m_vScrollBar ) - m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE ); - if ( m_hScrollBar ) - m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE ); +SInt32 wxMacControl::GetMinimum() const +{ + return ::GetControl32BitMinimum( m_controlRef ); } -bool wxWindowMac::AcceptsFocus() const +void wxMacControl::SetValue( SInt32 v ) { - return MacCanFocus() && wxWindowBase::AcceptsFocus(); + ::SetControl32BitValue( m_controlRef , v ); } -void wxWindowMac::MacSuperChangedPosition() +void wxMacControl::SetMinimum( SInt32 v ) { - // only window-absolute structures have to be moved i.e. controls + ::SetControl32BitMinimum( m_controlRef , v ); +} - m_cachedClippedRectValid = false ; +void wxMacControl::SetMaximum( SInt32 v ) +{ + ::SetControl32BitMaximum( m_controlRef , v ); +} - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - child->MacSuperChangedPosition() ; +void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum ) +{ + ::SetControl32BitMinimum( m_controlRef , minimum ); + ::SetControl32BitMaximum( m_controlRef , maximum ); + ::SetControl32BitValue( m_controlRef , value ); +} - node = node->GetNext(); - } +void wxMacControl::VisibilityChanged(bool WXUNUSED(shown)) +{ } -void wxWindowMac::MacTopLevelWindowChangedPosition() +void wxMacControl::SuperChangedPosition() { - // only screen-absolute structures have to be moved i.e. glcanvas +} - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) +void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle ) +{ + m_font = font; +#if wxMAC_USE_CORE_TEXT + if ( UMAGetSystemVersion() >= 0x1050 ) { - child = node->GetData(); - child->MacTopLevelWindowChangedPosition() ; + HIViewPartCode part = 0; + HIThemeTextHorizontalFlush flush = kHIThemeTextHorizontalFlushDefault; + if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL ) + flush = kHIThemeTextHorizontalFlushCenter; + else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT ) + flush = kHIThemeTextHorizontalFlushRight; + HIViewSetTextFont( m_controlRef , part , (CTFontRef) font.MacGetCTFont() ); + HIViewSetTextHorizontalFlush( m_controlRef, part, flush ); - node = node->GetNext(); + if ( foreground != *wxBLACK ) + { + ControlFontStyleRec fontStyle; + foreground.GetRGBColor( &fontStyle.foreColor ); + fontStyle.flags = kControlUseForeColorMask; + ::SetControlFontStyle( m_controlRef , &fontStyle ); + } } -} +#endif +#if wxMAC_USE_ATSU_TEXT + ControlFontStyleRec fontStyle; + if ( font.MacGetThemeFontID() != kThemeCurrentPortFont ) + { + switch ( font.MacGetThemeFontID() ) + { + case kThemeSmallSystemFont : + fontStyle.font = kControlFontSmallSystemFont; + break; -long wxWindowMac::MacGetLeftBorderSize() const -{ - if ( IsTopLevel() ) - return 0 ; + case 109 : // mini font + fontStyle.font = -5; + break; - SInt32 border = 0 ; + case kThemeSystemFont : + fontStyle.font = kControlFontBigSystemFont; + break; - if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER)) + default : + fontStyle.font = kControlFontBigSystemFont; + break; + } + + fontStyle.flags = kControlUseFontMask; + } + else { - // this metric is only the 'outset' outside the simple frame rect - GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; - border += 1 ; + fontStyle.font = font.MacGetFontNum(); + fontStyle.style = font.MacGetFontStyle(); + fontStyle.size = font.MacGetFontSize(); + fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask; } - else if (HasFlag(wxSIMPLE_BORDER)) + + fontStyle.just = teJustLeft; + fontStyle.flags |= kControlUseJustMask; + if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL ) + fontStyle.just = teJustCenter; + else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT ) + fontStyle.just = teJustRight; + + + // we only should do this in case of a non-standard color, as otherwise 'disabled' controls + // won't get grayed out by the system anymore + + if ( foreground != *wxBLACK ) { - // this metric is only the 'outset' outside the simple frame rect - GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; - border += 1 ; + foreground.GetRGBColor( &fontStyle.foreColor ); + fontStyle.flags |= kControlUseForeColorMask; } - return border ; + ::SetControlFontStyle( m_controlRef , &fontStyle ); +#endif } -long wxWindowMac::MacGetRightBorderSize() const +void wxMacControl::SetBackgroundColour( const wxColour &WXUNUSED(col) ) { - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; +// HITextViewSetBackgroundColor( m_textView , color ); } -long wxWindowMac::MacGetTopBorderSize() const +void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum ) { - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; + ::SetControl32BitMinimum( m_controlRef , minimum ); + ::SetControl32BitMaximum( m_controlRef , maximum ); } -long wxWindowMac::MacGetBottomBorderSize() const +short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers ) { - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; + return HandleControlKey( m_controlRef , keyCode , charCode , modifiers ); } -long wxWindowMac::MacRemoveBordersFromStyle( long style ) +void wxMacControl::SetActionProc( ControlActionUPP actionProc ) { - return style & ~wxBORDER_MASK ; + SetControlAction( m_controlRef , actionProc ); } -// Find the wxWindowMac at the current mouse position, returning the mouse -// position. -wxWindowMac * wxFindWindowAtPointer( wxPoint& pt ) +void wxMacControl::SetViewSize( SInt32 viewSize ) { - pt = wxGetMousePosition(); - wxWindowMac* found = wxFindWindowAtPoint(pt); + SetControlViewSize(m_controlRef , viewSize ); +} - return found; +SInt32 wxMacControl::GetViewSize() const +{ + return GetControlViewSize( m_controlRef ); } -// Get the current mouse position. -wxPoint wxGetMousePosition() +bool wxMacControl::IsVisible() const { - int x, y; + return IsControlVisible( m_controlRef ); +} - wxGetMousePosition( &x, &y ); +void wxMacControl::SetVisibility( bool visible ) +{ + SetControlVisibility( m_controlRef , visible, true ); +} - return wxPoint(x, y); +bool wxMacControl::IsEnabled() const +{ + return IsControlEnabled( m_controlRef ); } -void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) +bool wxMacControl::IsActive() const { - if ( event.GetEventType() == wxEVT_RIGHT_DOWN ) - { - // copied from wxGTK : CS - // VZ: shouldn't we move this to base class then? + return IsControlActive( m_controlRef ); +} - // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN - // except that: - // - // (a) it's a command event and so is propagated to the parent - // (b) under MSW it can be generated from kbd too - // (c) it uses screen coords (because of (a)) - wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, - this->GetId(), - this->ClientToScreen(event.GetPosition())); - evtCtx.SetEventObject(this); - if ( ! HandleWindowEvent(evtCtx) ) - event.Skip() ; - } +void wxMacControl::Enable( bool enable ) +{ + if ( enable ) + EnableControl( m_controlRef ); else - { - event.Skip() ; - } + DisableControl( m_controlRef ); } -void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) ) +void wxMacControl::SetDrawingEnabled( bool enable ) { - // for native controls: call their native paint method - if ( !MacIsUserPane() || ( IsTopLevel() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM ) ) + HIViewSetDrawingEnabled( m_controlRef , enable ); +} + +void wxMacControl::GetRectInWindowCoords( Rect *r ) +{ + GetControlBounds( m_controlRef , r ) ; + + WindowRef tlwref = GetControlOwner( m_controlRef ) ; + + wxNonOwnedWindow* tlwwx = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) tlwref ) ; + if ( tlwwx != NULL ) { - if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL - && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) - CallNextEventHandler( - (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , - (EventRef) wxTheApp->MacGetCurrentEvent() ) ; + ControlRef rootControl = tlwwx->GetPeer()->GetControlRef() ; + HIPoint hiPoint = CGPointMake( 0 , 0 ) ; + HIViewConvertPoint( &hiPoint , HIViewGetSuperview(m_controlRef) , rootControl ) ; + OffsetRect( r , (short) hiPoint.x , (short) hiPoint.y ) ; } } -void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control), - wxInt16 WXUNUSED(controlpart), - bool WXUNUSED(mouseStillDown)) +void wxMacControl::GetBestRect( Rect *r ) { + short baselineoffset; + + GetBestControlRect( m_controlRef , r , &baselineoffset ); } -Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) +void wxMacControl::SetLabel( const wxString &title ) { - int x, y, w, h ; + wxFontEncoding encoding; - window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ; - Rect bounds = { y, x, y + h, x + w }; + if ( m_font.Ok() ) + encoding = m_font.GetEncoding(); + else + encoding = wxFont::GetDefaultEncoding(); - return bounds ; + SetControlTitleWithCFString( m_controlRef , wxCFStringRef( title , encoding ) ); } -wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) +void wxMacControl::GetFeatures( UInt32 * features ) { - return eventNotHandledErr ; + GetControlFeatures( m_controlRef , features ); } -bool wxWindowMac::Reparent(wxWindowBase *newParentBase) +OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region ) { - wxWindowMac *newParent = (wxWindowMac *)newParentBase; - if ( !wxWindowBase::Reparent(newParent) ) - return false; + OSStatus err = GetControlRegion( m_controlRef , partCode , region ); + return err; +} - // copied from MacPostControlCreate - ControlRef container = (ControlRef) GetParent()->GetHandle() ; +// SetNeedsDisplay would not invalidate the children +static void InvalidateControlAndChildren( HIViewRef control ) +{ + HIViewSetNeedsDisplay( control , true ); + UInt16 childrenCount = 0; + OSStatus err = CountSubControls( control , &childrenCount ); + if ( err == errControlIsNotEmbedder ) + return; - wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; + wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ); - ::EmbedControl( m_peer->GetControlRef() , container ) ; + for ( UInt16 i = childrenCount; i >=1; --i ) + { + HIViewRef child; - return true; + err = GetIndexedSubControl( control , i , & child ); + if ( err == errControlIsNotEmbedder ) + return; + + InvalidateControlAndChildren( child ); + } } -bool wxWindowMac::SetTransparent(wxByte alpha) +void wxMacControl::InvalidateWithChildren() { - SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); + InvalidateControlAndChildren( m_controlRef ); +} - if ( alpha != m_macAlpha ) +OSType wxMacCreator = 'WXMC'; +OSType wxMacControlProperty = 'MCCT'; + +void wxMacControl::SetReferenceInNativeControl() +{ + void * data = this; + verify_noerr( SetControlProperty ( m_controlRef , + wxMacCreator,wxMacControlProperty, sizeof(data), &data ) ); +} + +wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control) +{ + wxMacControl* ctl = NULL; + ByteCount actualSize; + if ( GetControlProperty( control ,wxMacCreator,wxMacControlProperty, sizeof(ctl) , + &actualSize , &ctl ) == noErr ) { - m_macAlpha = alpha ; - Refresh() ; + return ctl; } - return true ; + return NULL; } -bool wxWindowMac::CanSetTransparent() -{ - return true ; -} +// +// Tab Control +// -wxByte wxWindowMac::GetTransparent() const +OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable ) { - return m_macAlpha ; + return ::SetTabEnabled( m_controlRef , tabNo , enable ); } -bool wxWindowMac::IsShownOnScreen() const + + +// Control Factory + +wxWidgetImpl* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now ) { -#if TARGET_API_MAC_OSX - if ( m_peer && m_peer->Ok() ) + // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of + // the content view, so we have to retrieve it explicitly + + wxMacControl* contentview = new wxMacControl(now , true /*isRootControl*/); + HIViewFindByID( HIViewGetRoot( (WindowRef) now->GetWXWindow() ) , kHIViewWindowContentID , + contentview->GetControlRefAddr() ) ; + if ( !contentview->IsOk() ) { - bool peerVis = m_peer->IsVisible(); - bool wxVis = wxWindowBase::IsShownOnScreen(); - if( peerVis != wxVis ) - { - // CS : put a breakpoint here to investigate differences - // between native an wx visibilities - // the only place where I've encountered them until now - // are the hiding/showing sequences where the vis-changed event is - // first sent to the innermost control, while wx does things - // from the outmost control - wxVis = wxWindowBase::IsShownOnScreen(); - return wxVis; - } - - return m_peer->IsVisible(); + // compatibility mode fallback + GetRootControl( (WindowRef) now->GetWXWindow() , contentview->GetControlRefAddr() ) ; } -#endif - return wxWindowBase::IsShownOnScreen(); + // the root control level handler + contentview->InstallEventHandler() ; + return contentview; } + +#endif // wxOSX_USE_CARBON