add better windows7/vista look by nico_w
authorWladimir J. van der Laan <laanwj@gmail.com>
Sat, 9 Jul 2011 13:26:57 +0000 (15:26 +0200)
committerWladimir J. van der Laan <laanwj@gmail.com>
Sat, 9 Jul 2011 13:26:57 +0000 (15:26 +0200)
bitcoin-qt.pro
src/qt/bitcoin.cpp
src/qt/qtwin.cpp [new file with mode: 0644]
src/qt/qtwin.h [new file with mode: 0644]

index 99b6eb3..5dd37b0 100644 (file)
@@ -81,7 +81,8 @@ HEADERS += src/qt/bitcoingui.h \
     src/qt/walletmodel.h \
     src/bitcoinrpc.h \
     src/qt/overviewpage.h \
-    src/qt/csvmodelwriter.h
+    src/qt/csvmodelwriter.h \
+    src/qt/qtwin.h
 SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
     src/qt/transactiontablemodel.cpp \
     src/qt/addresstablemodel.cpp \
@@ -119,7 +120,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
     src/qt/walletmodel.cpp \
     src/bitcoinrpc.cpp \
     src/qt/overviewpage.cpp \
-    src/qt/csvmodelwriter.cpp
+    src/qt/csvmodelwriter.cpp \
+    src/qt/qtwin.cpp
 
 RESOURCES += \
     src/qt/bitcoin.qrc
@@ -134,4 +136,3 @@ FORMS += \
 
 CODECFORTR = UTF-8
 TRANSLATIONS = src/qt/locale/bitcoin_nl.ts src/qt/locale/bitcoin_de.ts
-
index 78a20c5..bcc73de 100644 (file)
@@ -4,6 +4,7 @@
 #include "bitcoingui.h"
 #include "clientmodel.h"
 #include "walletmodel.h"
+#include "qtwin.h"
 
 #include "headers.h"
 #include "init.h"
@@ -119,10 +120,29 @@ int main(int argc, char *argv[])
                 BitcoinGUI window;
                 ClientModel clientModel(pwalletMain);
                 WalletModel walletModel(pwalletMain);
+
                 guiref = &window;
                 window.setClientModel(&clientModel);
                 window.setWalletModel(&walletModel);
 
+#ifdef Q_WS_WIN32
+                // Windows-specific customization
+                window.setAttribute(Qt::WA_TranslucentBackground);
+                window.setAttribute(Qt::WA_NoSystemBackground, false);
+                QPalette pal = window.palette();
+                QColor bg = pal.window().color();
+                bg.setAlpha(0);
+                pal.setColor(QPalette::Window, bg);
+                window.setPalette(pal);
+                window.ensurePolished();
+                window.setAttribute(Qt::WA_StyledBackground, false);
+#endif
+                if (QtWin::isCompositionEnabled())
+                {
+                    QtWin::extendFrameIntoClientArea(&window);
+                    window.setContentsMargins(0, 0, 0, 0);
+                }
+
                 window.show();
 
                 app.exec();
