refs #452 overlay messages (allows to display overlay messages in a widget)

* the overlay widget itself
* a QFrame derived class allowing to display such widgets as overlay
This commit is contained in:
Klaus Basan
2015-09-24 00:00:08 +02:00
committed by Mathew Sutcliffe
parent 2c91b3ada0
commit 61ace53989
5 changed files with 569 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackgui/overlaymessages.h"
#include "blackgui/stylesheetutility.h"
#include "ui_overlaymessages.h"
#include <QKeyEvent>
using namespace BlackGui::Models;
namespace BlackGui
{
COverlayMessages::COverlayMessages(int w, int h, QWidget *parent) :
QFrame(parent),
ui(new Ui::COverlayMessages)
{
this->init(w, h);
}
COverlayMessages::COverlayMessages(const QString &headerText, int w, int h, QWidget *parent) :
QFrame(parent),
ui(new Ui::COverlayMessages),
m_header(headerText)
{
this->init(w, h);
}
void COverlayMessages::init(int w, int h)
{
ui->setupUi(this);
resize(w, h);
this->setAutoFillBackground(true);
this->ui->tvp_StatusMessages->setMode(CStatusMessageListModel::Simplified);
connect(this->ui->tb_Close, &QToolButton::released, this, &COverlayMessages::close);
m_autoCloseTimer.setObjectName(objectName() + ":autoCloseTimer");
connect(&m_autoCloseTimer, &QTimer::timeout, this, &COverlayMessages::close);
}
void COverlayMessages::setHeader(const QString &header)
{
if (m_header.isEmpty())
{
ui->lbl_Header->setText(header);
}
else
{
ui->lbl_Header->setText(m_header);
}
}
COverlayMessages::~COverlayMessages()
{}
void COverlayMessages::showMessages(const BlackMisc::CStatusMessageList &messages, int timeOutMs)
{
if (messages.isEmpty()) { return; }
this->setModeToMessages();
this->ui->tvp_StatusMessages->updateContainer(messages);
this->display(timeOutMs);
}
void COverlayMessages::showMessage(const BlackMisc::CStatusMessage &message, int timeOutMs)
{
if (message.isEmpty()) { return; }
this->setModeToMessage();
this->ui->form_StatusMessage->setValue(message);
this->display(timeOutMs);
}
void COverlayMessages::setModeToMessages()
{
this->ui->sw_StatusMessagesComponent->setCurrentWidget(this->ui->pg_StatusMessages);
this->setHeader("Messages");
}
void COverlayMessages::setModeToMessage()
{
this->ui->sw_StatusMessagesComponent->setCurrentWidget(this->ui->pg_StatusMessage);
this->setHeader("Message");
}
void COverlayMessages::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape)
{
this->close();
event->setAccepted(true);
}
}
void COverlayMessages::close()
{
this->hide();
this->setEnabled(false);
}
void COverlayMessages::display(int timeOutMs)
{
this->show();
this->setEnabled(true);
if (timeOutMs > 250)
{
m_autoCloseTimer.start(timeOutMs);
}
else
{
m_autoCloseTimer.stop();
}
}
void BlackGui::COverlayMessages::paintEvent(QPaintEvent *event)
{
bool s = CStyleSheetUtility::useStyleSheetInDerivedWidget(this, QStyle::PE_Widget);
if (s) { return; }
QFrame::paintEvent(event);
}
} // ns

View File

@@ -0,0 +1,84 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKGUI_OVERLAYMESSAGES_H
#define BLACKGUI_OVERLAYMESSAGES_H
#include "blackmisc/statusmessagelist.h"
#include <QFrame>
#include <QScopedPointer>
#include <QTimer>
namespace Ui { class COverlayMessages; }
namespace BlackGui
{
/*!
* Display status messages (nested in another widget)
*/
class COverlayMessages : public QFrame
{
Q_OBJECT
public:
//! Constructor
explicit COverlayMessages(int w, int h, QWidget *parent);
//! Constructor
explicit COverlayMessages(const QString &headerText, int w, int h, QWidget *parent);
//! Destructor
~COverlayMessages();
//! Show multiple messages
void showMessages(const BlackMisc::CStatusMessageList &messages, int timeOutMs = -1);
//! Show single message
void showMessage(const BlackMisc::CStatusMessage &message, int timeOutMs = -1);
//! Messages mode
void setModeToMessages();
//! Single Message mode
void setModeToMessage();
//! Set header text
void setHeaderText(const QString &header);
public slots:
//! Close button clicked
void close();
protected:
//! Show message
void display(int timeOutMs = -1);
//! \copydoc QFrame::keyPressEvent
virtual void keyPressEvent(QKeyEvent *event) override;
//! \copydoc QFrame::paintEvent
virtual void paintEvent(QPaintEvent *event) override;
private:
QScopedPointer<Ui::COverlayMessages> ui;
QString m_header;
QTimer m_autoCloseTimer { this };
//! Init widget
void init(int w, int h);
//! Set header text
void setHeader(const QString &header);
};
} // ns
#endif // guard

