From 40cfdf30fa6c68da8a5cbd37e21d844239545585 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Wed, 14 Dec 2011 15:11:49 +0100 Subject: Enable Mac style on Mac OS X. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add styles/qmacstyle_mac back to the build, modify qstylefactory to load it on Q_OS_MAC. Move helper functions from platforms/mac to qmacstyle_mac.mm. QMacStyle should now be self- contained and not rely on anything from platforms/mac. Change-Id: I68fe40bb7f88c01269968bffd9579b7f3b932d4c Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/widgets/kernel/qguiplatformplugin.cpp | 2 +- src/widgets/kernel/qwidget.h | 10 +- src/widgets/platforms/mac/qpaintdevice_mac.cpp | 49 --- src/widgets/platforms/mac/qpaintengine_mac.cpp | 101 ----- src/widgets/platforms/mac/qregion_mac.cpp | 71 ---- src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm | 6 - src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h | 2 - src/widgets/platforms/mac/qt_mac.cpp | 18 - src/widgets/styles/qmacstyle_mac.h | 2 +- src/widgets/styles/qmacstyle_mac.mm | 432 +++++++++++++++++++-- src/widgets/styles/qmacstyle_mac_p.h | 26 +- src/widgets/styles/qstylefactory.cpp | 2 +- src/widgets/styles/styles.pri | 3 +- 13 files changed, 406 insertions(+), 318 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qguiplatformplugin.cpp b/src/widgets/kernel/qguiplatformplugin.cpp index 8acc7ec90d..aa17d0dc55 100644 --- a/src/widgets/kernel/qguiplatformplugin.cpp +++ b/src/widgets/kernel/qguiplatformplugin.cpp @@ -148,7 +148,7 @@ QString QGuiPlatformPlugin::styleName() return QLatin1String("CDE"); // default style for X11 on Solaris #elif defined(Q_WS_X11) && defined(Q_OS_IRIX) return QLatin1String("SGI"); // default style for X11 on IRIX -#elif defined(Q_WS_MAC) +#elif defined(Q_OS_MAC) return QLatin1String("Macintosh"); // default style for all Mac's #elif defined(Q_WS_X11) QString stylename; diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index f97b343463..2b4fc8897c 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -746,16 +746,8 @@ private: #endif // QT_NO_GESTURES friend class QWidgetEffectSourcePrivate; -#ifdef Q_WS_MAC - friend class QCoreGraphicsPaintEnginePrivate; - friend QPoint qt_mac_posInWindow(const QWidget *w); - friend OSWindowRef qt_mac_window_for(const QWidget *w); +#ifdef Q_OS_MAC friend bool qt_mac_is_metal(const QWidget *w); - friend OSViewRef qt_mac_nativeview_for(const QWidget *w); - friend void qt_event_request_window_change(QWidget *widget); - friend bool qt_mac_sendMacEventToWidget(QWidget *widget, EventRef ref); - friend class QRasterWindowSurface; - friend class QUnifiedToolbarSurface; #endif friend Q_WIDGETS_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget); friend Q_WIDGETS_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget); diff --git a/src/widgets/platforms/mac/qpaintdevice_mac.cpp b/src/widgets/platforms/mac/qpaintdevice_mac.cpp index 50bd4b8490..4bdb5d8733 100644 --- a/src/widgets/platforms/mac/qpaintdevice_mac.cpp +++ b/src/widgets/platforms/mac/qpaintdevice_mac.cpp @@ -100,53 +100,4 @@ Q_WIDGETS_EXPORT GrafPtr qt_mac_qd_context(const QPaintDevice *device) extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *pdev); -/*! \internal - - Returns the CoreGraphics CGContextRef of the paint device. 0 is - returned if it can't be obtained. It is the caller's responsiblity to - CGContextRelease the context when finished using it. - - \warning This function is only available on Mac OS X. -*/ - -Q_WIDGETS_EXPORT CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) -{ - if (pdev->devType() == QInternal::Pixmap) { - const QPixmap *pm = static_cast(pdev); - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev); - uint flags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - flags |= kCGBitmapByteOrder32Host; -#endif - CGContextRef ret = 0; - - // It would make sense to put this into a mac #ifdef'ed - // virtual function in the QPlatformPixmap at some point - if (pm->data->classId() == QPlatformPixmap::MacClass) { - const QMacPlatformPixmap *pmData = static_cast(pm->data.data()); - ret = CGBitmapContextCreate(pmData->pixels, pmData->w, pmData->h, - 8, pmData->bytesPerRow, colorspace, - flags); - if(!ret) - qWarning("QPaintDevice: Unable to create context for pixmap (%d/%d/%d)", - pmData->w, pmData->h, (pmData->bytesPerRow * pmData->h)); - } else if (pm->data->classId() == QPlatformPixmap::RasterClass) { - QImage *image = pm->data->buffer(); - ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - } - - CGContextTranslateCTM(ret, 0, pm->height()); - CGContextScaleCTM(ret, 1, -1); - return ret; - } else if (pdev->devType() == QInternal::Widget) { - CGContextRef ret = static_cast(static_cast(pdev)->macCGHandle()); - CGContextRetain(ret); - return ret; - } else if (pdev->devType() == QInternal::MacQuartz) { - return static_cast(pdev)->cgContext(); - } - return 0; -} - QT_END_NAMESPACE diff --git a/src/widgets/platforms/mac/qpaintengine_mac.cpp b/src/widgets/platforms/mac/qpaintengine_mac.cpp index af8e0e36c3..b3605adb19 100644 --- a/src/widgets/platforms/mac/qpaintengine_mac.cpp +++ b/src/widgets/platforms/mac/qpaintengine_mac.cpp @@ -87,60 +87,6 @@ extern QPixmap qt_pixmapForBrush(int, bool); //qbrush.cpp void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform); -//Implemented for qt_mac_p.h -QMacCGContext::QMacCGContext(QPainter *p) -{ - QPaintEngine *pe = p->paintEngine(); - if (pe->type() == QPaintEngine::MacPrinter) - pe = static_cast(pe)->paintEngine(); - pe->syncState(); - context = 0; - if(pe->type() == QPaintEngine::CoreGraphics) - context = static_cast(pe)->handle(); - - int devType = p->device()->devType(); - if (pe->type() == QPaintEngine::Raster - && (devType == QInternal::Widget || - devType == QInternal::Pixmap || - devType == QInternal::Image)) { - - extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice()); - uint flags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - flags |= kCGBitmapByteOrder32Host; -#endif - const QImage *image = (const QImage *) pe->paintDevice(); - - context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - - CGContextTranslateCTM(context, 0, image->height()); - CGContextScaleCTM(context, 1, -1); - - if (devType == QInternal::Widget) { - QRegion clip = p->paintEngine()->systemClip(); - QTransform native = p->deviceTransform(); - QTransform logical = p->combinedTransform(); - - if (p->hasClipping()) { - QRegion r = p->clipRegion(); - r.translate(native.dx(), native.dy()); - if (clip.isEmpty()) - clip = r; - else - clip &= r; - } - qt_mac_clip_cg(context, clip, 0); - - CGContextTranslateCTM(context, native.dx(), native.dy()); - } - } else { - CGContextRetain(context); - } -} - - /***************************************************************************** QCoreGraphicsPaintEngine utility functions *****************************************************************************/ @@ -152,13 +98,6 @@ CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &t) { return CGAffineTransformMake(t.m11(), t.m12(), t.m21(), t.m22(), t.dx(), t.dy()); } -CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) -{ - bool isWidget = (paintDevice->devType() == QInternal::Widget); - return QCoreGraphicsPaintEngine::macDisplayColorSpace(isWidget ? static_cast(paintDevice) - : 0); -} - inline static QCFType cgColorForQColor(const QColor &col, QPaintDevice *pdev) { CGFloat components[] = { @@ -317,46 +256,6 @@ CGColorSpaceRef QCoreGraphicsPaintEngine::macGenericColorSpace() return macDisplayColorSpace(); #endif } -void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) -{ - CGAffineTransform old_xform = CGAffineTransformIdentity; - if(orig_xform) { //setup xforms - old_xform = CGContextGetCTM(hd); - CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); - CGContextConcatCTM(hd, *orig_xform); - } - - //do the clipping - CGContextBeginPath(hd); - if(rgn.isEmpty()) { - CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); - } else { -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - QCFType shape = rgn.toHIMutableShape(); - Q_ASSERT(!HIShapeIsEmpty(shape)); - HIShapeReplacePathInCGContext(shape, hd); - } else -#endif - { - QVector rects = rgn.rects(); - const int count = rects.size(); - for(int i = 0; i < count; i++) { - const QRect &r = rects[i]; - CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height()); - CGContextAddRect(hd, mac_r); - } - } - - } - CGContextClip(hd); - - if(orig_xform) {//reset xforms - CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); - CGContextConcatCTM(hd, old_xform); - } -} - //pattern handling (tiling) #if 1 diff --git a/src/widgets/platforms/mac/qregion_mac.cpp b/src/widgets/platforms/mac/qregion_mac.cpp index b929d9c283..3a861f1cdd 100644 --- a/src/widgets/platforms/mac/qregion_mac.cpp +++ b/src/widgets/platforms/mac/qregion_mac.cpp @@ -47,75 +47,4 @@ QT_BEGIN_NAMESPACE QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0 }; - -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) -OSStatus QRegion::shape2QRegionHelper(int inMessage, HIShapeRef, - const CGRect *inRect, void *inRefcon) -{ - QRegion *region = static_cast(inRefcon); - if (!region) - return paramErr; - - switch (inMessage) { - case kHIShapeEnumerateRect: - *region += QRect(inRect->origin.x, inRect->origin.y, - inRect->size.width, inRect->size.height); - break; - case kHIShapeEnumerateInit: - // Assume the region is already setup correctly - case kHIShapeEnumerateTerminate: - default: - break; - } - return noErr; -} -#endif - -/*! - \internal - Create's a mutable shape, it's the caller's responsibility to release. - WARNING: this function clamps the coordinates to SHRT_MIN/MAX on 10.4 and below. -*/ -HIMutableShapeRef QRegion::toHIMutableShape() const -{ - HIMutableShapeRef shape = HIShapeCreateMutable(); -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { - if (d->qt_rgn && d->qt_rgn->numRects) { - int n = d->qt_rgn->numRects; - const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData(); - while (n--) { - CGRect cgRect = CGRectMake(qt_r->x(), qt_r->y(), qt_r->width(), qt_r->height()); - HIShapeUnionWithRect(shape, &cgRect); - ++qt_r; - } - } - } else -#endif - { - } - return shape; -} - - - -QRegion QRegion::fromHIShapeRef(HIShapeRef shape) -{ - QRegion returnRegion; - returnRegion.detach(); - // Begin gratuitous #if-defery -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) -# ifndef Q_WS_MAC64 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { -# endif - HIShapeEnumerate(shape, kHIShapeParseFromTopLeft, shape2QRegionHelper, &returnRegion); -# ifndef Q_WS_MAC64 - } else -# endif -#endif - { - } - return returnRegion; -} - QT_END_NAMESPACE diff --git a/src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm b/src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm index 20bb6bffbb..b8ec6bbcf3 100644 --- a/src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm +++ b/src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm @@ -219,12 +219,6 @@ DnDParams *macCurrentDnDParameters() } #endif -bool macWindowIsTextured( void * /*OSWindowRef*/ window ) -{ - OSWindowRef wnd = static_cast(window); - return ( [wnd styleMask] & NSTexturedBackgroundWindowMask ) ? true : false; -} - void macWindowToolbarShow(const QWidget *widget, bool show ) { OSWindowRef wnd = qt_mac_window_for(widget); diff --git a/src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h b/src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h index c85d39010c..79ae7df8b6 100644 --- a/src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h +++ b/src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h @@ -129,7 +129,6 @@ QT_BEGIN_NAMESPACE Qt::MouseButtons qt_mac_get_buttons(int buttons); Qt::MouseButton qt_mac_get_button(EventMouseButton button); void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0.15); -bool macWindowIsTextured(void * /*OSWindowRef*/ window); void macWindowToolbarShow(const QWidget *widget, bool show ); void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef ); bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ); @@ -140,7 +139,6 @@ void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::H void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widget); void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivate *widget); void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show); -void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm); void qt_mac_update_mouseTracking(QWidget *widget); OSStatus qt_mac_drawCGImage(CGContextRef cg, const CGRect *inbounds, CGImageRef); bool qt_mac_checkForNativeSizeGrip(const QWidget *widget); diff --git a/src/widgets/platforms/mac/qt_mac.cpp b/src/widgets/platforms/mac/qt_mac.cpp index b3c9371d24..bb7e047479 100644 --- a/src/widgets/platforms/mac/qt_mac.cpp +++ b/src/widgets/platforms/mac/qt_mac.cpp @@ -67,24 +67,6 @@ QFont qfontForThemeFont(ThemeFontID themeID) } #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) -static QColor qcolorFromCGColor(CGColorRef cgcolor) -{ - QColor pc; - CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(cgcolor)); - const CGFloat *components = CGColorGetComponents(cgcolor); - if (model == kCGColorSpaceModelRGB) { - pc.setRgbF(components[0], components[1], components[2], components[3]); - } else if (model == kCGColorSpaceModelCMYK) { - pc.setCmykF(components[0], components[1], components[2], components[3]); - } else if (model == kCGColorSpaceModelMonochrome) { - pc.setRgbF(components[0], components[0], components[0], components[1]); - } else { - // Colorspace we can't deal with. - qWarning("Qt: qcolorFromCGColor: cannot convert from colorspace model: %d", model); - Q_ASSERT(false); - } - return pc; -} static inline QColor leopardBrush(ThemeBrush brush) { diff --git a/src/widgets/styles/qmacstyle_mac.h b/src/widgets/styles/qmacstyle_mac.h index bb9175cca8..317a0cdc88 100644 --- a/src/widgets/styles/qmacstyle_mac.h +++ b/src/widgets/styles/qmacstyle_mac.h @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) +#if defined(Q_OS_MAC) && !defined(QT_NO_STYLE_MAC) class QPalette; diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index f6eacd28dc..9e9f5d48ed 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -45,17 +45,15 @@ */ #include "qmacstyle_mac.h" +#include "qmacstyle_mac_p.h" +#include "qmacstylepixmaps_mac_p.h" -#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) #define QMAC_QAQUASTYLE_SIZE_CONSTRAIN //#define DEBUG_SIZE_CONSTRAINT -#include +#include #include -#include -#include #include -#include #include #include #include @@ -97,11 +95,10 @@ #include #include #include -#include -#include -#include -#include "qmacstyle_mac_p.h" +#include +#include #include +#include QT_BEGIN_NAMESPACE @@ -138,9 +135,6 @@ typedef HIRect * (*PtrHIShapeGetBounds)(HIShapeRef, HIRect *); static PtrHIShapeGetBounds ptrHIShapeGetBounds = 0; static int closeButtonSize = 12; - -extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp - static bool isVerticalTabs(const QTabBar::Shape shape) { return (shape == QTabBar::RoundedEast || shape == QTabBar::TriangularEast @@ -417,18 +411,247 @@ static inline ThemeTabDirection getTabDirection(QTabBar::Shape shape) return ttd; } -QT_BEGIN_INCLUDE_NAMESPACE -#include "moc_qmacstyle_mac.cpp" -#include "moc_qmacstyle_mac_p.cpp" -QT_END_INCLUDE_NAMESPACE +static QString qt_mac_removeMnemonics(const QString &original) +{ + QString returnText(original.size(), 0); + int finalDest = 0; + int currPos = 0; + int l = original.length(); + while (l) { + if (original.at(currPos) == QLatin1Char('&') + && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) { + ++currPos; + --l; + if (l == 0) + break; + } + returnText[finalDest] = original.at(currPos); + ++currPos; + ++finalDest; + --l; + } + returnText.truncate(finalDest); + return returnText; +} -/***************************************************************************** - External functions - *****************************************************************************/ -extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp -extern QRegion qt_mac_convert_mac_region(HIShapeRef); //qregion_mac.cpp -void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp -extern QPaintDevice *qt_mac_safe_pdev; //qapplication_mac.cpp +class QMacCGContext +{ + CGContextRef context; +public: + QMacCGContext(QPainter *p); //qpaintengine_mac.cpp + inline QMacCGContext() { context = 0; } + inline QMacCGContext(const QPaintDevice *pdev) { + extern CGContextRef qt_mac_cg_context(const QPaintDevice *); + context = qt_mac_cg_context(pdev); + } + inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) { + context = cg; + if (!takeOwnership) + CGContextRetain(context); + } + inline QMacCGContext(const QMacCGContext ©) : context(0) { *this = copy; } + inline ~QMacCGContext() { + if (context) + CGContextRelease(context); + } + inline bool isNull() const { return context; } + inline operator CGContextRef() { return context; } + inline QMacCGContext &operator=(const QMacCGContext ©) { + if (context) + CGContextRelease(context); + context = copy.context; + CGContextRetain(context); + return *this; + } + inline QMacCGContext &operator=(CGContextRef cg) { + if (context) + CGContextRelease(context); + context = cg; + CGContextRetain(context); //we do not take ownership + return *this; + } +}; + +static QColor qcolorFromCGColor(CGColorRef cgcolor) +{ + QColor pc; + CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(cgcolor)); + const CGFloat *components = CGColorGetComponents(cgcolor); + if (model == kCGColorSpaceModelRGB) { + pc.setRgbF(components[0], components[1], components[2], components[3]); + } else if (model == kCGColorSpaceModelCMYK) { + pc.setCmykF(components[0], components[1], components[2], components[3]); + } else if (model == kCGColorSpaceModelMonochrome) { + pc.setRgbF(components[0], components[0], components[0], components[1]); + } else { + // Colorspace we can't deal with. + qWarning("Qt: qcolorFromCGColor: cannot convert from colorspace model: %d", model); + Q_ASSERT(false); + } + return pc; +} + +static inline QColor leopardBrush(ThemeBrush brush) +{ + QCFType cgClr = 0; + HIThemeBrushCreateCGColor(brush, &cgClr); + return qcolorFromCGColor(cgClr); +} + +QColor qcolorForTheme(ThemeBrush brush) +{ + return leopardBrush(brush); +} + +OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inRect, void *inRefcon) +{ + QRegion *region = static_cast(inRefcon); + if (!region) + return paramErr; + + switch (inMessage) { + case kHIShapeEnumerateRect: + *region += QRect(inRect->origin.x, inRect->origin.y, + inRect->size.width, inRect->size.height); + break; + case kHIShapeEnumerateInit: + // Assume the region is already setup correctly + case kHIShapeEnumerateTerminate: + default: + break; + } + return noErr; +} + + +/*! + \internal + Create's a mutable shape, it's the caller's responsibility to release. + WARNING: this function clamps the coordinates to SHRT_MIN/MAX on 10.4 and below. +*/ +HIMutableShapeRef qt_mac_toHIMutableShape(const QRegion ®ion) +{ + HIMutableShapeRef shape = HIShapeCreateMutable(); + if (region.rectCount() < 2 ) { + QRect qtRect = region.boundingRect(); + CGRect cgRect = CGRectMake(qtRect.x(), qtRect.y(), qtRect.width(), qtRect.height()); + HIShapeUnionWithRect(shape, &cgRect); + } else { + foreach (const QRect &qtRect, region.rects()) { + CGRect cgRect = CGRectMake(qtRect.x(), qtRect.y(), qtRect.width(), qtRect.height()); + HIShapeUnionWithRect(shape, &cgRect); + } + } + return shape; +} + +QRegion qt_mac_fromHIShapeRef(HIShapeRef shape) +{ + QRegion returnRegion; + //returnRegion.detach(); + HIShapeEnumerate(shape, kHIShapeParseFromTopLeft, qt_mac_shape2QRegionHelper, &returnRegion); + return returnRegion; +} + +CGColorSpaceRef m_genericColorSpace = 0; +QHash m_displayColorSpaceHash; +bool m_postRoutineRegistered = false; + +CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget); +CGColorSpaceRef qt_mac_genericColorSpace() +{ +#if 0 + if (!m_genericColorSpace) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { + m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + } else +#endif + { + m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); + } + if (!m_postRoutineRegistered) { + m_postRoutineRegistered = true; + qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces); + } + } + return m_genericColorSpace; +#else + // Just return the main display colorspace for the moment. + return qt_mac_displayColorSpace(0); +#endif +} + +/* + Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc. + to support multiple displays correctly. +*/ +CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget) +{ + CGColorSpaceRef colorSpace; + + CGDirectDisplayID displayID; + CMProfileRef displayProfile = 0; + if (widget == 0) { + displayID = CGMainDisplayID(); + } else { + displayID = CGMainDisplayID(); + /* + ### get correct display + const QRect &qrect = widget->window()->geometry(); + CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height()); + CGDisplayCount throwAway; + CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway); + if (dErr != kCGErrorSuccess) + return macDisplayColorSpace(0); // fall back on main display + */ + } + if ((colorSpace = m_displayColorSpaceHash.value(displayID))) + return colorSpace; + + CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile); + if (err == noErr) { + colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile); + } else if (widget) { + return qt_mac_displayColorSpace(0); // fall back on main display + } + + if (colorSpace == 0) + colorSpace = CGColorSpaceCreateDeviceRGB(); + + m_displayColorSpaceHash.insert(displayID, colorSpace); + CMCloseProfile(displayProfile); + if (!m_postRoutineRegistered) { + m_postRoutineRegistered = true; + void qt_mac_cleanUpMacColorSpaces(); + qAddPostRoutine(qt_mac_cleanUpMacColorSpaces); + } + return colorSpace; +} + +void qt_mac_cleanUpMacColorSpaces() +{ + if (m_genericColorSpace) { + CFRelease(m_genericColorSpace); + m_genericColorSpace = 0; + } + QHash::const_iterator it = m_displayColorSpaceHash.constBegin(); + while (it != m_displayColorSpaceHash.constEnd()) { + if (it.value()) + CFRelease(it.value()); + ++it; + } + m_displayColorSpaceHash.clear(); +} + +bool qt_macWindowIsTextured(const QWidget *window) +{ + NSWindow *nswindow = static_cast( + QApplication::platformNativeInterface()->nativeResourceForWindow("NSWindow", window->windowHandle())); + if (!nswindow) + return false; + return ([nswindow styleMask] & NSTexturedBackgroundWindowMask) ? true : false; +} /***************************************************************************** QMacCGStyle globals @@ -467,7 +690,7 @@ inline bool qt_mac_is_metal(const QWidget *w) if (w->testAttribute(Qt::WA_MacBrushedMetal)) return true; if (w->isWindow() && w->testAttribute(Qt::WA_WState_Created)) { // If not created will fall through to the opaque check and be fine anyway. - return macWindowIsTextured(qt_mac_window_for(w)); + return qt_macWindowIsTextured(w); } if (w->d_func()->isOpaque) break; @@ -1382,7 +1605,6 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti tdi->trackInfo.scrollbar.viewsize = slider->pageStep; } } -#endif QMacStylePrivate::QMacStylePrivate(QMacStyle *style) : timerID(-1), progressFrame(0), q(style), mouseDown(false) @@ -1750,8 +1972,9 @@ void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush QPoint dummy; const QPaintDevice *target = painter->device(); const QPaintDevice *redirected = QPainter::redirected(target, &dummy); - const bool usePainter = redirected && redirected != target; + //const bool usePainter = redirected && redirected != target; +#if 0 if (!usePainter && qt_mac_backgroundPattern && qt_mac_backgroundPattern->cacheKey() == brush.texture().cacheKey()) { @@ -1772,10 +1995,11 @@ void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush CGContextRestoreGState(cg); } else { +#endif const QRect rect(rgn.boundingRect()); painter->setClipRegion(rgn); painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); - } +// } } void QMacStyle::polish(QPalette &pal) @@ -1831,8 +2055,9 @@ void QMacStyle::polish(QWidget* w) mtinfo.version = qt_mac_hitheme_version; mtinfo.menuType = kThemeMenuTypePopUp; HIRect rect = CGRectMake(0, 0, px.width(), px.height()); - HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType(qt_mac_cg_context(&px)), - kHIThemeOrientationNormal); + // ### + //HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType(qt_mac_cg_context(&px)), + // kHIThemeOrientationNormal); QPalette pal = w->palette(); QBrush background(px); pal.setBrush(QPalette::All, QPalette::Window, background); @@ -2309,11 +2534,12 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w ret = 100; break; case SH_ScrollBar_LeftClickAbsolutePosition: { - extern bool qt_scrollbar_jump_to_pos; //qapplication_mac.cpp if(QApplication::keyboardModifiers() & Qt::AltModifier) - ret = !qt_scrollbar_jump_to_pos; + ret = false; + //ret = !qt_scrollbar_jump_to_pos; else - ret = qt_scrollbar_jump_to_pos; + ret = true; + //ret = qt_scrollbar_jump_to_pos; break; } case SH_TabBar_PreferNoArrows: ret = true; @@ -2547,7 +2773,8 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w mdi.menuType = kThemeMenuTypePopUp; QCFType shape; HIThemeGetMenuBackgroundShape(&menuRect, &mdi, &shape); - mask->region = QRegion::fromHIShapeRef(shape); + + mask->region = qt_mac_fromHIShapeRef(shape); } } break; @@ -3404,7 +3631,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QColor textColor = btn->palette.buttonText().color(); CGFloat colorComp[] = { textColor.redF(), textColor.greenF(), textColor.blueF(), textColor.alphaF() }; - CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace()); + CGContextSetFillColorSpace(cg, qt_mac_genericColorSpace()); CGContextSetFillColor(cg, colorComp); tti.fontID = themeId; tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter; @@ -3629,7 +3856,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QColor textColor = myTab.palette.windowText().color(); CGFloat colorComp[] = { textColor.redF(), textColor.greenF(), textColor.blueF(), textColor.alphaF() }; - CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace()); + CGContextSetFillColorSpace(cg, qt_mac_genericColorSpace()); CGContextSetFillColor(cg, colorComp); switch (d->aquaSizeConstrain(opt, w)) { default: @@ -3810,7 +4037,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QColor textColor = p->pen().color(); CGFloat colorComp[] = { textColor.redF(), textColor.greenF(), textColor.blueF(), textColor.alphaF() }; - CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace()); + CGContextSetFillColorSpace(cg, qt_mac_genericColorSpace()); CGContextSetFillColor(cg, colorComp); HIThemeTextInfo tti; tti.version = qt_mac_hitheme_version; @@ -4946,7 +5173,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex QColor textColor = groupBox->palette.windowText().color(); CGFloat colorComp[] = { textColor.redF(), textColor.greenF(), textColor.blueF(), textColor.alphaF() }; - CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace()); + CGContextSetFillColorSpace(cg, qt_mac_genericColorSpace()); CGContextSetFillColor(cg, colorComp); tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont; tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter; @@ -6075,4 +6302,135 @@ int QMacStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, return_SIZE(10, 8, 6); // guess } +void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) +{ + CGAffineTransform old_xform = CGAffineTransformIdentity; + if (orig_xform) { //setup xforms + old_xform = CGContextGetCTM(hd); + CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); + CGContextConcatCTM(hd, *orig_xform); + } + + //do the clipping + CGContextBeginPath(hd); + if (rgn.isEmpty()) { + CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); + } else { + QCFType shape = qt_mac_toHIMutableShape(rgn); + Q_ASSERT(!HIShapeIsEmpty(shape)); + HIShapeReplacePathInCGContext(shape, hd); + } + CGContextClip(hd); + + if (orig_xform) {//reset xforms + CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); + CGContextConcatCTM(hd, old_xform); + } +} + +QMacCGContext::QMacCGContext(QPainter *p) +{ + QPaintEngine *pe = p->paintEngine(); + pe->syncState(); + context = 0; + + int devType = p->device()->devType(); + if (pe->type() == QPaintEngine::Raster + && (devType == QInternal::Widget || + devType == QInternal::Pixmap || + devType == QInternal::Image)) { + + extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); + CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice()); + uint flags = kCGImageAlphaPremultipliedFirst; + flags |= kCGBitmapByteOrder32Host; + + const QImage *image = (const QImage *) pe->paintDevice(); + + context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(), + 8, image->bytesPerLine(), colorspace, flags); + + CGContextTranslateCTM(context, 0, image->height()); + CGContextScaleCTM(context, 1, -1); + + if (devType == QInternal::Widget) { + QRegion clip = p->paintEngine()->systemClip(); + QTransform native = p->deviceTransform(); + QTransform logical = p->combinedTransform(); + + if (p->hasClipping()) { + QRegion r = p->clipRegion(); + r.translate(native.dx(), native.dy()); + if (clip.isEmpty()) + clip = r; + else + clip &= r; + } + qt_mac_clip_cg(context, clip, 0); + + CGContextTranslateCTM(context, native.dx(), native.dy()); + } + } else { + qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType; + } +} + +CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) +{ + bool isWidget = (paintDevice->devType() == QInternal::Widget); + return qt_mac_displayColorSpace(isWidget ? static_cast(paintDevice) : 0); +} + +/*! \internal + + Returns the CoreGraphics CGContextRef of the paint device. 0 is + returned if it can't be obtained. It is the caller's responsibility to + CGContextRelease the context when finished using it. + + \warning This function is only available on Mac OS X. +*/ + +CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) +{ + if (pdev->devType() == QInternal::Pixmap) { + const QPixmap *pm = static_cast(pdev); + CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev); + uint flags = kCGImageAlphaPremultipliedFirst; + flags |= kCGBitmapByteOrder32Host; + CGContextRef ret = 0; + + QPlatformPixmap *data = const_cast(pm)->data_ptr().data(); + if (data->classId() == QPlatformPixmap::RasterClass) { + QImage *image = data->buffer(); + ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(), + 8, image->bytesPerLine(), colorspace, flags); + } else { + qDebug() << "qt_mac_cg_context: Unsupported pixmap class"; + } + + CGContextTranslateCTM(ret, 0, pm->height()); + CGContextScaleCTM(ret, 1, -1); + return ret; + } else if (pdev->devType() == QInternal::Widget) { + //CGContextRef ret = static_cast(static_cast(pdev)->macCGHandle()); + ///CGContextRetain(ret); + //return ret; + qDebug() << "qt_mac_cg_context: not implemented: Widget class"; + return 0; + } + return 0; +} + +/* +FontHash::FontHash() +{ + QHash::operator=(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFonts()); +} + +Q_GLOBAL_STATIC(FontHash, app_fonts) +FontHash *qt_app_fonts_hash() +{ + return app_fonts(); +} +*/ QT_END_NAMESPACE diff --git a/src/widgets/styles/qmacstyle_mac_p.h b/src/widgets/styles/qmacstyle_mac_p.h index 747779249c..fc10be507f 100644 --- a/src/widgets/styles/qmacstyle_mac_p.h +++ b/src/widgets/styles/qmacstyle_mac_p.h @@ -43,13 +43,13 @@ #ifndef QMACSTYLE_MAC_P_H #define QMACSTYLE_MAC_P_H -#include +#include +#undef check + +#include "qmacstyle_mac.h" #include #include -#include -#include #include -#include #include #include #include @@ -94,7 +94,8 @@ #include #include #include -#include + + // // W A R N I N G @@ -109,21 +110,6 @@ QT_BEGIN_NAMESPACE -#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5) -enum { - kThemePushButtonTextured = 31, - kThemePushButtonTexturedSmall = 32, - kThemePushButtonTexturedMini = 33 -}; - -/* Search fields */ -enum { - kHIThemeFrameTextFieldRound = 1000, - kHIThemeFrameTextFieldRoundSmall = 1001, - kHIThemeFrameTextFieldRoundMini = 1002 -}; -#endif - /* AHIG: Apple Human Interface Guidelines diff --git a/src/widgets/styles/qstylefactory.cpp b/src/widgets/styles/qstylefactory.cpp index 8c1b9cb7e1..4de4a7b495 100644 --- a/src/widgets/styles/qstylefactory.cpp +++ b/src/widgets/styles/qstylefactory.cpp @@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE -#if !defined(QT_NO_STYLE_MAC) && defined(Q_WS_MAC) +#if !defined(QT_NO_STYLE_MAC) && defined(Q_OS_MAC) QT_BEGIN_INCLUDE_NAMESPACE # include "qmacstyle_mac.h" QT_END_INCLUDE_NAMESPACE diff --git a/src/widgets/styles/styles.pri b/src/widgets/styles/styles.pri index cf7ee5a0a4..ef6827f74f 100644 --- a/src/widgets/styles/styles.pri +++ b/src/widgets/styles/styles.pri @@ -37,8 +37,7 @@ contains( styles, all ) { styles = mac windows windowsxp windowsvista } -# TODO, re-enable qmacstyle in tests/auto/widgets/styles/sytles.pro when done -styles -= mac +!macx-*:styles -= mac x11{ QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTKSTYLE -- cgit v1.2.3