diff --git a/src/qt/qtwin.cpp b/src/qt/qtwin.cpp
new file mode 100644 (file)
index 0000000..bb029bb
--- /dev/null
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Use, modification and distribution is allowed without limitation,
+** warranty, liability or support of any kind.
+**
+****************************************************************************/
+
+#include "qtwin.h"
+#include <QLibrary>
+#include <QApplication>
+#include <QWidget>
+#include <QList>
+#include <QPointer>
+
+#ifdef Q_WS_WIN
+
+#include <qt_windows.h>
+
+// Blur behind data structures
+#define DWM_BB_ENABLE                 0x00000001  // fEnable has been specified
+#define DWM_BB_BLURREGION             0x00000002  // hRgnBlur has been specified
+#define DWM_BB_TRANSITIONONMAXIMIZED  0x00000004  // fTransitionOnMaximized has been specified
+#define WM_DWMCOMPOSITIONCHANGED        0x031E    // Composition changed window message
+
+typedef struct _DWM_BLURBEHIND
+{
+    DWORD dwFlags;
+    BOOL fEnable;
+    HRGN hRgnBlur;
+    BOOL fTransitionOnMaximized;
+} DWM_BLURBEHIND, *PDWM_BLURBEHIND;
+
+typedef struct _MARGINS
+{
+    int cxLeftWidth;
+    int cxRightWidth;
+    int cyTopHeight;
+    int cyBottomHeight;
+} MARGINS, *PMARGINS;
+
+typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);
+typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset);
+typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind);
+typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend);
+
+static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0;
+static PtrDwmEnableBlurBehindWindow pDwmEnableBlurBehindWindow = 0;
+static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;
+static PtrDwmGetColorizationColor pDwmGetColorizationColor = 0;
+
+
+/*
+ * Internal helper class that notifies windows if the
+ * DWM compositing state changes and updates the widget
+ * flags correspondingly.
+ */
+class WindowNotifier : public QWidget
+{
+public:
+    WindowNotifier() { winId(); }
+    void addWidget(QWidget *widget) { widgets.append(widget); }
+    void removeWidget(QWidget *widget) { widgets.removeAll(widget); }
+    bool winEvent(MSG *message, long *result);
+
+private:
+    QWidgetList widgets;
+};
+
+static bool resolveLibs()
+{
+    if (!pDwmIsCompositionEnabled) {
+        QLibrary dwmLib(QString::fromAscii("dwmapi"));
+        pDwmIsCompositionEnabled =(PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");
+        pDwmExtendFrameIntoClientArea = (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea");
+        pDwmEnableBlurBehindWindow = (PtrDwmEnableBlurBehindWindow)dwmLib.resolve("DwmEnableBlurBehindWindow");
+        pDwmGetColorizationColor = (PtrDwmGetColorizationColor)dwmLib.resolve("DwmGetColorizationColor");
+    }
+    return pDwmIsCompositionEnabled != 0;
+}
+
+#endif
+
+/*!
+  * Chekcs and returns true if Windows DWM composition
+  * is currently enabled on the system.
+  *
+  * To get live notification on the availability of
+  * this feature, you will currently have to
+  * reimplement winEvent() on your widget and listen
+  * for the WM_DWMCOMPOSITIONCHANGED event to occur.
+  *
+  */
+bool QtWin::isCompositionEnabled()
+{
+#ifdef Q_WS_WIN
+    if (resolveLibs()) {
+        HRESULT hr = S_OK;
+        BOOL isEnabled = false;
+        hr = pDwmIsCompositionEnabled(&isEnabled);
+        if (SUCCEEDED(hr))
+            return isEnabled;
+    }
+#endif
+    return false;
+}
+
+/*!
+  * Enables Blur behind on a Widget.
+  *
+  * \a enable tells if the blur should be enabled or not
+  */
+bool QtWin::enableBlurBehindWindow(QWidget *widget, bool enable)
+{
+    Q_ASSERT(widget);
+    bool result = false;
+#ifdef Q_WS_WIN
+    if (resolveLibs()) {
+        DWM_BLURBEHIND bb = {0};
+        HRESULT hr = S_OK;
+        bb.fEnable = enable;
+        bb.dwFlags = DWM_BB_ENABLE;
+        bb.hRgnBlur = NULL;
+        widget->setAttribute(Qt::WA_TranslucentBackground, enable);
+        widget->setAttribute(Qt::WA_NoSystemBackground, enable);
+        hr = pDwmEnableBlurBehindWindow(widget->winId(), &bb);
+        if (SUCCEEDED(hr)) {
+            result = true;
+            windowNotifier()->addWidget(widget);
+        }
+    }
+#endif
+    return result;
+}
+
+/*!
+  * ExtendFrameIntoClientArea.
+  *
+  * This controls the rendering of the frame inside the window.
+  * Note that passing margins of -1 (the default value) will completely
+  * remove the frame from the window.
+  *
+  * \note you should not call enableBlurBehindWindow before calling
+  *       this functions
+  *
+  * \a enable tells if the blur should be enabled or not
+  */
+bool QtWin::extendFrameIntoClientArea(QWidget *widget, int left, int top, int right, int bottom)
+{
+
+    Q_ASSERT(widget);
+    Q_UNUSED(left);
+    Q_UNUSED(top);
+    Q_UNUSED(right);
+    Q_UNUSED(bottom);
+
+    bool result = false;
+#ifdef Q_WS_WIN
+    if (resolveLibs()) {
+        QLibrary dwmLib(QString::fromAscii("dwmapi"));
+        HRESULT hr = S_OK;
+        MARGINS m = {left, top, right, bottom};
+        hr = pDwmExtendFrameIntoClientArea(widget->winId(), &m);
+        if (SUCCEEDED(hr)) {
+            result = true;
+            windowNotifier()->addWidget(widget);
+        }
+        widget->setAttribute(Qt::WA_TranslucentBackground, result);
+    }
+#endif
+    return result;
+}
+
+/*!
+  * Returns the current colorizationColor for the window.
+  *
+  * \a enable tells if the blur should be enabled or not
+  */
+QColor QtWin::colorizatinColor()
+{
+    QColor resultColor = QApplication::palette().window().color();
+
+#ifdef Q_WS_WIN
+    if (resolveLibs()) {
+        DWORD color = 0;
+        BOOL opaque = FALSE;
+        QLibrary dwmLib(QString::fromAscii("dwmapi"));
+        HRESULT hr = S_OK;
+        hr = pDwmGetColorizationColor(&color, &opaque);
+        if (SUCCEEDED(hr))
+            resultColor = QColor(color);
+    }
+#endif
+    return resultColor;
+}
+
+#ifdef Q_WS_WIN
+WindowNotifier *QtWin::windowNotifier()
+{
+    static WindowNotifier *windowNotifierInstance = 0;
+    if (!windowNotifierInstance)
+        windowNotifierInstance = new WindowNotifier;
+    return windowNotifierInstance;
+}
+
+
+/* Notify all enabled windows that the DWM state changed */
+bool WindowNotifier::winEvent(MSG *message, long *result)
+{
+    if (message && message->message == WM_DWMCOMPOSITIONCHANGED) {
+        bool compositionEnabled = QtWin::isCompositionEnabled();
+        foreach(QWidget * widget, widgets) {
+            if (widget) {
+                widget->setAttribute(Qt::WA_NoSystemBackground, compositionEnabled);
+            }
+            widget->update();
+        }
+    }
+    return QWidget::winEvent(message, result);
+}
+#endif
diff --git a/src/qt/qtwin.h b/src/qt/qtwin.h
new file mode 100644 (file)
index 0000000..4008c7f
--- /dev/null
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Use, modification and distribution is allowed without limitation,
+** warranty, liability or support of any kind.
+**
+****************************************************************************/
+
+#ifndef QTWIN_H
+#define QTWIN_H
+
+#include <QColor>
+#include <QWidget>
+/**
+  * This is a helper class for using the Desktop Window Manager
+  * functionality on Windows 7 and Windows Vista. On other platforms
+  * these functions will simply not do anything.
+  */
+
+class WindowNotifier;
+
+class QtWin
+{
+public:
+    static bool enableBlurBehindWindow(QWidget *widget, bool enable = true);
+    static bool extendFrameIntoClientArea(QWidget *widget,
+                                          int left = -1, int top = -1,
+                                          int right = -1, int bottom = -1);
+    static bool isCompositionEnabled();
+    static QColor colorizatinColor();
+
+private:
+    static WindowNotifier *windowNotifier();
+};
+
+#endif // QTWIN_H