Ref T215, overlay message frame can be used with multiple widgets (not only QFrame)

This commit is contained in:
Klaus Basan
2017-12-29 03:15:04 +01:00
parent 1c05927c0c
commit 75202eb4ce
3 changed files with 206 additions and 193 deletions

View File

@@ -29,4 +29,24 @@
# define BLACKGUI_EXPORT # define BLACKGUI_EXPORT
#endif #endif
#endif // BLACKGUI_MACROS_H /*!
* \def BLACKGUI_EXPORT_DECLARE_TEMPLATE
* BLACKGUI Export Explicit Template Declaration Macro
*/
/*!
* \def BLACKGUI_EXPORT_DEFINE_TEMPLATE
* BLACKGUI Export Explicit Template Definition Macro
*/
#if defined(Q_OS_WIN) && defined(Q_CC_GNU)
# define BLACKGUI_EXPORT_DECLARE_TEMPLATE BLACKGUI_EXPORT
# define BLACKGUI_EXPORT_DEFINE_TEMPLATE
#elif defined(Q_OS_WIN) && defined(Q_CC_CLANG)
# define BLACKGUI_EXPORT_DECLARE_TEMPLATE
# define BLACKGUI_EXPORT_DEFINE_TEMPLATE BLACKGUI_EXPORT
#else
# define BLACKGUI_EXPORT_DECLARE_TEMPLATE
# define BLACKGUI_EXPORT_DEFINE_TEMPLATE
#endif
#endif // guard

View File

