aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2011-07-09 15:26:57 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2011-07-09 15:26:57 +0200
commit0b814f9ea3d47e35b6966061aa3f3c0aac5ab048 (patch)
tree3b3abab81932b2c7b4a08bbfb9711db3ee8c2702
parent7668631d1b65ff1d1e7ad09086f6dc91fdd7ed77 (diff)
downloadbitcoin-0b814f9ea3d47e35b6966061aa3f3c0aac5ab048.tar.xz
add better windows7/vista look by nico_w
-rw-r--r--bitcoin-qt.pro7
-rw-r--r--src/qt/bitcoin.cpp20
-rw-r--r--src/qt/qtwin.cpp222
-rw-r--r--src/qt/qtwin.h37
4 files changed, 283 insertions, 3 deletions
diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro
index 99b6eb3896..5dd37b0b7e 100644
--- a/bitcoin-qt.pro
+++ b/bitcoin-qt.pro
@@ -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
-
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 78a20c51c0..bcc73de865 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -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
index 0000000000..bb029bba24
--- /dev/null
+++ b/src/qt/qtwin.cpp
@@ -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
index 0000000000..4008c7fa28
--- /dev/null
+++ b/src/qt/qtwin.h
@@ -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