mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Minimize to tray
This commit is contained in:
parent
c480f8f4bc
commit
a45582585d
9 changed files with 203 additions and 1 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
signals:
|
||||
void close();
|
||||
void changeWindowTitle(const QString &msg);
|
||||
void unreadMessages(int count);
|
||||
|
||||
private slots:
|
||||
void showUnreadMessageNotification(int count);
|
||||
|
|
|
@ -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
58
include/TrayIcon.h
Normal 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_;
|
||||
};
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
93
src/TrayIcon.cc
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue