blob: e807d0bf356dca2b70bc2db0bb8387630292aa8e [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 Nanic6e4a39a2018-12-04 14:26:02 -050061 gearLabel_.setPixmap(QPixmap(":/images/icons/round-settings-24px.svg"));
Isa Nanic37ccc1c2018-10-26 14:16:28 -040062 gearLabel_.setParent(this);
63 gearLabel_.setStyleSheet("background: transparent;");
Andreas Traczyk43c08232018-10-31 13:42:09 -040064 setupSettingsButton();
Isa Nanic601de1d2018-10-23 11:37:26 -040065}
66
67CurrentAccountComboBox::~CurrentAccountComboBox()
68{
69 delete accountItemDelegate_;
70}
71
72void
73CurrentAccountComboBox::paintEvent(QPaintEvent* e)
74{
75 Q_UNUSED(e);
76
Andreas Traczykdc2703e2019-01-17 18:02:31 -050077 QPoint avatarTopLeft(16, 8);
Isa Nanic601de1d2018-10-23 11:37:26 -040078 QPainter painter(this);
Isa Nanic1c20ef12018-10-25 11:49:30 -040079 painter.setRenderHints((QPainter::Antialiasing | QPainter::TextAntialiasing), true);
Isa Nanic601de1d2018-10-23 11:37:26 -040080
81 QStyleOption opt;
82 opt.init(this);
Andreas Traczyk43c08232018-10-31 13:42:09 -040083 style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter);
Isa Nanic601de1d2018-10-23 11:37:26 -040084
Isa Nanic601de1d2018-10-23 11:37:26 -040085 // define and set the two fonts
86 QFont fontPrimary = painter.font();
87 QFont fontSecondary = painter.font();
Isa Nanic601de1d2018-10-23 11:37:26 -040088 fontPrimary.setWeight(QFont::ExtraLight);
Andreas Traczyk46508b52019-01-04 11:49:24 -050089 auto scalingRatio = MainWindow::instance().getCurrentScalingRatio();
90 if (scalingRatio > 1.0) {
91 fontPrimary.setPointSize(10);
92 fontSecondary.setPointSize(9);
93 } else {
94 fontPrimary.setPointSize(11);
95 fontSecondary.setPointSize(10);
96 }
Isa Nanic601de1d2018-10-23 11:37:26 -040097
98 QFontMetrics fontMetricPrimary(fontPrimary);
99 QFontMetrics fontMetricSecondary(fontSecondary);
100
Andreas Traczyk29650142019-01-03 20:33:56 -0500101 painter.drawPixmap(avatarTopLeft, currentAccountAvatarImage_);
Isa Nanic601de1d2018-10-23 11:37:26 -0400102
103 // fill in presence indicator if account is registered
104 auto accountStatus = LRCInstance::getCurrentAccountInfo().status;
105 if (accountStatus == lrc::api::account::Status::REGISTERED) {
106 // paint the presence indicator circle
107 QPainterPath outerCircle, innerCircle;
Andreas Traczykdc2703e2019-01-17 18:02:31 -0500108 QPointF presenceCenter(avatarSize_ + avatarTopLeft.x() - 9, avatarSize_ - 3);
109 qreal outerCircleRadius = avatarSize_ / 6;
Andreas Traczyk1c1302c2018-12-31 12:28:16 -0500110 qreal innerCircleRadius = outerCircleRadius * 0.75;
Isa Nanic601de1d2018-10-23 11:37:26 -0400111 outerCircle.addEllipse(presenceCenter, outerCircleRadius, outerCircleRadius);
112 innerCircle.addEllipse(presenceCenter, innerCircleRadius, innerCircleRadius);
113 painter.fillPath(outerCircle, Qt::white);
114 painter.fillPath(innerCircle, RingTheme::presenceGreen_);
115 }
116
Andreas Traczyk29650142019-01-03 20:33:56 -0500117 QRect comboBoxRect(
Andreas Traczykdc2703e2019-01-17 18:02:31 -0500118 avatarSize_ + avatarTopLeft.x() + 10 + 2,
119 8,
120 this->width() - avatarSize_,
121 avatarSize_ - 10); // [screen awareness]
Andreas Traczyk29650142019-01-03 20:33:56 -0500122
Isa Nanic601de1d2018-10-23 11:37:26 -0400123 // write primary and secondary account identifiers to combobox label
Isa Nanic601de1d2018-10-23 11:37:26 -0400124 QString primaryAccountID = QString::fromStdString(Utils::bestNameForAccount(LRCInstance::getCurrentAccountInfo()));
Andreas Traczyk29650142019-01-03 20:33:56 -0500125 painter.setFont(fontPrimary);
126 painter.setPen(RingTheme::lightBlack_);
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400127 primaryAccountID = fontMetricPrimary.elidedText(primaryAccountID, Qt::ElideRight,
128 comboBoxRect.width() - elidConst - (popupPresent ? 0 : 2 * gearSize_));
Isa Nanic601de1d2018-10-23 11:37:26 -0400129 painter.drawText(comboBoxRect, Qt::AlignLeft, primaryAccountID);
130
131 QString secondaryAccountID = QString::fromStdString(Utils::secondBestNameForAccount(LRCInstance::getCurrentAccountInfo()));
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400132 secondaryAccountID = fontMetricSecondary.elidedText(secondaryAccountID, Qt::ElideRight,
133 comboBoxRect.width() - elidConst - 2 - (popupPresent ? 0 : 2 * gearSize_)); // [screen awareness]
Isa Nanic601de1d2018-10-23 11:37:26 -0400134
135 if (secondaryAccountID.length()) { // if secondary accound id exists
136 painter.setFont(fontSecondary);
137 painter.setPen(Qt::lightGray);
138 painter.drawText(comboBoxRect, (Qt::AlignBottom | Qt::AlignLeft), secondaryAccountID);
139 }
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500140
141 if (QWidget* popupWidget = this->findChild<QFrame*>()) {
Andreas Traczyk2771e2e2019-01-08 17:44:33 -0500142 popupWidget->setStyleSheet("QFrame{border: 0px;border-bottom: 1px solid #f0f0f0;border-right: 1px solid #f0f0f0; }");
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500143 }
Andreas Traczyk43c08232018-10-31 13:42:09 -0400144}
Isa Nanic601de1d2018-10-23 11:37:26 -0400145
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500146void CurrentAccountComboBox::resizeEvent(QResizeEvent* event)
Andreas Traczyk43c08232018-10-31 13:42:09 -0400147{
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500148 Q_UNUSED(event);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400149 setupSettingsButton();
150}
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400151
Andreas Traczyk43c08232018-10-31 13:42:09 -0400152void
153CurrentAccountComboBox::setupSettingsButton()
154{
Andreas Traczyk59ba48a2019-01-04 16:12:03 -0500155 gearPoint_.setX(this->width() - gearSize_ - 5 * gearBorder_ - 1);
Andreas Traczykdc17c812019-01-11 15:35:20 -0500156 gearPoint_.setY(this->height() / 2 - gearLabel_.height() / 2 - 2 * gearBorder_ + 8);
Andreas Traczyk59ba48a2019-01-04 16:12:03 -0500157 gearLabel_.setGeometry(
158 gearPoint_.x(), gearPoint_.y(),
159 gearSize_ + 2 * gearBorder_,
160 gearSize_ + 2 * gearBorder_);
Andreas Traczyk43c08232018-10-31 13:42:09 -0400161 gearLabel_.setMargin(gearBorder_);
Isa Nanic601de1d2018-10-23 11:37:26 -0400162}
163
164// import account background account pixmap and scale pixmap to fit in label
165void
Isa Nanic1c20ef12018-10-25 11:49:30 -0400166CurrentAccountComboBox::importLabelPhoto(int index)
Isa Nanic601de1d2018-10-23 11:37:26 -0400167{
Isa Nanic1c20ef12018-10-25 11:49:30 -0400168 currentAccountAvatarImage_ = accountListModel_->data(accountListModel_->index(index, 0), // [efficiency improvement]
Andreas Traczykdc2703e2019-01-17 18:02:31 -0500169 AccountListModel::Role::Picture).value<QPixmap>().scaledToHeight(avatarSize_ - 4, Qt::SmoothTransformation);
Isa Nanic1c20ef12018-10-25 11:49:30 -0400170}
171
172void
173CurrentAccountComboBox::setCurrentIndex(int index)
174{
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500175 auto accountListSize = LRCInstance::accountModel().getAccountList().size();
176 if (index == accountListSize) {
177 emit newAccountClicked();
178 } else if (index < accountListSize) {
179 importLabelPhoto(index);
180 QComboBox::setCurrentIndex(index);
181 }
Isa Nanic1c20ef12018-10-25 11:49:30 -0400182}
183
184void
185CurrentAccountComboBox::accountListUpdate()
186{
187 accountListModel_.reset(new AccountListModel());
188 this->setModel(accountListModel_.get());
189}
Isa Nanic37ccc1c2018-10-26 14:16:28 -0400190
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400191// if gearLabel is clicked
192void
193CurrentAccountComboBox::mousePressEvent(QMouseEvent* mouseEvent)
194{
195 if (!gearLabel_.frameGeometry().contains(mouseEvent->localPos().toPoint())) {
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500196 QComboBox::mousePressEvent(mouseEvent);
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400197 } else {
198 emit settingsButtonClicked();
199 }
200}
201
202// if gear label is hovered over
203void
204CurrentAccountComboBox::mouseMoveEvent(QMouseEvent* mouseEvent)
205{
206 if (gearLabel_.frameGeometry().contains(mouseEvent->x(), mouseEvent->y())) {
207 QComboBox::mouseMoveEvent(mouseEvent);
Andreas Traczykdc2703e2019-01-17 18:02:31 -0500208 gearLabel_.setStyleSheet("background: rgb(237, 237, 237); border-width: 0px; border-radius: 15px;");
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400209 return;
210 }
211
212 gearLabel_.setStyleSheet("background: transparent;");
213}
214
215void
216CurrentAccountComboBox::showPopup()
217{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400218 gearLabel_.hide();
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400219 popupPresent = true;
220 QComboBox::showPopup();
221}
222
223void
224CurrentAccountComboBox::hidePopup()
225{
Andreas Traczyk43c08232018-10-31 13:42:09 -0400226 gearLabel_.show();
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400227 popupPresent = false;
228 QComboBox::hidePopup();
Andreas Traczykfd0d7c02018-10-30 17:14:06 -0400229}
230
231void
232CurrentAccountComboBox::leaveEvent(QEvent* event)
233{
234 gearLabel_.setStyleSheet("background: transparent;");
235 QComboBox::leaveEvent(event);
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500236}
237
238void
239CurrentAccountComboBox::updateComboBoxDisplay()
240{
Andreas Traczyk10523bf2018-12-31 16:49:03 -0500241 auto currAccIndex = LRCInstance::getCurrentAccountIndex();
242 if (currAccIndex != currentIndex())
243 setCurrentIndex(currAccIndex);
244 importLabelPhoto(currAccIndex);
Isa Nanic6e4a39a2018-12-04 14:26:02 -0500245}