@@ -22,164 +22,15 @@
#include <algorithm> #include <algorithm>
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Network;
namespace BlackGui namespace BlackGui
{ {
COverlayMessagesFrame::COverlayMessagesFrame(QWidget *parent) : COverlayMessagesFrame::COverlayMessagesFrame(QWidget *parent) : COverlayMessagesBase(parent)
QFrame(parent)
{
const bool isFrameless = CGuiUtility::isMainWindowFrameless();
m_middleFactor = isFrameless ? 1.25 : 1.5; // 2 is middle in normal window
}
COverlayMessagesFrame::~COverlayMessagesFrame()
{ } { }
void COverlayMessagesFrame::showStatusMessagesFrame() COverlayMessagesTabWidget::COverlayMessagesTabWidget(QWidget *parent) : COverlayMessagesBase(parent)
{ { }
this->initInnerFrame();
}
void COverlayMessagesFrame::setOverlaySizeFactors(double widthFactor, double heightFactor, double middleFactor)
{
m_widthFactor = widthFactor;
m_heightFactor = heightFactor;
m_middleFactor = middleFactor;
}
void COverlayMessagesFrame::showKillButton(bool killButton)
{
m_showKillButton = killButton;
if (m_overlayMessages)
{
m_overlayMessages->showKillButton(killButton);
}
}
void COverlayMessagesFrame::setForceSmall(bool force)
{
m_forceSmallMsgs = force;
if (m_overlayMessages)
{
m_overlayMessages->setForceSmall(force);
}
}
void COverlayMessagesFrame::showOverlayMessagesWithConfirmation(
const CStatusMessageList &messages, bool appendOldMessages,
const QString &confirmationMessage, std::function<void ()> okLambda,
QMessageBox::StandardButton defaultButton, int timeOutMs)
{
if (messages.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayMessagesWithConfirmation(messages, appendOldMessages, confirmationMessage, okLambda, defaultButton, timeOutMs);
this->repaint();
}
void COverlayMessagesFrame::clearOverlayMessages()
{
if (!m_overlayMessages) { return; }
m_overlayMessages->clearOverlayMessages();
}
void COverlayMessagesFrame::closeOverlay()
{
if (!m_overlayMessages) { return; }
m_overlayMessages->close();
}
void COverlayMessagesFrame::showOverlayMessage(const CStatusMessage &message, int timeOutMs)
{
if (message.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayMessage(message, timeOutMs);
this->repaint();
}
void COverlayMessagesFrame::showOverlayMessages(const CStatusMessageList &messages, bool appendOldMessages, int timeOutMs)
{
if (messages.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayMessages(messages, appendOldMessages, timeOutMs);
this->repaint();
}
void COverlayMessagesFrame::showOverlayTextMessage(const Network::CTextMessage &textMessage, int timeOutMs)
{
if (textMessage.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayTextMessage(textMessage, timeOutMs);
this->repaint();
}
void COverlayMessagesFrame::showOverlayVariant(const CVariant &variant, int timeOutMs)
{
this->initInnerFrame();
m_overlayMessages->showOverlayVariant(variant, timeOutMs);
this->repaint();
}
void COverlayMessagesFrame::showOverlayImage(const CPixmap &pixmap, int timeOutMs)
{
this->initInnerFrame();
m_overlayMessages->showOverlayImage(pixmap, timeOutMs);
this->repaint();
}
void COverlayMessagesFrame::keyPressEvent(QKeyEvent *event)
{
if (m_overlayMessages && event->key() == Qt::Key_Escape)
{
m_overlayMessages->close();
event->accept();
}
else
{
QFrame::keyPressEvent(event);
}
}
void COverlayMessagesFrame::resizeEvent(QResizeEvent *event)
{
QFrame::resizeEvent(event);
if (m_overlayMessages && m_overlayMessages->isVisible())
{
this->initInnerFrame();
}
}
QSize COverlayMessagesFrame::innerFrameSize() const
{
// check against minimum if widget is initialized, but not yet resized
const int w = std::max(this->width(), this->minimumWidth());
const int h = std::max(this->height(), this->minimumHeight());
int wInner = m_widthFactor * w;
int hInner = m_heightFactor * h;
if (wInner > this->maximumWidth()) { wInner = this->maximumWidth(); }
if (hInner > this->maximumHeight()) { hInner = this->maximumHeight(); }
return QSize(wInner, hInner);
}
void COverlayMessagesFrame::initInnerFrame()
{
const QSize inner(innerFrameSize());
if (!m_overlayMessages)
{
// lazy init
m_overlayMessages = new COverlayMessages(inner.width(), inner.height(), this);
m_overlayMessages->addShadow();
m_overlayMessages->showKillButton(m_showKillButton);
m_overlayMessages->setForceSmall(m_forceSmallMsgs);
}
Q_ASSERT(m_overlayMessages);
const QPoint middle = this->geometry().center();
const int w = inner.width();
const int h = inner.height();
const int x = middle.x() - w / 2;
const int y = middle.y() - h / m_middleFactor;
m_overlayMessages->setGeometry(x, y, w, h);
}
} // ns } // ns

View File

@@ -13,12 +13,16 @@
#define BLACKGUI_OVERLAYMESSAGES_FRAME_H #define BLACKGUI_OVERLAYMESSAGES_FRAME_H
#include "blackgui/blackguiexport.h" #include "blackgui/blackguiexport.h"
#include "blackgui/overlaymessages.h"
#include "blackgui/guiutility.h"
#include "blackmisc/pixmap.h" #include "blackmisc/pixmap.h"
#include "blackmisc/statusmessage.h" #include "blackmisc/statusmessage.h"
#include "blackmisc/statusmessagelist.h" #include "blackmisc/statusmessagelist.h"
#include "blackmisc/network/textmessage.h"
#include "blackmisc/variant.h" #include "blackmisc/variant.h"
#include <QFrame> #include <QFrame>
#include <QTabWidget>
#include <QMessageBox> #include <QMessageBox>
#include <QObject> #include <QObject>
#include <QSize> #include <QSize>
@@ -29,37 +33,53 @@ class QKeyEvent;
class QPaintEvent; class QPaintEvent;
class QWidget; class QWidget;
namespace BlackMisc { namespace Network { class CTextMessage; } }
namespace BlackGui namespace BlackGui
{ {
class COverlayMessages;
/*! /*!
* Display status messages (nested in this widget). * Base class to display overlay messages in different widgets
* Using this class provides a QFrame with the overlay functionality already integrated. * (nested in this widget).
* \fixme KB 2017-12 all header version, if someone manages to create a cpp version go ahead, I failed on gcc with "undefined reference to `BlackGui::COverlayMessagesBase<QFrame>::showOverlayMessages`"
*/ */
class BLACKGUI_EXPORT COverlayMessagesFrame : public QFrame template <class WIDGET> class COverlayMessagesBase : public WIDGET
{ {
Q_OBJECT
public: public:
//! Constructor
explicit COverlayMessagesFrame(QWidget *parent = nullptr);
//! Destructor //! Destructor
virtual ~COverlayMessagesFrame(); virtual ~COverlayMessagesBase()
{ }
//! Show the inner frame //! Show the inner frame
void showStatusMessagesFrame(); void showStatusMessagesFrame()
{
this->initInnerFrame();
}
//! Set the size factors //! Set the size factors
void setOverlaySizeFactors(double widthFactor, double heightFactor, double middleFactor); void setOverlaySizeFactors(double widthFactor, double heightFactor, double middleFactor = 2)
{
m_widthFactor = widthFactor;
m_heightFactor = heightFactor;
if (middleFactor >=0) { m_middleFactor = middleFactor; }
}
//! Show kill button //! \copydoc BlackGui::COverlayMessages::showKillButton
void showKillButton(bool killButton); void showKillButton(bool killButton)
{
m_showKillButton = killButton;
if (m_overlayMessages)
{
m_overlayMessages->showKillButton(killButton);
}
}
//! \copydoc COverlayMessages::setForceSmall //! \copydoc COverlayMessages::setForceSmall
void setForceSmall(bool force); void setForceSmall(bool force)
{
m_forceSmallMsgs = force;
if (m_overlayMessages)
{
m_overlayMessages->setForceSmall(force);
}
}
//! \copydoc COverlayMessages::showOverlayMessagesWithConfirmation //! \copydoc COverlayMessages::showOverlayMessagesWithConfirmation
void showOverlayMessagesWithConfirmation( void showOverlayMessagesWithConfirmation(
@@ -69,50 +89,172 @@ namespace BlackGui
std::function<void()> okLambda, std::function<void()> okLambda,
QMessageBox::StandardButton defaultButton = QMessageBox::Cancel, QMessageBox::StandardButton defaultButton = QMessageBox::Cancel,
int timeOutMs = -1 int timeOutMs = -1
); )
{
if (messages.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayMessagesWithConfirmation(messages, appendOldMessages, confirmationMessage, okLambda, defaultButton, timeOutMs);
WIDGET::repaint();
}
//! \copydoc COverlayMessages::clearOverlayMessages //! \copydoc COverlayMessages::clearOverlayMessages
void clearOverlayMessages(); void clearOverlayMessages()
{
if (!m_overlayMessages) { return; }
m_overlayMessages->clearOverlayMessages();
}
//! \copydoc COverlayMessages::close //! \copydoc COverlayMessages::close
void closeOverlay(); void closeOverlay()
{
if (!m_overlayMessages) { return; }
m_overlayMessages->close();
}
//! \copydoc COverlayMessages::showOverlayMessages //! \copydoc COverlayMessages::showOverlayMessages
void showOverlayMessages(const BlackMisc::CStatusMessageList &messages, bool appendOldMessages = false, int timeOutMs = -1); void showOverlayMessages(const BlackMisc::CStatusMessageList &messages, bool appendOldMessages = false, int timeOutMs = -1)
{
if (messages.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayMessages(messages, appendOldMessages, timeOutMs);
WIDGET::repaint();
}
//! \copydoc COverlayMessages::showOverlayMessage //! \copydoc COverlayMessages::showOverlayMessage
void showOverlayMessage(const BlackMisc::CStatusMessage &message, int timeOutMs = -1); void showOverlayMessage(const BlackMisc::CStatusMessage &message, int timeOutMs = -1)
{
if (message.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayMessage(message, timeOutMs);
WIDGET::repaint();
}
//! \copydoc COverlayMessages::showOverlayTextMessage //! \copydoc COverlayMessages::showOverlayTextMessage
void showOverlayTextMessage(const BlackMisc::Network::CTextMessage &textMessage, int timeOutMs = -1); void showOverlayTextMessage(const BlackMisc::Network::CTextMessage &textMessage, int timeOutMs = -1)
{
if (textMessage.isEmpty()) { return; }
this->initInnerFrame();
m_overlayMessages->showOverlayTextMessage(textMessage, timeOutMs);
WIDGET::repaint();
}
//! \copydoc COverlayMessages::showOverlayVariant //! \copydoc COverlayMessages::showOverlayVariant
void showOverlayVariant(const BlackMisc::CVariant &variant, int timeOutMs = -1); void showOverlayVariant(const BlackMisc::CVariant &variant, int timeOutMs = -1)
{
this->initInnerFrame();
m_overlayMessages->showOverlayVariant(variant, timeOutMs);
WIDGET::repaint();
}
//! \copydoc COverlayMessages::showOverlayImage //! \copydoc COverlayMessages::showOverlayImage
void showOverlayImage(const BlackMisc::CPixmap &pixmap, int timeOutMs = -1); void showOverlayImage(const BlackMisc::CPixmap &pixmap, int timeOutMs = -1)
{
this->initInnerFrame();
m_overlayMessages->showOverlayImage(pixmap, timeOutMs);
WIDGET::repaint();
}
protected: protected:
COverlayMessages *m_overlayMessages = nullptr; //!< embedded QFrame with status messages
//! Constructor
COverlayMessagesBase(QWidget *parent) : WIDGET(parent)
{
const bool isFrameless = CGuiUtility::isMainWindowFrameless();
m_middleFactor = isFrameless ? 1.25 : 1.5; // 2 is middle in normal window
}
//! Init the inner frame (if not yet initialized)
void initInnerFrame()
{
const QSize inner(innerFrameSize());
if (!m_overlayMessages)
{
// lazy init
m_overlayMessages = new COverlayMessages(inner.width(), inner.height(), this);
m_overlayMessages->addShadow();
m_overlayMessages->showKillButton(m_showKillButton);
m_overlayMessages->setForceSmall(m_forceSmallMsgs);
}
Q_ASSERT(m_overlayMessages);
const QPoint middle = WIDGET::geometry().center();
const int w = inner.width();
const int h = inner.height();
const int x = middle.x() - w / 2;
const int y = middle.y() - h / m_middleFactor;
m_overlayMessages->setGeometry(x, y, w, h);
}
//! \copydoc QFrame::keyPressEvent //! \copydoc QFrame::keyPressEvent
virtual void keyPressEvent(QKeyEvent *event) override; virtual void keyPressEvent(QKeyEvent *event) override
{
if (m_overlayMessages && event->key() == Qt::Key_Escape)
{
m_overlayMessages->close();
event->accept();
}
else
{
WIDGET::keyPressEvent(event);
}
}
//! \copydoc QFrame::resizeEvent //! \copydoc QFrame::resizeEvent
virtual void resizeEvent(QResizeEvent *event) override; virtual void resizeEvent(QResizeEvent *event) override
{
COverlayMessages *m_overlayMessages = nullptr; //!< embedded QFrame with Status messages WIDGET::resizeEvent(event);
if (m_overlayMessages && m_overlayMessages->isVisible())
{
this->initInnerFrame();
}
}
private: private:
//! Calculate inner frame size //! Calculate inner frame size
QSize innerFrameSize() const; QSize innerFrameSize() const
{
// check against minimum if widget is initialized, but not yet resized
const int w = std::max(WIDGET::width(), WIDGET::minimumWidth());
const int h = std::max(WIDGET::height(), WIDGET::minimumHeight());
//! Init the inner frame (if not yet initialized) int wInner = m_widthFactor * w;
void initInnerFrame(); int hInner = m_heightFactor * h;
if (wInner > WIDGET::maximumWidth()) { wInner = WIDGET::maximumWidth(); }
if (hInner > WIDGET::maximumHeight()) { hInner = WIDGET::maximumHeight(); }
return QSize(wInner, hInner);
}
bool m_showKillButton = false; //!< show kill button bool m_showKillButton = false; //!< show kill button
bool m_forceSmallMsgs = false; //!< force small messages bool m_forceSmallMsgs = false; //!< force small messages
double m_widthFactor = 0.7; //!< inner frame x factor double m_widthFactor = 0.7; //!< inner frame x factor
double m_heightFactor = 0.6; //!< inner frame x factor double m_heightFactor = 0.6; //!< inner frame x factor
double m_middleFactor = 2; //!< 2 means middle, 1 means on top double m_middleFactor = 2; //!< 2 means middle, 1 means on top
};
/*!
* Using this class provides a QFrame with the overlay functionality already integrated.
*/
class BLACKGUI_EXPORT COverlayMessagesFrame : public COverlayMessagesBase<QFrame>
{
Q_OBJECT
public:
//! Constructor
explicit COverlayMessagesFrame(QWidget *parent = nullptr);
};
/*!
* Using this class provides a QTabWidget with the overlay functionality already integrated.
*/
class BLACKGUI_EXPORT COverlayMessagesTabWidget : public COverlayMessagesBase<QTabWidget>
{
Q_OBJECT
public:
//! Constructor
explicit COverlayMessagesTabWidget(QWidget *parent = nullptr);
}; };
} // ns } // ns