blob: 03a2a64e1aa68e6944c350166d3211a7e1baf38a [file] [log] [blame]
Isa Nanic601de1d2018-10-23 11:37:26 -04001/***************************************************************************
Sébastien Blin68abac92019-01-02 17:41:31 -05002 * Copyright (C) 2019-2019 by Savoir-faire Linux *
Isa Nanic601de1d2018-10-23 11:37:26 -04003 * Author: Isa Nanic <isa.nanic@savoirfairelinux.com> *
4 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 **************************************************************************/
19
20#include "currentaccountcombobox.h"
Isa Nanic601de1d2018-10-23 11:37:26 -040021
Andreas Traczyk46508b52019-01-04 11:49:24 -050022#include <QPixmap>
23#include <QMouseEvent>
24
25#include "accountitemdelegate.h"
26#include "pixbufmanipulator.h"
Isa Nanic601de1d2018-10-23 11:37:26 -040027#include "utils.h"
28#include "ringthemeutils.h"
29#include "lrcinstance.h"
Andreas Traczyk46508b52019-01-04 11:49:24 -050030#include "mainwindow.h"
Isa Nanic601de1d2018-10-23 11:37:26 -040031
32#undef REGISTERED
33
Isa Nanic601de1d2018-10-23 11:37:26 -040034CurrentAccountComboBox::CurrentAccountComboBox(QWidget* parent)
35{
36 Q_UNUSED(parent);
37
Isa Nanic37ccc1c2018-10-26 14:16:28 -040038 setMouseTracking(true);
39 gearLabel_.setMouseTracking(true);
40
Isa Nanic1c20ef12018-10-25 11:49:30 -040041 accountListUpdate();
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050042 accountItemDelegate_ = new AccountItemDelegate(this);
Isa Nanic601de1d2018-10-23 11:37:26 -040043 this->setItemDelegate(accountItemDelegate_);
44
45 // combobox index changed and so must the avatar
46 connect(this, QOverload<int>::of(&QComboBox::currentIndexChanged),
47 [=](const int& index) {
Isa Nanic1c20ef12018-10-25 11:49:30 -040048 setCurrentIndex(index);
Isa Nanic601de1d2018-10-23 11:37:26 -040049 });
50
51 // account added to combobox
52 connect(&LRCInstance::accountModel(),
53 &lrc::api::NewAccountModel::accountAdded,
54 [this](const std::string& accountId) {
55 auto accountList = LRCInstance::accountModel().getAccountList();
56 auto it = std::find(accountList.begin(), accountList.end(), accountId);
57 if (it != accountList.end()) {
58 this->setCurrentIndex(std::distance(accountList.begin(), it));
59 }
60 });
Isa Nanic37ccc1c2018-10-26 14:16:28 -040061
Isa Nanic6e4a39a2018-12-04 14:26:02 -050062 gearLabel_.setPixmap(QPixmap(":/images/icons/round-settings-24px.svg"));
Isa Nanic37ccc1c2018-10-26 14:16:28 -040063 gearLabel_.setParent(this);
64 gearLabel_.setStyleSheet("background: transparent;");
Andreas Traczyk43c08232018-10-31 13:42:09 -040065 setupSettingsButton();
Isa Nanic601de1d2018-10-23 11:37:26 -040066}
67
68CurrentAccountComboBox::~CurrentAccountComboBox()
69{
70 delete accountItemDelegate_;
71}
72
73void
74CurrentAccountComboBox::paintEvent(QPaintEvent* e)
75{
76 Q_UNUSED(e);
77
Andreas Traczykdc17c812019-01-11 15:35:20 -050078 QPoint avatarTopLeft(16, 6);
Isa Nanic601de1d2018-10-23 11:37:26 -040079 QPainter painter(this);
Isa Nanic1c20ef12018-10-25 11:49:30 -040080 painter.setRenderHints((QPainter::Antialiasing | QPainter::TextAntialiasing), true);
Isa Nanic601de1d2018-10-23 11:37:26 -040081
82 QStyleOption opt;
83 opt.init(this);
Andreas Traczyk43c08232018-10-31 13:42:09 -040084 style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter);
Isa Nanic601de1d2018-10-23 11:37:26 -040085
Isa Nanic601de1d2018-10-23 11:37:26 -040086 // define and set the two fonts
87 QFont fontPrimary = painter.font();
88 QFont fontSecondary = painter.font();
Isa Nanic601de1d2018-10-23 11:37:26 -040089 fontPrimary.setWeight(QFont::ExtraLight);
Andreas Traczyk46508b52019-01-04 11:49:24 -050090 auto scalingRatio = MainWindow::instance().getCurrentScalingRatio();
91 if (scalingRatio > 1.0) {
92 fontPrimary.setPointSize(10);
93 fontSecondary.setPointSize(9);
94 } else {
95 fontPrimary.setPointSize(11);
96 fontSecondary.setPointSize(10);
97 }
Isa Nanic601de1d2018-10-23 11:37:26 -040098
99 QFontMetrics fontMetricPrimary(fontPrimary);
100 QFontMetrics fontMetricSecondary(fontSecondary);
101
Andreas Traczyk29650142019-01-03 20:33:56 -0500102 painter.drawPixmap(avatarTopLeft, currentAccountAvatarImage_);
Isa Nanic601de1d2018-10-23 11:37:26 -0400103
104 // fill in presence indicator if account is registered
105 auto accountStatus = LRCInstance::getCurrentAccountInfo().status;
106 if (accountStatus == lrc::api::account::Status::REGISTERED) {
107 // paint the presence indicator circle
108 QPainterPath outerCircle, innerCircle;
Andreas Traczyk29650142019-01-03 20:33:56 -0500109 QPointF presenceCenter(40.0 + avatarTopLeft.x(), 40.0);
Isa Nanic601de1d2018-10-23 11:37:26 -0400110 qreal outerCircleRadius = cellHeight_/6.5;
Andreas Traczyk1c1302c2018-12-31 12:28:16 -0500111 qreal innerCircleRadius = outerCircleRadius * 0.75;
Isa Nanic601de1d2018-10-23 11:37:26 -0400112 outerCircle.addEllipse(presenceCenter, outerCircleRadius, outerCircleRadius);
113 innerCircle.addEllipse(presenceCenter, innerCircleRadius, innerCircleRadius);
114 painter.fillPath(outerCircle, Qt::white);
115 painter.fillPath(innerCircle, RingTheme::presenceGreen_);
116 }
117
Andreas Traczyk29650142019-01-03 20:33:56 -0500118 QRect comboBoxRect(
119 cellHeight_ + avatarTopLeft.x() + 10 + 2,
120 6,
121 this->width() - cellHeight_,
122 cellHeight_ - 10); // [screen awareness]
123
Isa Nanic601de1d2018-10-23 11:37:26 -0400124 // write primary and secondary account identifiers to combobox label
Isa Nanic601de1d2018-10-23 11:37:26 -0400125 QString primaryAccountID = QString::fromStdString(Utils::bestNameForAccount(LRCInstance::getCurrentAccountInfo()));
Andreas Traczyk29650142019-01-03 20:33:56 -0500126 painter.setFont(fontPrimary);
127 painter.setPen(RingTheme::lightBlack_);
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400128 primaryAccountID = fontMetricPrimary.elidedText(primaryAccountID, Qt::ElideRight,
129 comboBoxRect.width() - elidConst - (popupPresent ? 0 : 2 * gearSize_));
Isa Nanic601de1d2018-10-23 11:37:26 -0400130 painter.drawText(comboBoxRect, Qt::AlignLeft, primaryAccountID);
131
132 QString secondaryAccountID = QString::fromStdString(Utils::secondBestNameForAccount(LRCInstance::getCurrentAccountInfo()));
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400133 secondaryAccountID = fontMetricSecondary.elidedText(secondaryAccountID, Qt::ElideRight,
134 comboBoxRect.width() - elidConst - 2 - (popupPresent ? 0 : 2 * gearSize_)); // [screen awareness]
Isa Nanic601de1d2018-10-23 11:37:26 -0400135
136 if (secondaryAccountID.length()) { // if secondary accound id exists
137 painter.setFont(fontSecondary);
138 painter.setPen(Qt::lightGray);
139 painter.drawText(comboBoxRect, (Qt::AlignBottom | Qt::AlignLeft), secondaryAccountID);
140 }
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500141
142 if (QWidget* popupWidget = this->findChild<QFrame*>()) {
Andreas Traczyk2771e2e2019-01-08 17:44:33 -0500143 popupWidget->setStyleSheet("QFrame{border: 0px;border-bottom: 1px solid #f0f0f0;border-right: 1px solid #f0f0f0; }");
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500144 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400145}
Isa Nanic601de1d2018-10-23 11:37:26 -0400146
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500147void CurrentAccountComboBox::resizeEvent(QResizeEvent* event)
Andreas Traczyk43c08232018-10-31 13:42:09 -0400148{
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500149 Q_UNUSED(event);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400150 setupSettingsButton();
151}
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400152
Andreas Traczyk43c08232018-10-31 13:42:09 -0400153void
154CurrentAccountComboBox::setupSettingsButton()
155{
Andreas Traczyk59ba48a2019-01-04 16:12:03 -0500156 gearPoint_.setX(this->width() - gearSize_ - 5 * gearBorder_ - 1);
Andreas Traczykdc17c812019-01-11 15:35:20 -0500157 gearPoint_.setY(this->height() / 2 - gearLabel_.height() / 2 - 2 * gearBorder_ + 8);
Andreas Traczyk59ba48a2019-01-04 16:12:03 -0500158 gearLabel_.setGeometry(
159 gearPoint_.x(), gearPoint_.y(),
160 gearSize_ + 2 * gearBorder_,
161 gearSize_ + 2 * gearBorder_);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400162 gearLabel_.setMargin(gearBorder_);
Isa Nanic601de1d2018-10-23 11:37:26 -0400163}
164
165// import account background account pixmap and scale pixmap to fit in label
166void
Isa Nanic1c20ef12018-10-25 11:49:30 -0400167CurrentAccountComboBox::importLabelPhoto(int index)
Isa Nanic601de1d2018-10-23 11:37:26 -0400168{
Isa Nanic1c20ef12018-10-25 11:49:30 -0400169 currentAccountAvatarImage_ = accountListModel_->data(accountListModel_->index(index, 0), // [efficiency improvement]
Isa Nanic601de1d2018-10-23 11:37:26 -0400170 AccountListModel::Role::Picture).value<QPixmap>().scaledToHeight(cellHeight_ - 4, Qt::SmoothTransformation);
Isa Nanic1c20ef12018-10-25 11:49:30 -0400171}
172
173void
174CurrentAccountComboBox::setCurrentIndex(int index)
175{
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500176 auto accountListSize = LRCInstance::accountModel().getAccountList().size();
177 if (index == accountListSize) {
178 emit newAccountClicked();
179 } else if (index < accountListSize) {
180 importLabelPhoto(index);
181 QComboBox::setCurrentIndex(index);
182 }
Isa Nanic1c20ef12018-10-25 11:49:30 -0400183}
184
185void
186CurrentAccountComboBox::accountListUpdate()
187{
188 accountListModel_.reset(new AccountListModel());
189 this->setModel(accountListModel_.get());
190}
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400191
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400192// if gearLabel is clicked
193void
194CurrentAccountComboBox::mousePressEvent(QMouseEvent* mouseEvent)
195{
196 if (!gearLabel_.frameGeometry().contains(mouseEvent->localPos().toPoint())) {
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500197 QComboBox::mousePressEvent(mouseEvent);
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400198 } else {
199 emit settingsButtonClicked();
200 }
201}
202
203// if gear label is hovered over
204void
205CurrentAccountComboBox::mouseMoveEvent(QMouseEvent* mouseEvent)
206{
207 if (gearLabel_.frameGeometry().contains(mouseEvent->x(), mouseEvent->y())) {
208 QComboBox::mouseMoveEvent(mouseEvent);
209 gearLabel_.setStyleSheet("background: rgb(237, 237, 237); border-width: 0px; border-radius: 8px;");
210 return;
211 }
212
213 gearLabel_.setStyleSheet("background: transparent;");
214}
215
216void
217CurrentAccountComboBox::showPopup()
218{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400219 gearLabel_.hide();
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400220 popupPresent = true;
221 QComboBox::showPopup();
222}
223
224void
225CurrentAccountComboBox::hidePopup()
226{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400227 gearLabel_.show();
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400228 popupPresent = false;
229 QComboBox::hidePopup();
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400230}
231
232void
233CurrentAccountComboBox::leaveEvent(QEvent* event)
234{
235 gearLabel_.setStyleSheet("background: transparent;");
236 QComboBox::leaveEvent(event);
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500237}
238
239void
240CurrentAccountComboBox::updateComboBoxDisplay()
241{
Andreas Traczyk10523bf2018-12-31 16:49:03 -0500242 auto currAccIndex = LRCInstance::getCurrentAccountIndex();
243 if (currAccIndex != currentIndex())
244 setCurrentIndex(currAccIndex);
245 importLabelPhoto(currAccIndex);
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500246}