Minimize to tray

This commit is contained in:
Konstantinos Sideris 2017-05-21 16:36:06 +03:00
parent c480f8f4bc
commit a45582585d
9 changed files with 203 additions and 1 deletions

View File

@ -100,6 +100,7 @@ set(SRC_FILES
src/Splitter.cc
src/Sync.cc
src/TextInputWidget.cc
src/TrayIcon.cc
src/TopRoomBar.cc
src/UserInfoWidget.cc
src/WelcomePage.cc
@ -171,6 +172,7 @@ qt5_wrap_cpp(MOC_HEADERS
include/UserInfoWidget.h
include/SlidingStackWidget.h
include/TopRoomBar.h
include/TrayIcon.h
include/TextInputWidget.h
include/WelcomePage.h

View File

@ -44,6 +44,7 @@ public:
signals:
void close();
void changeWindowTitle(const QString &msg);
void unreadMessages(int count);
private slots:
void showUnreadMessageNotification(int count);

View File

@ -27,6 +27,7 @@
#include "OverlayModal.h"
#include "RegisterPage.h"
#include "SlidingStackWidget.h"
#include "TrayIcon.h"
#include "WelcomePage.h"
class MainWindow : public QMainWindow
@ -37,7 +38,13 @@ public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void closeEvent(QCloseEvent *event);
private slots:
// Handle interaction with the tray icon.
void iconActivated(QSystemTrayIcon::ActivationReason reason);
// Show the welcome page in the main window.
void showWelcomePage();
@ -74,4 +81,7 @@ private:
// Matrix Client API provider.
QSharedPointer<MatrixClient> client_;
// Tray icon that shows the unread message count.
TrayIcon *trayIcon_;
};

58
include/TrayIcon.h Normal file
View File

@ -0,0 +1,58 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QAction>
#include <QIcon>
#include <QIconEngine>
#include <QMenu>
#include <QPainter>
#include <QRect>
#include <QSystemTrayIcon>
class MsgCountComposedIcon : public QIconEngine
{
public:
MsgCountComposedIcon(const QString &filename);
virtual void paint(QPainter *p, const QRect &rect, QIcon::Mode mode, QIcon::State state);
virtual QIconEngine *clone() const;
int msgCount = 0;
private:
const int BubbleDiameter = 15;
QIcon icon_;
};
class TrayIcon : public QSystemTrayIcon
{
Q_OBJECT
public:
TrayIcon(const QString &filename, QWidget *parent);
public slots:
void setUnreadCount(int count);
private:
QAction *viewAction_;
QAction *quitAction_;
MsgCountComposedIcon *icon_;
};

View File

@ -311,6 +311,8 @@ void ChatPage::changeTopRoomInfo(const QString &room_id)
void ChatPage::showUnreadMessageNotification(int count)
{
emit unreadMessages(count);
// TODO: Make the default title a const.
if (count == 0)
emit changeWindowTitle("nheko");

View File

@ -26,6 +26,8 @@ LoginPage::LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent)
, login_settings_{nullptr}
, client_{client}
{
setStyleSheet("background-color: #f9f9f9");
top_layout_ = new QVBoxLayout();
top_bar_layout_ = new QHBoxLayout();

View File

@ -20,6 +20,7 @@
#include <QLayout>
#include <QNetworkReply>
#include <QSettings>
#include <QSystemTrayIcon>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
@ -29,16 +30,18 @@ MainWindow::MainWindow(QWidget *parent)
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
setSizePolicy(sizePolicy);
setWindowTitle("nheko");
setObjectName("MainWindow");
setStyleSheet("QWidget#MainWindow {background-color: #f9f9f9}");
resize(1066, 600); // 16:9 ratio
setMinimumSize(QSize(950, 600));
setStyleSheet("background-color: #f9f9f9");
QFont font("Open Sans", 12);
font.setStyleStrategy(QFont::PreferAntialias);
setFont(font);
client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org"));
trayIcon_ = new TrayIcon(":/logos/nheko-32.png", this);
welcome_page_ = new WelcomePage(this);
login_page_ = new LoginPage(client_, this);
@ -62,6 +65,12 @@ MainWindow::MainWindow(QWidget *parent)
connect(chat_page_, SIGNAL(close()), this, SLOT(showWelcomePage()));
connect(chat_page_, SIGNAL(changeWindowTitle(QString)), this, SLOT(setWindowTitle(QString)));
connect(chat_page_, SIGNAL(unreadMessages(int)), trayIcon_, SLOT(setUnreadCount(int)));
connect(trayIcon_,
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this,
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
connect(client_.data(),
SIGNAL(initialSyncCompleted(const SyncResponse &)),
@ -159,6 +168,29 @@ void MainWindow::showRegisterPage()
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::RIGHT_TO_LEFT);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (isVisible()) {
event->ignore();
hide();
}
}
void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
switch (reason) {
case QSystemTrayIcon::Trigger:
if (!isVisible()) {
show();
} else {
hide();
}
break;
default:
break;
}
}
MainWindow::~MainWindow()
{
}

View File

@ -25,6 +25,8 @@ RegisterPage::RegisterPage(QSharedPointer<MatrixClient> client, QWidget *parent)
: QWidget(parent)
, client_(client)
{
setStyleSheet("background-color: #f9f9f9");
top_layout_ = new QVBoxLayout();
back_layout_ = new QHBoxLayout();

93
src/TrayIcon.cc Normal file
View File

@ -0,0 +1,93 @@
/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QTimer>
#include "TrayIcon.h"
MsgCountComposedIcon::MsgCountComposedIcon(const QString &filename)
: QIconEngine()
{
icon_ = QIcon(filename);
}
void MsgCountComposedIcon::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state)
{
icon_.paint(painter, rect, Qt::AlignCenter, mode, state);
if (msgCount <= 0)
return;
QColor backgroundColor("red");
QColor textColor("white");
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(backgroundColor);
painter->setBrush(brush);
painter->setPen(Qt::NoPen);
painter->setFont(QFont("Open Sans", 7, QFont::Black));
QRectF bubble(rect.width() - BubbleDiameter,
rect.height() - BubbleDiameter,
BubbleDiameter,
BubbleDiameter);
painter->drawEllipse(bubble);
painter->setPen(QPen(textColor));
painter->setBrush(Qt::NoBrush);
painter->drawText(bubble, Qt::AlignCenter, QString::number(msgCount));
}
QIconEngine *MsgCountComposedIcon::clone() const
{
return new MsgCountComposedIcon(*this);
}
TrayIcon::TrayIcon(const QString &filename, QWidget *parent)
: QSystemTrayIcon(parent)
{
icon_ = new MsgCountComposedIcon(filename);
setIcon(QIcon(icon_));
QMenu *menu = new QMenu(parent);
viewAction_ = new QAction("Show", parent);
quitAction_ = new QAction("Quit", parent);
connect(viewAction_, SIGNAL(triggered()), parent, SLOT(show()));
connect(quitAction_, SIGNAL(triggered()), parent, SLOT(close()));
menu->addAction(viewAction_);
menu->addAction(quitAction_);
setContextMenu(menu);
// We wait a little for the icon to load.
QTimer::singleShot(500, this, [=]() {
show();
});
}
void TrayIcon::setUnreadCount(int count)
{
MsgCountComposedIcon *tmp = static_cast<MsgCountComposedIcon *>(icon_->clone());
tmp->msgCount = count;
setIcon(QIcon(tmp));
icon_ = tmp;
}