From 6239ee05567eac71754f56c2a154222d10b57ff1 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 9 Nov 2007 21:12:22 +0000 Subject: [PATCH] forward port from 2.8 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49792 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/mac/carbon/accel.cpp | 8 +- src/mac/carbon/app.cpp | 176 ++++---- src/mac/carbon/bitmap.cpp | 701 +++++++++++++++++++++----------- src/mac/carbon/bmpbuttn.cpp | 1 + src/mac/carbon/button.cpp | 49 ++- src/mac/carbon/checklst.cpp | 1 + src/mac/carbon/clipbrd.cpp | 322 +++------------ src/mac/carbon/cursor.cpp | 70 ++-- src/mac/carbon/dataobj.cpp | 558 +++++++++++++++++++++++-- src/mac/carbon/dcclient.cpp | 3 + src/mac/carbon/dcmemory.cpp | 26 +- src/mac/carbon/dcscreen.cpp | 4 + src/mac/carbon/dialog.cpp | 40 +- src/mac/carbon/dirdlg.cpp | 6 +- src/mac/carbon/dnd.cpp | 285 +++---------- src/mac/carbon/filedlg.cpp | 67 ++- src/mac/carbon/font.cpp | 205 ++++++++-- src/mac/carbon/graphics.cpp | 290 +++++++++---- src/mac/carbon/icon.cpp | 36 +- src/mac/carbon/listbox.cpp | 1 + src/mac/carbon/listctrl_mac.cpp | 43 +- src/mac/carbon/mediactrl.cpp | 10 + src/mac/carbon/menu.cpp | 76 ++++ src/mac/carbon/menuitem.cpp | 10 + src/mac/carbon/metafile.cpp | 299 ++++++++++---- src/mac/carbon/msgdlg.cpp | 4 +- src/mac/carbon/overlay.cpp | 2 +- src/mac/carbon/popupwin.cpp | 141 +++++-- src/mac/carbon/radiobox.cpp | 33 ++ src/mac/carbon/renderer.cpp | 28 +- src/mac/carbon/slider.cpp | 2 +- src/mac/carbon/sound.cpp | 15 + src/mac/carbon/stattext.cpp | 2 + src/mac/carbon/taskbar.cpp | 157 ++++--- src/mac/carbon/textctrl.cpp | 210 ++++++---- src/mac/carbon/toolbar.cpp | 72 ++-- src/mac/carbon/tooltip.cpp | 34 -- src/mac/carbon/toplevel.cpp | 152 ++++--- src/mac/carbon/uma.cpp | 88 +++- src/mac/carbon/utils.cpp | 12 +- src/mac/carbon/window.cpp | 294 +++++++++----- 41 files changed, 2912 insertions(+), 1621 deletions(-) diff --git a/src/mac/carbon/accel.cpp b/src/mac/carbon/accel.cpp index d15f454626..b221f9107c 100644 --- a/src/mac/carbon/accel.cpp +++ b/src/mac/carbon/accel.cpp @@ -91,10 +91,10 @@ int wxAcceleratorTable::GetCommand( wxKeyEvent &event ) { wxAcceleratorEntry *entry = node->GetData(); if ((event.m_keyCode == entry->GetKeyCode()) && - (((entry->GetFlags() & wxACCEL_CTRL) == 0) || event.ControlDown()) && - (((entry->GetFlags() & wxACCEL_SHIFT) == 0) || event.ShiftDown()) && - (((entry->GetFlags() & wxACCEL_ALT) == 0) || event.AltDown()) && - (((entry->GetFlags() & wxACCEL_CMD) == 0) || event.CmdDown())) + (((entry->GetFlags() & wxACCEL_CTRL) != 0) == event.ControlDown()) && + (((entry->GetFlags() & wxACCEL_SHIFT) != 0) == event.ShiftDown()) && + (((entry->GetFlags() & wxACCEL_ALT) != 0) == event.AltDown()) && + (((entry->GetFlags() & wxACCEL_CMD) != 0) == event.CmdDown())) { return entry->GetCommand(); } diff --git a/src/mac/carbon/app.cpp b/src/mac/carbon/app.cpp index 4b45779556..4204a53721 100644 --- a/src/mac/carbon/app.cpp +++ b/src/mac/carbon/app.cpp @@ -355,18 +355,25 @@ void wxApp::MacReopenApp() else { wxTopLevelWindow* firstIconized = NULL ; + wxTopLevelWindow* firstHidden = NULL ; while (node) { wxTopLevelWindow* win = (wxTopLevelWindow*) node->GetData(); - if ( !win->IsIconized() ) + if ( !win->IsShown() ) { - firstIconized = NULL ; - break ; + // make sure we don't show 'virtual toplevel windows' like wxTaskBarIconWindow + if ( firstHidden == NULL && ( wxDynamicCast( win, wxFrame ) || wxDynamicCast( win, wxDialog ) ) ) + firstHidden = win ; + } + else if ( win->IsIconized() ) + { + if ( firstIconized == NULL ) + firstIconized = win ; } else { - if ( firstIconized == NULL ) - firstIconized = win ; + // we do have a visible, non-iconized toplevelwindow -> do nothing + return; } node = node->GetNext(); @@ -374,6 +381,8 @@ void wxApp::MacReopenApp() if ( firstIconized ) firstIconized->Iconize( false ) ; + else if ( firstHidden ) + firstHidden->Show( true ); } } @@ -469,6 +478,7 @@ UInt32 wxIdToMacCommand( int wxId ) wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) { wxMenu* itemMenu = NULL ; +#ifndef __WXUNIVERSAL__ int id = 0 ; // for 'standard' commands which don't have a wx-menu @@ -511,7 +521,7 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) item = (wxMenuItem*) refCon ; } } - +#endif return itemMenu ; } @@ -549,6 +559,7 @@ wxMacAppMenuEventHandler( EventHandlerCallRef WXUNUSED(handler), { wxMacCarbonEvent cEvent( event ) ; MenuRef menuRef = cEvent.GetParameter(kEventParamDirectObject) ; +#ifndef __WXUNIVERSAL__ wxMenu* menu = wxFindMenuFromMacMenu( menuRef ) ; if ( menu ) @@ -594,7 +605,7 @@ wxMacAppMenuEventHandler( EventHandlerCallRef WXUNUSED(handler), } } } - +#endif return eventNotHandledErr; } @@ -621,60 +632,11 @@ wxMacAppCommandEventHandler( EventHandlerCallRef WXUNUSED(handler) , switch ( cEvent.GetKind() ) { case kEventProcessCommand : - { - if (item->IsCheckable()) - item->Check( !item->IsChecked() ) ; - - if ( itemMenu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ) - result = noErr ; - } + result = itemMenu->MacHandleCommandProcess( item, id ); break ; case kEventCommandUpdateStatus: - { - wxUpdateUIEvent event(id); - event.SetEventObject( itemMenu ); - - bool processed = false; - - // Try the menu's event handler - { - wxEvtHandler *handler = itemMenu->GetEventHandler(); - if ( handler ) - processed = handler->ProcessEvent(event); - } - - // Try the window the menu was popped up from - // (and up through the hierarchy) - if ( !processed ) - { - const wxMenuBase *menu = itemMenu; - while ( menu ) - { - wxWindow *win = menu->GetInvokingWindow(); - if ( win ) - { - processed = win->GetEventHandler()->ProcessEvent(event); - break; - } - - menu = menu->GetParent(); - } - } - - if ( processed ) - { - // if anything changed, update the changed attribute - if (event.GetSetText()) - itemMenu->SetLabel(id, event.GetText()); - if (event.GetSetChecked()) - itemMenu->Check(id, event.GetChecked()); - if (event.GetSetEnabled()) - itemMenu->Enable(id, event.GetEnabled()); - - result = noErr ; - } - } + result = itemMenu->MacHandleCommandUpdateStatus( item, id ); break ; default : @@ -947,6 +909,9 @@ bool wxApp::OnInitGui() sQuitHandler , 0 , FALSE ) ; } + if ( !wxMacInitCocoa() ) + return false; + return true ; } @@ -1145,10 +1110,14 @@ wxApp::wxApp() void wxApp::OnIdle(wxIdleEvent& WXUNUSED(event)) { - wxMacProcessNotifierEvents(); - + // If they are pending events, we must process them: pending events are + // either events to the threads other than main or events posted with + // wxPostEvent() functions + wxMacProcessNotifierAndPendingEvents(); +#ifndef __WXUNIVERSAL__ if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar()) wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar(); +#endif } void wxApp::WakeUpIdle() @@ -1248,6 +1217,7 @@ bool wxApp::Yield(bool onlyIfNeeded) void wxApp::MacDoOneEvent() { + wxMacAutoreleasePool autoreleasepool; EventRef theEvent; s_inReceiveEvent = true ; @@ -1690,57 +1660,65 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess { // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier // and look at the character after +#ifdef __LP64__ + // TODO new implementation using TextInputSources +#else UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey | shiftKey | optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); +#endif } long keyval = wxMacTranslateKey(keychar, keycode) ; if ( keyval == keychar && ( event.GetEventType() == wxEVT_KEY_UP || event.GetEventType() == wxEVT_KEY_DOWN ) ) keyval = wxToupper( keyval ) ; - // Check for NUMPAD keys - if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) + // Check for NUMPAD keys. For KEY_UP/DOWN events we need to use the + // WXK_NUMPAD constants, but for the CHAR event we want to use the + // standard ascii values + if ( event.GetEventType() != wxEVT_CHAR ) { - keyval = (keyval - '0') + WXK_NUMPAD0; - } - else if (keycode >= 67 && keycode <= 81) - { - switch (keycode) + if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) { - case 76 : - keyval = WXK_NUMPAD_ENTER; - break; - - case 81: - keyval = WXK_NUMPAD_EQUAL; - break; - - case 67: - keyval = WXK_NUMPAD_MULTIPLY; - break; - - case 75: - keyval = WXK_NUMPAD_DIVIDE; - break; - - case 78: - keyval = WXK_NUMPAD_SUBTRACT; - break; - - case 69: - keyval = WXK_NUMPAD_ADD; - break; - - case 65: - keyval = WXK_NUMPAD_DECIMAL; - break; - - default: - break; - } // end switch + keyval = (keyval - '0') + WXK_NUMPAD0; + } + else if (keycode >= 65 && keycode <= 81) + { + switch (keycode) + { + case 76 : + keyval = WXK_NUMPAD_ENTER; + break; + + case 81: + keyval = WXK_NUMPAD_EQUAL; + break; + + case 67: + keyval = WXK_NUMPAD_MULTIPLY; + break; + + case 75: + keyval = WXK_NUMPAD_DIVIDE; + break; + + case 78: + keyval = WXK_NUMPAD_SUBTRACT; + break; + + case 69: + keyval = WXK_NUMPAD_ADD; + break; + + case 65: + keyval = WXK_NUMPAD_DECIMAL; + break; + default: + break; + } + } } - + event.m_shiftDown = modifiers & shiftKey; event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index 8f5c67a4c6..1b52261571 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -30,6 +30,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) #ifdef __DARWIN__ #include + #include #else #include #endif @@ -46,8 +47,20 @@ IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) // under Quartz then content is transformed into a CGImageRef representing the same data // which can be transferred to the GPU by the OS for fast rendering -// we don't dare use premultiplied alpha yet +#if wxMAC_USE_CORE_GRAPHICS + #define wxMAC_USE_PREMULTIPLIED_ALPHA 1 + static const int kBestByteAlignement = 16; + static const int kMaskBytesPerPixel = 1; +#else #define wxMAC_USE_PREMULTIPLIED_ALPHA 0 + static const int kBestByteAlignement = 4; + static const int kMaskBytesPerPixel = 4; +#endif + +static int GetBestBytesPerRow( int rawBytes ) +{ + return (((rawBytes)+kBestByteAlignement-1) & ~(kBestByteAlignement-1) ); +} #if wxUSE_BMPBUTTON @@ -60,7 +73,22 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi if ( bmap == NULL ) return ; - if ( ( bmap->HasNativeSize() && forceType == 0 ) || forceType == kControlContentIconRef ) + if ( forceType == 0 ) + { + // NOTE : For testing Panther behaviour under higher + // Systems make this always be false + if ( UMAGetSystemVersion() >= 0x1040 ) + { + // as soon as it is supported, it's a better default + forceType = kControlContentCGImageRef; + } + else if ( bmap->HasNativeSize() ) + { + forceType = kControlContentIconRef; + } + } + + if ( forceType == kControlContentIconRef ) { wxBitmap scaleBmp ; wxBitmapRefData* bmp = bmap ; @@ -84,13 +112,11 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi info->u.iconRef = bmp->GetIconRef() ; AcquireIconRef( info->u.iconRef ) ; } -#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 else if ( forceType == kControlContentCGImageRef ) { info->contentType = kControlContentCGImageRef ; info->u.imageRef = (CGImageRef) bmap->CGImageCreate() ; } -#endif else { #ifndef __LP64__ @@ -101,6 +127,14 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi } } +CGImageRef wxMacCreateCGImageFromBitmap( const wxBitmap& bitmap ) +{ + wxBitmapRefData * bmap = bitmap.GetBitmapData() ; + if ( bmap == NULL ) + return NULL ; + return (CGImageRef) bmap->CGImageCreate(); +} + void wxMacReleaseBitmapButton( ControlButtonContentInfo*info ) { if ( info->contentType == kControlContentIconRef ) @@ -136,6 +170,7 @@ void wxBitmapRefData::Init() m_width = 0 ; m_height = 0 ; m_depth = 0 ; + m_bytesPerRow = 0; m_ok = false ; m_bitmapMask = NULL ; @@ -146,8 +181,10 @@ void wxBitmapRefData::Init() m_iconRef = NULL ; m_pictHandle = NULL ; m_hBitmap = NULL ; +#if! wxMAC_USE_CORE_GRAPHICS m_hMaskBitmap = NULL; m_maskBytesPerRow = 0 ; +#endif m_rawAccessCount = 0 ; m_hasAlpha = false; @@ -160,19 +197,13 @@ wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy) if (tocopy.m_bitmapMask) m_bitmapMask = new wxMask(*tocopy.m_bitmapMask); + else if (tocopy.m_hasAlpha) + UseAlpha(true); unsigned char* dest = (unsigned char*)GetRawAccess(); unsigned char* source = (unsigned char*)tocopy.GetRawAccess(); - size_t numbytes = tocopy.m_width * tocopy.m_height * 4; - - for (size_t i=0; i= MAC_OS_X_VERSION_10_5 + if ( UMAGetSystemVersion() >= 0x1050 ) + { + dataType = kIconServices128PixelDataARGB ; + } + else +#endif + { + dataType = kThumbnail32BitData ; + maskType = kThumbnail8BitMask ; + } break; case 48: - dataType = kHuge32BitData ; - maskType = kHuge8BitMask ; +#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( UMAGetSystemVersion() >= 0x1050 ) + { + dataType = kIconServices48PixelDataARGB ; + } + else +#endif + { + dataType = kHuge32BitData ; + maskType = kHuge8BitMask ; + } break; case 32: - dataType = kLarge32BitData ; - maskType = kLarge8BitMask ; +#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( UMAGetSystemVersion() >= 0x1050 ) + { + dataType = kIconServices32PixelDataARGB ; + } + else +#endif + { + dataType = kLarge32BitData ; + maskType = kLarge8BitMask ; + } break; case 16: - dataType = kSmall32BitData ; - maskType = kSmall8BitMask ; +#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( UMAGetSystemVersion() >= 0x1050 ) + { + dataType = kIconServices16PixelDataARGB ; + } + else +#endif + { + dataType = kSmall32BitData ; + maskType = kSmall8BitMask ; + } break; default: @@ -351,73 +430,138 @@ IconRef wxBitmapRefData::GetIconRef() if ( dataType != 0 ) { - // setup the header properly - - Handle data = NULL ; - Handle maskdata = NULL ; - unsigned char * maskptr = NULL ; - unsigned char * ptr = NULL ; - size_t datasize, masksize ; - - datasize = sz * sz * 4 ; - data = NewHandle( datasize ) ; - HLock( data ) ; - ptr = (unsigned char*) *data ; - memset( ptr , 0, datasize ) ; - - masksize = sz * sz ; - maskdata = NewHandle( masksize ) ; - HLock( maskdata ) ; - maskptr = (unsigned char*) *maskdata ; - memset( maskptr , 0 , masksize ) ; - - bool hasAlpha = HasAlpha() ; - wxMask *mask = m_bitmapMask ; - unsigned char * source = (unsigned char*) GetRawAccess() ; - unsigned char * masksource = mask ? (unsigned char*) mask->GetRawAccess() : NULL ; - - for ( int y = 0 ; y < h ; ++y ) +#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( maskType == 0 && UMAGetSystemVersion() >= 0x1050 ) { - unsigned char * dest = ptr + y * sz * 4 ; - unsigned char * maskdest = maskptr + y * sz ; - unsigned char a, r, g, b; - - for ( int x = 0 ; x < w ; ++x ) + size_t datasize = sz * sz * 4 ; + Handle data = NewHandle( datasize ) ; + HLock( data ) ; + unsigned char* ptr = (unsigned char*) *data ; + memset( ptr, 0, datasize ); + bool hasAlpha = HasAlpha() ; + wxMask *mask = m_bitmapMask ; + unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ; + unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ; + + for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 ) { - a = *source ++ ; - r = *source ++ ; - g = *source ++ ; - b = *source ++ ; + unsigned char * source = sourcePtr; + unsigned char * masksource = masksourcePtr; + unsigned char * dest = ptr + y * sz * 4 ; + unsigned char a, r, g, b; - *dest++ = 0 ; - *dest++ = r ; - *dest++ = g ; - *dest++ = b ; + for ( int x = 0 ; x < w ; ++x ) + { + a = *source ++ ; + r = *source ++ ; + g = *source ++ ; + b = *source ++ ; + + if ( mask ) + { + a = 0xFF - *masksource++ ; + } + else if ( !hasAlpha ) + a = 0xFF ; + else + { +#if wxMAC_USE_PREMULTIPLIED_ALPHA + // this must be non-premultiplied data + if ( a != 0xFF && a!= 0 ) + { + r = r * 255 / a; + g = g * 255 / a; + b = b * 255 / a; + } +#endif + } + *dest++ = a ; + *dest++ = r ; + *dest++ = g ; + *dest++ = b ; - if ( mask ) + } + } + HUnlock( data ); + OSStatus err = SetIconFamilyData( iconFamily, dataType , data ); + wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ); + DisposeHandle( data ); + } + else +#endif + { + // setup the header properly + + Handle data = NULL ; + Handle maskdata = NULL ; + unsigned char * maskptr = NULL ; + unsigned char * ptr = NULL ; + size_t datasize, masksize ; + + datasize = sz * sz * 4 ; + data = NewHandle( datasize ) ; + HLock( data ) ; + ptr = (unsigned char*) *data ; + memset( ptr , 0, datasize ) ; + + masksize = sz * sz ; + maskdata = NewHandle( masksize ) ; + HLock( maskdata ) ; + maskptr = (unsigned char*) *maskdata ; + memset( maskptr , 0 , masksize ) ; + + bool hasAlpha = HasAlpha() ; + wxMask *mask = m_bitmapMask ; + unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ; + unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ; + + for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 ) + { + unsigned char * source = sourcePtr; + unsigned char * masksource = masksourcePtr; + unsigned char * dest = ptr + y * sz * 4 ; + unsigned char * maskdest = maskptr + y * sz ; + unsigned char a, r, g, b; + + for ( int x = 0 ; x < w ; ++x ) { - *maskdest++ = 0xFF - *masksource++ ; - masksource++ ; - masksource++ ; - masksource++ ; + a = *source ++ ; + r = *source ++ ; + g = *source ++ ; + b = *source ++ ; + + *dest++ = 0 ; + *dest++ = r ; + *dest++ = g ; + *dest++ = b ; + + if ( mask ) + { + *maskdest++ = 0xFF - *masksource++ ; +#if !wxMAC_USE_CORE_GRAPHICS + masksource++ ; + masksource++ ; + masksource++ ; +#endif + } + else if ( hasAlpha ) + *maskdest++ = a ; + else + *maskdest++ = 0xFF ; } - else if ( hasAlpha ) - *maskdest++ = a ; - else - *maskdest++ = 0xFF ; } + + OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ; + wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; + + err = SetIconFamilyData( iconFamily, maskType , maskdata ) ; + wxASSERT_MSG( err == noErr , wxT("Error when adding mask") ) ; + + HUnlock( data ) ; + HUnlock( maskdata ) ; + DisposeHandle( data ) ; + DisposeHandle( maskdata ) ; } - - OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ; - wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; - - err = SetIconFamilyData( iconFamily, maskType , maskdata ) ; - wxASSERT_MSG( err == noErr , wxT("Error when adding mask") ) ; - - HUnlock( data ) ; - HUnlock( maskdata ) ; - DisposeHandle( data ) ; - DisposeHandle( maskdata ) ; } else { @@ -425,23 +569,12 @@ IconRef wxBitmapRefData::GetIconRef() SetIconFamilyData( iconFamily, 'PICT' , (Handle) pic ) ; } // transform into IconRef -#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + // cleaner version existing from 10.3 upwards HLock((Handle) iconFamily); OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &m_iconRef ); HUnlock((Handle) iconFamily); wxASSERT_MSG( err == noErr , wxT("Error when constructing icon ref") ); -#else - static int iconCounter = 2 ; - - OSStatus err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &m_iconRef ) ; - wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; - - // we have to retain a reference, as Unregister will decrement it - AcquireIconRef( m_iconRef ) ; - UnregisterIconRef( 'WXNG' , (OSType) iconCounter ) ; - ++iconCounter ; -#endif DisposeHandle( (Handle) iconFamily ) ; } @@ -452,7 +585,7 @@ PicHandle wxBitmapRefData::GetPictHandle() { if ( m_pictHandle == NULL ) { -#ifndef __LP64__ +#if !wxMAC_USE_CORE_GRAPHICS CGrafPtr origPort = NULL ; GDHandle origDev = NULL ; GWorldPtr wp = NULL ; @@ -522,6 +655,34 @@ PicHandle wxBitmapRefData::GetPictHandle() SetGWorld( origPort , origDev ) ; if ( clipRgn ) DisposeRgn( clipRgn ) ; +#else +#ifndef __LP64__ + GraphicsExportComponent exporter = 0; + OSStatus err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePicture, &exporter); + if (noErr == err) + { + m_pictHandle = (PicHandle) NewHandle(0); + if ( m_pictHandle ) + { + // QT does not correctly export the mask + // TODO if we get around to it create a synthetic PICT with the CopyBits and Mask commands + CGImageRef imageRef = CGImageCreate(); + err = GraphicsExportSetInputCGImage( exporter, imageRef ); + err = GraphicsExportSetOutputHandle(exporter, (Handle)m_pictHandle); + err = GraphicsExportDoExport(exporter, NULL); + CGImageRelease( imageRef ); + + size_t handleSize = GetHandleSize( (Handle) m_pictHandle ); + // the 512 bytes header is only needed for pict files, but not in memory + if ( handleSize >= 512 ) + { + memmove( *m_pictHandle , (char*)(*m_pictHandle)+512, handleSize - 512 ); + SetHandleSize( (Handle) m_pictHandle, handleSize - 512 ); + } + } + CloseComponent( exporter ); + } +#endif #endif } @@ -545,76 +706,95 @@ CGImageRef wxBitmapRefData::CGImageCreate() const CGImageRef image ; if ( m_rawAccessCount > 0 || m_cgImageRef == NULL ) { - size_t imageSize = m_width * m_height * 4 ; - void * dataBuffer = m_memBuf.GetData() ; - int w = m_width ; - int h = m_height ; - CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ; - wxMemoryBuffer* membuf = NULL ; - - if ( m_bitmapMask ) +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) && wxMAC_USE_CORE_GRAPHICS + if ( UMAGetSystemVersion() >= 0x1040 && m_depth != 1 && m_bitmapMask == NULL ) { - alphaInfo = kCGImageAlphaFirst ; - membuf = new wxMemoryBuffer( imageSize ) ; - memcpy( membuf->GetData() , dataBuffer , imageSize ) ; - unsigned char *sourcemaskstart = (unsigned char *) m_bitmapMask->GetRawAccess() ; - int maskrowbytes = m_bitmapMask->GetBytesPerRow() ; - unsigned char *destalpha = (unsigned char *) membuf->GetData() ; - for ( int y = 0 ; y < h ; ++y , sourcemaskstart += maskrowbytes) + if ( m_bitmapMask ) { - unsigned char *sourcemask = sourcemaskstart ; - for ( int x = 0 ; x < w ; ++x , sourcemask += 4 , destalpha += 4 ) - { - *destalpha = 0xFF - *sourcemask ; - } + CGImageRef tempImage = CGBitmapContextCreateImage( m_hBitmap ); + CGImageRef tempMask = CGBitmapContextCreateImage((CGContextRef) m_bitmapMask->GetHBITMAP() ); + image = CGImageCreateWithMask( tempImage, tempMask ); + CGImageRelease(tempMask); + CGImageRelease(tempImage); } + else + image = CGBitmapContextCreateImage( m_hBitmap ); } else +#endif { - if ( m_hasAlpha ) + size_t imageSize = m_height * m_bytesPerRow ; + void * dataBuffer = m_memBuf.GetData() ; + int w = m_width ; + int h = m_height ; + CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ; + wxMemoryBuffer* membuf = NULL ; + + if ( m_bitmapMask ) { + alphaInfo = kCGImageAlphaFirst ; + membuf = new wxMemoryBuffer( imageSize ) ; + memcpy( membuf->GetData() , dataBuffer , imageSize ) ; + unsigned char *sourcemaskstart = (unsigned char *) m_bitmapMask->GetRawAccess() ; + int maskrowbytes = m_bitmapMask->GetBytesPerRow() ; + unsigned char *destalphastart = (unsigned char *) membuf->GetData() ; + for ( int y = 0 ; y < h ; ++y , destalphastart += m_bytesPerRow, sourcemaskstart += maskrowbytes) + { + unsigned char *sourcemask = sourcemaskstart ; + unsigned char *destalpha = destalphastart ; + for ( int x = 0 ; x < w ; ++x , sourcemask += kMaskBytesPerPixel , destalpha += 4 ) + { + *destalpha = 0xFF - *sourcemask ; + } + } + } + else + { + if ( m_hasAlpha ) + { #if wxMAC_USE_PREMULTIPLIED_ALPHA - alphaInfo = kCGImageAlphaPremultipliedFirst ; + alphaInfo = kCGImageAlphaPremultipliedFirst ; #else - alphaInfo = kCGImageAlphaFirst ; + alphaInfo = kCGImageAlphaFirst ; #endif + } + + membuf = new wxMemoryBuffer( m_memBuf ) ; } - - membuf = new wxMemoryBuffer( m_memBuf ) ; - } - - CGDataProviderRef dataProvider = NULL ; - if ( m_depth == 1 ) - { - wxMemoryBuffer* maskBuf = new wxMemoryBuffer( m_width * m_height ); - unsigned char * maskBufData = (unsigned char *) maskBuf->GetData(); - unsigned char * bufData = (unsigned char *) membuf->GetData() ; - // copy one color component - for( int i = 0 ; i < m_width * m_height ; ++i ) - maskBufData[i] = bufData[i*4+3]; - dataProvider = - CGDataProviderCreateWithData( - maskBuf , (const void *) maskBufData , m_width * m_height, - wxMacMemoryBufferReleaseProc ); - // as we are now passing the mask buffer to the data provider, we have - // to release the membuf ourselves - delete membuf ; - - image = ::CGImageMaskCreate( w, h, 8, 8, m_width , dataProvider, NULL, false ); - } - else - { - CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace(); - dataProvider = - CGDataProviderCreateWithData( - membuf , (const void *)membuf->GetData() , imageSize, - wxMacMemoryBufferReleaseProc ); - image = - ::CGImageCreate( - w, h, 8 , 32 , 4 * m_width , colorSpace, alphaInfo , - dataProvider, NULL , false , kCGRenderingIntentDefault ); + + CGDataProviderRef dataProvider = NULL ; + if ( m_depth == 1 ) + { + wxMemoryBuffer* maskBuf = new wxMemoryBuffer( m_width * m_height ); + unsigned char * maskBufData = (unsigned char *) maskBuf->GetData(); + unsigned char * bufData = (unsigned char *) membuf->GetData() ; + // copy one color component + for( int i = 0 ; i < m_width * m_height ; ++i ) + maskBufData[i] = bufData[i*4+3]; + dataProvider = + CGDataProviderCreateWithData( + maskBuf , (const void *) maskBufData , m_width * m_height, + wxMacMemoryBufferReleaseProc ); + // as we are now passing the mask buffer to the data provider, we have + // to release the membuf ourselves + delete membuf ; + + image = ::CGImageMaskCreate( w, h, 8, 8, m_width , dataProvider, NULL, false ); + } + else + { + CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace(); + dataProvider = + CGDataProviderCreateWithData( + membuf , (const void *)membuf->GetData() , imageSize, + wxMacMemoryBufferReleaseProc ); + image = + ::CGImageCreate( + w, h, 8 , 32 , m_bytesPerRow , colorSpace, alphaInfo , + dataProvider, NULL , false , kCGRenderingIntentDefault ); + } + CGDataProviderRelease( dataProvider); } - CGDataProviderRelease( dataProvider); } else { @@ -633,6 +813,12 @@ CGImageRef wxBitmapRefData::CGImageCreate() const } #endif +#if wxMAC_USE_CORE_GRAPHICS +CGContextRef wxBitmapRefData::GetBitmapContext() const +{ + return m_hBitmap; +} +#else GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const { wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); @@ -645,22 +831,17 @@ GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const } else if ( m_hasAlpha ) { -#if !wxMAC_USE_CORE_GRAPHICS if ( m_rawAccessCount > 0 ) UpdateAlphaMask() ; -#else - // this structure is not kept in synch when using CG, so if something - // is really accessing the GrafPorts, we have to sync it - UpdateAlphaMask() ; -#endif - *mask = m_hMaskBitmap ; } } return m_hBitmap ; } +#endif +#if !wxMAC_USE_CORE_GRAPHICS void wxBitmapRefData::UpdateAlphaMask() const { if ( m_hasAlpha ) @@ -686,6 +867,7 @@ void wxBitmapRefData::UpdateAlphaMask() const } } } +#endif void wxBitmapRefData::Free() { @@ -711,13 +893,19 @@ void wxBitmapRefData::Free() KillPicture( m_pictHandle ) ; m_pictHandle = NULL ; } +#endif if ( m_hBitmap ) { +#if !wxMAC_USE_CORE_GRAPHICS DisposeGWorld( MAC_WXHBITMAP(m_hBitmap) ) ; +#else + CGContextRelease(m_hBitmap); +#endif m_hBitmap = NULL ; } +#if !wxMAC_USE_CORE_GRAPHICS if ( m_hMaskBitmap ) { DisposeGWorld( MAC_WXHBITMAP(m_hMaskBitmap) ) ; @@ -806,11 +994,18 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) { for ( int x = 0 ; x < w ; ++x ) { - *destination++ = *sourcemask++ ; + unsigned char a = *sourcemask++; + *destination++ = a; source++ ; +#if wxMAC_USE_PREMULTIPLIED_ALPHA + *destination++ = ( (*source++) * a + 127 ) / 255; + *destination++ = ( (*source++) * a + 127 ) / 255; + *destination++ = ( (*source++) * a + 127 ) / 255; +#else *destination++ = *source++ ; *destination++ = *source++ ; *destination++ = *source++ ; +#endif } } @@ -853,10 +1048,11 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits linesize += sizeof(unsigned char); unsigned char* linestart = (unsigned char*) bits ; - unsigned char* destination = (unsigned char*) BeginRawAccess() ; + unsigned char* destptr = (unsigned char*) BeginRawAccess() ; - for ( int y = 0 ; y < the_height ; ++y , linestart += linesize ) + for ( int y = 0 ; y < the_height ; ++y , linestart += linesize, destptr += M_BITMAPDATA->GetBytesPerRow() ) { + unsigned char* destination = destptr; int index, bit, mask; for ( int x = 0 ; x < the_width ; ++x ) @@ -956,7 +1152,6 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const wxBitmap ret( rect.width, rect.height, GetDepth() ); wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") ); - int sourcewidth = GetWidth() ; int destwidth = rect.width ; int destheight = rect.height ; @@ -965,8 +1160,8 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const unsigned char *destdata = (unsigned char*) ret.BeginRawAccess() ; wxASSERT( (sourcedata != NULL) && (destdata != NULL) ) ; - int sourcelinesize = sourcewidth * 4 ; - int destlinesize = destwidth * 4 ; + int sourcelinesize = GetBitmapData()->GetBytesPerRow() ; + int destlinesize = ret.GetBitmapData()->GetBytesPerRow() ; unsigned char *source = sourcedata + rect.x * 4 + rect.y * sourcelinesize ; unsigned char *dest = destdata ; @@ -981,7 +1176,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const if ( M_BITMAPDATA->m_bitmapMask ) { wxMemoryBuffer maskbuf ; - int rowBytes = ( destwidth * 4 + 3 ) & 0xFFFFFFC ; + int rowBytes = GetBestBytesPerRow( destwidth * kMaskBytesPerPixel ); size_t maskbufsize = rowBytes * destheight ; int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ; @@ -991,7 +1186,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const unsigned char *destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ; wxASSERT( (source != NULL) && (destdata != NULL) ) ; - source += rect.x * 4 + rect.y * sourcelinesize ; + source += rect.x * kMaskBytesPerPixel + rect.y * sourcelinesize ; unsigned char *dest = destdata ; for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize) @@ -1073,17 +1268,17 @@ bool wxBitmap::Create(const void* data, wxBitmapType type, int width, int height wxBitmap::wxBitmap(const wxImage& image, int depth) { wxCHECK_RET( image.Ok(), wxT("invalid image") ); - + // width and height of the device-dependent bitmap int width = image.GetWidth(); int height = image.GetHeight(); - + m_refData = new wxBitmapRefData( width , height , depth ) ; - + // Create picture - + bool hasAlpha = false ; - + if ( image.HasMask() ) { // takes precedence, don't mix with alpha info @@ -1092,44 +1287,47 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) { hasAlpha = image.HasAlpha() ; } - + if ( hasAlpha ) UseAlpha() ; - - unsigned char* destination = (unsigned char*) BeginRawAccess() ; + + unsigned char* destinationstart = (unsigned char*) BeginRawAccess() ; register unsigned char* data = image.GetData(); - const unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL ; - - for (int y = 0; y < height; y++) + if ( destinationstart != NULL && data != NULL ) { - for (int x = 0; x < width; x++) + const unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL ; + for (int y = 0; y < height; destinationstart += M_BITMAPDATA->GetBytesPerRow(), y++) { - if ( hasAlpha ) + unsigned char * destination = destinationstart; + for (int x = 0; x < width; x++) { - const unsigned char a = *alpha++; - *destination++ = a ; - + if ( hasAlpha ) + { + const unsigned char a = *alpha++; + *destination++ = a ; + #if wxMAC_USE_PREMULTIPLIED_ALPHA - *destination++ = ((*data++) * a + 127) / 255 ; - *destination++ = ((*data++) * a + 127) / 255 ; - *destination++ = ((*data++) * a + 127) / 255 ; + *destination++ = ((*data++) * a + 127) / 255 ; + *destination++ = ((*data++) * a + 127) / 255 ; + *destination++ = ((*data++) * a + 127) / 255 ; #else - *destination++ = *data++ ; - *destination++ = *data++ ; - *destination++ = *data++ ; + *destination++ = *data++ ; + *destination++ = *data++ ; + *destination++ = *data++ ; #endif - } - else - { - *destination++ = 0xFF ; - *destination++ = *data++ ; - *destination++ = *data++ ; - *destination++ = *data++ ; + } + else + { + *destination++ = 0xFF ; + *destination++ = *data++ ; + *destination++ = *data++ ; + *destination++ = *data++ ; + } } } + + EndRawAccess() ; } - - EndRawAccess() ; if ( image.HasMask() ) SetMask( new wxMask( *this , wxColour( image.GetMaskRed() , image.GetMaskGreen() , image.GetMaskBlue() ) ) ) ; } @@ -1148,7 +1346,7 @@ wxImage wxBitmap::ConvertToImage() const unsigned char *data = image.GetData(); wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") ); - unsigned char* source = (unsigned char*) GetRawAccess() ; + unsigned char* sourcestart = (unsigned char*) GetRawAccess() ; bool hasAlpha = false ; bool hasMask = false ; @@ -1182,9 +1380,10 @@ wxImage wxBitmap::ConvertToImage() const static const int MASK_BLUE = 3; static const int MASK_BLUE_REPLACEMENT = 2; - for (int yy = 0; yy < height; yy++ , mask += maskBytesPerRow ) + for (int yy = 0; yy < height; yy++ , sourcestart += M_BITMAPDATA->GetBytesPerRow() , mask += maskBytesPerRow ) { unsigned char * maskp = mask ; + unsigned char * source = sourcestart; unsigned char a, r, g, b; long color; @@ -1212,13 +1411,25 @@ wxImage wxBitmap::ConvertToImage() const } else if ( r == MASK_RED && g == MASK_GREEN && b == MASK_BLUE ) b = MASK_BLUE_REPLACEMENT ; - +#if !wxMAC_USE_CORE_GRAPHICS maskp++ ; maskp++ ; maskp++ ; +#endif } else if ( hasAlpha ) + { *alpha++ = a ; +#if wxMAC_USE_PREMULTIPLIED_ALPHA + // this must be non-premultiplied data + if ( a != 0xFF && a!= 0 ) + { + r = r * 255 / a; + g = g * 255 / a; + b = b * 255 / a; + } +#endif + } data[index ] = r ; data[index + 1] = g ; @@ -1350,7 +1561,11 @@ void wxBitmap::SetMask(wxMask *mask) WXHBITMAP wxBitmap::GetHBITMAP(WXHBITMAP* mask) const { +#if !wxMAC_USE_CORE_GRAPHICS return WXHBITMAP(M_BITMAPDATA->GetHBITMAP((GWorldPtr*)mask)); +#else + return WXHBITMAP(M_BITMAPDATA->GetBitmapContext()); +#endif } // ---------------------------------------------------------------------------- @@ -1373,11 +1588,7 @@ wxMask::wxMask(const wxMask &tocopy) size_t size = m_bytesPerRow * m_height; unsigned char* dest = (unsigned char*)m_memBuf.GetWriteBuf( size ); unsigned char* source = (unsigned char*)tocopy.m_memBuf.GetData(); - for (size_t i=0; i 0x10 ) { *destdata++ = 0xFF ; +#if !wxMAC_USE_CORE_GRAPHICS *destdata++ = 0xFF ; *destdata++ = 0xFF ; *destdata++ = 0xFF ; +#endif } else { *destdata++ = 0x00 ; +#if !wxMAC_USE_CORE_GRAPHICS *destdata++ = 0x00 ; *destdata++ = 0x00 ; *destdata++ = 0x00 ; +#endif } } } @@ -1519,17 +1750,19 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) { m_width = bitmap.GetWidth() ; m_height = bitmap.GetHeight() ; - m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ; + m_bytesPerRow = GetBestBytesPerRow( m_width * kMaskBytesPerPixel ) ; size_t size = m_bytesPerRow * m_height ; unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ; wxASSERT( destdatabase != NULL ) ; memset( destdatabase , 0 , size ) ; - unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ; + unsigned char * srcdatabase = (unsigned char*) bitmap.GetRawAccess() ; + size_t sourceBytesRow = bitmap.GetBitmapData()->GetBytesPerRow(); - for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow) + for ( int y = 0 ; y < m_height ; ++y , srcdatabase+= sourceBytesRow, destdatabase += m_bytesPerRow) { + unsigned char *srcdata = srcdatabase ; unsigned char *destdata = destdatabase ; unsigned char r, g, b; @@ -1543,16 +1776,20 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) if ( colour == wxColour( r , g , b ) ) { *destdata++ = 0xFF ; +#if !wxMAC_USE_CORE_GRAPHICS *destdata++ = 0xFF ; *destdata++ = 0xFF ; *destdata++ = 0xFF ; +#endif } else { *destdata++ = 0x00 ; +#if !wxMAC_USE_CORE_GRAPHICS *destdata++ = 0x00 ; *destdata++ = 0x00 ; *destdata++ = 0x00 ; +#endif } } } @@ -1612,7 +1849,7 @@ bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, { wxMetafile mf ; - mf.SetHMETAFILE( (WXHMETAFILE) thePict ) ; + mf.SetPICT( thePict ) ; bitmap->Create( mf.GetWidth() , mf.GetHeight() ) ; wxMemoryDC dc ; dc.SelectObject( *bitmap ) ; @@ -1644,7 +1881,7 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int WXUNUSED(bpp)) data.m_width = GetWidth() ; data.m_height = GetHeight() ; - data.m_stride = GetWidth() * 4 ; + data.m_stride = GetBitmapData()->GetBytesPerRow() ; return BeginRawAccess() ; } diff --git a/src/mac/carbon/bmpbuttn.cpp b/src/mac/carbon/bmpbuttn.cpp index 0d9e2d3956..2c688e59e4 100644 --- a/src/mac/carbon/bmpbuttn.cpp +++ b/src/mac/carbon/bmpbuttn.cpp @@ -121,6 +121,7 @@ bool wxBitmapButton::Create( wxWindow *parent, #ifdef __WXMAC_OSX__ if ( HasFlag( wxBORDER_NONE ) ) { + // contrary to the docs this control only works with iconrefs wxMacCreateBitmapButton( &info, m_bmpNormal, kControlContentIconRef ); err = CreateIconControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), diff --git a/src/mac/carbon/button.cpp b/src/mac/carbon/button.cpp index 9da363eb50..42e2004f51 100644 --- a/src/mac/carbon/button.cpp +++ b/src/mac/carbon/button.cpp @@ -16,6 +16,7 @@ #ifndef WX_PRECOMP #include "wx/panel.h" #include "wx/toplevel.h" + #include "wx/dcclient.h" #endif #include "wx/stockitem.h" @@ -122,14 +123,12 @@ wxSize wxButton::DoGetBestSize() const return wxSize( 20 , 20 ) ; wxSize sz = GetDefaultSize() ; - int charspace = 8 ; switch (GetWindowVariant()) { case wxWINDOW_VARIANT_NORMAL: case wxWINDOW_VARIANT_LARGE: sz.y = 20 ; - charspace = 10 ; break; case wxWINDOW_VARIANT_SMALL: @@ -148,14 +147,54 @@ wxSize wxButton::DoGetBestSize() const m_peer->GetBestRect( &bestsize ) ; int wBtn; - if ( EmptyRect( &bestsize ) ) + if ( EmptyRect( &bestsize ) || ( GetWindowStyle() & wxBU_EXACTFIT) ) { - wBtn = m_label.length() * charspace + 12 ; + Point bounds; + + ControlFontStyleRec controlFont; + OSStatus err = m_peer->GetData( kControlEntireControl, kControlFontStyleTag, &controlFont ); + verify_noerr( err ); + + SInt16 baseline; + wxMacCFStringHolder str( m_label, m_font.GetEncoding() ); + +#ifndef __LP64__ + if ( m_font.MacGetThemeFontID() != kThemeCurrentPortFont ) + { + err = GetThemeTextDimensions( + (!m_label.empty() ? (CFStringRef)str : CFSTR(" ")), + m_font.MacGetThemeFontID(), kThemeStateActive, false, &bounds, &baseline ); + verify_noerr( err ); + } + else +#endif + { +#if wxMAC_USE_CORE_GRAPHICS + wxClientDC dc(const_cast(this)); + wxCoord width, height ; + dc.GetTextExtent( m_label , &width, &height); + bounds.h = width; + bounds.v = height; +#else + wxMacWindowStateSaver sv( this ); + ::TextFont( m_font.MacGetFontNum() ); + ::TextSize( (short)(m_font.MacGetFontSize()) ); + ::TextFace( m_font.MacGetFontStyle() ); + + err = GetThemeTextDimensions( + (!m_label.empty() ? (CFStringRef)str : CFSTR(" ")), + kThemeCurrentPortFont, kThemeStateActive, false, &bounds, &baseline ); + verify_noerr( err ); +#endif + } + + wBtn = bounds.h + sz.y; } else { wBtn = bestsize.right - bestsize.left ; - sz.y = bestsize.bottom - bestsize.top ; + // non 'normal' window variants don't return the correct height + // sz.y = bestsize.bottom - bestsize.top ; } if ((wBtn > sz.x) || ( GetWindowStyle() & wxBU_EXACTFIT)) diff --git a/src/mac/carbon/checklst.cpp b/src/mac/carbon/checklst.cpp index 1374f2646c..8b12a0590d 100644 --- a/src/mac/carbon/checklst.cpp +++ b/src/mac/carbon/checklst.cpp @@ -89,6 +89,7 @@ bool wxCheckListBox::Create( // this will be increased by our Append command wxMacDataBrowserCheckListControl* control = new wxMacDataBrowserCheckListControl( this, pos, size, style ); + // TODO CHECK control->SetClientDataType( m_clientDataItemsType ); m_peer = control; MacPostControlCreate(pos,size); diff --git a/src/mac/carbon/clipbrd.cpp b/src/mac/carbon/clipbrd.cpp index 413b80df02..99a8fba35c 100644 --- a/src/mac/carbon/clipbrd.cpp +++ b/src/mac/carbon/clipbrd.cpp @@ -27,10 +27,6 @@ #include "wx/metafile.h" -#ifndef __DARWIN__ -#include -#endif - #include "wx/mac/uma.h" #define wxUSE_DATAOBJ 1 @@ -43,153 +39,90 @@ // (there will be a *lot* of them!) static const wxChar *TRACE_CLIPBOARD = wxT("clipboard"); +IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) + +// in order to keep the binary interface the same this class +// serves just to have a few additional member variables inside +// the clipboard class -void * wxGetClipboardData( wxDataFormat dataFormat, long *len ) +class wxMacBinaryCompatHelper : public wxDataObject { - OSStatus err = noErr; - void * data = NULL; - Size byteCount; - - switch (dataFormat.GetType()) +public : + wxMacBinaryCompatHelper() { - case wxDF_OEMTEXT: - dataFormat = wxDF_TEXT; - break; - - case wxDF_TEXT: - case wxDF_UNICODETEXT: - break; - - case wxDF_BITMAP: - case wxDF_METAFILE: - break; - - default: - // custom datatype - break; + m_trueData = NULL; } -#if TARGET_CARBON - ScrapRef scrapRef; - - err = GetCurrentScrap( &scrapRef ); - if ( err != noTypeErr && err != memFullErr ) + ~wxMacBinaryCompatHelper() { - ScrapFlavorFlags flavorFlags; + if (m_trueData != NULL) + { + delete m_trueData; + m_trueData = NULL; + } + } - err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags ); - if (err == noErr) + virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const { - err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount ); - if (err == noErr) - { - Size allocSize = byteCount; - if ( dataFormat.GetType() == wxDF_TEXT ) - allocSize += 1; - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - allocSize += 2; - - data = new char[ allocSize ]; + return wxDataFormat(); + } - if (( err = GetScrapFlavorData( scrapRef, dataFormat.GetFormatId(), &byteCount , data )) == noErr ) + virtual size_t GetFormatCount(Direction dir = Get) const { - *len = allocSize; - if ( dataFormat.GetType() == wxDF_TEXT ) - ((char*)data)[ byteCount ] = 0; - if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - { - // "data" format is UTF16, so 2 bytes = one character - // wxChar size depends on platform, so just clear last 2 bytes - ((char*)data)[ byteCount + 0 ] = - ((char*)data)[ byteCount + 1 ] = 0; + return 0; } - } - else + + virtual void GetAllFormats(wxDataFormat *formats, + Direction dir = Get) const { - delete [] (char*)data; - data = NULL; - } - } - } } -#else - long offset; - Handle datahandle = NewHandle( 0 ); - HLock( datahandle ); - err = (OSStatus)GetScrap( datahandle, dataFormat.GetFormatId(), &offset ); - HUnlock( datahandle ); - if ( GetHandleSize( datahandle ) > 0 ) + virtual size_t GetDataSize(const wxDataFormat& format) const { - byteCount = GetHandleSize( datahandle ); - Size allocSize = byteCount; - if ( dataFormat.GetType() == wxDF_TEXT ) - allocSize += 1; - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - allocSize += 2; - - data = new char[ allocSize ]; - - memcpy( (char*) data, (char*) *datahandle, byteCount ); - if ( dataFormat.GetType() == wxDF_TEXT ) - ((char*)data)[ byteCount ] = 0; - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - ((wxChar*)data)[ byteCount / 2 ] = 0; - *len = byteCount; + return 0; } - DisposeHandle( datahandle ); -#endif - - if (err != noErr) + virtual bool GetDataHere(const wxDataFormat& format, void *buf) const { - wxLogSysError(wxT("Failed to get clipboard data.")); - - return NULL; + return false; } - if (dataFormat.GetType() == wxDF_TEXT) - wxMacConvertNewlines10To13( (char*)data ); + // only relevant from here on - return data; -} + wxDataObject* m_trueData; + wxCFRef m_pasteboard; +}; -IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) +#define M_CLIPBOARD ((wxMacBinaryCompatHelper*)m_data) wxClipboard::wxClipboard() { m_open = false; - m_data = NULL; + m_data = new wxMacBinaryCompatHelper() ; + PasteboardRef clipboard = 0; + OSStatus err = PasteboardCreate( kPasteboardClipboard, &clipboard ); + if (err != noErr) + { + wxLogSysError( wxT("Failed to create the clipboard.") ); + } + M_CLIPBOARD->m_pasteboard.reset(clipboard); } wxClipboard::~wxClipboard() { - if (m_data != NULL) - { + M_CLIPBOARD->m_pasteboard.reset((PasteboardRef)0); delete m_data; - m_data = NULL; - } } void wxClipboard::Clear() { - if ( IsUsingPrimarySelection() ) - return; - - if (m_data != NULL) + if (M_CLIPBOARD->m_trueData != NULL) { - delete m_data; - m_data = NULL; + delete M_CLIPBOARD->m_trueData; + M_CLIPBOARD->m_trueData = NULL; } -#if TARGET_CARBON - OSStatus err; - err = ClearCurrentScrap(); -#else - OSErr err; - err = ZeroScrap(); -#endif - + OSStatus err = PasteboardClear( M_CLIPBOARD->m_pasteboard ); if (err != noErr) { wxLogSysError( wxT("Failed to empty the clipboard.") ); @@ -241,72 +174,13 @@ bool wxClipboard::AddData( wxDataObject *data ) // we can only store one wxDataObject Clear(); - m_data = data; - - // get formats from wxDataObjects - wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ]; - m_data->GetAllFormats( array ); - - for (size_t i = 0; i < m_data->GetFormatCount(); i++) - { - if (array[i].IsStandard()) - { - wxLogTrace( TRACE_CLIPBOARD, - wxT("wxClipboard now supports standard atom type %d"), - array[i].GetType() ); - } - else - { - wxLogTrace( TRACE_CLIPBOARD, - wxT("wxClipboard now supports atom %s"), - array[i].GetId().c_str() ); - } - - size_t sz = data->GetDataSize( array[ i ] ); - void* buf = malloc( sz + 1 ); - if ( buf != NULL ) - { - // empty the buffer because in some case GetDataHere does not fill buf - memset( buf, 0, sz + 1 ); - data->GetDataHere( array[ i ], buf ); - OSType mactype = 0; - switch ( array[i].GetType() ) - { - case wxDF_TEXT: - case wxDF_OEMTEXT: - mactype = kScrapFlavorTypeText; - sz -= 1; - break; - -#if wxUSE_UNICODE - case wxDF_UNICODETEXT: - mactype = kScrapFlavorTypeUnicode; - sz -= 2; - break; -#endif - -#if wxUSE_DRAG_AND_DROP - case wxDF_METAFILE: - mactype = kScrapFlavorTypePicture; - break; -#endif - - case wxDF_BITMAP: - case wxDF_DIB: - mactype = kScrapFlavorTypePicture; - break; - - default: - mactype = (OSType)(array[ i ].GetFormatId()); - break; - } + PasteboardSyncFlags syncFlags = PasteboardSynchronize( M_CLIPBOARD->m_pasteboard ); + wxCHECK_MSG( !(syncFlags&kPasteboardModified), false, wxT("clipboard modified after clear") ); + wxCHECK_MSG( (syncFlags&kPasteboardClientIsOwner), false, wxT("client couldn't own clipboard") ); - UMAPutScrap( sz , mactype , buf ); - free( buf ); - } - } + M_CLIPBOARD->m_trueData = data; - delete [] array; + data->AddToPasteboard( M_CLIPBOARD->m_pasteboard, 1 ); return true; } @@ -320,64 +194,18 @@ void wxClipboard::Close() // Get rid of cached object. // If this is not done, copying data from // another application will only work once - if (m_data) + if (M_CLIPBOARD->m_trueData) { - delete m_data; - m_data = (wxDataObject*) NULL; + delete M_CLIPBOARD->m_trueData; + M_CLIPBOARD->m_trueData = (wxDataObject*) NULL; } } bool wxClipboard::IsSupported( const wxDataFormat &dataFormat ) { - if ( IsUsingPrimarySelection() ) - return false; - - if ( m_data ) - return m_data->IsSupported( dataFormat ); - - bool hasData = false; - -#if TARGET_CARBON - OSStatus err = noErr; - ScrapRef scrapRef; - - err = GetCurrentScrap( &scrapRef ); - if ( err != noTypeErr && err != memFullErr ) - { - ScrapFlavorFlags flavorFlags; - Size byteCount; - - err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags ); - if (err == noErr) - { - err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount ); - if (err == noErr) - hasData = true; - } - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - { - err = GetScrapFlavorFlags( scrapRef, 'TEXT', &flavorFlags ); - if (err == noErr) - { - err = GetScrapFlavorSize( scrapRef, 'TEXT', &byteCount ); - if (err == noErr) - hasData = true; - } - } - } - -#else - - long offset = 0; - Handle datahandle = NewHandle( 0 ); - HLock( datahandle ); - GetScrap( datahandle, dataFormat.GetFormatId(), &offset ); - HUnlock( datahandle ); - hasData = GetHandleSize( datahandle ) > 0; - DisposeHandle( datahandle ); -#endif - - return hasData; + if ( M_CLIPBOARD->m_trueData ) + return M_CLIPBOARD->m_trueData->IsSupported( dataFormat ); + return wxDataObject::IsFormatInPasteboard( M_CLIPBOARD->m_pasteboard, dataFormat ); } bool wxClipboard::GetData( wxDataObject& data ) @@ -394,14 +222,14 @@ bool wxClipboard::GetData( wxDataObject& data ) bool transferred = false; - if ( m_data ) + if ( M_CLIPBOARD->m_trueData ) { for (size_t i = 0; !transferred && i < formatcount; i++) { wxDataFormat format = array[ i ]; - if ( m_data->IsSupported( format ) ) + if ( M_CLIPBOARD->m_trueData->IsSupported( format ) ) { - int dataSize = m_data->GetDataSize( format ); + int dataSize = M_CLIPBOARD->m_trueData->GetDataSize( format ); transferred = true; if (dataSize == 0) @@ -411,7 +239,7 @@ bool wxClipboard::GetData( wxDataObject& data ) else { char *d = new char[ dataSize ]; - m_data->GetDataHere( format, (void*)d ); + M_CLIPBOARD->m_trueData->GetDataHere( format, (void*)d ); data.SetData( format, dataSize, d ); delete [] d; } @@ -422,33 +250,7 @@ bool wxClipboard::GetData( wxDataObject& data ) // get formats from wxDataObjects if ( !transferred ) { - for (size_t i = 0; !transferred && i < formatcount; i++) - { - wxDataFormat format = array[ i ]; - - switch ( format.GetType() ) - { - // NOTE: this is usable for all data types - case wxDF_TEXT: - case wxDF_UNICODETEXT: - case wxDF_OEMTEXT: - case wxDF_BITMAP: - case wxDF_METAFILE: - default: - { - long len; - char* s = (char*)wxGetClipboardData( format, &len ); - if (s != NULL) - { - data.SetData( format, len, s ); - delete [] s; - - transferred = true; - } - } - break; - } - } + transferred = data.GetFromPasteboard( M_CLIPBOARD->m_pasteboard ) ; } delete [] array; diff --git a/src/mac/carbon/cursor.cpp b/src/mac/carbon/cursor.cpp index f6cb3ddfa3..2dab20662a 100644 --- a/src/mac/carbon/cursor.cpp +++ b/src/mac/carbon/cursor.cpp @@ -31,6 +31,7 @@ class WXDLLEXPORT wxCursorRefData: public wxBitmapRefData { DECLARE_NO_COPY_CLASS(wxCursorRefData) + friend class wxBitmap; friend class wxCursor; public: @@ -38,33 +39,20 @@ public: virtual ~wxCursorRefData(); protected: +#if wxMAC_USE_COCOA + WX_NSCursor m_hCursor; +#else WXHCURSOR m_hCursor; bool m_disposeHandle; bool m_releaseHandle; bool m_isColorCursor; long m_themeCursor; +#endif }; #define M_CURSORDATA wx_static_cast(wxCursorRefData*, m_refData) -const short kwxCursorBullseye = 0; -const short kwxCursorBlank = 1; -const short kwxCursorPencil = 2; -const short kwxCursorMagnifier = 3; -const short kwxCursorNoEntry = 4; -const short kwxCursorPaintBrush = 5; -const short kwxCursorPointRight = 6; -const short kwxCursorPointLeft = 7; -const short kwxCursorQuestionArrow = 8; -const short kwxCursorRightArrow = 9; -const short kwxCursorSizeNS = 10; -const short kwxCursorSize = 11; -const short kwxCursorSizeNESW = 12; -const short kwxCursorSizeNWSE = 13; -const short kwxCursorRoller = 14; -const short kwxCursorLast = kwxCursorRoller; - -Cursor gMacCursors[kwxCursorLast+1] = +ClassicCursor gMacCursors[kwxCursorLast+1] = { { @@ -191,6 +179,7 @@ Cursor gMacCursors[kwxCursorLast+1] = wxCursor gMacCurrentCursor ; +#if !wxMAC_USE_COCOA CursHandle wxGetStockCursor( int number ) { wxASSERT_MSG( number >= 0 && number <=kwxCursorLast , wxT("invalid stock cursor id") ) ; @@ -206,20 +195,28 @@ CursHandle wxGetStockCursor( int number ) #endif return c ; } +#endif wxCursorRefData::wxCursorRefData() { SetWidth( 16 ); SetHeight( 16 ); m_hCursor = NULL; +#if wxMAC_USE_COCOA +#else m_disposeHandle = false; m_releaseHandle = false; m_isColorCursor = false; m_themeCursor = -1; +#endif } wxCursorRefData::~wxCursorRefData() { +#if wxMAC_USE_COCOA + if ( m_hCursor ) + wxMacCocoaRelease(m_hCursor); +#else if ( m_isColorCursor ) { #ifndef __LP64__ @@ -235,6 +232,7 @@ wxCursorRefData::~wxCursorRefData() // we don't release the resource since it may already // be in use again } +#endif } wxCursor::wxCursor() @@ -284,9 +282,14 @@ WXHCURSOR wxCursor::GetHCURSOR() const bool wxCursor::IsOk() const { +#if wxMAC_USE_COCOA + return GetHCURSOR() != NULL; +#else return (m_refData != NULL && ( M_CURSORDATA->m_hCursor != NULL || M_CURSORDATA->m_themeCursor != -1 ) ) ; +#endif } +#if !wxMAC_USE_COCOA short GetCTabIndex( CTabHandle colors , RGBColor *col ) { short retval = 0 ; @@ -307,19 +310,28 @@ short GetCTabIndex( CTabHandle colors , RGBColor *col ) return retval ; } +#endif #if wxUSE_IMAGE 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 + wxBitmap bmp( image ); + CGImageRef cgimage = wxMacCreateCGImageFromBitmap(bmp); + if ( cgimage ) + { + M_CURSORDATA->m_hCursor = wxMacCocoaCreateCursorFromCGImage( cgimage, hotSpotX, hotSpotY ); + CFRelease( cgimage ); + } +#else #ifndef __LP64__ int w = 16; int h = 16; - int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X); - int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y); int image_w = image.GetWidth(); int image_h = image.GetHeight(); @@ -446,7 +458,7 @@ void wxCursor::CreateFromImage(const wxImage & image) M_CURSORDATA->m_hCursor = ch ; M_CURSORDATA->m_isColorCursor = true ; #endif - +#endif } #endif //wxUSE_IMAGE @@ -456,6 +468,9 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho m_refData = new wxCursorRefData; if ( flags == wxBITMAP_TYPE_MACCURSOR_RESOURCE ) { +#if wxMAC_USE_COCOA + wxFAIL_MSG( wxT("Not implemented") ); +#else #ifndef __LP64__ Str255 theName ; wxMacStringToPascal( cursor_file , theName ) ; @@ -489,6 +504,7 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho M_CURSORDATA->m_releaseHandle = true ; } } +#endif #endif } else @@ -512,7 +528,9 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho wxCursor::wxCursor(int cursor_type) { m_refData = new wxCursorRefData; - +#if wxMAC_USE_COCOA + M_CURSORDATA->m_hCursor = wxMacCocoaCreateStockCursor( cursor_type ); +#else switch (cursor_type) { case wxCURSOR_COPY_ARROW: @@ -615,11 +633,16 @@ wxCursor::wxCursor(int cursor_type) if ( M_CURSORDATA->m_themeCursor == -1 ) M_CURSORDATA->m_releaseHandle = true; +#endif } void wxCursor::MacInstall() const { gMacCurrentCursor = *this ; +#if wxMAC_USE_COCOA + if ( IsOk() ) + wxMacCocoaSetCursor( M_CURSORDATA->m_hCursor ); +#else if ( m_refData && M_CURSORDATA->m_themeCursor != -1 ) { SetThemeCursor( M_CURSORDATA->m_themeCursor ) ; @@ -637,6 +660,7 @@ void wxCursor::MacInstall() const { SetThemeCursor( kThemeArrowCursor ) ; } +#endif } wxCursor::~wxCursor() diff --git a/src/mac/carbon/dataobj.cpp b/src/mac/carbon/dataobj.cpp index b3b42de40a..5273411436 100644 --- a/src/mac/carbon/dataobj.cpp +++ b/src/mac/carbon/dataobj.cpp @@ -27,10 +27,10 @@ #include "wx/metafile.h" #include "wx/tokenzr.h" -#include "wx/mac/private.h" +#include "wx/mac/uma.h" -#ifndef __DARWIN__ -#include +#ifdef __DARWIN__ + #include #endif @@ -46,48 +46,109 @@ wxDataFormat::wxDataFormat() wxDataFormat::wxDataFormat( wxDataFormatId vType ) { + m_format = 0; + m_type = wxDF_INVALID; SetType( vType ); } +wxDataFormat::wxDataFormat( const wxChar *zId ) +{ + m_format = 0; + m_type = wxDF_INVALID; + SetId( zId ); +} + wxDataFormat::wxDataFormat( const wxString& rId ) { + m_format = 0; + m_type = wxDF_INVALID; SetId( rId ); } +wxDataFormat::wxDataFormat(const wxDataFormat& rFormat) +{ + if ( rFormat.m_format ) + m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format); + else + m_format = 0; + m_type = rFormat.m_type; + m_id = rFormat.m_id; +} + wxDataFormat::wxDataFormat( NativeFormat vFormat ) { + m_format = 0; + m_type = wxDF_INVALID; SetId( vFormat ); } +wxDataFormat::~wxDataFormat() +{ + if ( m_format != 0 ) + { + CFRelease( (CFStringRef) m_format ); + m_format = 0; + } +} + +// in order to be correct for 10.3 we restrict to the available types there +// http://developer.apple.com/qa/qa2005/qa1406.html +// TODO : Use UTCoreTypes.h constants once we support 10.4+ only + +wxDataFormat& wxDataFormat::operator=(const wxDataFormat& rFormat) +{ + if ( m_format != 0 ) + { + CFRelease( (CFStringRef) m_format ); + m_format = 0; + } + if ( rFormat.m_format ) + m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format); + m_type = rFormat.m_type; + m_id = rFormat.m_id; + return *this; +} + void wxDataFormat::SetType( wxDataFormatId dataType ) { m_type = dataType; + if ( m_format != 0 ) + { + CFRelease( (CFStringRef) m_format ); + m_format = 0; + } switch (m_type) { case wxDF_TEXT: - m_format = kScrapFlavorTypeText; + m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.plain-text") ); break; case wxDF_UNICODETEXT: - m_format = kScrapFlavorTypeUnicode; + m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.utf16-plain-text") ); break; case wxDF_BITMAP: +#if wxMAC_USE_CORE_GRAPHICS + m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.tiff") ); +#else + m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.apple.pict") ); +#endif + break; case wxDF_METAFILE: - m_format = kScrapFlavorTypePicture; +#if wxMAC_USE_CORE_GRAPHICS + m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.adobe.pdf") ); +#else + m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.apple.pict") ); +#endif break; case wxDF_FILENAME: - m_format = kDragFlavorTypeHFS; + m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.file-url") ); break; default: wxFAIL_MSG( wxT("invalid data format") ); - - // NB: this translates to '????' ASCII but it can't be used in the code - // because '??' will get parsed as a trigraph! - m_format = 0x3f3f3f3f; break; } } @@ -102,33 +163,43 @@ wxString wxDataFormat::GetId() const void wxDataFormat::SetId( NativeFormat format ) { - m_format = format; - - switch (m_format) + if ( m_format != 0 ) + { + CFRelease( (CFStringRef) m_format ); + m_format = 0; + } + m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format); + if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-plain-text") ) ) { - case kScrapFlavorTypeText: - m_type = wxDF_TEXT; - break; - - case kScrapFlavorTypeUnicode: m_type = wxDF_UNICODETEXT; - break; - - case kScrapFlavorTypePicture: + } + else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.plain-text") ) ) + { + m_type = wxDF_TEXT; + } +#if wxMAC_USE_CORE_GRAPHICS + else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.tiff") ) ) + { m_type = wxDF_BITMAP; - break; - - case kDragFlavorTypeHFS: + } + else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("com.adobe.pdf") ) ) + { + m_type = wxDF_METAFILE; + } +#else + else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("com.apple.pict") ) ) + { + m_type = wxDF_METAFILE; + } +#endif + else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.file-url") ) ) + { m_type = wxDF_FILENAME; - break; - - default: + } + else + { m_type = wxDF_PRIVATE; - char text[5]; - memcpy( text, (const char*)&format, 4 ); - text[4] = 0; - m_id = wxString::FromAscii( text ); - break; + m_id = wxMacCFStringHolder( (CFStringRef) CFRetain((CFStringRef) format )).AsString(); } } @@ -136,7 +207,13 @@ void wxDataFormat::SetId( const wxString& zId ) { m_type = wxDF_PRIVATE; m_id = zId; - m_format = 'WXPR'; + if ( m_format != 0 ) + { + CFRelease( (CFStringRef) m_format ); + m_format = 0; + } + // since it is private, no need to conform to anything ... + m_format = (long) wxMacCFStringHolder(m_id).Detach(); } bool wxDataFormat::operator==(const wxDataFormat& format) const @@ -144,7 +221,7 @@ bool wxDataFormat::operator==(const wxDataFormat& format) const if (IsStandard() || format.IsStandard()) return (format.m_type == m_type); else - return (m_id == format.m_id); + return ( UTTypeConformsTo( (CFStringRef) m_format , (CFStringRef) format.m_format ) ); } //------------------------------------------------------------------------- @@ -184,6 +261,300 @@ bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDi return found; } +void wxDataObject::AddToPasteboard( void * pb, int itemID ) +{ + PasteboardRef pasteboard = (PasteboardRef) pb; + // get formats from wxDataObjects + wxDataFormat *array = new wxDataFormat[ GetFormatCount() ]; + GetAllFormats( array ); + + for (size_t i = 0; i < GetFormatCount(); i++) + { + wxDataFormat thisFormat = array[ i ]; + + // add four bytes at the end for data objs like text that + // have a datasize = strlen but still need a buffer for the + // string including trailing zero + + size_t datasize = GetDataSize( thisFormat ); + size_t sz = datasize + 4; + void* buf = malloc( sz ); + if ( buf != NULL ) + { + // empty the buffer because in some case GetDataHere does not fill buf + memset( buf, 0, sz ); + if ( GetDataHere( array[ i ], buf ) ) + { + int counter = 1 ; + if ( thisFormat.GetType() == wxDF_FILENAME ) + { + // the data is D-normalized UTF8 strings of filenames delimited with \n + char *fname = strtok((char*) buf,"\n"); + while (fname != NULL) + { + // translate the filepath into a fileurl and put that into the pasteobard + CFStringRef path = CFStringCreateWithBytes(NULL,(UInt8*)fname,strlen(fname),kCFStringEncodingUTF8,false); + CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path , kCFURLPOSIXPathStyle, false); + CFRelease(path); + CFDataRef data = CFURLCreateData(NULL,url,kCFStringEncodingUTF8,true); + CFRelease(url); + PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) counter, + (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags); + CFRelease( data ); + counter++; + fname = strtok (NULL,"\n"); + } + + } + else + { + CFDataRef data = CFDataCreate( kCFAllocatorDefault, (UInt8*)buf, datasize ); + if ( thisFormat.GetType() == wxDF_TEXT ) + PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID, + CFSTR("com.apple.traditional-mac-plain-text") , data, kPasteboardFlavorNoFlags); + else + PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID, + (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags); + CFRelease( data ); + } + } + free( buf ); + } + } + + delete [] array; +} + +bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataFormat ) +{ + PasteboardRef pasteboard = (PasteboardRef) pb; + bool hasData = false; + OSStatus err = noErr; + ItemCount itemCount; + + // we synchronize here once again, so we don't mind which flags get returned + PasteboardSynchronize( pasteboard ); + + err = PasteboardGetItemCount( pasteboard, &itemCount ); + if ( err == noErr ) + { + for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ ) + { + PasteboardItemID itemID; + CFArrayRef flavorTypeArray; + CFIndex flavorCount; + + err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); + if ( err != noErr ) + continue; + + err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); + if ( err != noErr ) + continue; + + flavorCount = CFArrayGetCount( flavorTypeArray ); + + for( CFIndex flavorIndex = 0; flavorIndex < flavorCount && hasData == false ; flavorIndex++ ) + { + CFStringRef flavorType; + + flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, + flavorIndex ); + + wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); + if ( dataFormat == flavorFormat ) + hasData = true; + else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) + hasData = true; + } + CFRelease (flavorTypeArray); + } + } + + return hasData; +} + +bool wxDataObject::GetFromPasteboard( void * pb ) +{ + PasteboardRef pasteboard = (PasteboardRef) pb; + size_t formatcount = GetFormatCount() + 1; + wxDataFormat *array = new wxDataFormat[ formatcount ]; + array[0] = GetPreferredFormat(); + GetAllFormats( &array[1] ); + ItemCount itemCount = 0; + wxString filenamesPassed; + bool transferred = false; + + // we synchronize here once again, so we don't mind which flags get returned + PasteboardSynchronize( pasteboard ); + + OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); + if ( err == noErr ) + { + for (size_t i = 0; !transferred && i < formatcount; i++) + { + // go through the data in our order of preference + wxDataFormat dataFormat = array[ i ]; + + for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) + { + PasteboardItemID itemID = 0; + CFArrayRef flavorTypeArray = NULL; + CFIndex flavorCount = 0; + + err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); + if ( err != noErr ) + continue; + + err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); + if ( err != noErr ) + continue; + + flavorCount = CFArrayGetCount( flavorTypeArray ); + + for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ ) + { + CFStringRef flavorType; + CFDataRef flavorData; + CFIndex flavorDataSize; + + flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, + flavorIndex ); + + wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); + + if ( dataFormat == flavorFormat ) + { + err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData ); + if ( err == noErr ) + { + flavorDataSize = CFDataGetLength( flavorData ); + if (dataFormat.GetType() == wxDF_FILENAME ) + { + // revert the translation and decomposition to arrive at a proper utf8 string again + CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL ); + CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); + CFRelease( url ); + CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString); + CFRelease( cfString ); + CFStringNormalize(cfMutableString,kCFStringNormalizationFormC); + wxString path = wxMacCFStringHolder(cfMutableString).AsString(); + if (!path.empty()) + filenamesPassed += path + wxT("\n"); + } + else + { + // because some data implementation expect trailing a trailing NUL, we add some headroom + void *buf = malloc( flavorDataSize + 4 ); + if ( buf ) + { + memset( buf, 0, flavorDataSize + 4 ); + memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize ); + + if (dataFormat.GetType() == wxDF_TEXT) + wxMacConvertNewlines10To13( (char*) buf ); + SetData( flavorFormat, flavorDataSize, buf ); + transferred = true; + free( buf ); + } + } + CFRelease (flavorData); + } + } + else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) + { + err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType, &flavorData ); + if ( err == noErr ) + { + flavorDataSize = CFDataGetLength( flavorData ); + void *asciibuf = malloc( flavorDataSize + 1 ); + if ( asciibuf ) + { + memset( asciibuf, 0, flavorDataSize + 1 ); + memcpy( asciibuf, CFDataGetBytePtr( flavorData ), flavorDataSize ); + CFRelease (flavorData); + + SetData( wxDF_TEXT, flavorDataSize, asciibuf ); + transferred = true; + free( asciibuf ); + } + else + CFRelease (flavorData); + } + } + } + CFRelease( flavorTypeArray ); + } + if (filenamesPassed.length() > 0) + { + wxCharBuffer buf = filenamesPassed.fn_str(); + SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); + transferred = true; + } + } + } + return transferred; +} + +bool wxDataObject::HasDataInPasteboard( void * pb ) +{ + PasteboardRef pasteboard = (PasteboardRef) pb; + size_t formatcount = GetFormatCount() + 1; + wxDataFormat *array = new wxDataFormat[ formatcount ]; + array[0] = GetPreferredFormat(); + GetAllFormats( &array[1] ); + ItemCount itemCount = 0; + bool hasData = false; + + // we synchronize here once again, so we don't mind which flags get returned + PasteboardSynchronize( pasteboard ); + + OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); + if ( err == noErr ) + { + for (size_t i = 0; !hasData && i < formatcount; i++) + { + // go through the data in our order of preference + wxDataFormat dataFormat = array[ i ]; + + for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ ) + { + PasteboardItemID itemID = 0; + CFArrayRef flavorTypeArray = NULL; + CFIndex flavorCount = 0; + + err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); + if ( err != noErr ) + continue; + + err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); + if ( err != noErr ) + continue; + + flavorCount = CFArrayGetCount( flavorTypeArray ); + + for( CFIndex flavorIndex = 0; !hasData && flavorIndex < flavorCount ; flavorIndex++ ) + { + CFStringRef flavorType; + + flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, + flavorIndex ); + + wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); + + if ( dataFormat == flavorFormat || + dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) + { + hasData = true; + } + } + CFRelease( flavorTypeArray ); + } + } + } + return hasData; +} + // ---------------------------------------------------------------------------- // wxTextDataObject // ---------------------------------------------------------------------------- @@ -236,7 +607,7 @@ size_t wxFileDataObject::GetDataSize() const GetFileNames( buf ); buffLength = strlen( buf ); - + // terminating 0 return buffLength + 1; } @@ -276,8 +647,12 @@ wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& rBitmap ) if (m_bitmap.Ok()) { +#if wxMAC_USE_CORE_GRAPHICS + SetBitmap( rBitmap ); +#else m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle(); m_pictCreated = false; +#endif } } @@ -292,8 +667,51 @@ void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap ) wxBitmapDataObjectBase::SetBitmap( rBitmap ); if (m_bitmap.Ok()) { +#if wxMAC_USE_CORE_GRAPHICS + CGImageRef cgImageRef = (CGImageRef) m_bitmap.CGImageCreate(); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if ( UMAGetSystemVersion() >= 0x1040 ) + { + CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); + CGImageDestinationRef destination = CGImageDestinationCreateWithData( data , kUTTypeTIFF , 1 , NULL ); + if ( destination ) + { + CGImageDestinationAddImage( destination, cgImageRef, NULL ); + CGImageDestinationFinalize( destination ); + CFRelease( destination ); + } + m_pictHandle = NewHandle(CFDataGetLength(data)); + if ( m_pictHandle ) + { + memcpy( *(Handle)m_pictHandle, (const char *)CFDataGetBytePtr(data), CFDataGetLength(data) ); + } + CFRelease( data ); + } + else +#endif +#ifndef __LP64__ + { + // export as TIFF + GraphicsExportComponent exporter = 0; + OSStatus err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeTIFF, &exporter); + if (noErr == err) + { + m_pictHandle = NewHandle(0); + if ( m_pictHandle ) + { + err = GraphicsExportSetInputCGImage( exporter, cgImageRef); + err = GraphicsExportSetOutputHandle(exporter, (Handle)m_pictHandle); + err = GraphicsExportDoExport(exporter, NULL); + } + CloseComponent( exporter ); + } + } +#endif + CGImageRelease(cgImageRef); +#else m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle(); m_pictCreated = false; +#endif } } @@ -307,13 +725,14 @@ void wxBitmapDataObject::Clear() { if (m_pictHandle != NULL) { -#ifndef __LP64__ +#if wxMAC_USE_CORE_GRAPHICS + DisposeHandle( (Handle) m_pictHandle ); +#else if (m_pictCreated) KillPicture( (PicHandle)m_pictHandle ); #endif m_pictHandle = NULL; } - m_pictCreated = false; } @@ -341,6 +760,17 @@ size_t wxBitmapDataObject::GetDataSize() const return 0; } +Handle MacCreateDataReferenceHandle(Handle theDataHandle) +{ + Handle dataRef = NULL; + OSErr err = noErr; + + // Create a data reference handle for our data. + err = PtrToHand( &theDataHandle, &dataRef, sizeof(Handle)); + + return dataRef; +} + bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf ) { Clear(); @@ -348,10 +778,59 @@ bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf ) if ((pBuf == NULL) || (nSize == 0)) return false; +#if wxMAC_USE_CORE_GRAPHICS + Handle picHandle = NewHandle( nSize ); + memcpy( *picHandle, pBuf, nSize ); + m_pictHandle = picHandle; + CGImageRef cgImageRef = 0; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if ( UMAGetSystemVersion() >= 0x1040 ) + { + CFDataRef data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) pBuf, nSize, kCFAllocatorNull); + CGImageSourceRef source = CGImageSourceCreateWithData( data, NULL ); + if ( source ) + { + cgImageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); + } + CFRelease( source ); + CFRelease( data ); + } + else +#endif +#ifndef __LP64__ + { + // import from TIFF + GraphicsImportComponent importer = 0; + OSStatus err = OpenADefaultComponent(GraphicsImporterComponentType, kQTFileTypeTIFF, &importer); + if (noErr == err) + { + if ( picHandle ) + { + ComponentResult result = GraphicsImportSetDataHandle(importer, picHandle); + if ( result == noErr ) + { + Rect frame; + GraphicsImportGetNaturalBounds( importer, &frame ); + GraphicsImportCreateCGImage( importer, &cgImageRef, kGraphicsImportCreateCGImageUsingCurrentSettings ); + } + } + CloseComponent( importer ); + } + } +#endif + if ( cgImageRef ) + { + m_bitmap.Create( CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) ); + CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) ); + // since our context is upside down we dont use CGContextDrawImage + HIViewDrawCGImage( (CGContextRef) m_bitmap.GetHBITMAP() , &r, cgImageRef ) ; + CGImageRelease(cgImageRef); + cgImageRef = NULL; + } +#else PicHandle picHandle = (PicHandle)NewHandle( nSize ); memcpy( *picHandle, pBuf, nSize ); m_pictHandle = picHandle; - // ownership is transferred to the bitmap m_pictCreated = false; #ifndef __LP64__ @@ -368,6 +847,7 @@ bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf ) mf.Play( &mdc ); #endif mdc.SelectObject( wxNullBitmap ); +#endif #endif return m_bitmap.Ok(); diff --git a/src/mac/carbon/dcclient.cpp b/src/mac/carbon/dcclient.cpp index 2ec91c4760..7729ec0dbb 100644 --- a/src/mac/carbon/dcclient.cpp +++ b/src/mac/carbon/dcclient.cpp @@ -226,6 +226,7 @@ wxBitmap wxWindowDC::DoGetAsBitmap(const wxRect *subrect) const wxBitmap bmp = wxBitmap(width, height, 32); wxAlphaPixelData pixData(bmp, wxPoint(0,0), wxSize(width, height)); + pixData.UseAlpha(); wxAlphaPixelData::Iterator p(pixData); for (int y=0; yGetClientAreaOrigin() ; m_window->GetClientSize( &m_width , &m_height); SetDeviceOrigin( origin.x, origin.y ); @@ -265,6 +267,7 @@ wxClientDC::wxClientDC(wxWindow *window) : #else wxClientDC::wxClientDC(wxWindow *window) { + wxCHECK_RET( window, _T("invalid window in wxClientDC") ); m_window = window ; wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ; if (!rootwindow) diff --git a/src/mac/carbon/dcmemory.cpp b/src/mac/carbon/dcmemory.cpp index f30ed64d0f..cc8c8115ee 100644 --- a/src/mac/carbon/dcmemory.cpp +++ b/src/mac/carbon/dcmemory.cpp @@ -44,10 +44,8 @@ wxMemoryDC::~wxMemoryDC() { #if wxMAC_USE_CORE_GRAPHICS m_selected.EndRawAccess() ; - CGContextRef bmCtx = (CGContextRef) m_graphicContext->GetNativeContext() ; delete m_graphicContext ; m_graphicContext = NULL ; - CGContextRelease( bmCtx ) ; #else // TODO: UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) ); #endif @@ -60,10 +58,8 @@ void wxMemoryDC::DoSelect( const wxBitmap& bitmap ) { #if wxMAC_USE_CORE_GRAPHICS m_selected.EndRawAccess() ; - CGContextRef bmCtx = (CGContextRef) m_graphicContext->GetNativeContext() ; delete m_graphicContext ; m_graphicContext = NULL ; - CGContextRelease( bmCtx ) ; #else // TODO: UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) ); #endif @@ -75,30 +71,16 @@ void wxMemoryDC::DoSelect( const wxBitmap& bitmap ) #if wxMAC_USE_CORE_GRAPHICS if ( m_selected.GetDepth() != 1 ) m_selected.UseAlpha() ; - void * data = m_selected.BeginRawAccess() ; - - int bitsPerComp = 8 ; - int bytesPerPixel = 4 ; - int w = bitmap.GetWidth() ; - int h = bitmap.GetHeight() ; - m_width = w; - m_height = h; - - // TODO: should this be kCGImageAlphaPremultiplied[First,Last] ? - CGImageAlphaInfo a = kCGImageAlphaNoneSkipFirst ; - + m_selected.BeginRawAccess() ; + m_width = bitmap.GetWidth(); + m_height = bitmap.GetHeight(); CGColorSpaceRef genericColorSpace = wxMacGetGenericRGBColorSpace(); - CGContextRef bmCtx = CGBitmapContextCreate( data , w, h, bitsPerComp , bytesPerPixel * w , genericColorSpace, a ); - wxASSERT_MSG( bmCtx , wxT("Unable to create bitmap context") ) ; + CGContextRef bmCtx = (CGContextRef) m_selected.GetHBITMAP(); if ( bmCtx ) { CGContextSetFillColorSpace( bmCtx, genericColorSpace ); CGContextSetStrokeColorSpace( bmCtx, genericColorSpace ); - - CGContextTranslateCTM( bmCtx , 0 , m_selected.GetHeight() ) ; - CGContextScaleCTM( bmCtx , 1 , -1 ) ; - SetGraphicsContext( wxGraphicsContext::CreateFromNative( bmCtx ) ); } m_ok = (m_graphicContext != NULL) ; diff --git a/src/mac/carbon/dcscreen.cpp b/src/mac/carbon/dcscreen.cpp index 07e8218b4b..95bfe9dc35 100644 --- a/src/mac/carbon/dcscreen.cpp +++ b/src/mac/carbon/dcscreen.cpp @@ -18,6 +18,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC) +// TODO : for the Screenshot use case, which doesn't work in Quartz +// we should do a GetAsBitmap using something like +// http://www.cocoabuilder.com/archive/message/cocoa/2005/8/13/144256 + // Create a DC representing the whole screen wxScreenDC::wxScreenDC() { diff --git a/src/mac/carbon/dialog.cpp b/src/mac/carbon/dialog.cpp index 2a127e7631..aa23b77e34 100644 --- a/src/mac/carbon/dialog.cpp +++ b/src/mac/carbon/dialog.cpp @@ -53,13 +53,6 @@ bool wxDialog::Create( wxWindow *parent, if ( !wxTopLevelWindow::Create( parent, id, title, pos, size, style, name ) ) return false; -#if TARGET_API_MAC_OSX - HIViewRef growBoxRef = 0 ; - OSStatus err = HIViewFindByID( HIViewGetRoot( (WindowRef)m_macWindow ), kHIViewWindowGrowBoxID, &growBoxRef ); - if ( err == noErr && growBoxRef != 0 ) - HIGrowBoxViewSetTransparent( growBoxRef, true ) ; -#endif - return true; } @@ -116,6 +109,8 @@ bool wxDialog::Show(bool show) // usually will result in TransferDataToWindow() being called InitDialog(); + HiliteMenu(0); + if ( m_isModalStyle ) { if ( show ) @@ -145,13 +140,19 @@ void wxDialog::DoShowModal() SetFocus() ; -#if TARGET_CARBON - BeginAppModalStateForWindow( (WindowRef) MacGetWindowRef()) ; -#else - // TODO : test whether parent gets disabled - bool formerModal = s_macIsInModalLoop ; - s_macIsInModalLoop = true ; -#endif + WindowRef windowRef = (WindowRef) MacGetWindowRef(); + WindowGroupRef windowGroup; + WindowGroupRef formerParentGroup; + bool resetGroupParent = false; + + if ( GetParent() == NULL ) + { + windowGroup = GetWindowGroup(windowRef) ; + formerParentGroup = GetWindowGroupParent( windowGroup ); + SetWindowGroupParent( windowGroup, GetWindowGroupOfClass( kMovableModalWindowClass ) ); + resetGroupParent = true; + } + BeginAppModalStateForWindow(windowRef) ; while ( IsModal() ) { @@ -159,12 +160,11 @@ void wxDialog::DoShowModal() // calls process idle itself } -#if TARGET_CARBON - EndAppModalStateForWindow( (WindowRef) MacGetWindowRef() ) ; -#else - // TODO probably reenable the parent window if any - s_macIsInModalLoop = formerModal ; -#endif + EndAppModalStateForWindow(windowRef) ; + if ( resetGroupParent ) + { + SetWindowGroupParent( windowGroup , formerParentGroup ); + } } diff --git a/src/mac/carbon/dirdlg.cpp b/src/mac/carbon/dirdlg.cpp index f63080f4e1..3b596c9f51 100644 --- a/src/mac/carbon/dirdlg.cpp +++ b/src/mac/carbon/dirdlg.cpp @@ -77,13 +77,14 @@ wxDirDialog::wxDirDialog(wxWindow *parent, int wxDirDialog::ShowModal() { - NavDialogRef dialog; + NavDialogRef dialog = NULL; NavDialogCreationOptions options; NavReplyRecord reply ; bool disposeReply = false ; OSStatus err = noErr; err = NavGetDefaultDialogCreationOptions(&options); + options.optionFlags &= ~kNavAllowMultipleFiles; if (err == noErr) { wxMacCFStringHolder message(m_message, m_font.GetEncoding()); @@ -135,6 +136,9 @@ int wxDirDialog::ShowModal() if ( err != noErr && err != userCanceledErr ) m_path = wxEmptyString ; + if ( dialog ) + ::NavDialogDispose(dialog); + return (err == noErr) ? wxID_OK : wxID_CANCEL ; } diff --git a/src/mac/carbon/dnd.cpp b/src/mac/carbon/dnd.cpp index 6f5a325730..dc9b4b60b1 100644 --- a/src/mac/carbon/dnd.cpp +++ b/src/mac/carbon/dnd.cpp @@ -23,11 +23,6 @@ #include "wx/mac/private.h" -#ifndef __DARWIN__ - #include -#endif - - // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- @@ -86,6 +81,8 @@ wxDragResult wxDropTarget::OnData( bool wxDropTarget::CurrentDragHasSupportedFormat() { bool supported = false; + if (m_dataObject == NULL) + return false; if ( gTrackingGlobals.m_currentSource != NULL ) { @@ -112,27 +109,11 @@ bool wxDropTarget::CurrentDragHasSupportedFormat() if ( !supported ) { - UInt16 items; - ItemReference theItem; - FlavorType theType; - UInt16 flavors = 0; + PasteboardRef pasteboard; - CountDragItems( (DragReference)m_currentDrag, &items ); - for (UInt16 index = 1; index <= items && !supported; ++index) + if ( GetDragPasteboard( (DragReference)m_currentDrag, &pasteboard ) == noErr ) { - flavors = 0; - GetDragItemReferenceNumber( (DragReference)m_currentDrag, index, &theItem ); - CountDragItemFlavors( (DragReference)m_currentDrag, theItem, &flavors ); - - for ( UInt16 flavor = 1; flavor <= flavors; ++flavor ) - { - GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType ); - if ( m_dataObject->IsSupportedFormat( wxDataFormat( theType ) ) ) - { - supported = true; - break; - } - } + supported = m_dataObject->HasDataInPasteboard( pasteboard ); } } @@ -185,116 +166,15 @@ bool wxDropTarget::GetData() if ( !transferred ) { - UInt16 items; - OSErr result; - ItemReference theItem; - FlavorType theType; - FlavorFlags theFlags; - UInt16 flavors; - wxString filenamesPassed; - - CountDragItems( (DragReference)m_currentDrag, &items ); - for (UInt16 index = 1; index <= items; ++index) - { - flavors = 0; - GetDragItemReferenceNumber( (DragReference)m_currentDrag, index, &theItem ); - CountDragItemFlavors( (DragReference)m_currentDrag, theItem, &flavors ); - wxDataFormat preferredFormat = m_dataObject->GetPreferredFormat( wxDataObject::Set ); - bool hasPreferredFormat = false; - - for (UInt16 flavor = 1; flavor <= flavors; ++flavor) - { - result = GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType ); - wxDataFormat format( theType ); - if (preferredFormat == format) - { - hasPreferredFormat = true; - break; - } - } - - for (UInt16 flavor = 1; flavor <= flavors; ++flavor) - { - result = GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType ); - wxDataFormat format( theType ); - if ((hasPreferredFormat && format == preferredFormat) - || (!hasPreferredFormat && m_dataObject->IsSupportedFormat( format ))) - { - result = GetFlavorFlags( (DragReference)m_currentDrag, theItem, theType, &theFlags ); - if (result == noErr) - { - Size dataSize; - Ptr theData; - - GetFlavorDataSize( (DragReference)m_currentDrag, theItem, theType, &dataSize ); - if (theType == kScrapFlavorTypeText) - { - // this increment is only valid for allocating: - // on the next GetFlavorData call it is reset again to the original value - dataSize++; - } - else if (theType == kScrapFlavorTypeUnicode) - { - // this increment is only valid for allocating: - // on the next GetFlavorData call it is reset again to the original value - dataSize++; - dataSize++; - } - - if (dataSize > 0) - theData = new char[dataSize]; - else - theData = NULL; - - GetFlavorData( (DragReference)m_currentDrag, theItem, theType, (void*)theData, &dataSize, 0L ); - switch (theType) - { - case kScrapFlavorTypeText: - theData[dataSize] = 0; - m_dataObject->SetData( wxDataFormat(wxDF_TEXT), dataSize, theData ); - break; - -#if wxUSE_UNICODE - case kScrapFlavorTypeUnicode: - theData[dataSize + 0] = - theData[dataSize + 1] = 0; - m_dataObject->SetData( wxDataFormat(wxDF_UNICODETEXT), dataSize, theData ); - break; -#endif - - case kDragFlavorTypeHFS: - if (theData != NULL) - { - HFSFlavor* theFile = (HFSFlavor*)theData; -#ifndef __LP64__ - wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec ); - - if (!name.empty()) - filenamesPassed += name + wxT("\n"); -#endif - } - break; - - default: - m_dataObject->SetData( format, dataSize, theData ); - break; - } - - delete [] theData; - } - break; - } - } - } + PasteboardRef pasteboard; - if (filenamesPassed.length() > 0) + if ( GetDragPasteboard( (DragReference)m_currentDrag, &pasteboard ) == noErr ) { - wxCharBuffer buf = filenamesPassed.fn_str(); - m_dataObject->SetData( wxDataFormat(wxDF_FILENAME), strlen( buf ), (const char*)buf ); + transferred = m_dataObject->GetFromPasteboard( pasteboard ); } } - return true; + return transferred; } //------------------------------------------------------------------------- @@ -332,6 +212,16 @@ wxDropSource::~wxDropSource() { } +OSStatus wxMacPromiseKeeper( PasteboardRef inPasteboard, PasteboardItemID inItem, CFStringRef inFlavorType, + void *inContext ) +{ + OSStatus err = noErr; + + // we might add promises here later, inContext is the wxDropSource* + + return err; +} + wxDragResult wxDropSource::DoDragDrop(int flags) { wxASSERT_MSG( m_data, wxT("Drop source: no data") ); @@ -341,114 +231,61 @@ wxDragResult wxDropSource::DoDragDrop(int flags) DragReference theDrag; RgnHandle dragRegion; - - if (NewDrag( &theDrag ) != noErr) - return wxDragNone; - + OSStatus err = noErr; + PasteboardRef pasteboard; + // add data to drag - size_t formatCount = m_data->GetFormatCount(); - wxDataFormat *formats = new wxDataFormat[formatCount]; - m_data->GetAllFormats( formats ); - ItemReference theItem = (ItemReference) 1; - - for ( size_t i = 0; i < formatCount; ++i ) + + err = PasteboardCreate( kPasteboardUniqueName, &pasteboard ); + if ( err != noErr ) + return wxDragNone; + + // we add a dummy promise keeper because of strange messages when linking against carbon debug + err = PasteboardSetPromiseKeeper( pasteboard, wxMacPromiseKeeper, this ); + if ( err != noErr ) { - size_t dataSize = m_data->GetDataSize( formats[i] ); - Ptr dataPtr = new char[dataSize]; - m_data->GetDataHere( formats[i], dataPtr ); - OSType type = formats[i].GetFormatId(); - if ( type == 'TEXT' || type == 'utxt' ) - { - if ( dataSize > 0 ) - dataSize--; - dataPtr[ dataSize ] = 0; - if ( type == 'utxt' ) - { - if ( dataSize > 0 ) - dataSize--; - dataPtr[ dataSize ] = 0; - } - - AddDragItemFlavor( theDrag, theItem, type, dataPtr, dataSize, 0 ); - } - else if (type == kDragFlavorTypeHFS ) - { - HFSFlavor theFlavor; - OSErr err = noErr; -#ifndef __LP64__ - CInfoPBRec cat; - - wxMacFilename2FSSpec( wxString( dataPtr, *wxConvCurrent ), &theFlavor.fileSpec ); - - memset( &cat, 0, sizeof(cat) ); - cat.hFileInfo.ioNamePtr = theFlavor.fileSpec.name; - cat.hFileInfo.ioVRefNum = theFlavor.fileSpec.vRefNum; - cat.hFileInfo.ioDirID = theFlavor.fileSpec.parID; - cat.hFileInfo.ioFDirIndex = 0; - err = PBGetCatInfoSync( &cat ); -#endif - if (err == noErr) - { -#ifndef __LP64__ - theFlavor.fdFlags = cat.hFileInfo.ioFlFndrInfo.fdFlags; - if (theFlavor.fileSpec.parID == fsRtParID) - { - theFlavor.fileCreator = 'MACS'; - theFlavor.fileType = 'disk'; - } - else if ((cat.hFileInfo.ioFlAttrib & ioDirMask) != 0) - { - theFlavor.fileCreator = 'MACS'; - theFlavor.fileType = 'fold'; - } - else - { - theFlavor.fileCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator; - theFlavor.fileType = cat.hFileInfo.ioFlFndrInfo.fdType; - } -#endif - AddDragItemFlavor( theDrag, theItem, type, &theFlavor, sizeof(theFlavor), 0 ); - } - } - else - { - AddDragItemFlavor( theDrag, theItem, type, dataPtr, dataSize, 0 ); - } - - delete [] dataPtr; + CFRelease( pasteboard ); + return wxDragNone; } - - delete [] formats; - + + err = PasteboardClear( pasteboard ); + if ( err != noErr ) + { + CFRelease( pasteboard ); + return wxDragNone; + } + PasteboardSynchronize( pasteboard ); + + m_data->AddToPasteboard( pasteboard, 1 ); + + if (NewDragWithPasteboard( pasteboard , &theDrag) != noErr) + { + CFRelease( pasteboard ); + return wxDragNone; + } + dragRegion = NewRgn(); RgnHandle tempRgn = NewRgn(); - EventRecord* ev = NULL; - -#if !TARGET_CARBON // TODO - ev = (EventRecord*) wxTheApp->MacGetCurrentEvent(); -#else EventRecord rec; - ev = &rec; - wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent(), &rec ); -#endif + ConvertEventRefToEventRecord( (EventRef) wxTheApp->MacGetCurrentEvent(), &rec ); const short dragRegionOuterBoundary = 10; const short dragRegionInnerBoundary = 9; SetRectRgn( dragRegion, - ev->where.h - dragRegionOuterBoundary, - ev->where.v - dragRegionOuterBoundary, - ev->where.h + dragRegionOuterBoundary, - ev->where.v + dragRegionOuterBoundary ); + rec.where.h - dragRegionOuterBoundary, + rec.where.v - dragRegionOuterBoundary, + rec.where.h + dragRegionOuterBoundary, + rec.where.v + dragRegionOuterBoundary ); SetRectRgn( tempRgn, - ev->where.h - dragRegionInnerBoundary, - ev->where.v - dragRegionInnerBoundary, - ev->where.h + dragRegionInnerBoundary, - ev->where.v + dragRegionInnerBoundary ); + rec.where.h - dragRegionInnerBoundary, + rec.where.v - dragRegionInnerBoundary, + rec.where.h + dragRegionInnerBoundary, + rec.where.v + dragRegionInnerBoundary ); DiffRgn( dragRegion, tempRgn, dragRegion ); DisposeRgn( tempRgn ); @@ -460,9 +297,11 @@ wxDragResult wxDropSource::DoDragDrop(int flags) gTrackingGlobals.m_result = wxDragNone; gTrackingGlobals.m_flags = flags; - TrackDrag( theDrag, ev, dragRegion ); + err = TrackDrag( theDrag, &rec, dragRegion ); + DisposeRgn( dragRegion ); DisposeDrag( theDrag ); + CFRelease( pasteboard ); gTrackingGlobals.m_currentSource = NULL; return gTrackingGlobals.m_result; @@ -614,7 +453,7 @@ pascal OSErr wxMacWindowDragTrackingHandler( if ( trackingGlobals->m_currentTarget ) { trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ); - trackingGlobals->m_currentTarget->OnDragOver( localx, localy, result ); + result = trackingGlobals->m_currentTarget->OnDragOver( localx, localy, result ); } } diff --git a/src/mac/carbon/filedlg.cpp b/src/mac/carbon/filedlg.cpp index 38bce04759..a94dce6b81 100644 --- a/src/mac/carbon/filedlg.cpp +++ b/src/mac/carbon/filedlg.cpp @@ -83,12 +83,14 @@ static pascal void NavEventProc( ::NavCustomControl(ioParams->context, kNavCtlSetLocation, (void *) &theLocation); } - NavMenuItemSpec menuItem; - menuItem.version = kNavMenuItemSpecVersion; - menuItem.menuCreator = 'WXNG'; - menuItem.menuType = data->currentfilter; - wxMacStringToPascal( data->name[data->currentfilter] , (StringPtr)(menuItem.menuItemName) ) ; - ::NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &menuItem); + if( data->extensions.GetCount() > 0 ) + { + NavMenuItemSpec menuItem; + memset( &menuItem, 0, sizeof(menuItem) ); + menuItem.version = kNavMenuItemSpecVersion; + menuItem.menuType = data->currentfilter; + ::NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &menuItem); + } } else if ( inSelector == kNavCBPopupMenuSelect ) { @@ -112,7 +114,7 @@ static pascal void NavEventProc( sfilename = cfString.AsString() ; int pos = sfilename.Find('.', true) ; - if ( pos != wxNOT_FOUND ) + if ( pos != wxNOT_FOUND && extension != wxT("*") ) { sfilename = sfilename.Left(pos+1)+extension ; cfString.Assign( sfilename , wxFONTENCODING_DEFAULT ) ; @@ -228,34 +230,6 @@ static Boolean CheckFile( const wxString &filename , OSType type , OpenUserDataR return true ; } -#if !TARGET_API_MAC_OSX -static pascal Boolean CrossPlatformFileFilter(CInfoPBPtr myCInfoPBPtr, void *dataPtr) -{ - OpenUserDataRecPtr data = (OpenUserDataRecPtr) dataPtr ; - // return true if this item is invisible or a file - - Boolean visibleFlag; - Boolean folderFlag; - - visibleFlag = ! (myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible); - folderFlag = (myCInfoPBPtr->hFileInfo.ioFlAttrib & 0x10); - - // because the semantics of the filter proc are "true means don't show - // it" we need to invert the result that we return - - if ( !visibleFlag ) - return true ; - - if ( !folderFlag ) - { - wxString file = wxMacMakeStringFromPascal( myCInfoPBPtr->hFileInfo.ioNamePtr ) ; - return !CheckFile( file , myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdType , data ) ; - } - - return false ; -} -#endif - // end wxmac wxFileDialog::wxFileDialog( @@ -281,11 +255,8 @@ pascal Boolean CrossPlatformFilterCallback( // filter string. // However, packages should be dealt with like files and not like folders. So // check if a folder is a package before deciding what to do. - FSRef fsref; NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*) info ; - AECoerceDesc (theItem, typeFSRef, theItem); - if ( AEGetDescData (theItem, &fsref, sizeof (FSRef)) != noErr) - return true; + FSRef fsref; if ( theInfo->isFolder ) { @@ -305,10 +276,15 @@ pascal Boolean CrossPlatformFilterCallback( !(lsInfo.flags & (kLSItemInfoIsApplication | kLSItemInfoIsPackage)) ) return true; } - - wxString file = wxMacFSRefToPath( &fsref ) ; - return CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ; - + else + { + AECoerceDesc (theItem, typeFSRef, theItem); + if ( AEGetDescData (theItem, &fsref, sizeof (FSRef)) == noErr) + { + wxString file = wxMacFSRefToPath( &fsref ) ; + return CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ; + } + } } return true; @@ -402,7 +378,10 @@ int wxFileDialog::ShowModal() ::DisposeNavObjectFilterUPP(navFilterUPP); if (err != noErr) + { + ::NavDialogDispose(dialog); return wxID_CANCEL; + } NavReplyRecord navReply; err = ::NavDialogGetReply(dialog, &navReply); @@ -433,6 +412,7 @@ int wxFileDialog::ShowModal() if (!thePath) { ::NavDisposeReply(&navReply); + ::NavDialogDispose(dialog); return wxID_CANCEL; } @@ -449,6 +429,7 @@ int wxFileDialog::ShowModal() } ::NavDisposeReply(&navReply); + ::NavDialogDispose(dialog); return (err == noErr) ? wxID_OK : wxID_CANCEL; } diff --git a/src/mac/carbon/font.cpp b/src/mac/carbon/font.cpp index 90f88f2d00..9e0fe30b92 100644 --- a/src/mac/carbon/font.cpp +++ b/src/mac/carbon/font.cpp @@ -48,11 +48,14 @@ public: , m_underlined(false) , m_faceName(wxT("applicationfont")) , m_encoding(wxFONTENCODING_DEFAULT) +#ifdef __LP64__ +#else , m_macFontFamily(0) , m_macFontSize(0) , m_macFontStyle(0) - , m_macATSUStyle(0) , m_macATSUFontID(0) +#endif + , m_macATSUStyle(0) { Init(m_pointSize, m_family, m_style, m_weight, m_underlined, m_faceName, m_encoding); @@ -68,11 +71,14 @@ public: , m_underlined(data.m_underlined) , m_faceName(data.m_faceName) , m_encoding(data.m_encoding) +#ifdef __LP64__ +#else , m_macFontFamily(data.m_macFontFamily) , m_macFontSize(data.m_macFontSize) , m_macFontStyle(data.m_macFontStyle) - , m_macATSUStyle(0) , m_macATSUFontID(data.m_macATSUFontID) +#endif + , m_macATSUStyle(0) { Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight, data.m_underlined, data.m_faceName, data.m_encoding); @@ -93,11 +99,14 @@ public: , m_underlined(underlined) , m_faceName(faceName) , m_encoding(encoding) +#ifdef __LP64__ +#else , m_macFontFamily(0) , m_macFontSize(0) , m_macFontStyle(0) - , m_macATSUStyle(0) , m_macATSUFontID(0) +#endif + , m_macATSUStyle(0) { Init(size, family, style, weight, underlined, faceName, encoding); } @@ -134,6 +143,7 @@ protected: bool m_noAA; // No anti-aliasing public: +#ifndef __LP64__ FMFontFamily m_macFontFamily; FMFontSize m_macFontSize; FMFontStyle m_macFontStyle; @@ -144,14 +154,17 @@ public: // contain some styles (special bold fonts etc) and // these are the additional qd styles that are not // included in the ATSU font id - ATSUStyle m_macATSUStyle ; ATSUFontID m_macATSUFontID; FMFontStyle m_macATSUAdditionalQDStyles ; // for true themeing support we must store the correct font // information here, as this speeds up and optimizes rendering ThemeFontID m_macThemeFontID ; - +#else + CTFontRef m_macFontRef; + CTFontUIFontType m_macUIFontType; +#endif + ATSUStyle m_macATSUStyle ; wxNativeFontInfo m_info; }; @@ -182,15 +195,19 @@ void wxFontRefData::Init(int pointSize, m_underlined = underlined; m_faceName = faceName; m_encoding = encoding; - +#ifdef __LP64__ + m_macUIFontType = kCTFontNoFontType; + m_macFontRef = 0; +#else m_macFontFamily = 0 ; m_macFontSize = 0; m_macFontStyle = 0; m_macATSUFontID = 0; m_macATSUAdditionalQDStyles = 0 ; - m_macATSUStyle = NULL ; m_macThemeFontID = kThemeCurrentPortFont ; +#endif + m_macATSUStyle = NULL ; m_noAA = false; } @@ -205,9 +222,116 @@ wxFontRefData::~wxFontRefData() void wxFontRefData::MacFindFont() { - OSStatus status ; - + OSStatus status = noErr; Str255 qdFontName ; + +#ifdef __LP64__ + if ( m_faceName.empty() && m_family == wxDEFAULT ) + { + m_macUIFontType = kCTFontSystemFontType; + } + + if ( m_macUIFontType != kCTFontNoFontType ) + { + m_macFontRef = CTFontCreateUIFontForLanguage( m_macUIFontType, 0.0, NULL ); + wxMacCFStringHolder name( CTFontCopyFamilyName( m_macFontRef ) ); + m_faceName = name.AsString(); + } + else + { + if ( m_faceName.empty() ) + { + switch ( m_family ) + { + case wxSCRIPT : + case wxROMAN : + case wxDECORATIVE : + m_faceName = wxT("Times"); + break ; + + case wxSWISS : + m_faceName = wxT("Lucida Grande"); + break ; + + case wxMODERN : + case wxTELETYPE: + m_faceName = wxT("Monaco"); + break ; + + default: + m_faceName = wxT("Times"); + break ; + } + } + + wxMacCFStringHolder cf( m_faceName, wxLocale::GetSystemEncoding() ); + m_macFontRef = CTFontCreateWithName( cf, m_pointSize, NULL); + } + + if ( m_macATSUStyle ) + { + ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle); + m_macATSUStyle = NULL ; + } + + status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle); + wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ); + + ATSUAttributeTag atsuTags[] = + { + kATSUSizeTag , + kATSUVerticalCharacterTag, + kATSUQDBoldfaceTag , + kATSUQDItalicTag , + kATSUQDUnderlineTag , + kATSUQDCondensedTag , + kATSUQDExtendedTag , + kATSUFontTag , + }; + ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = + { + sizeof( Fixed ) , + sizeof( ATSUVerticalCharacterType), + sizeof( Boolean ) , + sizeof( Boolean ) , + sizeof( Boolean ) , + sizeof( Boolean ) , + sizeof( Boolean ) , + sizeof( ATSUFontID ) , + }; + + Boolean kTrue = true ; + Boolean kFalse = false ; + + Fixed atsuSize = IntToFixed( m_pointSize ); + short m_macATSUAdditionalQDStyles = 0; + ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; + ATSUFontID atsuFontID = 0; + int attributeCount = sizeof(atsuTags) / sizeof(ATSUAttributeTag) ; + + // attempt to add atsu font + status = ATSUFindFontFromName(m_faceName.c_str(), strlen(m_faceName.c_str()), kFontFamilyName, kFontNoPlatform, kFontNoScript, kFontNoLanguage, &atsuFontID); + if ( status != noErr ) + { + attributeCount--; + } + + ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = + { + &atsuSize , + &kHorizontal, + (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse , + &atsuFontID , + }; + + status = ::ATSUSetAttributes( (ATSUStyle)m_macATSUStyle, attributeCount, atsuTags, atsuSizes, atsuValues); + + wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ); +#else if ( m_macThemeFontID != kThemeCurrentPortFont ) { Style style ; @@ -223,9 +347,7 @@ void wxFontRefData::MacFindFont() if ( m_macFontStyle & underline ) m_underlined = true ; m_pointSize = m_macFontSize ; -#ifndef __LP64__ m_macFontFamily = FMGetFontFamilyFromName( qdFontName ); -#endif } else { @@ -233,11 +355,9 @@ void wxFontRefData::MacFindFont() { if ( m_family == wxDEFAULT ) { -#ifndef __LP64__ m_macFontFamily = GetAppFont(); FMGetFontFamilyName(m_macFontFamily,qdFontName); m_faceName = wxMacMakeStringFromPascal( qdFontName ); -#endif } else { @@ -262,7 +382,6 @@ void wxFontRefData::MacFindFont() m_faceName = wxT("Times"); break ; } -#ifndef __LP64__ wxMacStringToPascal( m_faceName , qdFontName ); m_macFontFamily = FMGetFontFamilyFromName( qdFontName ); if ( m_macFontFamily == kInvalidFontFamily ) @@ -270,30 +389,19 @@ void wxFontRefData::MacFindFont() wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName.c_str() ); m_macFontFamily = GetAppFont(); } -#endif } } else { -#ifndef __LP64__ if ( m_faceName == wxT("systemfont") ) m_macFontFamily = GetSysFont(); else if ( m_faceName == wxT("applicationfont") ) m_macFontFamily = GetAppFont(); else -#else - if ( m_faceName == wxT("systemfont") ) - m_faceName = wxT("Lucida Grande"); - else if ( m_faceName == wxT("applicationfont") ) - m_faceName = wxT("Lucida Grande"); -#endif { wxMacCFStringHolder cf( m_faceName, wxLocale::GetSystemEncoding() ); ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault ); - - // ATSFontFamilyRef is an unsigned type, so check against max - // for an invalid value, not -1. - if ( atsfamily == 0xffffffff ) + if ( atsfamily == (ATSFontFamilyRef) -1 ) { wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName ); m_macFontFamily = GetAppFont(); @@ -318,10 +426,8 @@ void wxFontRefData::MacFindFont() // ATSUFontID and FMFont are equivalent FMFontStyle intrinsicStyle = 0 ; -#ifndef __LP64__ status = FMGetFontFromFontFamilyInstance( m_macFontFamily , m_macFontStyle , &m_macATSUFontID , &intrinsicStyle); wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") ); -#endif m_macATSUAdditionalQDStyles = m_macFontStyle & (~intrinsicStyle ); if ( m_macATSUStyle ) @@ -379,6 +485,7 @@ void wxFontRefData::MacFindFont() atsuTags, atsuSizes, atsuValues); wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ); +#endif } // ---------------------------------------------------------------------------- @@ -418,8 +525,29 @@ bool wxFont::Create(int pointSize, return true; } +#ifdef __LP64__ + +bool wxFont::MacCreateUIFont(wxUint32 ctFontType ) +{ + UnRef(); + + m_refData = new wxFontRefData( + 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, + false, wxEmptyString, wxFONTENCODING_DEFAULT ); + + M_FONTDATA->m_macUIFontType = ctFontType ; + RealizeResource(); + + return true; +} + +#endif + bool wxFont::MacCreateThemeFont(wxUint16 themeFontID) { +#ifdef __LP64__ + return MacCreateUIFont(HIThemeGetUIFontType(themeFontID)); +#else UnRef(); m_refData = new wxFontRefData( @@ -430,6 +558,7 @@ bool wxFont::MacCreateThemeFont(wxUint16 themeFontID) RealizeResource(); return true; +#endif } wxFont::~wxFont() @@ -553,6 +682,7 @@ wxSize wxFont::GetPixelSize() const dc->SetFont(*(wxFont *)this,*wxBLACK); wxDouble width, height = 0; dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL); + delete dc; return wxSize((int)width, (int)height); #else return wxFontBase::GetPixelSize(); @@ -608,6 +738,8 @@ bool wxFont::GetNoAntiAliasing() const return M_FONTDATA->m_noAA; } +#ifndef __LP64__ + short wxFont::MacGetFontNum() const { wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); @@ -656,6 +788,23 @@ wxUint16 wxFont::MacGetThemeFontID() const return M_FONTDATA->m_macThemeFontID; } +#else +const void * wxFont::MacGetCTFont() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macFontRef; +} + +// to be removed +void * wxFont::MacGetATSUStyle() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") ); + + return M_FONTDATA->m_macATSUStyle; +} + +#endif const wxNativeFontInfo * wxFont::GetNativeFontInfo() const { diff --git a/src/mac/carbon/graphics.cpp b/src/mac/carbon/graphics.cpp index 6e0196b7fb..521ea9c809 100644 --- a/src/mac/carbon/graphics.cpp +++ b/src/mac/carbon/graphics.cpp @@ -20,6 +20,7 @@ #include "wx/dcmemory.h" #include "wx/log.h" #include "wx/region.h" + #include "wx/image.h" #endif #include "wx/mac/uma.h" @@ -297,7 +298,7 @@ wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer { Init(); - float components[4] = { pen.GetColour().Red() / 255.0 , pen.GetColour().Green() / 255.0 , + CGFloat components[4] = { pen.GetColour().Red() / 255.0 , pen.GetColour().Green() / 255.0 , pen.GetColour().Blue() / 255.0 , pen.GetColour().Alpha() / 255.0 } ; m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ; @@ -478,70 +479,60 @@ void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext* context ) // Brush // -class wxMacCoreGraphicsBrushData : public wxGraphicsObjectRefData -{ -public: - wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer ); - wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer, const wxBrush &brush ); - ~wxMacCoreGraphicsBrushData (); - - virtual void Apply( wxGraphicsContext* context ); - void CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, - const wxColour&c1, const wxColour&c2 ); - void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, - const wxColour &oColor, const wxColour &cColor ); - - virtual bool IsShading() { return m_isShading; } - CGShadingRef GetShading() { return m_shading; } -protected: - CGFunctionRef CreateGradientFunction( const wxColour& c1, const wxColour& c2 ); - static void CalculateShadingValues (void *info, const CGFloat *in, CGFloat *out); - virtual void Init(); - - wxMacCFRefHolder m_color; - wxMacCFRefHolder m_colorSpace; - - bool m_isPattern; - wxMacCFRefHolder m_pattern; - CGFloat* m_patternColorComponents; - - bool m_isShading; - CGFunctionRef m_gradientFunction; - CGShadingRef m_shading; - CGFloat *m_gradientComponents; +static const char *gs_stripedback_xpm[] = { +/* columns rows colors chars-per-pixel */ +"4 4 2 1", +". c #F0F0F0", +"X c #ECECEC", +/* pixels */ +"....", +"....", +"XXXX", +"XXXX" }; -wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer) : wxGraphicsObjectRefData( renderer ) +wxBitmap gs_stripedback_bmp( wxImage( (const char* const* ) gs_stripedback_xpm ), -1 ) ; + +wxMacCoreGraphicsColour::~wxMacCoreGraphicsColour() { - Init(); + delete[] m_patternColorComponents; } -void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, - const wxColour&c1, const wxColour&c2 ) +void wxMacCoreGraphicsColour::Init() { - m_gradientFunction = CreateGradientFunction( c1, c2 ); - m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake(x1,y1), CGPointMake(x2,y2), m_gradientFunction, true, true ) ; - m_isShading = true ; + m_isPattern = false; + m_patternColorComponents = NULL; } -void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, - const wxColour &oColor, const wxColour &cColor ) +void wxMacCoreGraphicsColour::Apply( CGContextRef cgContext ) { - m_gradientFunction = CreateGradientFunction( oColor, cColor ); - m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake(xo,yo), 0, CGPointMake(xc,yc), radius, m_gradientFunction, true, true ) ; - m_isShading = true ; + if ( m_isPattern ) + { + CGAffineTransform matrix = CGContextGetCTM( cgContext ); + CGContextSetPatternPhase( cgContext, CGSizeMake(matrix.tx, matrix.ty) ); + CGContextSetFillColorSpace( cgContext , m_colorSpace ); + CGContextSetFillPattern( cgContext, m_pattern , m_patternColorComponents ); + } + else + { + CGContextSetFillColorWithColor( cgContext, m_color ); + } } -wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* renderer, const wxBrush &brush) : wxGraphicsObjectRefData( renderer ) +wxMacCoreGraphicsColour::wxMacCoreGraphicsColour() { Init(); +} +wxMacCoreGraphicsColour::wxMacCoreGraphicsColour( const wxBrush &brush ) +{ + Init(); if ( brush.GetStyle() == wxSOLID ) { if ( brush.MacGetBrushKind() == kwxMacBrushTheme ) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if ( HIThemeBrushCreateCGColor != 0 ) + if ( UMAGetSystemVersion() >= 0x1040 ) { CGColorRef color ; HIThemeBrushCreateCGColor( brush.MacGetTheme(), &color ); @@ -550,17 +541,30 @@ wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* rende else #endif { - // as close as we can get, unfortunately < 10.4 things get difficult - RGBColor color; - GetThemeBrushAsColor( brush.MacGetTheme(), 32, true, &color ); - float components[4] = { (CGFloat) color.red / 65536, - (CGFloat) color.green / 65536, (CGFloat) color.blue / 65536, 1 } ; - m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ; + if( brush.MacGetTheme() == kThemeBrushDialogBackgroundActive ) + { + // striped background is a pattern, we have to emulate it + + m_isPattern = true; + m_patternColorComponents = new CGFloat[1] ; + m_patternColorComponents[0] = 1.0; + m_colorSpace.Set( CGColorSpaceCreatePattern( NULL ) ); + m_pattern.Set( *( new ImagePattern( &gs_stripedback_bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) ); + } + else + { + // as close as we can get, unfortunately < 10.4 things get difficult + RGBColor color; + GetThemeBrushAsColor( brush.MacGetTheme(), 32, true, &color ); + CGFloat components[4] = { (CGFloat) color.red / 65536, + (CGFloat) color.green / 65536, (CGFloat) color.blue / 65536, 1 } ; + m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ; + } } } else { - float components[4] = { brush.GetColour().Red() / 255.0 , brush.GetColour().Green() / 255.0 , + CGFloat components[4] = { brush.GetColour().Red() / 255.0 , brush.GetColour().Green() / 255.0 , brush.GetColour().Blue() / 255.0 , brush.GetColour().Alpha() / 255.0 } ; m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ; } @@ -592,6 +596,62 @@ wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* rende } } +class wxMacCoreGraphicsBrushData : public wxGraphicsObjectRefData +{ +public: + wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer ); + wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer, const wxBrush &brush ); + ~wxMacCoreGraphicsBrushData (); + + virtual void Apply( wxGraphicsContext* context ); + void CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, + const wxColour&c1, const wxColour&c2 ); + void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, + const wxColour &oColor, const wxColour &cColor ); + + virtual bool IsShading() { return m_isShading; } + CGShadingRef GetShading() { return m_shading; } +protected: + CGFunctionRef CreateGradientFunction( const wxColour& c1, const wxColour& c2 ); + static void CalculateShadingValues (void *info, const CGFloat *in, CGFloat *out); + virtual void Init(); + + wxMacCoreGraphicsColour m_cgColor; + + bool m_isShading; + CGFunctionRef m_gradientFunction; + CGShadingRef m_shading; + CGFloat *m_gradientComponents; +}; + +wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer) : wxGraphicsObjectRefData( renderer ) +{ + Init(); +} + +void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, + const wxColour&c1, const wxColour&c2 ) +{ + m_gradientFunction = CreateGradientFunction( c1, c2 ); + m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake(x1,y1), CGPointMake(x2,y2), m_gradientFunction, true, true ) ; + m_isShading = true ; +} + +void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, + const wxColour &oColor, const wxColour &cColor ) +{ + m_gradientFunction = CreateGradientFunction( oColor, cColor ); + m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake(xo,yo), 0, CGPointMake(xc,yc), radius, m_gradientFunction, true, true ) ; + m_isShading = true ; +} + +wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* renderer, const wxBrush &brush) : wxGraphicsObjectRefData( renderer ), + m_cgColor( brush ) +{ + Init(); + +} + wxMacCoreGraphicsBrushData::~wxMacCoreGraphicsBrushData() { if ( m_shading ) @@ -601,15 +661,12 @@ wxMacCoreGraphicsBrushData::~wxMacCoreGraphicsBrushData() CGFunctionRelease(m_gradientFunction); delete[] m_gradientComponents; - delete[] m_patternColorComponents; } void wxMacCoreGraphicsBrushData::Init() { - m_patternColorComponents = NULL; m_gradientFunction = NULL; m_shading = NULL; - m_isPattern = false; m_gradientComponents = NULL; m_isShading = false; } @@ -624,17 +681,7 @@ void wxMacCoreGraphicsBrushData::Apply( wxGraphicsContext* context ) } else { - if ( m_isPattern ) - { - CGAffineTransform matrix = CGContextGetCTM( cg ); - CGContextSetPatternPhase( cg, CGSizeMake(matrix.tx, matrix.ty) ); - CGContextSetFillColorSpace( cg , m_colorSpace ); - CGContextSetFillPattern( cg, m_pattern , m_patternColorComponents ); - } - else - { - CGContextSetFillColorWithColor( cg, m_color ); - } + m_cgColor.Apply( cg ); } } @@ -1131,7 +1178,7 @@ bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, int fillStyle) class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext { public: - wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext ); + wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width = 0, wxDouble height = 0 ); wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window ); @@ -1145,6 +1192,15 @@ public: void Init(); + // returns the size of the graphics context in device coordinates + virtual void GetSize( wxDouble* width, wxDouble* height); + + virtual void StartPage( wxDouble width, wxDouble height ); + + virtual void EndPage(); + + virtual void Flush(); + // push the current state of the context, ie the transformation matrix on a stack virtual void PushState(); @@ -1241,6 +1297,8 @@ private: WindowRef m_windowRef; bool m_releaseContext; CGAffineTransform m_windowTransform; + wxDouble m_width; + wxDouble m_height; wxMacCFRefHolder m_clipRgn; }; @@ -1263,20 +1321,44 @@ private: IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsContext, wxGraphicsContext) +class wxQuartzOffsetHelper +{ +public : + wxQuartzOffsetHelper( CGContextRef cg , bool offset ) + { + m_cg = cg; + m_offset = offset; + if ( m_offset ) + CGContextTranslateCTM( m_cg, 0.5, 0.5 ); + } + ~wxQuartzOffsetHelper( ) + { + if ( m_offset ) + CGContextTranslateCTM( m_cg, -0.5, -0.5 ); + } +public : + CGContextRef m_cg; + bool m_offset; +} ; + void wxMacCoreGraphicsContext::Init() { m_cgContext = NULL; m_releaseContext = false; m_windowRef = NULL; + m_width = 0; + m_height = 0; HIRect r = CGRectMake(0,0,0,0); m_clipRgn.Set(HIShapeCreateWithRect(&r)); } -wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext ) : wxGraphicsContext(renderer) +wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer) { Init(); SetNativeContext(cgcontext); + m_width = width; + m_height = height; } wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window ): wxGraphicsContext(renderer) @@ -1316,11 +1398,46 @@ wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext() SetNativeContext(NULL); } +void wxMacCoreGraphicsContext::GetSize( wxDouble* width, wxDouble* height) +{ + *width = m_width; + *height = m_height; +} + + +void wxMacCoreGraphicsContext::StartPage( wxDouble width, wxDouble height ) +{ + CGRect r; + if ( width != 0 && height != 0) + r = CGRectMake( 0 , 0 , width , height ); + else + r = CGRectMake( 0 , 0 , m_width , m_height ); + + CGContextBeginPage(m_cgContext, &r ); +// CGContextTranslateCTM( m_cgContext , 0 , height == 0 ? m_height : height ); +// CGContextScaleCTM( m_cgContext , 1 , -1 ); +} + +void wxMacCoreGraphicsContext::EndPage() +{ + CGContextEndPage(m_cgContext); +} + +void wxMacCoreGraphicsContext::Flush() +{ + CGContextFlush(m_cgContext); +} + void wxMacCoreGraphicsContext::EnsureIsValid() { if ( !m_cgContext ) { - OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext ); + OSStatus status = +#ifndef __LP64__ + QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext ); +#else + paramErr; +#endif wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ); CGContextConcatCTM( m_cgContext, m_windowTransform ); @@ -1340,6 +1457,8 @@ void wxMacCoreGraphicsContext::EnsureIsValid() } } +// TODO test whether the private CGContextSetCompositeOperation works under 10.3 (using NSCompositingModes) + bool wxMacCoreGraphicsContext::SetLogicalFunction( int function ) { if (m_logicalFunction == function) @@ -1447,16 +1566,11 @@ void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath &path ) EnsureIsValid(); - bool offset = ShouldOffset(); - if ( offset ) - CGContextTranslateCTM( m_cgContext, 0.5, 0.5 ); + wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() ); ((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this); CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() ); CGContextStrokePath( m_cgContext ); - - if ( offset ) - CGContextTranslateCTM( m_cgContext, -0.5, -0.5 ); } void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , int fillStyle ) @@ -1502,16 +1616,10 @@ void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , int fillSt if ( !m_pen.IsNull() ) ((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this); - bool offset = ShouldOffset(); - - if ( offset ) - CGContextTranslateCTM( m_cgContext, 0.5, 0.5 ); + wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() ); CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() ); CGContextDrawPath( m_cgContext , mode ); - - if ( offset ) - CGContextTranslateCTM( m_cgContext, -0.5, -0.5 ); } void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , int fillStyle ) @@ -1551,7 +1659,11 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg ) CGContextRestoreGState( m_cgContext ); CGContextRestoreGState( m_cgContext ); if ( m_releaseContext ) + { +#ifndef __LP64__ QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext); +#endif + } else CGContextRelease(m_cgContext); } @@ -1786,6 +1898,18 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid { wxCHECK_RET( !m_font.IsNull(), wxT("wxDC(cg)::DoGetTextExtent - no valid font set") ); + if ( width ) + *width = 0; + if ( height ) + *height = 0; + if ( descent ) + *descent = 0; + if ( externalLeading ) + *externalLeading = 0; + + if (str.empty()) + return; + OSStatus status = noErr; ATSUTextLayout atsuLayout; diff --git a/src/mac/carbon/icon.cpp b/src/mac/carbon/icon.cpp index e774075ae3..ee61c69a8d 100644 --- a/src/mac/carbon/icon.cpp +++ b/src/mac/carbon/icon.cpp @@ -152,18 +152,34 @@ bool wxIcon::LoadFile( } else { -#if 0 - Str255 theName ; - OSType theType ; - wxMacStringToPascal( name , theName ) ; - - Handle resHandle = GetNamedResource( 'cicn' , theName ) ; - if ( resHandle != 0L ) + IconRef iconRef = NULL ; + + // first look in the resource fork + if ( iconRef == NULL ) + { + Str255 theName ; + + wxMacStringToPascal( filename , theName ) ; + Handle resHandle = GetNamedResource( 'icns' , theName ) ; + if ( resHandle != 0L ) + { + IconFamilyHandle iconFamily = (IconFamilyHandle) resHandle ; + HLock((Handle) iconFamily); + OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); + HUnlock((Handle) iconFamily); + wxASSERT_MSG( err == noErr , wxT("Error when constructing icon ref") ); + ReleaseResource( resHandle ) ; + } + } + if ( iconRef == NULL ) { - GetResInfo( resHandle , &theId , &theType , theName ) ; - ReleaseResource( resHandle ) ; + // TODO add other attempts to load it from files etc here } -#endif + if ( iconRef ) + { + m_refData = new wxIconRefData( (WXHICON) iconRef ) ; + return true ; + } } if ( theId != 0 ) diff --git a/src/mac/carbon/listbox.cpp b/src/mac/carbon/listbox.cpp index b43aaba328..dc7cf7ec1f 100644 --- a/src/mac/carbon/listbox.cpp +++ b/src/mac/carbon/listbox.cpp @@ -82,6 +82,7 @@ bool wxListBox::Create( return false; wxMacDataBrowserListControl* control = new wxMacDataBrowserListControl( this, pos, size, style ); + // TODO CHECK control->SetClientDataType( m_clientDataItemsType ); m_peer = control; MacPostControlCreate( pos, size ); diff --git a/src/mac/carbon/listctrl_mac.cpp b/src/mac/carbon/listctrl_mac.cpp index 52c83c10a7..6fbe91e190 100644 --- a/src/mac/carbon/listctrl_mac.cpp +++ b/src/mac/carbon/listctrl_mac.cpp @@ -102,7 +102,7 @@ wxEND_HANDLERS_TABLE() wxCONSTRUCTOR_5( wxListCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle ) /* - TODO : Expose more information of a list's layout etc. via appropriate objects (à la NotebookPageInfo) + TODO : Expose more information of a list's layout etc. via appropriate objects (ï¿  la NotebookPageInfo) */ #else IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl) @@ -2770,19 +2770,29 @@ void wxMacDataBrowserListCtrlControl::DrawItem( } HIThemeTextHorizontalFlush hFlush = kHIThemeTextHorizontalFlushLeft; - UInt16 fontID = kThemeViewsFont; + HIThemeTextInfo info; + +#ifdef __LP64__ + info.version = kHIThemeTextInfoVersionOne; + info.fontID = kThemeViewsFont; + if (font.Ok()) + { + info.fontID = kThemeSpecifiedFont; + info.font = (CTFontRef) font.MacGetCTFont(); + } +#else + info.version = kHIThemeTextInfoVersionZero; + info.fontID = kThemeViewsFont; if (font.Ok()) { if (font.GetFamily() != wxFONTFAMILY_DEFAULT) - fontID = font.MacGetThemeFontID(); + info.fontID = font.MacGetThemeFontID(); -// FIXME: replace these with CG or ATSUI calls so we can remove this #ifndef. -#ifndef __LP64__ ::TextSize( (short)(font.MacGetFontSize()) ) ; ::TextFace( font.MacGetFontStyle() ) ; -#endif } +#endif wxListItem item; list->GetColumn(listColumn, item); @@ -2799,10 +2809,7 @@ void wxMacDataBrowserListCtrlControl::DrawItem( } } - HIThemeTextInfo info; - info.version = kHIThemeTextInfoVersionZero; info.state = active ? kThemeStateActive : kThemeStateInactive; - info.fontID = fontID; info.horizontalFlushness = hFlush; info.verticalFlushness = kHIThemeTextVerticalFlushCenter; info.options = kHIThemeTextBoxOptionNone; @@ -2818,8 +2825,10 @@ void wxMacDataBrowserListCtrlControl::DrawItem( CGContextRestoreGState(context); +#ifndef __LP64__ if (savedState != NULL) SetThemeDrawingState(savedState, true); +#endif } OSStatus wxMacDataBrowserListCtrlControl::GetSetItemData(DataBrowserItemID itemID, @@ -2867,13 +2876,19 @@ OSStatus wxMacDataBrowserListCtrlControl::GetSetItemData(DataBrowserItemID itemI if ( list && list->HasFlag( wxLC_EDIT_LABELS ) ) { verify_noerr(SetDataBrowserItemDataBooleanValue( itemData, true )); + err = noErr ; } break ; default : if ( property >= kMinColumnId ) { - wxMacCFStringHolder cfStr(text); - verify_noerr( ::SetDataBrowserItemDataText( itemData, cfStr) ); + wxMacCFStringHolder cfStr; + + if (!text.IsEmpty()){ + cfStr.Assign( text, wxLocale::GetSystemEncoding() ); + err = ::SetDataBrowserItemDataText( itemData, cfStr ); + err = noErr; + } @@ -2944,7 +2959,6 @@ void wxMacDataBrowserListCtrlControl::ItemNotification(DataBrowserItemID itemID, bool trigger = false; wxListEvent event( wxEVT_COMMAND_LIST_ITEM_SELECTED, list->GetId() ); - bool isSingle = (list->GetWindowStyle() & wxLC_SINGLE_SEL) != 0; event.SetEventObject( list ); if ( !list->IsVirtual() ) @@ -2964,8 +2978,9 @@ void wxMacDataBrowserListCtrlControl::ItemNotification(DataBrowserItemID itemID, { case kDataBrowserItemDeselected: event.SetEventType(wxEVT_COMMAND_LIST_ITEM_DESELECTED); - if ( !isSingle ) - trigger = !IsSelectionSuppressed(); + // as the generic implementation is also triggering this + // event for single selection, we do the same (different than listbox) + trigger = !IsSelectionSuppressed(); break; case kDataBrowserItemSelected: diff --git a/src/mac/carbon/mediactrl.cpp b/src/mac/carbon/mediactrl.cpp index 210b7d930e..f3ff582a13 100644 --- a/src/mac/carbon/mediactrl.cpp +++ b/src/mac/carbon/mediactrl.cpp @@ -57,6 +57,14 @@ #include #endif +#if !defined(__DARWIN__) || !defined(__LP64__) +#define USE_QUICKTIME 1 +#else +#define USE_QUICKTIME 0 +#endif + +#if USE_QUICKTIME + //--------------------------------------------------------------------------- // Height and Width of movie controller in the movie control (apple samples) //--------------------------------------------------------------------------- @@ -1226,6 +1234,8 @@ pascal OSStatus wxQTMediaBackend::WindowEventHandler( return eventNotHandledErr; } +#endif + // in source file that contains stuff you don't directly use #include "wx/html/forcelnk.h" FORCE_LINK_ME(basewxmediabackends) diff --git a/src/mac/carbon/menu.cpp b/src/mac/carbon/menu.cpp index 860ec771f7..a947e73f60 100644 --- a/src/mac/carbon/menu.cpp +++ b/src/mac/carbon/menu.cpp @@ -554,6 +554,82 @@ void wxMenu::MacAfterDisplay( bool isSubMenu ) } } +wxInt32 wxMenu::MacHandleCommandProcess( wxMenuItem* item, int id, wxWindow* targetWindow ) +{ + OSStatus result = eventNotHandledErr ; + if (item->IsCheckable()) + item->Check( !item->IsChecked() ) ; + + if ( SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ) + result = noErr ; + else + { + if ( targetWindow != NULL ) + { + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id); + event.SetEventObject(targetWindow); + event.SetInt(item->IsCheckable() ? item->IsChecked() : -1); + + if ( targetWindow->GetEventHandler()->ProcessEvent(event) ) + result = noErr ; + } + } + return result; +} + +wxInt32 wxMenu::MacHandleCommandUpdateStatus( wxMenuItem* item, int id, wxWindow* targetWindow ) +{ + OSStatus result = eventNotHandledErr ; + wxUpdateUIEvent event(id); + event.SetEventObject( this ); + + bool processed = false; + + // Try the menu's event handler + { + wxEvtHandler *handler = GetEventHandler(); + if ( handler ) + processed = handler->ProcessEvent(event); + } + + // Try the window the menu was popped up from + // (and up through the hierarchy) + if ( !processed ) + { + const wxMenuBase *menu = this; + while ( menu ) + { + wxWindow *win = menu->GetInvokingWindow(); + if ( win ) + { + processed = win->GetEventHandler()->ProcessEvent(event); + break; + } + + menu = menu->GetParent(); + } + } + + if ( !processed && targetWindow != NULL) + { + processed = targetWindow->GetEventHandler()->ProcessEvent(event); + } + + if ( processed ) + { + // if anything changed, update the changed attribute + if (event.GetSetText()) + SetLabel(id, event.GetText()); + if (event.GetSetChecked()) + Check(id, event.GetChecked()); + if (event.GetSetEnabled()) + Enable(id, event.GetEnabled()); + + result = noErr ; + } + return result; +} + // Menu Bar /* diff --git a/src/mac/carbon/menuitem.cpp b/src/mac/carbon/menuitem.cpp index 0d8d3d589c..39156dce67 100644 --- a/src/mac/carbon/menuitem.cpp +++ b/src/mac/carbon/menuitem.cpp @@ -63,6 +63,13 @@ void wxMenuItem::UpdateItemBitmap() MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ; MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ; + DoUpdateItemBitmap( mhandle, index ); +} + +void wxMenuItem::DoUpdateItemBitmap( WXHMENU menu, wxUint16 index) +{ + MenuHandle mhandle = (MenuHandle) menu; + if ( mhandle == NULL || index == 0) return ; @@ -76,6 +83,9 @@ void wxMenuItem::UpdateItemBitmap() if ( info.contentType == kControlContentIconRef ) SetMenuItemIconHandle( mhandle , index , kMenuIconRefType , (Handle) info.u.iconRef ) ; + else if ( info.contentType == kControlContentCGImageRef ) + SetMenuItemIconHandle( mhandle , index , + kMenuCGImageRefType , (Handle) info.u.imageRef ) ; } wxMacReleaseBitmapButton( &info ) ; #endif diff --git a/src/mac/carbon/metafile.cpp b/src/mac/carbon/metafile.cpp index aebbf38e04..5dce1f01a0 100644 --- a/src/mac/carbon/metafile.cpp +++ b/src/mac/carbon/metafile.cpp @@ -24,7 +24,7 @@ #include "wx/metafile.h" #include "wx/clipbrd.h" -#include "wx/mac/private.h" +#include "wx/mac/uma.h" #include "wx/graphics.h" #include @@ -33,58 +33,186 @@ IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject) IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC) +#define M_METAFILEREFDATA( a ) ((wxMetafileRefData*)(a).GetRefData()) + class wxMetafileRefData: public wxGDIRefData { - friend class wxMetafile; - public: - wxMetafileRefData(); +#if wxMAC_USE_CORE_GRAPHICS + // creates a metafile from memory, assumes ownership + wxMetafileRefData(CFDataRef data); +#else + // creates a metafile from memory, assumes ownership + wxMetafileRefData(PicHandle data); +#endif + // prepares a recording metafile + wxMetafileRefData( int width, int height); + // prepares a metafile to be read from a file (if filename is not empty) + wxMetafileRefData( const wxString& filename); virtual ~wxMetafileRefData(); -private: - PicHandle m_metafile; + void Init(); + + int GetWidth() const { return m_width; } + int GetHeight() const { return m_height; } #if wxMAC_USE_CORE_GRAPHICS - QDPictRef m_qdPictRef; + CGPDFDocumentRef GetPDFDocument() const { return m_pdfDoc; } + void UpdateDocumentFromData() ; + + const wxCFDataRef& GetData() const { return m_data; } + CGContextRef GetContext() const { return m_context; } +#else + PicHandle GetHandle() const { return m_metafile; } #endif + // ends the recording + void Close(); +private: +#if wxMAC_USE_CORE_GRAPHICS + wxCFDataRef m_data; + wxCFRef m_pdfDoc; + CGContextRef m_context; +#else + PicHandle m_metafile; +#endif + int m_width ; + int m_height ; }; -wxMetafileRefData::wxMetafileRefData() +#if !wxMAC_USE_CORE_GRAPHICS +wxMetafileRefData::wxMetafileRefData(PicHandle pict) +{ + Init(); + m_metafile = pict; + + Rect r; + wxMacGetPictureBounds( m_metafile, &r ); + m_width = r.right - r.left; + m_height = r.bottom - r.top; +} +#else +wxMetafileRefData::wxMetafileRefData(CFDataRef data) : + m_data(data) +{ + Init(); + UpdateDocumentFromData(); +} +#endif + +wxMetafileRefData::wxMetafileRefData( const wxString& filename ) { + Init(); +#if wxMAC_USE_CORE_GRAPHICS + if ( !filename.empty() ) + { + wxCFRef cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxMacCFStringHolder(filename))); + CFStringNormalize(cfMutableString,kCFStringNormalizationFormD); + wxCFRef url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false)); + m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url)); + } +#else + wxASSERT_MSG( filename.empty(), wxT("no file-based metafile support yet") ); m_metafile = NULL; +#endif +} + + +wxMetafileRefData::wxMetafileRefData( int width, int height) +{ + Init(); + m_width = width; + m_height = height; #if wxMAC_USE_CORE_GRAPHICS - m_qdPictRef = NULL; + CGRect r = CGRectMake( 0 , 0 , width , height ); + + CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); + m_data.reset(data); + CGDataConsumerRef dataConsumer = UMACGDataConsumerCreateWithCFData(data); + m_context = CGPDFContextCreate( dataConsumer, (width != 0 && height != 0) ? &r : NULL , NULL ); + CGDataConsumerRelease( dataConsumer ); + if ( m_context ) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if ( &CGPDFContextBeginPage != NULL ) + CGPDFContextBeginPage(m_context, NULL); + else +#endif + CGContextBeginPage(m_context, &r); + + CGColorSpaceRef genericColorSpace = wxMacGetGenericRGBColorSpace(); + + CGContextSetFillColorSpace( m_context, genericColorSpace ); + CGContextSetStrokeColorSpace( m_context, genericColorSpace ); + + CGContextTranslateCTM( m_context , 0 , height ) ; + CGContextScaleCTM( m_context , 1 , -1 ) ; + } +#else + Rect r = { 0, 0, height, width }; + m_metafile = OpenPicture( &r ) ; #endif } wxMetafileRefData::~wxMetafileRefData() { +#if! wxMAC_USE_CORE_GRAPHICS if (m_metafile) { -#ifndef __LP64__ KillPicture( (PicHandle)m_metafile ); m_metafile = NULL; + } +#endif +} +void wxMetafileRefData::Init() +{ #if wxMAC_USE_CORE_GRAPHICS - QDPictRelease( m_qdPictRef ); - m_qdPictRef = NULL; -#endif + m_context = NULL; +#else + m_metafile = NULL; #endif - } + m_width = -1; + m_height = -1; } -wxMetaFile::wxMetaFile(const wxString& file) +void wxMetafileRefData::Close() { - m_refData = new wxMetafileRefData; +#if wxMAC_USE_CORE_GRAPHICS +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if ( &CGPDFContextEndPage != NULL ) + CGPDFContextEndPage(m_context); + else +#endif + CGContextEndPage(m_context); - M_METAFILEDATA->m_metafile = NULL; - wxASSERT_MSG( file.empty(), wxT("no file-based metafile support yet") ); + CGContextRelease(m_context); + m_context = NULL; + + UpdateDocumentFromData(); +#else + ClosePicture(); +#endif +} -#if 0 - if (!file.IsNull() && (file.Cmp("") == 0)) - M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile( file ); +#if wxMAC_USE_CORE_GRAPHICS +void wxMetafileRefData::UpdateDocumentFromData() +{ + wxCFRef provider(UMACGDataProviderCreateWithCFData(m_data)); + m_pdfDoc.reset(CGPDFDocumentCreateWithProvider(provider)); + if ( m_pdfDoc != NULL ) + { + CGPDFPageRef page = CGPDFDocumentGetPage( m_pdfDoc, 1 ); + CGRect rect = CGPDFPageGetBoxRect ( page, kCGPDFMediaBox); + m_width = rect.size.width; + m_height = rect.size.height; + } +} #endif + +wxMetaFile::wxMetaFile(const wxString& file) +{ + m_refData = new wxMetafileRefData(file); } wxMetaFile::~wxMetaFile() @@ -93,12 +221,20 @@ wxMetaFile::~wxMetaFile() bool wxMetaFile::IsOk() const { - return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != NULL)); +#if wxMAC_USE_CORE_GRAPHICS + return (M_METAFILEDATA && (M_METAFILEDATA->GetData() != NULL)); +#else + return (M_METAFILEDATA && (M_METAFILEDATA->GetHandle() != NULL)); +#endif } WXHMETAFILE wxMetaFile::GetHMETAFILE() const { - return (WXHMETAFILE) M_METAFILEDATA->m_metafile; +#if wxMAC_USE_CORE_GRAPHICS + return (WXHMETAFILE) (CFDataRef) M_METAFILEDATA->GetData(); +#else + return (WXHMETAFILE) M_METAFILEDATA->GetHandle(); +#endif } bool wxMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height)) @@ -106,7 +242,6 @@ bool wxMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height)) bool success = true; #if wxUSE_DRAG_AND_DROP - // TODO: to finish this port, we need the data object first if (m_refData == NULL) return false; @@ -130,28 +265,31 @@ void wxMetafile::SetHMETAFILE(WXHMETAFILE mf) { UnRef(); - m_refData = new wxMetafileRefData; +#if wxMAC_USE_CORE_GRAPHICS + m_refData = new wxMetafileRefData((CFDataRef)mf); +#else + m_refData = new wxMetafileRefData((PicHandle)mf); +#endif +} - M_METAFILEDATA->m_metafile = (PicHandle)mf; +void wxMetafile::SetPICT(void* pictHandle) +{ + UnRef(); #if wxMAC_USE_CORE_GRAPHICS - size_t sz = GetHandleSize( (Handle) M_METAFILEDATA->m_metafile ); - wxMemoryBuffer* membuf = new wxMemoryBuffer( sz ); - void *data = membuf->GetWriteBuf( sz ); - - memcpy( data, *M_METAFILEDATA->m_metafile, sz ); - membuf->UngetWriteBuf( sz ); - CGDataProviderRef provider = CGDataProviderCreateWithData( - membuf, data, sz, wxMacMemoryBufferReleaseProc ); - M_METAFILEDATA->m_qdPictRef = NULL; - -#ifndef __LP64__ - if (provider != NULL) - { - M_METAFILEDATA->m_qdPictRef = QDPictCreateWithProvider( provider ); - CGDataProviderRelease( provider ); - } -#endif + Handle picHandle = (Handle) pictHandle; + HLock(picHandle); + CFDataRef data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) *picHandle, GetHandleSize(picHandle), kCFAllocatorNull); + wxCFRef provider(UMACGDataProviderCreateWithCFData(data)); + QDPictRef pictRef = QDPictCreateWithProvider(provider); + CGRect rect = QDPictGetBounds(pictRef); + m_refData = new wxMetafileRefData( rect.size.width, rect.size.height ); + QDPictDrawToCGContext( ((wxMetafileRefData*) m_refData)->GetContext(), rect, pictRef ); + CFRelease( data ); + QDPictRelease( pictRef ); + ((wxMetafileRefData*) m_refData)->Close(); +#else + m_refData = new wxMetafileRefData((PicHandle)pictHandle); #endif } @@ -165,17 +303,13 @@ bool wxMetaFile::Play(wxDC *dc) { #if wxMAC_USE_CORE_GRAPHICS -#ifndef __LP64__ - QDPictRef cgPictRef = M_METAFILEDATA->m_qdPictRef; CGContextRef cg = (CGContextRef) dc->GetGraphicsContext()->GetNativeContext(); - CGRect bounds = QDPictGetBounds( cgPictRef ); - - CGContextSaveGState( cg ); - CGContextTranslateCTM( cg, 0, bounds.size.width ); - CGContextScaleCTM( cg, 1, -1 ); - QDPictDrawToCGContext( cg, bounds, cgPictRef ); - CGContextRestoreGState( cg ); -#endif + CGPDFDocumentRef doc = M_METAFILEDATA->GetPDFDocument(); + CGPDFPageRef page = CGPDFDocumentGetPage( doc, 1 ); + wxMacCGContextStateSaver save(cg); + CGContextDrawPDFPage( cg, page ); +// CGContextTranslateCTM( cg, 0, bounds.size.width ); +// CGContextScaleCTM( cg, 1, -1 ); #else PicHandle pict = (PicHandle)GetHMETAFILE(); wxMacPortSetter helper( dc ); @@ -193,13 +327,8 @@ wxSize wxMetaFile::GetSize() const if (Ok()) { -#ifndef __LP64__ - PicHandle pict = (PicHandle)GetHMETAFILE(); - Rect r; - wxMacGetPictureBounds( pict, &r ); - dataSize.x = r.right - r.left; - dataSize.y = r.bottom - r.top; -#endif + dataSize.x = M_METAFILEDATA->GetWidth(); + dataSize.y = M_METAFILEDATA->GetHeight(); } return dataSize; @@ -219,17 +348,17 @@ wxMetaFileDC::wxMetaFileDC( wxASSERT_MSG( filename.empty(), wxT("no file based metafile support yet")); m_metaFile = new wxMetaFile( filename ); - + wxMetafileRefData* metafiledata = new wxMetafileRefData(width, height); + m_metaFile->UnRef(); + m_metaFile->SetRefData( metafiledata ); #if wxMAC_USE_CORE_GRAPHICS + SetGraphicsContext( wxGraphicsContext::CreateFromNative(metafiledata->GetContext())); + m_ok = (m_graphicContext != NULL) ; #else Rect r = { 0, 0, height, width }; - RectRgn( (RgnHandle)m_macBoundaryClipRgn, &r ); CopyRgn( (RgnHandle)m_macBoundaryClipRgn, (RgnHandle)m_macCurrentClipRgn ); - - m_metaFile->SetHMETAFILE( (WXHMETAFILE)OpenPicture( &r ) ); ::GetPort( (GrafPtr*)&m_macPort ); - m_ok = true; #endif @@ -253,36 +382,68 @@ void wxMetaFileDC::DoGetSize(int *width, int *height) const wxMetaFile *wxMetaFileDC::Close() { -#ifndef __LP64__ - ClosePicture(); +#if wxMAC_USE_CORE_GRAPHICS + delete m_graphicContext; + m_graphicContext = NULL; + m_ok = false; #endif + + M_METAFILEREFDATA(*m_metaFile)->Close(); + return m_metaFile; } #if wxUSE_DATAOBJ size_t wxMetafileDataObject::GetDataSize() const { +#if wxMAC_USE_CORE_GRAPHICS + CFIndex length = 0; + wxMetafileRefData* refData = M_METAFILEREFDATA(m_metafile); + if ( refData ) + length = refData->GetData().GetLength(); + return length; +#else return GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() ); +#endif } bool wxMetafileDataObject::GetDataHere(void *buf) const { + bool result = false; +#if wxMAC_USE_CORE_GRAPHICS + wxMetafileRefData* refData = M_METAFILEREFDATA(m_metafile); + if ( refData ) + { + CFIndex length = refData->GetData().GetLength(); + if ( length > 0 ) + { + result = true ; + refData->GetData().GetBytes(CFRangeMake(0,length), (UInt8 *) buf); + } + } +#else Handle pictH = (Handle)(*((wxMetafile*)&m_metafile)).GetHMETAFILE(); - bool result = (pictH != NULL); + result = (pictH != NULL); if (result) memcpy( buf, *pictH, GetHandleSize( pictH ) ); +#endif return result; } bool wxMetafileDataObject::SetData(size_t len, const void *buf) { +#if wxMAC_USE_CORE_GRAPHICS + wxMetafileRefData* metafiledata = new wxMetafileRefData(wxCFRefFromGet(wxCFDataRef((UInt8*)buf, len).get())); + m_metafile.UnRef(); + m_metafile.SetRefData( metafiledata ); +#else Handle handle = NewHandle( len ); SetHandleSize( handle, len ); memcpy( *handle, buf, len ); m_metafile.SetHMETAFILE( (WXHMETAFILE) handle ); - +#endif return true; } #endif diff --git a/src/mac/carbon/msgdlg.cpp b/src/mac/carbon/msgdlg.cpp index 0b4f029de2..dff0c7e064 100644 --- a/src/mac/carbon/msgdlg.cpp +++ b/src/mac/carbon/msgdlg.cpp @@ -75,13 +75,13 @@ int wxMessageDialog::ShowModal() AlertType alertType = kAlertPlainAlert; if (style & wxICON_EXCLAMATION) - alertType = kAlertNoteAlert; + alertType = kAlertCautionAlert; else if (style & wxICON_HAND) alertType = kAlertStopAlert; else if (style & wxICON_INFORMATION) alertType = kAlertNoteAlert; else if (style & wxICON_QUESTION) - alertType = kAlertCautionAlert; + alertType = kAlertNoteAlert; // work out what to display diff --git a/src/mac/carbon/overlay.cpp b/src/mac/carbon/overlay.cpp index ec49a7fc9e..933aa8bf01 100644 --- a/src/mac/carbon/overlay.cpp +++ b/src/mac/carbon/overlay.cpp @@ -142,7 +142,7 @@ void wxOverlayImpl::BeginDrawing( wxWindowDC* dc) void wxOverlayImpl::EndDrawing( wxWindowDC* dc) { dc->SetGraphicsContext(NULL); - CGContextSynchronize( m_overlayContext ); + CGContextFlush( m_overlayContext ); } void wxOverlayImpl::Clear(wxWindowDC* WXUNUSED(dc)) diff --git a/src/mac/carbon/popupwin.cpp b/src/mac/carbon/popupwin.cpp index bd4fe547fa..f3f91de491 100644 --- a/src/mac/carbon/popupwin.cpp +++ b/src/mac/carbon/popupwin.cpp @@ -13,7 +13,7 @@ // declarations // ============================================================================ -// CAUTION : This is not functional yet +// CAUTION : This is only experimental stuff right now // ---------------------------------------------------------------------------- // headers @@ -32,6 +32,7 @@ #endif //WX_PRECOMP #include "wx/popupwin.h" +#include "wx/tooltip.h" #include "wx/mac/private.h" @@ -39,79 +40,131 @@ // implementation // ============================================================================ +wxPopupWindow::~wxPopupWindow() +{ + if ( m_popupWindowRef ) + { +#if wxUSE_TOOLTIPS + wxToolTip::NotifyWindowDelete(m_popupWindowRef) ; +#endif + wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_popupWindowRef ) ) ; + } +} + bool wxPopupWindow::Create(wxWindow *parent, int flags) { + m_macIsUserPane = false ; + // popup windows are created hidden by default Hide(); - return wxPopupWindowBase::Create(parent) && - wxWindow::Create(parent, wxID_ANY, - wxDefaultPosition, wxDefaultSize, - flags | wxPOPUP_WINDOW); + if ( ! wxPopupWindowBase::Create(parent) ) + return false; + + WindowClass wclass = kHelpWindowClass; + WindowAttributes attr = kWindowCompositingAttribute ; + WindowRef parentWindow =(WindowRef) parent->MacGetTopLevelWindowRef(); + + Rect bounds = { 0,0,0,0 }; + OSStatus err = ::CreateNewWindow( wclass , attr , &bounds , (WindowRef*)&m_popupWindowRef ) ; + if ( err == noErr ) + { +// SetWindowGroup( (WindowRef) m_popupWindowRef, GetWindowGroup(parentWindow)); // Put them in the same group so that their window layers are consistent } -void wxPopupWindow::DoGetPosition(int *x, int *y) const + m_peer = new wxMacControl(this , true /*isRootControl*/) ; + + HIViewFindByID( HIViewGetRoot( (WindowRef) m_popupWindowRef ) , kHIViewWindowContentID , + m_peer->GetControlRefAddr() ) ; + if ( !m_peer->Ok() ) { - // the position of a "top level" window such as this should be in - // screen coordinates, not in the client ones which MSW gives us - // (because we are a child window) - wxPopupWindowBase::DoGetPosition(x, y); + // compatibility mode fallback + GetRootControl( (WindowRef) m_popupWindowRef , m_peer->GetControlRefAddr() ) ; + if ( !m_peer->Ok() ) + CreateRootControl( (WindowRef) m_popupWindowRef , m_peer->GetControlRefAddr() ) ; + } + + // the root control level handler + MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ; - GetParent()->ClientToScreen(x, y); + // the frame window event handler + InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_popupWindowRef)) ) ; + // MacInstallTopLevelWindowEventHandler() ; + + if ( parent ) + parent->AddChild(this); + + return true; } -/* -WXDWORD wxPopupWindow::MSWGetStyle(long flags, WXDWORD *exstyle) const +void wxPopupWindow::DoMoveWindow(int x, int y, int width, int height) { - // we only honour the border flags, the others don't make sense for us - WXDWORD style = wxWindow::MSWGetStyle(flags & wxBORDER_MASK, exstyle); + Rect bounds = { y , x , y + height , x + width } ; + verify_noerr(SetWindowBounds( (WindowRef) m_popupWindowRef, kWindowStructureRgn , &bounds )) ; + wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified +} - if ( exstyle ) +void wxPopupWindow::DoGetPosition( int *x, int *y ) const { - // a popup window floats on top of everything - *exstyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW; + Rect bounds ; + + verify_noerr(GetWindowBounds((WindowRef) m_popupWindowRef, kWindowStructureRgn , &bounds )) ; + + if (x) + *x = bounds.left ; + if (y) + *y = bounds.top ; } - return style; +void wxPopupWindow::DoGetSize( int *width, int *height ) const +{ + Rect bounds ; + + verify_noerr(GetWindowBounds((WindowRef) m_popupWindowRef, kWindowStructureRgn , &bounds )) ; + + if (width) + *width = bounds.right - bounds.left ; + if (height) + *height = bounds.bottom - bounds.top ; } -WXHWND wxPopupWindow::MSWGetParent() const +void wxPopupWindow::DoGetClientSize( int *width, int *height ) const { - // we must be a child of the desktop to be able to extend beyond the parent - // window client area (like the comboboxes drop downs do) - // - // NB: alternative implementation would be to use WS_POPUP instead of - // WS_CHILD but then showing a popup would deactivate the parent which - // is ugly and working around this, although possible, is even more - // ugly - // GetDesktopWindow() is not always supported on WinCE, and if - // it is, it often returns NULL. -#ifdef __WXWINCE__ - return 0; -#else - return (WXHWND)::GetDesktopWindow(); -#endif + Rect bounds ; + + verify_noerr(GetWindowBounds((WindowRef) m_popupWindowRef, kWindowContentRgn , &bounds )) ; + + if (width) + *width = bounds.right - bounds.left ; + if (height) + *height = bounds.bottom - bounds.top ; } -*/ bool wxPopupWindow::Show(bool show) { if ( !wxWindowMac::Show(show) ) return false; -/* + if ( show ) { - // raise to top of z order - if (!::SetWindowPos(GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)) - { - wxLogLastError(_T("SetWindowPos")); - } + ::ShowWindow( (WindowRef)m_popupWindowRef ); + ::SelectWindow( (WindowRef)m_popupWindowRef ) ; - // and set it as the foreground window so the mouse can be captured - ::SetForegroundWindow(GetHwnd()); + // because apps expect a size event to occur at this moment + wxSizeEvent event(GetSize() , m_windowId); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); + } + else + { + ::HideWindow( (WindowRef)m_popupWindowRef ); } -*/ return true; } +WXWindow wxPopupWindow::MacGetPopupWindowRef() const +{ + return m_popupWindowRef; +} + #endif // #if wxUSE_POPUPWIN diff --git a/src/mac/carbon/radiobox.cpp b/src/mac/carbon/radiobox.cpp index 68ad272a3c..69ce082c1b 100644 --- a/src/mac/carbon/radiobox.cpp +++ b/src/mac/carbon/radiobox.cpp @@ -181,6 +181,22 @@ bool wxRadioBox::Enable(unsigned int item, bool enable) return current->Enable( enable ); } +bool wxRadioBox::IsItemEnabled(unsigned int item) const +{ + if (!IsValid( item )) + return false; + + unsigned int i = 0; + wxRadioButton *current = m_radioButtonCycle; + while (i != item) + { + i++; + current = current->NextInCycle(); + } + + return current->IsEnabled(); +} + // Returns the radiobox label // wxString wxRadioBox::GetLabel() const @@ -309,6 +325,23 @@ bool wxRadioBox::Show(unsigned int item, bool show) return current->Show( show ); } +bool wxRadioBox::IsItemShown(unsigned int item) const +{ + if (!IsValid( item )) + return false; + + unsigned int i = 0; + wxRadioButton *current = m_radioButtonCycle; + while (i != item) + { + i++; + current = current->NextInCycle(); + } + + return current->IsShown(); +} + + // Simulates the effect of the user issuing a command to the item // void wxRadioBox::Command( wxCommandEvent& event ) diff --git a/src/mac/carbon/renderer.cpp b/src/mac/carbon/renderer.cpp index 1a58d904af..182ee90912 100644 --- a/src/mac/carbon/renderer.cpp +++ b/src/mac/carbon/renderer.cpp @@ -57,6 +57,11 @@ public: wxOrientation orient, int flags = 0 ); + virtual void DrawCheckBox(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags = 0); + virtual void DrawComboBoxDropButton(wxWindow *win, wxDC& dc, const wxRect& rect, @@ -151,8 +156,13 @@ int wxRendererMac::DrawHeaderButton( wxWindow *win, CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top ); CGContextScaleCTM( cgContext, 1, -1 ); - HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ), cgContext ); - CGContextClip( cgContext ); + HIShapeRef shape = HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ); + if ( shape != 0 ) + { + HIShapeReplacePathInCGContext( shape , cgContext ); + CFRelease( shape ); + CGContextClip( cgContext ); + } HIViewConvertRect( &headerRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() ); #endif @@ -462,6 +472,8 @@ wxRendererMac::DrawMacThemeButton(wxWindow *win, drawInfo.kind = kind; drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive; drawInfo.value = (flags & wxCONTROL_SELECTED) ? kThemeButtonOn : kThemeButtonOff; + if (flags & wxCONTROL_UNDETERMINED) + drawInfo.value = kThemeButtonMixed; drawInfo.adornment = adornment; HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect ); @@ -474,6 +486,18 @@ wxRendererMac::DrawMacThemeButton(wxWindow *win, } } +void +wxRendererMac::DrawCheckBox(wxWindow *win, + wxDC& dc, + const wxRect& rect, + int flags) +{ + if (flags & wxCONTROL_CHECKED) + flags |= wxCONTROL_SELECTED; + + DrawMacThemeButton(win, dc, rect, flags, + kThemeCheckBox, kThemeAdornmentNone); +} void wxRendererMac::DrawComboBoxDropButton(wxWindow *win, diff --git a/src/mac/carbon/slider.cpp b/src/mac/carbon/slider.cpp index 7c87118ba6..484c775e73 100644 --- a/src/mac/carbon/slider.cpp +++ b/src/mac/carbon/slider.cpp @@ -252,7 +252,7 @@ void wxSlider::SetLineSize(int lineSize) int wxSlider::GetLineSize() const { // TODO - return 0; + return m_lineSize; } int wxSlider::GetSelEnd() const diff --git a/src/mac/carbon/sound.cpp b/src/mac/carbon/sound.cpp index b4ecddd1e0..c99967756a 100644 --- a/src/mac/carbon/sound.cpp +++ b/src/mac/carbon/sound.cpp @@ -79,6 +79,13 @@ static wxTimer* lastSoundTimer=NULL; static bool lastSoundIsPlaying=false; +#if !defined(__DARWIN__) || !defined(__LP64__) +#define USE_QUICKTIME 1 +#else +#define USE_QUICKTIME 0 +#endif + +#if USE_QUICKTIME // ------------------------------------------------------------------ // wxQTTimer - Handle Asyncronous Playing // ------------------------------------------------------------------ @@ -244,6 +251,8 @@ inline bool wxInitQT () } } +#endif + wxSound::wxSound() : m_hSnd(NULL), m_waveLength(0), m_pTimer(NULL), m_type(wxSound_NONE) { @@ -296,6 +305,8 @@ bool wxSound::DoPlay(unsigned flags) const { Stop(); +#if USE_QUICKTIME + Movie movie; switch(m_type) @@ -439,6 +450,7 @@ bool wxSound::DoPlay(unsigned flags) const DisposeMovie(movie); } +#endif return true; } @@ -460,10 +472,13 @@ void wxSound::Stop() void* wxSound::GetHandle() { +#if USE_QUICKTIME if(m_type == wxSound_RESOURCE) return (void*) ((wxSMTimer*)m_pTimer)->GetChannel(); return (void*) ((wxQTTimer*) m_pTimer)->GetMovie(); +#endif + return NULL; } #endif //wxUSE_SOUND diff --git a/src/mac/carbon/stattext.cpp b/src/mac/carbon/stattext.cpp index fdbdf4ba0f..2ae2746a0b 100644 --- a/src/mac/carbon/stattext.cpp +++ b/src/mac/carbon/stattext.cpp @@ -95,6 +95,7 @@ wxSize wxStaticText::DoGetBestSize() const SInt16 baseline; wxMacCFStringHolder str( m_label, m_font.GetEncoding() ); +#ifndef __LP64__ if ( m_font.MacGetThemeFontID() != kThemeCurrentPortFont ) { err = GetThemeTextDimensions( @@ -103,6 +104,7 @@ wxSize wxStaticText::DoGetBestSize() const verify_noerr( err ); } else +#endif { #if wxMAC_USE_CORE_GRAPHICS wxClientDC dc(const_cast(this)); diff --git a/src/mac/carbon/taskbar.cpp b/src/mac/carbon/taskbar.cpp index 5479c2ade1..6f12415372 100644 --- a/src/mac/carbon/taskbar.cpp +++ b/src/mac/carbon/taskbar.cpp @@ -141,109 +141,89 @@ wxDockEventHandler(EventHandlerCallRef WXUNUSED(inHandlerCallRef), wxDockTaskBarIcon* pTB = (wxDockTaskBarIcon*) pData; const UInt32 eventClass = GetEventClass(inEvent); const UInt32 eventKind = GetEventKind(inEvent); + + OSStatus err = eventNotHandledErr; // Handle wxTaskBar menu events (note that this is a global event handler // so it will actually get called by all commands/menus) - if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess)) + if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess || eventKind == kEventCommandUpdateStatus )) { // if we have no taskbar menu quickly pass it back to wxApp - if (pTB->m_pMenu == NULL) - return eventNotHandledErr; - - // This is the real reason why we need this. Normally menus - // get handled in wxMacAppEventHandler - // - // pascal OSStatus wxMacAppEventHandler(EventHandlerCallRef handler, - // EventRef event, void *data) - // - // However, in the case of a taskbar menu call - // command.menu.menuRef IS NULL! - // Which causes the wxApp handler just to skip it. - MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu()); - OSStatus err; - - // get the HICommand from the event - HICommand command; - err = GetEventParameter( - inEvent, kEventParamDirectObject, - typeHICommand, NULL, - sizeof(HICommand), NULL, &command ); - if (err == noErr) + if (pTB->m_pMenu != NULL) { - // Obtain the REAL menuRef and the menuItemIndex in the real menuRef - // - // NOTE: menuRef is generally used here for submenus, as - // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass - // just the top level wxTaskBar menu - MenuItemIndex menuItemIndex; - MenuRef menuRef; - - err = GetIndMenuItemWithCommandID( - taskbarMenuRef, - command.commandID, - 1, &menuRef, &menuItemIndex ); - if (err == noErr) + // This is the real reason why we need this. Normally menus + // get handled in wxMacAppEventHandler + // However, in the case of a taskbar menu call + // command.menu.menuRef IS NULL! + // Which causes the wxApp handler just to skip it. + + // get the HICommand from the event + HICommand command; + if (GetEventParameter(inEvent, kEventParamDirectObject, + typeHICommand, NULL,sizeof(HICommand), NULL, &command ) == noErr) { - MenuCommand id = command.commandID; - wxMenuItem *item = NULL; - - if (id != 0) // get the wxMenuItem reference from the MenuRef - GetMenuItemRefCon( menuRef, menuItemIndex, (URefCon*) &item ); - - if (item) + // Obtain the REAL menuRef and the menuItemIndex in the real menuRef + // + // NOTE: menuRef is generally used here for submenus, as + // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass + // just the top level wxTaskBar menu + MenuItemIndex menuItemIndex; + MenuRef menuRef; + MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu()); + + // the next command is only successful if it was a command from the taskbar menu + // otherwise we pass it on + if (GetIndMenuItemWithCommandID(taskbarMenuRef,command.commandID, + 1, &menuRef, &menuItemIndex ) == noErr) { - // Handle items that are checkable - // FIXME: Doesn't work (at least on 10.2)! - if (item->IsCheckable()) - item->Check( !item->IsChecked() ); - - // send the wxEvent to the wxMenu - item->GetMenu()->SendEvent( id, item->IsCheckable() ? item->IsChecked() : -1 ); - - // successfully handled the event - err = noErr; + wxMenu* itemMenu = wxFindMenuFromMacMenu( menuRef ) ; + int id = wxMacCommandToId( command.commandID ) ; + wxMenuItem *item = NULL; + + if (id != 0) // get the wxMenuItem reference from the MenuRef + GetMenuItemRefCon( menuRef, menuItemIndex, (URefCon*) &item ); + + if (item && itemMenu ) + { + if ( eventKind == kEventCommandProcess ) + err = itemMenu->MacHandleCommandProcess( item, id ); + else if ( eventKind == kEventCommandUpdateStatus ) + err = itemMenu->MacHandleCommandUpdateStatus( item, id ); + } } } } //end if noErr on getting HICommand from event - - // return whether we handled the event or not - return err; } + else if ((eventClass == kEventClassApplication) && (eventKind == kEventAppGetDockTileMenu )) + { + // process the right click events + // NB: This may result in double or even triple-creation of the menus + // We need to do this for 2.4 compat, however + wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL); + pTB->m_parent->ProcessEvent(downevt); - // We better have a kEventClassApplication/kEventAppGetDockTileMenu combo here, - // otherwise something is truly funky - wxASSERT(eventClass == kEventClassApplication && - eventKind == kEventAppGetDockTileMenu); - - // process the right click events - // NB: This may result in double or even triple-creation of the menus - // We need to do this for 2.4 compat, however - wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL); - pTB->m_parent->ProcessEvent(downevt); - - wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL); - pTB->m_parent->ProcessEvent(upevt); - - // create popup menu - wxMenu* menu = pTB->DoCreatePopupMenu(); + wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL); + pTB->m_parent->ProcessEvent(upevt); - OSStatus err = eventNotHandledErr; + // create popup menu + wxMenu* menu = pTB->DoCreatePopupMenu(); - if (menu != NULL) - { - // note to self - a MenuRef *is* a MenuHandle - MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu()); - - // When SetEventParameter is called it will decrement - // the reference count of the menu - we need to make - // sure it stays around in the wxMenu class here - CFRetain(hMenu); - - // set the actual dock menu - err = SetEventParameter( - inEvent, kEventParamMenuRef, - typeMenuRef, sizeof(MenuRef), &hMenu ); - verify_noerr( err ); + if (menu != NULL) + { + // note to self - a MenuRef *is* a MenuHandle + MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu()); + + // When SetEventParameter is called it will decrement + // the reference count of the menu - we need to make + // sure it stays around in the wxMenu class here + CFRetain(hMenu); + + // set the actual dock menu + err = SetEventParameter( + inEvent, kEventParamMenuRef, + typeMenuRef, sizeof(MenuRef), &hMenu ); + verify_noerr( err ); + } } return err; @@ -319,6 +299,7 @@ wxDockTaskBarIcon::wxDockTaskBarIcon(wxTaskBarIcon* parent) EventTypeSpec tbEventList[] = { { kEventClassCommand, kEventProcessCommand }, + { kEventClassCommand, kEventCommandUpdateStatus }, { kEventClassApplication, kEventAppGetDockTileMenu } }; diff --git a/src/mac/carbon/textctrl.cpp b/src/mac/carbon/textctrl.cpp index 5c885f6fb0..cffeb61822 100644 --- a/src/mac/carbon/textctrl.cpp +++ b/src/mac/carbon/textctrl.cpp @@ -51,10 +51,6 @@ #include #endif -#ifndef __DARWIN__ -#include -#endif - #ifndef __DARWIN__ #include #include @@ -261,7 +257,6 @@ public : protected : HIViewRef m_scrollView ; HIViewRef m_textView ; - EventHandlerRef m_textEventHandlerRef ; }; #endif @@ -424,32 +419,27 @@ void wxTextCtrl::CreatePeer( forceMLTE = true ; } #endif -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - forceMLTE = false; -#endif -#ifdef __WXMAC_OSX__ -#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + if ( UMAGetSystemVersion() >= 0x1050 ) + forceMLTE = false; + if ( UMAGetSystemVersion() >= 0x1030 && !forceMLTE ) { if ( m_windowStyle & wxTE_MULTILINE ) m_peer = new wxMacMLTEHIViewControl( this , str , pos , size , style ) ; } -#endif if ( !m_peer ) { -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 if ( !(m_windowStyle & wxTE_MULTILINE) && !forceMLTE ) -#endif { m_peer = new wxMacUnicodeTextControl( this , str , pos , size , style ) ; } } -#endif - // the horizontal single line scrolling bug that made us keep -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 + // the horizontal single line scrolling bug that made us keep the classic implementation + // is fixed in 10.5 +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 if ( !m_peer ) m_peer = new wxMacMLTEClassicControl( this , str , pos , size , style ) ; #endif @@ -1373,6 +1363,7 @@ bool wxMacUnicodeTextControl::Create( wxTextCtrl *wxPeer, { m_font = wxPeer->GetFont() ; m_windowStyle = style ; + m_selection.selStart = m_selection.selEnd = 0; Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ; wxString st = str ; wxMacConvertNewlines10To13( &st ) ; @@ -1387,14 +1378,13 @@ bool wxMacUnicodeTextControl::Create( wxTextCtrl *wxPeer, InstallControlEventHandler( m_controlRef , GetwxMacUnicodeTextControlEventHandlerUPP(), GetEventTypeCount(unicodeTextControlEventList), unicodeTextControlEventList, this, - &m_focusHandlerRef); + NULL); return true; } wxMacUnicodeTextControl::~wxMacUnicodeTextControl() { - ::RemoveEventHandler( m_focusHandlerRef ); } void wxMacUnicodeTextControl::VisibilityChanged(bool shown) @@ -1805,11 +1795,27 @@ void wxMacMLTEControl::AdjustCreationAttributes(const wxColour &background, options |= kTXNSupportEditCommandProcessing | kTXNSupportEditCommandUpdating - | kTXNSupportSpellCheckCommandProcessing - | kTXNSupportSpellCheckCommandUpdating | kTXNSupportFontCommandProcessing | kTXNSupportFontCommandUpdating; + // only spell check when not read-only + // use system options for the default + bool checkSpelling = false ; + if ( !(m_windowStyle & wxTE_READONLY) ) + { +#if wxUSE_SYSTEM_OPTIONS + if ( wxSystemOptions::HasOption( wxMAC_TEXTCONTROL_USE_SPELL_CHECKER ) && (wxSystemOptions::GetOptionInt( wxMAC_TEXTCONTROL_USE_SPELL_CHECKER ) == 1) ) + { + checkSpelling = true ; + } +#endif + } + + if ( checkSpelling ) + options |= + kTXNSupportSpellCheckCommandProcessing + | kTXNSupportSpellCheckCommandUpdating; + TXNSetCommandEventSupport( m_txn , options ) ; } } @@ -1830,61 +1836,121 @@ void wxMacMLTEControl::TXNSetAttribute( const wxTextAttr& style , long from , lo { TXNTypeAttributes typeAttr[4] ; RGBColor color ; - int attrCount = 0 ; + size_t typeAttrCount = 0 ; + + TXNMargins margins; + TXNControlTag controlTags[4]; + TXNControlData controlData[4]; + size_t controlAttrCount = 0; + + TXNTab* tabs = NULL; + + bool relayout = false; if ( style.HasFont() ) { - wxFont font(style.GetFont()) ; - -#if 0 // old version - Str255 fontName = "\pMonaco" ; - SInt16 fontSize = 12 ; - Style fontStyle = normal ; - wxMacStringToPascal( font.GetFaceName() , fontName ) ; - fontSize = font.GetPointSize() ; - if ( font.GetUnderlined() ) - fontStyle |= underline ; - if ( font.GetWeight() == wxBOLD ) - fontStyle |= bold ; - if ( font.GetStyle() == wxITALIC ) - fontStyle |= italic ; - - typeAttr[attrCount].tag = kTXNQDFontNameAttribute ; - typeAttr[attrCount].size = kTXNQDFontNameAttributeSize ; - typeAttr[attrCount].data.dataPtr = (void*)fontName ; - attrCount++ ; - - typeAttr[attrCount].tag = kTXNQDFontSizeAttribute ; - typeAttr[attrCount].size = kTXNFontSizeAttributeSize ; - typeAttr[attrCount].data.dataValue = (fontSize << 16) ; - attrCount++ ; - - typeAttr[attrCount].tag = kTXNQDFontStyleAttribute ; - typeAttr[attrCount].size = kTXNQDFontStyleAttributeSize ; - typeAttr[attrCount].data.dataValue = fontStyle ; - attrCount++ ; -#else - typeAttr[attrCount].tag = kTXNATSUIStyle ; - typeAttr[attrCount].size = kTXNATSUIStyleSize ; - typeAttr[attrCount].data.dataPtr = font.MacGetATSUStyle() ; - attrCount++ ; -#endif + wxASSERT( typeAttrCount < WXSIZEOF(typeAttr) ); + const wxFont &font = style.GetFont() ; + typeAttr[typeAttrCount].tag = kTXNATSUIStyle ; + typeAttr[typeAttrCount].size = kTXNATSUIStyleSize ; + typeAttr[typeAttrCount].data.dataPtr = font.MacGetATSUStyle() ; + typeAttrCount++ ; } if ( style.HasTextColour() ) { + wxASSERT( typeAttrCount < WXSIZEOF(typeAttr) ); color = MAC_WXCOLORREF(style.GetTextColour().GetPixel()) ; - typeAttr[attrCount].tag = kTXNQDFontColorAttribute ; - typeAttr[attrCount].size = kTXNQDFontColorAttributeSize ; - typeAttr[attrCount].data.dataPtr = (void*) &color ; - attrCount++ ; + typeAttr[typeAttrCount].tag = kTXNQDFontColorAttribute ; + typeAttr[typeAttrCount].size = kTXNQDFontColorAttributeSize ; + typeAttr[typeAttrCount].data.dataPtr = (void*) &color ; + typeAttrCount++ ; } + + if ( style.HasAlignment() ) + { + wxASSERT( controlAttrCount < WXSIZEOF(controlTags) ); + SInt32 align; + + switch ( style.GetAlignment() ) + { + case wxTEXT_ALIGNMENT_LEFT: + align = kTXNFlushLeft; + break; + case wxTEXT_ALIGNMENT_CENTRE: + align = kTXNCenter; + break; + case wxTEXT_ALIGNMENT_RIGHT: + align = kTXNFlushRight; + break; + case wxTEXT_ALIGNMENT_JUSTIFIED: + align = kTXNFullJust; + break; + default : + case wxTEXT_ALIGNMENT_DEFAULT: + align = kTXNFlushDefault; + break; + } + + controlTags[controlAttrCount] = kTXNJustificationTag ; + controlData[controlAttrCount].sValue = align ; + controlAttrCount++ ; + } + + if ( style.HasLeftIndent() || style.HasRightIndent() ) + { + wxASSERT( controlAttrCount < WXSIZEOF(controlTags) ); + controlTags[controlAttrCount] = kTXNMarginsTag; + controlData[controlAttrCount].marginsPtr = &margins; + verify_noerr( TXNGetTXNObjectControls (m_txn, 1 , + &controlTags[controlAttrCount], &controlData[controlAttrCount]) ); + if ( style.HasLeftIndent() ) + { + margins.leftMargin = style.GetLeftIndent() / 254.0 * 72 + 0.5; + } + if ( style.HasRightIndent() ) + { + margins.rightMargin = style.GetRightIndent() / 254.0 * 72 + 0.5; + } + controlAttrCount++ ; + } + + if ( style.HasTabs() ) + { + const wxArrayInt& tabarray = style.GetTabs(); + // unfortunately Mac only applies a tab distance, not individually different tabs + controlTags[controlAttrCount] = kTXNTabSettingsTag; + if ( tabarray.size() > 0 ) + controlData[controlAttrCount].tabValue.value = tabarray[0] / 254.0 * 72 + 0.5; + else + controlData[controlAttrCount].tabValue.value = 72 ; - if ( attrCount > 0 ) + controlData[controlAttrCount].tabValue.tabType = kTXNLeftTab; + controlAttrCount++ ; + } + + // unfortunately the relayout is not automatic + if ( controlAttrCount > 0 ) + { + verify_noerr( TXNSetTXNObjectControls (m_txn, false /* don't clear all */, controlAttrCount, + controlTags, controlData) ); + relayout = true; + } + + if ( typeAttrCount > 0 ) + { + verify_noerr( TXNSetTypeAttributes( m_txn , typeAttrCount, typeAttr, from , to ) ); + relayout = true; + } + + if ( tabs != NULL ) + { + delete[] tabs; + } + + if ( relayout ) { - verify_noerr( TXNSetTypeAttributes( m_txn , attrCount , typeAttr, from , to ) ); - // unfortunately the relayout is not automatic TXNRecalcTextLayout( m_txn ); } } @@ -1905,21 +1971,16 @@ void wxMacMLTEControl::SetStyle( long start, long end, const wxTextAttr& style ) void wxMacMLTEControl::Copy() { - ClearCurrentScrap(); TXNCopy( m_txn ); - TXNConvertToPublicScrap(); } void wxMacMLTEControl::Cut() { - ClearCurrentScrap(); TXNCut( m_txn ); - TXNConvertToPublicScrap(); } void wxMacMLTEControl::Paste() { - TXNConvertFromPublicScrap(); TXNPaste( m_txn ); } @@ -1983,7 +2044,10 @@ void wxMacMLTEControl::Remove( long from , long to ) void wxMacMLTEControl::GetSelection( long* from, long* to) const { - TXNGetSelection( m_txn , (TXNOffset*) from , (TXNOffset*) to ) ; + TXNOffset f,t ; + TXNGetSelection( m_txn , &f , &t ) ; + *from = f; + *to = t; } void wxMacMLTEControl::SetSelection( long from , long to ) @@ -2263,7 +2327,7 @@ int wxMacMLTEControl::GetLineLength(long lineNo) const return theLength ; } -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 // ---------------------------------------------------------------------------- // MLTE control implementation (classic part) @@ -3080,12 +3144,11 @@ wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxTextCtrl *wxPeer, InstallControlEventHandler( m_textView , GetwxMacTextControlEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, - &m_textEventHandlerRef); + NULL); } wxMacMLTEHIViewControl::~wxMacMLTEHIViewControl() { - ::RemoveEventHandler( m_textEventHandlerRef ) ; } OSStatus wxMacMLTEHIViewControl::SetFocus( ControlFocusPart focusPart ) @@ -3096,6 +3159,9 @@ OSStatus wxMacMLTEHIViewControl::SetFocus( ControlFocusPart focusPart ) bool wxMacMLTEHIViewControl::HasFocus() const { ControlRef control ; + if ( GetUserFocusWindow() == NULL ) + return false; + GetKeyboardFocus( GetUserFocusWindow() , &control ) ; return control == m_textView ; } diff --git a/src/mac/carbon/toolbar.cpp b/src/mac/carbon/toolbar.cpp index f65f88223e..0c35f4809a 100644 --- a/src/mac/carbon/toolbar.cpp +++ b/src/mac/carbon/toolbar.cpp @@ -129,7 +129,11 @@ public: if ( m_toolbarItemRef ) { CFIndex count = CFGetRetainCount( m_toolbarItemRef ) ; - wxASSERT_MSG( count == 1 , wxT("Reference Count of native tool was not 1 in wxToolBarTool destructor") ); + // different behaviour under Leopard + if ( UMAGetSystemVersion() < 0x1050 ) + { + wxASSERT_MSG( count == 1 , wxT("Reference Count of native tool was not 1 in wxToolBarTool destructor") ); + } wxTheApp->MacAddToAutorelease(m_toolbarItemRef); CFRelease(m_toolbarItemRef); m_toolbarItemRef = NULL; @@ -476,12 +480,15 @@ void wxToolBarTool::UpdateToggleImage( bool toggle ) dc.DrawBitmap( m_bmpNormal, 0, 0, true ); dc.SelectObject( wxNullBitmap ); ControlButtonContentInfo info; - wxMacCreateBitmapButton( &info, bmp, kControlContentIconRef ); + wxMacCreateBitmapButton( &info, bmp ); SetControlData( m_controlHandle, 0, kControlIconContentTag, sizeof(info), (Ptr)&info ); #if wxMAC_USE_NATIVE_TOOLBAR if (m_toolbarItemRef != NULL) { - HIToolbarItemSetIconRef( m_toolbarItemRef, info.u.iconRef ); + ControlButtonContentInfo info2; + wxMacCreateBitmapButton( &info2, bmp, kControlContentCGImageRef); + HIToolbarItemSetImage( m_toolbarItemRef, info2.u.imageRef ); + wxMacReleaseBitmapButton( &info2 ); } #endif wxMacReleaseBitmapButton( &info ); @@ -489,12 +496,15 @@ void wxToolBarTool::UpdateToggleImage( bool toggle ) else { ControlButtonContentInfo info; - wxMacCreateBitmapButton( &info, m_bmpNormal, kControlContentIconRef ); + wxMacCreateBitmapButton( &info, m_bmpNormal ); SetControlData( m_controlHandle, 0, kControlIconContentTag, sizeof(info), (Ptr)&info ); #if wxMAC_USE_NATIVE_TOOLBAR if (m_toolbarItemRef != NULL) { - HIToolbarItemSetIconRef( m_toolbarItemRef, info.u.iconRef ); + ControlButtonContentInfo info2; + wxMacCreateBitmapButton( &info2, m_bmpNormal, kControlContentCGImageRef); + HIToolbarItemSetImage( m_toolbarItemRef, info2.u.imageRef ); + wxMacReleaseBitmapButton( &info2 ); } #endif wxMacReleaseBitmapButton( &info ); @@ -850,7 +860,7 @@ bool wxToolBar::Create( #if wxMAC_USE_NATIVE_TOOLBAR if (parent->IsKindOf(CLASSINFO(wxFrame)) && wxSystemOptions::GetOptionInt(wxT("mac.toolbar.no-native")) != 1) { - wxString labelStr = wxString::Format( wxT("%xd"), (int)this ); + wxString labelStr = wxString::Format( wxT("%p"), this ); err = HIToolbarCreate( wxMacCFStringHolder( labelStr, wxFont::GetDefaultEncoding() ), 0, (HIToolbarRef*) &m_macHIToolbarRef ); @@ -889,8 +899,11 @@ wxToolBar::~wxToolBar() MacInstallNativeToolbar( false ); CFIndex count = CFGetRetainCount( m_macHIToolbarRef ) ; - wxASSERT_MSG( count == 1 , wxT("Reference Count of native control was not 1 in wxToolBar destructor") ); - + // Leopard seems to have one refcount more, so we cannot check reliably at the moment + if ( UMAGetSystemVersion() < 0x1050 ) + { + wxASSERT_MSG( count == 1 , wxT("Reference Count of native control was not 1 in wxToolBar destructor") ); + } CFRelease( (HIToolbarRef)m_macHIToolbarRef ); m_macHIToolbarRef = NULL; } @@ -1462,8 +1475,14 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase) tool->Attach( this ); #if wxMAC_USE_NATIVE_TOOLBAR - HIToolbarItemRef item; -#endif + wxString label = tool->GetLabel(); + if (m_macHIToolbarRef && !label.empty() ) + { + // strip mnemonics from the label for compatibility + // with the usual labels in wxStaticText sense + label = wxStripMenuCodes(label); + } +#endif // wxMAC_USE_NATIVE_TOOLBAR switch (tool->GetStyle()) { @@ -1501,11 +1520,15 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase) { wxASSERT( tool->GetControlHandle() == NULL ); ControlButtonContentInfo info; - wxMacCreateBitmapButton( &info, tool->GetNormalBitmap(), kControlContentIconRef ); + wxMacCreateBitmapButton( &info, tool->GetNormalBitmap() ); if ( UMAGetSystemVersion() >= 0x1000) { + // contrary to the docs this control only works with iconrefs + ControlButtonContentInfo info; + wxMacCreateBitmapButton( &info, tool->GetNormalBitmap(), kControlContentIconRef ); CreateIconControl( window, &toolrect, &info, false, &controlHandle ); + wxMacReleaseBitmapButton( &info ); } else { @@ -1520,19 +1543,25 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase) #if wxMAC_USE_NATIVE_TOOLBAR if (m_macHIToolbarRef != NULL) { - wxString labelStr = wxString::Format(wxT("%xd"), (int)tool); + HIToolbarItemRef item; + wxString labelStr = wxString::Format(wxT("%p"), tool); err = HIToolbarItemCreate( wxMacCFStringHolder(labelStr, wxFont::GetDefaultEncoding()), kHIToolbarItemCantBeRemoved | kHIToolbarItemAnchoredLeft | kHIToolbarItemAllowDuplicates, &item ); if (err == noErr) { + ControlButtonContentInfo info2; + wxMacCreateBitmapButton( &info2, tool->GetNormalBitmap(), kControlContentCGImageRef); + InstallEventHandler( HIObjectGetEventTarget(item), GetwxMacToolBarEventHandlerUPP(), GetEventTypeCount(toolBarEventList), toolBarEventList, tool, NULL ); - - HIToolbarItemSetIconRef( item, info.u.iconRef ); + HIToolbarItemSetLabel( item, wxMacCFStringHolder(label, m_font.GetEncoding()) ); + HIToolbarItemSetImage( item, info2.u.imageRef ); HIToolbarItemSetCommandID( item, kHIToolbarCommandPressAction ); tool->SetToolbarItemRef( item ); + + wxMacReleaseBitmapButton( &info2 ); } } else @@ -1560,7 +1589,7 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase) if (m_macHIToolbarRef != NULL) { wxCHECK_MSG( tool->GetControl(), false, _T("control must be non-NULL") ); - + HIToolbarItemRef item; HIViewRef viewRef = (HIViewRef) tool->GetControl()->GetHandle() ; CFDataRef data = CFDataCreate( kCFAllocatorDefault , (UInt8*) &viewRef , sizeof(viewRef) ) ; err = HIToolbarCreateItemWithIdentifier((HIToolbarRef) m_macHIToolbarRef,kControlToolbarItemClassID, @@ -1586,19 +1615,6 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase) break; } -#if wxMAC_USE_NATIVE_TOOLBAR - wxString label = tool->GetLabel(); - if (m_macHIToolbarRef && !label.empty() ) - { - // strip mnemonics from the label for compatibility - // with the usual labels in wxStaticText sense - label = wxStripMenuCodes(label); - - HIToolbarItemSetLabel(item, - wxMacCFStringHolder(label, m_font.GetEncoding())); - } -#endif // wxMAC_USE_NATIVE_TOOLBAR - if ( err == noErr ) { if ( controlHandle ) diff --git a/src/mac/carbon/tooltip.cpp b/src/mac/carbon/tooltip.cpp index 18c9ca7ada..91856f165d 100644 --- a/src/mac/carbon/tooltip.cpp +++ b/src/mac/carbon/tooltip.cpp @@ -27,40 +27,6 @@ // global data //----------------------------------------------------------------------------- -class wxMacToolTipTimer ; - -class wxMacToolTip -{ -public : - wxMacToolTip() ; - ~wxMacToolTip() ; - - void Setup( WindowRef window , const wxString& text , const wxPoint& localPosition ) ; - void Draw() ; - void Clear() ; - - long GetMark() - { return m_mark ; } - - bool IsShown() - { return m_shown ; } - -private : - wxString m_label ; - wxPoint m_position ; - Rect m_rect ; - WindowRef m_window ; - PicHandle m_backpict ; - bool m_shown ; - long m_mark ; -#if wxUSE_TIMER - wxMacToolTipTimer* m_timer ; -#endif -#if TARGET_CARBON - wxMacCFStringHolder m_helpTextRef ; -#endif -} ; - #if wxUSE_TIMER class wxMacToolTipTimer : public wxTimer { diff --git a/src/mac/carbon/toplevel.cpp b/src/mac/carbon/toplevel.cpp index cc7fde5a17..6cab8c7543 100644 --- a/src/mac/carbon/toplevel.cpp +++ b/src/mac/carbon/toplevel.cpp @@ -79,7 +79,6 @@ static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 BEGIN_EVENT_TABLE(wxTopLevelWindowMac, wxTopLevelWindowBase) END_EVENT_TABLE() - // --------------------------------------------------------------------------- // Carbon Events // --------------------------------------------------------------------------- @@ -260,11 +259,15 @@ void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) UInt32 modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; Point screenMouseLocation = cEvent.GetParameter(kEventParamMouseLocation) ; - // this parameter are not given for all events + // these parameters are not given for all events EventMouseButton button = 0 ; UInt32 clickCount = 0 ; + UInt32 mouseChord = 0; + cEvent.GetParameter( kEventParamMouseButton, typeMouseButton , &button ) ; cEvent.GetParameter( kEventParamClickCount, typeUInt32 , &clickCount ) ; + // the chord is the state of the buttons pressed currently + cEvent.GetParameter( kEventParamMouseChord, typeUInt32 , &mouseChord ) ; wxevent.m_x = screenMouseLocation.h; wxevent.m_y = screenMouseLocation.v; @@ -282,6 +285,7 @@ void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) button = kEventMouseButtonSecondary ; thisButtonIsFakeRight = true ; } + // otherwise we report double clicks by connecting a left click with a ctrl-left click if ( clickCount > 1 && button != g_lastButton ) clickCount = 1 ; @@ -303,28 +307,19 @@ void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) else if ( g_lastButton == kEventMouseButtonSecondary && g_lastButtonWasFakeRight ) button = g_lastButton ; - // determine the correct down state, wx does not want a 'down' for a mouseUp event, - // while mac delivers this button - if ( button != 0 && cEvent.GetKind() != kEventMouseUp ) - { - switch ( button ) - { - case kEventMouseButtonPrimary : - wxevent.m_leftDown = true ; - break ; + // Adjust the chord mask to remove the primary button and add the + // secondary button. It is possible that the secondary button is + // already pressed, e.g. on a mouse connected to a laptop, but this + // possibility is ignored here: + if( thisButtonIsFakeRight && ( mouseChord & 1U ) ) + mouseChord = ((mouseChord & ~1U) | 2U); - case kEventMouseButtonSecondary : + if(mouseChord & 1U) + wxevent.m_leftDown = true ; + if(mouseChord & 2U) wxevent.m_rightDown = true ; - break ; - - case kEventMouseButtonTertiary : + if(mouseChord & 4U) wxevent.m_middleDown = true ; - break ; - - default: - break ; - } - } // translate into wx types switch ( cEvent.GetKind() ) @@ -384,8 +379,13 @@ void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) } break ; - default : + case kEventMouseEntered : + case kEventMouseExited : + case kEventMouseDragged : + case kEventMouseMoved : wxevent.SetEventType( wxEVT_MOTION ) ; + break; + default : break ; } } @@ -500,7 +500,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), else if ( (IsWindowActive(window) && windowPart == inContent) ) { ControlPartCode part ; - control = wxMacFindControlUnderMouse( toplevelWindow , windowMouseLocation , window , &part ) ; + control = FindControlUnderMouse( windowMouseLocation , window , &part ) ; // if there is no control below the mouse position, send the event to the toplevel window itself if ( control == 0 ) { @@ -508,7 +508,8 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), } else { - currentMouseWindow = wxFindControlFromMacControl( control ) ; + currentMouseWindow = (wxWindow*) wxFindControlFromMacControl( control ) ; +#ifndef __WXUNIVERSAL__ if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved ) { #if wxUSE_TOOLBAR @@ -516,11 +517,12 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), // instead of its children (wxToolBarTools) ControlRef parent ; GetSuperControl(control, &parent ); - wxWindow *wxParent = wxFindControlFromMacControl( parent ) ; + wxWindow *wxParent = (wxWindow*) wxFindControlFromMacControl( parent ) ; if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) ) currentMouseWindow = wxParent ; #endif } +#endif } // disabled windows must not get any input messages @@ -575,6 +577,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), if ( cEvent.GetKind() == kEventMouseDown ) { ::MenuSelect( screenMouseLocation ) ; + ::HiliteMenu(0); result = noErr ; } } @@ -744,6 +747,7 @@ wxMacTopLevelWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), wxRect r( newRect.left , newRect.top , newRect.right - newRect.left , newRect.bottom - newRect.top ) ; if ( attributes & kWindowBoundsChangeSizeChanged ) { +#ifndef __WXUNIVERSAL__ // according to the other ports we handle this within the OS level // resize event, not within a wxSizeEvent wxFrame *frame = wxDynamicCast( toplevelWindow , wxFrame ) ; @@ -751,7 +755,7 @@ wxMacTopLevelWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), { frame->PositionBars(); } - +#endif wxSizeEvent event( r.GetSize() , toplevelWindow->GetId() ) ; event.SetEventObject( toplevelWindow ) ; @@ -947,22 +951,15 @@ void wxTopLevelWindowMac::Init() m_macFullScreenData = NULL ; } -class wxMacDeferredWindowDeleter : public wxObject +wxMacDeferredWindowDeleter::wxMacDeferredWindowDeleter( WindowRef windowRef ) { -public : - wxMacDeferredWindowDeleter( WindowRef windowRef ) - { - m_macWindow = windowRef ; - } - - virtual ~wxMacDeferredWindowDeleter() - { - UMADisposeWindow( (WindowRef) m_macWindow ) ; - } + m_macWindow = windowRef ; +} -protected : - WindowRef m_macWindow ; -} ; +wxMacDeferredWindowDeleter::~wxMacDeferredWindowDeleter() +{ + UMADisposeWindow( (WindowRef) m_macWindow ) ; +} bool wxTopLevelWindowMac::Create(wxWindow *parent, wxWindowID id, @@ -982,7 +979,7 @@ bool wxTopLevelWindowMac::Create(wxWindow *parent, m_windowId = id == -1 ? NewControlId() : id; wxWindow::SetLabel( title ) ; - MacCreateRealWindow( title, pos , size , style , name ) ; + DoMacCreateRealWindow( parent, title, pos , size , style , name ) ; SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); @@ -1086,6 +1083,13 @@ wxPoint wxTopLevelWindowMac::GetClientAreaOrigin() const return wxPoint(0, 0) ; } +#ifndef __WXUNIVERSAL__ +void wxTopLevelWindowMac::SetIcons( const wxIconBundle& icons ) +{ +// { SetIcon( icons.GetIcon( -1 ) ); } +} +#endif + void wxTopLevelWindowMac::MacSetBackgroundBrush( const wxBrush &brush ) { wxTopLevelWindowBase::MacSetBackgroundBrush( brush ) ; @@ -1096,16 +1100,19 @@ void wxTopLevelWindowMac::MacSetBackgroundBrush( const wxBrush &brush ) } } +void wxTopLevelWindowMacInstallTopLevelWindowEventHandler(WindowRef window, EventHandlerRef* handler, void *ref) +{ + InstallWindowEventHandler(window, GetwxMacTopLevelEventHandlerUPP(), + GetEventTypeCount(eventList), eventList, ref, handler ); +} + void wxTopLevelWindowMac::MacInstallTopLevelWindowEventHandler() { if ( m_macEventHandler != NULL ) { verify_noerr( ::RemoveEventHandler( (EventHandlerRef) m_macEventHandler ) ) ; } - - InstallWindowEventHandler( - MAC_WXHWND(m_macWindow), GetwxMacTopLevelEventHandlerUPP(), - GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macEventHandler ); + wxTopLevelWindowMacInstallTopLevelWindowEventHandler(MAC_WXHWND(m_macWindow),(EventHandlerRef *)&m_macEventHandler,this); } void wxTopLevelWindowMac::MacCreateRealWindow( @@ -1114,6 +1121,17 @@ void wxTopLevelWindowMac::MacCreateRealWindow( const wxSize& size, long style, const wxString& name ) +{ + DoMacCreateRealWindow( NULL, title, pos, size, style, name ); +} + +void wxTopLevelWindowMac::DoMacCreateRealWindow( + wxWindow* parent, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name ) { OSStatus err = noErr ; SetName(name); @@ -1142,6 +1160,8 @@ void wxTopLevelWindowMac::MacCreateRealWindow( WindowClass wclass = 0; WindowAttributes attr = kWindowNoAttributes ; WindowGroupRef group = NULL ; + bool activationScopeSet = false; + WindowActivationScope activationScope = kWindowActivationScopeNone; if ( HasFlag( wxFRAME_TOOL_WINDOW) ) { @@ -1151,7 +1171,10 @@ void wxTopLevelWindowMac::MacCreateRealWindow( HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT) ) { - wclass = kFloatingWindowClass ; + if ( HasFlag( wxSTAY_ON_TOP ) ) + wclass = kUtilityWindowClass; + else + wclass = kFloatingWindowClass ; if ( HasFlag(wxTINY_CAPTION_VERT) ) attr |= kWindowSideTitlebarAttribute ; @@ -1159,6 +1182,8 @@ void wxTopLevelWindowMac::MacCreateRealWindow( else { wclass = kPlainWindowClass ; + activationScopeSet = true; + activationScope = kWindowActivationScopeNone; } } else if ( HasFlag( wxPOPUP_WINDOW ) ) @@ -1193,6 +1218,10 @@ void wxTopLevelWindowMac::MacCreateRealWindow( { wclass = kDocumentWindowClass ; } + else if ( HasFlag( wxNO_BORDER ) ) + { + wclass = kSimpleWindowClass ; + } else { wclass = kPlainWindowClass ; @@ -1224,6 +1253,13 @@ void wxTopLevelWindowMac::MacCreateRealWindow( if ( HasFlag( wxFRAME_FLOAT_ON_PARENT ) ) group = GetWindowGroupOfClass(kFloatingWindowClass) ; + if ( group == NULL && parent != NULL ) + { + WindowRef parenttlw = (WindowRef) parent->MacGetTopLevelWindowRef(); + if( parenttlw ) + group = GetWindowGroupParent( GetWindowGroup( parenttlw ) ); + } + attr |= kWindowCompositingAttribute; #if 0 // wxMAC_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale) attr |= kWindowFrameworkScaledAttribute; @@ -1254,9 +1290,16 @@ void wxTopLevelWindowMac::MacCreateRealWindow( wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") ); // setup a separate group for each window, so that overlays can be handled easily - verify_noerr( CreateWindowGroup( kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrHideOnCollapse, &group )); - verify_noerr( SetWindowGroupParent( group, GetWindowGroup( (WindowRef) m_macWindow ))); - verify_noerr( SetWindowGroup( (WindowRef) m_macWindow , group )); + + WindowGroupRef overlaygroup = NULL; + verify_noerr( CreateWindowGroup( kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrHideOnCollapse, &overlaygroup )); + verify_noerr( SetWindowGroupParent( overlaygroup, GetWindowGroup( (WindowRef) m_macWindow ))); + verify_noerr( SetWindowGroup( (WindowRef) m_macWindow , overlaygroup )); + + if ( activationScopeSet ) + { + verify_noerr( SetWindowActivationScope( (WindowRef) m_macWindow , activationScope )); + } // the create commands are only for content rect, // so we have to set the size again as structure bounds @@ -1296,6 +1339,11 @@ void wxTopLevelWindowMac::MacCreateRealWindow( } #endif + HIViewRef growBoxRef = 0 ; + err = HIViewFindByID( HIViewGetRoot( (WindowRef)m_macWindow ), kHIViewWindowGrowBoxID, &growBoxRef ); + if ( err == noErr && growBoxRef != 0 ) + HIGrowBoxViewSetTransparent( growBoxRef, true ) ; + // the frame window event handler InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ; MacInstallTopLevelWindowEventHandler() ; @@ -1598,6 +1646,12 @@ void wxTopLevelWindowMac::DoGetClientSize( int *width, int *height ) const *height = bounds.bottom - bounds.top ; } +void wxTopLevelWindowMac::DoCentre(int dir) +{ + if ( m_macWindow != 0 ) + wxTopLevelWindowBase::DoCentre(dir); +} + void wxTopLevelWindowMac::MacSetMetalAppearance( bool set ) { #if TARGET_API_MAC_OSX diff --git a/src/mac/carbon/uma.cpp b/src/mac/carbon/uma.cpp index b8f477e055..75132f7124 100644 --- a/src/mac/carbon/uma.cpp +++ b/src/mac/carbon/uma.cpp @@ -31,9 +31,7 @@ # endif #endif -#ifndef __DARWIN__ -# include -#endif +#include "wx/mac/uma.h" // since we have decided that we only support 8.6 upwards we are // checking for these minimum requirements in the startup code of @@ -219,7 +217,7 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEn macKey = 0 ; glyph = kMenuF1Glyph + ( key - WXK_F1 ) ; if ( key >= WXK_F13 ) - glyph += 13 ; + glyph += 12 ; } else { @@ -756,22 +754,6 @@ wxMacPortStateHelper::~wxMacPortStateHelper() #endif -OSStatus UMAPutScrap( Size size , OSType type , void *data ) -{ - OSStatus err = noErr ; - -#if !TARGET_CARBON - err = PutScrap( size , type , data ) ; -#else - ScrapRef scrap; - err = GetCurrentScrap( &scrap ); - if ( err == noErr ) - err = PutScrapFlavor( scrap, type , 0, size, data ); -#endif - - return err ; -} - Rect * UMAGetControlBoundsInWindowCoords( ControlRef theControl, Rect *bounds ) { GetControlBounds( theControl , bounds ) ; @@ -792,6 +774,72 @@ Rect * UMAGetControlBoundsInWindowCoords( ControlRef theControl, Rect *bounds ) return bounds ; } +size_t UMAPutBytesCFRefCallback( void *info, const void *bytes, size_t count ) +{ + CFMutableDataRef data = (CFMutableDataRef) info; + if ( data ) + { + CFDataAppendBytes( data, (const UInt8*) bytes, count ); + } + return count; +} + +void UMAReleaseCFDataProviderCallback( void *info, const void *data, size_t count ) +{ + if ( info ) + CFRelease( (CFDataRef) info ); +} + +void UMAReleaseCFDataConsumerCallback( void *info ) +{ + if ( info ) + CFRelease( (CFDataRef) info ); +} + +CGDataProviderRef UMACGDataProviderCreateWithCFData( CFDataRef data ) +{ + if ( data == NULL ) + return NULL; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if( &CGDataProviderCreateWithCFData != NULL ) + { + return CGDataProviderCreateWithCFData( data ); + } +#endif + + // make sure we keep it until done + CFRetain( data ); + CGDataProviderRef provider = CGDataProviderCreateWithData( (void*) data , CFDataGetBytePtr( data ) , + CFDataGetLength( data ), UMAReleaseCFDataProviderCallback ); + // if provider couldn't be created, release the data again + if ( provider == NULL ) + CFRelease( data ); + return provider; +} + +CGDataConsumerRef UMACGDataConsumerCreateWithCFData( CFMutableDataRef data ) +{ + if ( data == NULL ) + return NULL; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if( &CGDataConsumerCreateWithCFData != NULL ) + { + return CGDataConsumerCreateWithCFData( data ); + } +#endif + // make sure we keep it until done + CFRetain( data ); + CGDataConsumerCallbacks callbacks; + callbacks.putBytes = UMAPutBytesCFRefCallback; + callbacks.releaseConsumer = UMAReleaseCFDataConsumerCallback; + CGDataConsumerRef consumer = CGDataConsumerCreate( data , &callbacks ); + // if consumer couldn't be created, release the data again + if ( consumer == NULL ) + CFRelease( data ); + return consumer; +} #endif // wxUSE_GUI #if wxUSE_BASE diff --git a/src/mac/carbon/utils.cpp b/src/mac/carbon/utils.cpp index 202080f5df..b39f646238 100644 --- a/src/mac/carbon/utils.cpp +++ b/src/mac/carbon/utils.cpp @@ -943,6 +943,7 @@ void wxMacControl::SuperChangedPosition() void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle ) { m_font = font; +#ifndef __LP64__ ControlFontStyleRec fontStyle; if ( font.MacGetThemeFontID() != kThemeCurrentPortFont ) { @@ -993,6 +994,7 @@ void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , l } ::SetControlFontStyle( m_controlRef , &fontStyle ); +#endif } void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) ) @@ -2181,7 +2183,15 @@ void * wxMacDataItemBrowserControl::MacGetClientData( unsigned int n) const void wxMacDataItemBrowserControl::MacScrollTo( unsigned int n ) { - RevealItem( GetItemFromLine( n) , kDataBrowserRevealWithoutSelecting ); + UInt32 top , left ; + GetScrollPosition( &top , &left ) ; + wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n ); + + UInt16 height ; + GetRowHeight( (DataBrowserItemID) item , &height ) ; + SetScrollPosition( n * ((UInt32)height) , left ) ; + + RevealItem( item , kDataBrowserRevealWithoutSelecting ); } diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index b13a595ec9..92fd22dcb0 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -53,6 +53,10 @@ #include "wx/caret.h" #endif +#if wxUSE_POPUPWIN + #include "wx/popupwin.h" +#endif + #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" #endif @@ -65,7 +69,6 @@ #ifndef __DARWIN__ #include #include -#include #include #endif @@ -460,9 +463,13 @@ wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler), textCtrl->GetSelection( &from , &to ) ; wxString val = textCtrl->GetValue() ; val = val.Mid( from , to - from ) ; - ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ; - verify_noerr( ClearScrap( &scrapRef ) ) ; - verify_noerr( PutScrapFlavor( scrapRef , kTXNTextData , 0 , val.length() , val.c_str() ) ) ; + 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 ; @@ -470,22 +477,34 @@ wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler), case kEventServicePaste : if ( textCtrl ) { - ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ; - Size textSize, pastedSize ; - verify_noerr( GetScrapFlavorSize(scrapRef, kTXNTextData, &textSize) ) ; - textSize++ ; - char *content = new char[textSize] ; - GetScrapFlavorData(scrapRef, kTXNTextData, &pastedSize, content ); - content[textSize - 1] = 0 ; - + 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 ) ); + textCtrl->WriteText( wxString( content , wxConvLocal ) ); #else - textCtrl->WriteText( wxString( content ) ) ; + textCtrl->WriteText( wxString( content ) ) ; #endif - delete[] content ; - result = noErr ; + delete[] content ; + result = noErr ; + } + } + } } break ; @@ -647,74 +666,11 @@ wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), switch ( cEvent.GetKind() ) { case kEventProcessCommand : - { - if (item->IsCheckable()) - item->Check( !item->IsChecked() ) ; - - if ( itemMenu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ) - result = noErr ; - else - { - wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id); - event.SetEventObject(focus); - event.SetInt(item->IsCheckable() ? item->IsChecked() : -1); - - if ( focus->GetEventHandler()->ProcessEvent(event) ) - result = noErr ; - } - } + result = itemMenu->MacHandleCommandProcess( item, id, focus ); break ; case kEventCommandUpdateStatus: - { - wxUpdateUIEvent event(id); - event.SetEventObject( itemMenu ); - - bool processed = false; - - // Try the menu's event handler - { - wxEvtHandler *handler = itemMenu->GetEventHandler(); - if ( handler ) - processed = handler->ProcessEvent(event); - } - - // Try the window the menu was popped up from - // (and up through the hierarchy) - if ( !processed ) - { - const wxMenuBase *menu = itemMenu; - while ( menu ) - { - wxWindow *win = menu->GetInvokingWindow(); - if ( win ) - { - processed = win->GetEventHandler()->ProcessEvent(event); - break; - } - - menu = menu->GetParent(); - } - } - - if ( !processed ) - { - processed = focus->GetEventHandler()->ProcessEvent(event); - } - - if ( processed ) - { - // if anything changed, update the changed attribute - if (event.GetSetText()) - itemMenu->SetLabel(id, event.GetText()); - if (event.GetSetChecked()) - itemMenu->Check(id, event.GetChecked()); - if (event.GetSetEnabled()) - itemMenu->Enable(id, event.GetEnabled()); - - result = noErr ; - } - } + result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus ); break ; default : @@ -1047,12 +1003,14 @@ wxWindowMac::~wxWindowMac() if ( g_MacLastWindow == this ) g_MacLastWindow = NULL ; - wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ; +#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 @@ -1242,7 +1200,9 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) void wxWindowMac::MacUpdateControlFont() { m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; - Refresh() ; + // do not trigger refreshes upon invisible and possible partly created objects + if ( MacIsReallyShown() ) + Refresh() ; } bool wxWindowMac::SetFont(const wxFont& font) @@ -1800,7 +1760,8 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) #if wxUSE_MENUS bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { - menu->SetInvokingWindow(this); +#ifndef __WXUNIVERSAL__ + menu->SetInvokingWindow((wxWindow*)this); menu->UpdateUI(); if ( x == wxDefaultCoord && y == wxDefaultCoord ) @@ -1837,6 +1798,10 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) menu->SetInvokingWindow( NULL ); return true; +#else + // actually this shouldn't be called, because universal is having its own implementation + return false; +#endif } #endif @@ -2130,12 +2095,14 @@ void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) void wxWindowMac::SetLabel(const wxString& title) { - m_label = wxStripMenuCodes(title, wxStrip_Mnemonics) ; + m_label = title ; if ( m_peer && m_peer->Ok() ) - m_peer->SetLabel( m_label ) ; + m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; - Refresh() ; + // do not trigger refreshes upon invisible and possible partly created objects + if ( MacIsReallyShown() ) + Refresh() ; } wxString wxWindowMac::GetLabel() const @@ -2484,11 +2451,47 @@ wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag) if ( needVisibilityUpdate ) DoUpdateScrollbarVisibility(); } + // // 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() +{ + if ( IsTopLevel() ) + return ; + +#if wxMAC_USE_CORE_GRAPHICS + if ( MacHasScrollBarCorner() ) + { + Rect rect ; + + CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ; + wxASSERT( cgContext ) ; + + m_peer->GetRect( &rect ) ; + + 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_macBackgroundBrush.Ok() && m_macBackgroundBrush.GetStyle() != wxTRANSPARENT ) + { + wxMacCoreGraphicsColour bkgnd( m_macBackgroundBrush ) ; + bkgnd.Apply( cgContext ); + } + else + { + CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 ); + } + CGContextFillRect( cgContext, cgrect ); + CGContextRestoreGState( cgContext ); + } +#endif +} + void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) ) { if ( IsTopLevel() ) @@ -2496,7 +2499,6 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right Rect rect ; bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ; - bool hasBothScrollbars = (m_hScrollBar && m_hScrollBar->IsShown()) && (m_vScrollBar && m_vScrollBar->IsShown()) ; // back to the surrounding frame rectangle m_peer->GetRect( &rect ) ; @@ -2532,11 +2534,12 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right { 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 ( hasBothScrollbars ) + if ( MacHasScrollBarCorner() ) { - int size = m_hScrollBar->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL ? 16 : 12 ; + 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 ; @@ -2544,10 +2547,12 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right info.version = 0 ; info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; info.kind = kHIThemeGrowBoxKindNone ; + // contrary to the docs ...SizeSmall does not work info.size = kHIThemeGrowBoxSizeNormal ; - info.direction = kThemeGrowRight | kThemeGrowDown ; + info.direction = 0 ; HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ; } +#endif } #else { @@ -2566,12 +2571,14 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right if ( hasFocus ) DrawThemeFocusRect( &rect , true ) ; - - if ( hasBothScrollbars ) + // TODO REMOVE + /* + if ( hasBothScrollbars ) // hasBothScrollbars is not declared { // GetThemeStandaloneGrowBoxBounds // DrawThemeStandaloneNoGrowBox } + */ } #endif } @@ -2769,7 +2776,7 @@ void wxWindowMac::OnSetFocus( wxFocusEvent& event ) Rect rect ; m_peer->GetRect( &rect ) ; - // auf den umgebenden Rahmen zurÂŸck + // auf den umgebenden Rahmen zurチᅡ゚ck InsetRect( &rect, -1 , -1 ) ; wxTopLevelWindowMac* top = MacGetTopLevelWindow(); @@ -2802,7 +2809,7 @@ void wxWindowMac::OnInternalIdle() { // This calls the UI-update mechanism (querying windows for // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -3057,6 +3064,8 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) delete dc ; } + MacPaintGrowBox(); + // calculate a client-origin version of the update rgn and set m_updateRegion to that OffsetRgn( newupdate , -origin.x , -origin.y ) ; m_updateRegion = newupdate ; @@ -3136,28 +3145,99 @@ WXWindow wxWindowMac::MacGetTopLevelWindowRef() const while ( iter ) { if ( iter->IsTopLevel() ) - return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ; - + { + wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow); + if ( toplevel ) + return toplevel->MacGetWindowRef(); +#if wxUSE_POPUPWIN + wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow); + if ( popupwin ) + return popupwin->MacGetPopupWindowRef(); +#endif + } iter = iter->GetParent() ; } return 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() ) ) + { + // Both scroll bars visible + 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 ; + } + } + } + + // No parent frame found + return false ; + } +} + void wxWindowMac::MacCreateScrollBars( long style ) { wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; if ( style & ( wxVSCROLL | wxHSCROLL ) ) { - bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ; int scrlsize = MAC_SCROLLBAR_SIZE ; if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI ) { scrlsize = MAC_SMALL_SCROLLBAR_SIZE ; } - int adjust = hasBoth ? scrlsize - 1: 0 ; + int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ; int width, height ; GetClientSize( &width , &height ) ; @@ -3166,11 +3246,18 @@ void wxWindowMac::MacCreateScrollBars( long style ) wxPoint hPoint(0, height - scrlsize) ; wxSize hSize(width - adjust, scrlsize) ; + // 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(this, wxID_ANY, vPoint, vSize , wxVERTICAL); + { + m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL); + m_vScrollBar->SetMinSize( wxDefaultSize ); + } if ( style & wxHSCROLL ) - m_hScrollBar = new wxScrollBar(this, wxID_ANY, hPoint, hSize , wxHORIZONTAL); + { + m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL); + m_hScrollBar->SetMinSize( wxDefaultSize ); + } } // because the create does not take into account the client area origin @@ -3190,9 +3277,8 @@ void wxWindowMac::MacRepositionScrollBars() if ( !m_hScrollBar && !m_vScrollBar ) return ; - bool hasBoth = (m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ; int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; - int adjust = hasBoth ? scrlsize - 1 : 0 ; + int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ; // get real client area int width, height ; -- 2.47.2