1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2017 LoRd_MuldeR <MuldeR2@GMX.de>
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
23 #include <MUtils/GUI.h>
24 #include <MUtils/OSSupport.h>
27 #include "Utils_Win32.h"
31 #include <QApplication>
34 #include <QDesktopWidget>
38 #define WIN32_LEAN_AND_MEAN 1
42 ///////////////////////////////////////////////////////////////////////////////
44 ///////////////////////////////////////////////////////////////////////////////
46 bool MUtils::GUI::broadcast(int eventType
, const bool &onlyToVisible
)
48 if(QApplication
*app
= dynamic_cast<QApplication
*>(QApplication::instance()))
50 qDebug("Broadcasting %d", eventType
);
53 QEvent
poEvent(static_cast<QEvent::Type
>(eventType
));
54 QWidgetList list
= app
->topLevelWidgets();
56 while(!list
.isEmpty())
58 QWidget
*widget
= list
.takeFirst();
59 if(!onlyToVisible
|| widget
->isVisible())
61 if(!app
->sendEvent(widget
, &poEvent
))
68 qDebug("Broadcast %d done (%s)", eventType
, (allOk
? "OK" : "Stopped"));
73 qWarning("Broadcast failed, could not get QApplication instance!");
78 ///////////////////////////////////////////////////////////////////////////////
80 ///////////////////////////////////////////////////////////////////////////////
88 class WindowIconHelper
: public QObject
91 WindowIconHelper(QWidget
*const parent
, const HICON hIcon
, const bool &bIsBigIcon
)
96 SendMessage(reinterpret_cast<HWND
>(parent
->winId()), WM_SETICON
, (bIsBigIcon
? ICON_BIG
: ICON_SMALL
), LPARAM(hIcon
));
99 virtual ~WindowIconHelper(void)
103 DestroyIcon(m_hIcon
);
114 bool MUtils::GUI::set_window_icon(QWidget
*const window
, const QIcon
&icon
, const bool bIsBigIcon
)
116 if ((!icon
.isNull()) && window
->winId())
118 const int extend
= (bIsBigIcon
? 32 : 16);
119 if (const HICON hIcon
= (HICON
)MUtils::Win32Utils::qicon_to_hicon(&icon
, extend
, extend
))
121 new Internal::WindowIconHelper(window
, hIcon
, bIsBigIcon
); /*will be free'd using QObject parent mechanism*/
128 ///////////////////////////////////////////////////////////////////////////////
130 ///////////////////////////////////////////////////////////////////////////////
132 static QMutex g_blinkMutex
;
134 void MUtils::GUI::blink_window(QWidget
*const poWindow
, const unsigned int &count
, const unsigned int &delay
)
136 const double maxOpac
= 1.0;
137 const double minOpac
= 0.3;
138 const double delOpac
= 0.1;
140 if (!g_blinkMutex
.tryLock())
142 qWarning("Blinking is already in progress, skipping!");
148 const int steps
= static_cast<int>(ceil(maxOpac
- minOpac
) / delOpac
);
149 const int sleep
= static_cast<int>(floor(static_cast<double>(delay
) / static_cast<double>(steps
)));
150 const double opacity
= poWindow
->windowOpacity();
152 for (unsigned int i
= 0; i
< count
; i
++)
154 for (double x
= maxOpac
; x
>= minOpac
; x
-= delOpac
)
156 poWindow
->setWindowOpacity(x
);
157 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents
);
158 MUtils::OS::sleep_ms(sleep
);
161 for (double x
= minOpac
; x
<= maxOpac
; x
+= delOpac
)
163 poWindow
->setWindowOpacity(x
);
164 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents
);
165 MUtils::OS::sleep_ms(sleep
);
169 poWindow
->setWindowOpacity(opacity
);
170 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents
);
174 qWarning("Exception error while blinking!");
177 g_blinkMutex
.unlock();
180 ///////////////////////////////////////////////////////////////////////////////
182 ///////////////////////////////////////////////////////////////////////////////
184 double MUtils::GUI::dpi_scale(void)
186 if (const QApplication
*const app
= dynamic_cast<QApplication
*>(QCoreApplication::instance()))
188 const double dpiX
= static_cast<double>(app
->desktop()->logicalDpiX());
189 const double dpiY
= static_cast<double>(app
->desktop()->logicalDpiY());
190 return qBound(1.0, ((dpiX
+ dpiY
) / 192.0), 2.0);
195 bool MUtils::GUI::scale_widget(QWidget
*const widget
, const bool recenter
)
197 if (widget
&& (!widget
->parentWidget()))
199 const double dpiScale
= dpi_scale();
200 if ((dpiScale
> 0.0) && (!qFuzzyCompare(dpiScale
, 1.0)))
202 const QSize originalSize
= widget
->size();
203 widget
->resize(qRound(originalSize
.width() * dpiScale
), qRound(originalSize
.height() * dpiScale
));
204 return recenter
? center_widget(widget
) : true;
210 bool MUtils::GUI::center_widget(QWidget
*const widget
)
212 if (widget
&& (!widget
->parentWidget()))
214 const QRect desktopRect
= QApplication::desktop()->screenGeometry();
215 const QRect thisRect
= widget
->geometry();
216 widget
->move((desktopRect
.width() - thisRect
.width()) / 2, (desktopRect
.height() - thisRect
.height()) / 2);
222 ///////////////////////////////////////////////////////////////////////////////
224 ///////////////////////////////////////////////////////////////////////////////
226 void MUtils::GUI::force_quit(void)
228 qApp
->closeAllWindows();
232 ///////////////////////////////////////////////////////////////////////////////