View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>COverlayMessages</class>
<widget class="QFrame" name="COverlayMessages">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="vl_StatusMessages">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QFrame" name="fr_StatusMessagesComponentsInner">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="vl_StatusMessagesComponentInner">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="fr_Header">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="hl_Header">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="lbl_Header">
<property name="text">
<string>Status messages</string>
</property>
</widget>
</item>
<item>
<spacer name="hs_Header">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>309</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="tb_Close">
<property name="text">
<string>PushButton</string>
</property>
<property name="icon">
<iconset resource="../blackmisc/blackmisc.qrc">
<normaloff>:/diagona/icons/diagona/icons/cross-button.png</normaloff>:/diagona/icons/diagona/icons/cross-button.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="sw_StatusMessagesComponent">
<widget class="QWidget" name="pg_StatusMessages">
<layout class="QVBoxLayout" name="vl_PgStatusMessages">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="BlackGui::Views::CStatusMessageView" name="tvp_StatusMessages">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="pg_StatusMessage">
<layout class="QVBoxLayout" name="vl_PgStatusMessage">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="BlackGui::CStatusMessageForm" name="form_StatusMessage">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BlackGui::Views::CStatusMessageView</class>
<extends>QTableView</extends>
<header>blackgui/views/statusmessageview.h</header>
</customwidget>
<customwidget>
<class>BlackGui::CStatusMessageForm</class>
<extends>QFrame</extends>
<header>blackgui/statusmessageform.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../blackmisc/blackmisc.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,95 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackgui/overlaymessagesframe.h"
#include "blackgui/stylesheetutility.h"
#include <QPainter>
#include <QKeyEvent>
namespace BlackGui
{
COverlayMessagesFrame::COverlayMessagesFrame(QWidget *parent) :
QFrame(parent)
{ }
COverlayMessagesFrame::~COverlayMessagesFrame()
{}
void COverlayMessagesFrame::showStatusMessagesFrame()
{
this->initInnerFrame();
}
void COverlayMessagesFrame::hideStatusMessagesFrame()
{
if (!m_statusMessages) { return; }
}
void COverlayMessagesFrame::showMessages(const BlackMisc::CStatusMessageList &messages)
{
if (messages.isEmpty()) { return; }
this->initInnerFrame();
this->m_statusMessages->showMessages(messages);
this->repaint();
}
void COverlayMessagesFrame::showMessage(const BlackMisc::CStatusMessage &message)
{
if (message.isEmpty()) { return; }
this->initInnerFrame();
this->m_statusMessages->showMessage(message);
this->repaint();
}
void COverlayMessagesFrame::paintEvent(QPaintEvent *event)
{
bool s = CStyleSheetUtility::useStyleSheetInDerivedWidget(this, QStyle::PE_Widget);
if (s) { return; }
QFrame::paintEvent(event);
}
void COverlayMessagesFrame::keyPressEvent(QKeyEvent *event)
{
if (!m_statusMessages) { QFrame::keyPressEvent(event); }
if (event->key() == Qt::Key_Escape)
{
m_statusMessages->close();
event->setAccepted(true);
}
else
{
QFrame::keyPressEvent(event);
}
}
QSize COverlayMessagesFrame::innerFrameSize() const
{
int w = this->width();
int h = this->height();
int wInner = 0.7 * w;
int hInner = 0.7 * h;
return QSize(wInner, hInner);
}
void COverlayMessagesFrame::initInnerFrame()
{
QSize inner(innerFrameSize());
if (!this->m_statusMessages)
{
this->m_statusMessages = new COverlayMessages(inner.width(), inner.height(), this);
}
QPoint middle = this->geometry().center();
int w = inner.width();
int h = inner.height();
int x = middle.x() - w / 2;
int y = middle.y() - h / 2;
this->m_statusMessages->setGeometry(x, y, w, h);
}
} // ns

View File

@@ -0,0 +1,65 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKGUI_OVERLAYMESSAGES_FRAME_H
#define BLACKGUI_OVERLAYMESSAGES_FRAME_H
#include "blackgui/overlaymessages.h"
#include <QFrame>
namespace BlackGui
{
/*!
* Display status messages (nested in another widget)
*/
class COverlayMessagesFrame : public QFrame
{
Q_OBJECT
public:
//! Constructor
explicit COverlayMessagesFrame(QWidget *parent = nullptr);
//! Destructor
~COverlayMessagesFrame();
//! Show the inner frame
void showStatusMessagesFrame();
//! Hide the inner frame
void hideStatusMessagesFrame();
//! Show multiple messages
void showMessages(const BlackMisc::CStatusMessageList &messages);
//! Show single message
void showMessage(const BlackMisc::CStatusMessage &message);
protected:
//! \copydoc QFrame::paintEvent
virtual void paintEvent(QPaintEvent *event) override;
//! \copydoc QFrame::keyPressEvent
virtual void keyPressEvent(QKeyEvent *event) override;
COverlayMessages *m_statusMessages = nullptr; //!< embedded QFrame with Status messages
private:
//! Calculate inner frame size
QSize innerFrameSize() const;
//! Init the inner frame (if not yet initialized)
void initInnerFrame();
};
} // ns
#endif // guard