mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
added basic user info popup
This commit is contained in:
parent
86e4a669ad
commit
c308883a2a
13 changed files with 453 additions and 241 deletions
|
@ -217,7 +217,7 @@ SOURCES += \
|
||||||
src/controllers/taggedusers/taggedusersmodel.cpp \
|
src/controllers/taggedusers/taggedusersmodel.cpp \
|
||||||
src/util/emotemap.cpp \
|
src/util/emotemap.cpp \
|
||||||
src/providers/irc/ircconnection2.cpp \
|
src/providers/irc/ircconnection2.cpp \
|
||||||
src/widgets/accountpopup2.cpp
|
src/widgets/userinfopopup.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/precompiled_header.hpp \
|
src/precompiled_header.hpp \
|
||||||
|
@ -376,7 +376,8 @@ HEADERS += \
|
||||||
src/util/qstringhash.hpp \
|
src/util/qstringhash.hpp \
|
||||||
src/util/mutexvalue.hpp \
|
src/util/mutexvalue.hpp \
|
||||||
src/providers/irc/ircconnection2.hpp \
|
src/providers/irc/ircconnection2.hpp \
|
||||||
src/widgets/accountpopup2.hpp
|
src/widgets/helper/line.hpp \
|
||||||
|
src/widgets/userinfopopup.hpp
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources/resources.qrc
|
resources/resources.qrc
|
||||||
|
|
|
@ -86,6 +86,8 @@ void ThemeManager::actuallyUpdate(double hue, double multiplier)
|
||||||
this->messages.textColors.caret = //
|
this->messages.textColors.caret = //
|
||||||
this->messages.textColors.regular = isLight ? "#000" : "#fff";
|
this->messages.textColors.regular = isLight ? "#000" : "#fff";
|
||||||
|
|
||||||
|
QColor highlighted = lightWin ? QColor("#b60505") : QColor("#ee6166");
|
||||||
|
|
||||||
/// TABS
|
/// TABS
|
||||||
if (lightWin) {
|
if (lightWin) {
|
||||||
this->tabs.regular = {QColor("#444"),
|
this->tabs.regular = {QColor("#444"),
|
||||||
|
@ -93,9 +95,8 @@ void ThemeManager::actuallyUpdate(double hue, double multiplier)
|
||||||
{QColor("#fff"), QColor("#fff"), QColor("#fff")}};
|
{QColor("#fff"), QColor("#fff"), QColor("#fff")}};
|
||||||
this->tabs.newMessage = {
|
this->tabs.newMessage = {
|
||||||
fg, {bg, QColor("#ccc"), bg}, {QColor("#aaa"), QColor("#aaa"), QColor("#aaa")}};
|
fg, {bg, QColor("#ccc"), bg}, {QColor("#aaa"), QColor("#aaa"), QColor("#aaa")}};
|
||||||
this->tabs.highlighted = {fg,
|
this->tabs.highlighted = {
|
||||||
{bg, QColor("#ccc"), bg},
|
fg, {bg, QColor("#ccc"), bg}, {highlighted, highlighted, highlighted}};
|
||||||
{QColor("#b60505"), QColor("#b60505"), QColor("#b60505")}};
|
|
||||||
this->tabs.selected = {QColor("#000"),
|
this->tabs.selected = {QColor("#000"),
|
||||||
{QColor("#b4d7ff"), QColor("#b4d7ff"), QColor("#b4d7ff")},
|
{QColor("#b4d7ff"), QColor("#b4d7ff"), QColor("#b4d7ff")},
|
||||||
{QColor("#00aeef"), QColor("#00aeef"), QColor("#00aeef")}};
|
{QColor("#00aeef"), QColor("#00aeef"), QColor("#00aeef")}};
|
||||||
|
@ -108,13 +109,15 @@ void ThemeManager::actuallyUpdate(double hue, double multiplier)
|
||||||
{QColor("#888"), QColor("#888"), QColor("#888")}};
|
{QColor("#888"), QColor("#888"), QColor("#888")}};
|
||||||
this->tabs.highlighted = {fg,
|
this->tabs.highlighted = {fg,
|
||||||
{QColor("#252525"), QColor("#252525"), QColor("#252525")},
|
{QColor("#252525"), QColor("#252525"), QColor("#252525")},
|
||||||
{QColor("#ee6166"), QColor("#ee6166"), QColor("#ee6166")}};
|
{highlighted, highlighted, highlighted}};
|
||||||
|
|
||||||
this->tabs.selected = {QColor("#fff"),
|
this->tabs.selected = {QColor("#fff"),
|
||||||
{QColor("#555555"), QColor("#555555"), QColor("#555555")},
|
{QColor("#555555"), QColor("#555555"), QColor("#555555")},
|
||||||
{QColor("#00aeef"), QColor("#00aeef"), QColor("#00aeef")}};
|
{QColor("#00aeef"), QColor("#00aeef"), QColor("#00aeef")}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->splits.input.focusedLine = highlighted;
|
||||||
|
|
||||||
// scrollbar
|
// scrollbar
|
||||||
this->scrollbars.highlights.highlight = QColor("#ee6166");
|
this->scrollbars.highlights.highlight = QColor("#ee6166");
|
||||||
this->scrollbars.highlights.subscription = QColor("#C466FF");
|
this->scrollbars.highlights.subscription = QColor("#C466FF");
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
QColor border;
|
QColor border;
|
||||||
QColor background;
|
QColor background;
|
||||||
QColor selection;
|
QColor selection;
|
||||||
|
QColor focusedLine;
|
||||||
QColor text;
|
QColor text;
|
||||||
QString styleSheet;
|
QString styleSheet;
|
||||||
// int margin;
|
// int margin;
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
#include "accountpopup2.hpp"
|
|
||||||
|
|
||||||
#include "application.hpp"
|
|
||||||
#include "singletons/resourcemanager.hpp"
|
|
||||||
#include "util/layoutcreator.hpp"
|
|
||||||
#include "widgets/helper/rippleeffectlabel.hpp"
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
namespace widgets {
|
|
||||||
|
|
||||||
AccountPopup2::AccountPopup2()
|
|
||||||
: BaseWindow(nullptr, BaseWindow::Frameless)
|
|
||||||
{
|
|
||||||
auto app = getApp();
|
|
||||||
|
|
||||||
auto layout = util::LayoutCreator<AccountPopup2>(this).setLayoutType<QVBoxLayout>();
|
|
||||||
|
|
||||||
// first line
|
|
||||||
auto head = layout.emplace<QHBoxLayout>();
|
|
||||||
{
|
|
||||||
// avatar
|
|
||||||
auto avatar = head.emplace<QLabel>("Avatar").assign(&this->ui.label);
|
|
||||||
avatar->setFixedSize(100, 100);
|
|
||||||
|
|
||||||
// items on the right
|
|
||||||
auto vbox = head.emplace<QVBoxLayout>();
|
|
||||||
{
|
|
||||||
vbox.emplace<QLabel>("Name");
|
|
||||||
vbox.emplace<QLabel>("Views");
|
|
||||||
vbox.emplace<QLabel>("Followers");
|
|
||||||
vbox.emplace<QLabel>("Create date");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// second line
|
|
||||||
auto user = layout.emplace<QHBoxLayout>();
|
|
||||||
{
|
|
||||||
user->addStretch(1);
|
|
||||||
|
|
||||||
auto ignore = user.emplace<RippleEffectLabel>();
|
|
||||||
ignore->getLabel().setText("Ignore");
|
|
||||||
ignore->setScaleIndependantHeight(24);
|
|
||||||
|
|
||||||
auto ignoreHighlights = user.emplace<RippleEffectLabel>();
|
|
||||||
ignoreHighlights->getLabel().setText("Ignore highlights");
|
|
||||||
ignoreHighlights->setScaleIndependantHeight(24);
|
|
||||||
|
|
||||||
user->addStretch(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// third line
|
|
||||||
auto moderation = layout.emplace<QHBoxLayout>();
|
|
||||||
moderation->setSpacing(0);
|
|
||||||
{
|
|
||||||
auto unban = moderation.emplace<RippleEffectLabel>();
|
|
||||||
unban->setPixmap(app->resources->buttons.unban);
|
|
||||||
unban->setScaleIndependantSize(32, 32);
|
|
||||||
unban->setBorderColor(QColor(255, 255, 255, 127));
|
|
||||||
|
|
||||||
moderation.emplace<TimeoutWidget>();
|
|
||||||
|
|
||||||
auto ban = moderation.emplace<RippleEffectLabel>();
|
|
||||||
ban->setPixmap(app->resources->buttons.ban);
|
|
||||||
ban->setScaleIndependantSize(32, 32);
|
|
||||||
ban->setBorderColor(QColor(255, 255, 255, 127));
|
|
||||||
|
|
||||||
// auto mod = moderation.emplace<RippleEffectButton>(this);
|
|
||||||
// mod->setPixmap(app->resources->buttons.mod);
|
|
||||||
// mod->setScaleIndependantSize(30, 30);
|
|
||||||
// auto unmod = moderation.emplace<RippleEffectLabel>();
|
|
||||||
// unmod->setPixmap(app->resources->buttons.unmod);
|
|
||||||
// unmod->setScaleIndependantSize(30, 30);
|
|
||||||
|
|
||||||
this->userStateChanged.connect([=]() mutable {
|
|
||||||
// mod->setVisible(this->isBroadcaster_);
|
|
||||||
// unmod->setVisible(this->isBroadcaster_);
|
|
||||||
|
|
||||||
ban->setVisible(this->isMod_);
|
|
||||||
unban->setVisible(this->isMod_);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this->setStyleSheet("font-size: 12pt");
|
|
||||||
}
|
|
||||||
|
|
||||||
// void AccountPopup2::scaleChangedEvent(float newScale)
|
|
||||||
//{
|
|
||||||
//}
|
|
||||||
|
|
||||||
void AccountPopup2::setName(const QString &name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AccountPopup2::setChannel(const ChannelPtr &_channel)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// TimeoutWidget
|
|
||||||
//
|
|
||||||
AccountPopup2::TimeoutWidget::TimeoutWidget()
|
|
||||||
: BaseWidget(nullptr)
|
|
||||||
{
|
|
||||||
auto layout = util::LayoutCreator<TimeoutWidget>(this).setLayoutType<QHBoxLayout>();
|
|
||||||
|
|
||||||
QColor color1(255, 255, 255, 127);
|
|
||||||
QColor color2(255, 255, 255, 80);
|
|
||||||
|
|
||||||
int buttonWidth = 40;
|
|
||||||
int buttonWidth2 = 20;
|
|
||||||
int buttonHeight = 32;
|
|
||||||
|
|
||||||
layout->setSpacing(1);
|
|
||||||
|
|
||||||
auto a = layout.emplace<RippleEffectLabel>();
|
|
||||||
a->getLabel().setText("1s");
|
|
||||||
a->setScaleIndependantSize(buttonWidth, buttonHeight);
|
|
||||||
a->setBorderColor(color1);
|
|
||||||
auto a1 = layout.emplace<RippleEffectLabel>(nullptr);
|
|
||||||
// a1->getLabel().setText("1m");
|
|
||||||
a1->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
|
||||||
a1->setBorderColor(color2);
|
|
||||||
auto a2 = layout.emplace<RippleEffectLabel>(nullptr);
|
|
||||||
// a2->getLabel().setText("5m");
|
|
||||||
a2->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
|
||||||
a2->setBorderColor(color2);
|
|
||||||
|
|
||||||
auto b = layout.emplace<RippleEffectLabel>();
|
|
||||||
b->getLabel().setText("10m");
|
|
||||||
b->setScaleIndependantSize(buttonWidth, buttonHeight);
|
|
||||||
b->setBorderColor(color1);
|
|
||||||
auto b1 = layout.emplace<RippleEffectLabel>(nullptr);
|
|
||||||
b1->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
|
||||||
b1->setBorderColor(color2);
|
|
||||||
// b1->getLabel().setText("1h");
|
|
||||||
auto b2 = layout.emplace<RippleEffectLabel>(nullptr);
|
|
||||||
b2->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
|
||||||
b2->setBorderColor(color2);
|
|
||||||
// b2->getLabel().setText("4h");
|
|
||||||
|
|
||||||
auto c = layout.emplace<RippleEffectLabel>();
|
|
||||||
c->getLabel().setText("1d");
|
|
||||||
c->setScaleIndependantSize(buttonWidth, buttonHeight);
|
|
||||||
c->setBorderColor(color1);
|
|
||||||
auto c1 = layout.emplace<RippleEffectLabel>(nullptr);
|
|
||||||
// c1->getLabel().setText("3d");
|
|
||||||
c1->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
|
||||||
c1->setBorderColor(color2);
|
|
||||||
auto c2 = layout.emplace<RippleEffectLabel>(nullptr);
|
|
||||||
// c2->getLabel().setText("1w");
|
|
||||||
c2->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
|
||||||
c2->setBorderColor(color2);
|
|
||||||
|
|
||||||
auto d = layout.emplace<RippleEffectLabel>();
|
|
||||||
d->getLabel().setText("2w");
|
|
||||||
d->setScaleIndependantSize(buttonWidth, buttonHeight);
|
|
||||||
d->setBorderColor(color1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AccountPopup2::TimeoutWidget::paintEvent(QPaintEvent *)
|
|
||||||
{
|
|
||||||
// QPainter painter(this);
|
|
||||||
|
|
||||||
// painter.setPen(QColor(255, 255, 255, 63));
|
|
||||||
|
|
||||||
// painter.drawLine(0, this->height() / 2, this->width(), this->height() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace widgets
|
|
||||||
} // namespace chatterino
|
|
|
@ -1,45 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "channel.hpp"
|
|
||||||
#include "widgets/basewindow.hpp"
|
|
||||||
|
|
||||||
#include <pajlada/signals/signal.hpp>
|
|
||||||
|
|
||||||
class QLabel;
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
namespace widgets {
|
|
||||||
|
|
||||||
class AccountPopup2 final : public BaseWindow
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AccountPopup2();
|
|
||||||
|
|
||||||
void setName(const QString &name);
|
|
||||||
void setChannel(const ChannelPtr &_channel);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
QLabel *label = nullptr;
|
|
||||||
} ui;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// virtual void scaleChangedEvent(float newScale) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isMod_;
|
|
||||||
bool isBroadcaster_;
|
|
||||||
|
|
||||||
pajlada::Signals::NoArgSignal userStateChanged;
|
|
||||||
|
|
||||||
class TimeoutWidget : public BaseWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TimeoutWidget();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *event) override;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace widgets
|
|
||||||
} // namespace chatterino
|
|
|
@ -44,6 +44,10 @@ BaseWindow::BaseWindow(QWidget *parent, Flags _flags)
|
||||||
this->setWindowFlag(Qt::FramelessWindowHint);
|
this->setWindowFlag(Qt::FramelessWindowHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->flags & DeleteOnFocusOut) {
|
||||||
|
this->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
}
|
||||||
|
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +205,17 @@ void BaseWindow::themeRefreshEvent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseWindow::event(QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::WindowDeactivate) {
|
||||||
|
if (this->flags & DeleteOnFocusOut) {
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
void BaseWindow::addTitleBarButton(const TitleBarButton::Style &style,
|
void BaseWindow::addTitleBarButton(const TitleBarButton::Style &style,
|
||||||
std::function<void()> onClicked)
|
std::function<void()> onClicked)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,13 @@ class BaseWindow : public BaseWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Flags { None = 0, EnableCustomFrame = 1, Frameless = 2, TopMost = 4 };
|
enum Flags {
|
||||||
|
None = 0,
|
||||||
|
EnableCustomFrame = 1,
|
||||||
|
Frameless = 2,
|
||||||
|
TopMost = 4,
|
||||||
|
DeleteOnFocusOut = 8
|
||||||
|
};
|
||||||
|
|
||||||
explicit BaseWindow(QWidget *parent = nullptr, Flags flags = None);
|
explicit BaseWindow(QWidget *parent = nullptr, Flags flags = None);
|
||||||
|
|
||||||
|
@ -37,18 +43,19 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#ifdef USEWINSDK
|
#ifdef USEWINSDK
|
||||||
void showEvent(QShowEvent *) override;
|
virtual void showEvent(QShowEvent *) override;
|
||||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||||
void scaleChangedEvent(float) override;
|
virtual void scaleChangedEvent(float) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *) override;
|
virtual void paintEvent(QPaintEvent *) override;
|
||||||
|
|
||||||
void changeEvent(QEvent *) override;
|
virtual void changeEvent(QEvent *) override;
|
||||||
void leaveEvent(QEvent *) override;
|
virtual void leaveEvent(QEvent *) override;
|
||||||
void resizeEvent(QResizeEvent *) override;
|
virtual void resizeEvent(QResizeEvent *) override;
|
||||||
|
|
||||||
void themeRefreshEvent() override;
|
virtual void themeRefreshEvent() override;
|
||||||
|
virtual bool event(QEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include "ui_accountpopupform.h"
|
#include "ui_accountpopupform.h"
|
||||||
#include "util/benchmark.hpp"
|
#include "util/benchmark.hpp"
|
||||||
#include "util/distancebetweenpoints.hpp"
|
#include "util/distancebetweenpoints.hpp"
|
||||||
#include "widgets/accountpopup2.hpp"
|
|
||||||
#include "widgets/split.hpp"
|
#include "widgets/split.hpp"
|
||||||
#include "widgets/tooltipwidget.hpp"
|
#include "widgets/tooltipwidget.hpp"
|
||||||
|
#include "widgets/userinfopopup.hpp"
|
||||||
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -1105,9 +1105,8 @@ void ChannelView::handleLinkClick(QMouseEvent *event, const messages::Link &link
|
||||||
switch (link.type) {
|
switch (link.type) {
|
||||||
case messages::Link::UserInfo: {
|
case messages::Link::UserInfo: {
|
||||||
auto user = link.value;
|
auto user = link.value;
|
||||||
auto *userPopup = new AccountPopup2;
|
auto *userPopup = new UserInfoPopup;
|
||||||
userPopup->setChannel(this->channel);
|
userPopup->setData(user, this->channel);
|
||||||
userPopup->setName(user);
|
|
||||||
userPopup->setAttribute(Qt::WA_DeleteOnClose);
|
userPopup->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
userPopup->show();
|
userPopup->show();
|
||||||
|
|
||||||
|
|
42
src/widgets/helper/line.hpp
Normal file
42
src/widgets/helper/line.hpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "widgets/basewidget.hpp"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
namespace chatterino {
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
class Line : public BaseWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Line(bool vertical)
|
||||||
|
: BaseWidget(nullptr)
|
||||||
|
, vertical_(vertical)
|
||||||
|
{
|
||||||
|
if (this->vertical_) {
|
||||||
|
this->setScaleIndependantWidth(8);
|
||||||
|
} else {
|
||||||
|
this->setScaleIndependantHeight(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
painter.setPen(QColor("#999"));
|
||||||
|
|
||||||
|
if (this->vertical_) {
|
||||||
|
painter.drawLine(this->width() / 2, 0, this->width() / 2, this->height());
|
||||||
|
} else {
|
||||||
|
painter.drawLine(0, this->height() / 2, this->width(), this->height() / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool vertical_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace widgets
|
||||||
|
} // namespace chatterino
|
|
@ -15,6 +15,8 @@ RippleEffectButton::RippleEffectButton(BaseWidget *parent)
|
||||||
|
|
||||||
this->effectTimer_.setInterval(20);
|
this->effectTimer_.setInterval(20);
|
||||||
this->effectTimer_.start();
|
this->effectTimer_.start();
|
||||||
|
|
||||||
|
this->setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RippleEffectButton::setMouseEffectColor(boost::optional<QColor> color)
|
void RippleEffectButton::setMouseEffectColor(boost::optional<QColor> color)
|
||||||
|
@ -83,12 +85,12 @@ void RippleEffectButton::fancyPaint(QPainter &painter)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hoverMultiplier_ > 0) {
|
if (this->hoverMultiplier_ > 0) {
|
||||||
QRadialGradient gradient(mousePos_.x(), mousePos_.y(), 50, mousePos_.x(), mousePos_.y());
|
QRadialGradient gradient(QPointF(mousePos_), this->width() / 2);
|
||||||
|
|
||||||
gradient.setColorAt(0,
|
gradient.setColorAt(0,
|
||||||
QColor(c.red(), c.green(), c.blue(), int(24 * this->hoverMultiplier_)));
|
QColor(c.red(), c.green(), c.blue(), int(60 * this->hoverMultiplier_)));
|
||||||
gradient.setColorAt(1,
|
gradient.setColorAt(1,
|
||||||
QColor(c.red(), c.green(), c.blue(), int(12 * this->hoverMultiplier_)));
|
QColor(c.red(), c.green(), c.blue(), int(40 * this->hoverMultiplier_)));
|
||||||
|
|
||||||
painter.fillRect(this->rect(), gradient);
|
painter.fillRect(this->rect(), gradient);
|
||||||
}
|
}
|
||||||
|
@ -145,6 +147,8 @@ void RippleEffectButton::mouseReleaseEvent(QMouseEvent *event)
|
||||||
void RippleEffectButton::mouseMoveEvent(QMouseEvent *event)
|
void RippleEffectButton::mouseMoveEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
this->mousePos_ = event->pos();
|
this->mousePos_ = event->pos();
|
||||||
|
|
||||||
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RippleEffectButton::onMouseEffectTimeout()
|
void RippleEffectButton::onMouseEffectTimeout()
|
||||||
|
@ -172,9 +176,9 @@ void RippleEffectButton::onMouseEffectTimeout()
|
||||||
performUpdate = true;
|
performUpdate = true;
|
||||||
|
|
||||||
for (auto it = this->clickEffects_.begin(); it != this->clickEffects_.end();) {
|
for (auto it = this->clickEffects_.begin(); it != this->clickEffects_.end();) {
|
||||||
(*it).progress += mouseDown_ ? 0.02 : 0.07;
|
it->progress += mouseDown_ ? 0.02 : 0.07;
|
||||||
|
|
||||||
if ((*it).progress >= 1.0) {
|
if (it->progress >= 1.0) {
|
||||||
it = this->clickEffects_.erase(it);
|
it = this->clickEffects_.erase(it);
|
||||||
} else {
|
} else {
|
||||||
it++;
|
it++;
|
||||||
|
|
|
@ -326,6 +326,10 @@ void SplitInput::paintEvent(QPaintEvent *)
|
||||||
painter.setPen(QColor("#333"));
|
painter.setPen(QColor("#333"));
|
||||||
painter.drawRect(rect);
|
painter.drawRect(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int offset = 2;
|
||||||
|
// painter.fillRect(offset, this->height() - offset, this->width() - 2 * offset, 1,
|
||||||
|
// getApp()->themes->splits.input.focusedLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitInput::resizeEvent(QResizeEvent *)
|
void SplitInput::resizeEvent(QResizeEvent *)
|
||||||
|
|
297
src/widgets/userinfopopup.cpp
Normal file
297
src/widgets/userinfopopup.cpp
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
#include "userinfopopup.hpp"
|
||||||
|
|
||||||
|
#include "application.hpp"
|
||||||
|
#include "singletons/resourcemanager.hpp"
|
||||||
|
#include "util/layoutcreator.hpp"
|
||||||
|
#include "util/posttothread.hpp"
|
||||||
|
#include "util/urlfetch.hpp"
|
||||||
|
#include "widgets/helper/line.hpp"
|
||||||
|
#include "widgets/helper/rippleeffectlabel.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
namespace chatterino {
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
UserInfoPopup::UserInfoPopup()
|
||||||
|
: BaseWindow(nullptr, BaseWindow::Flags(BaseWindow::Frameless | BaseWindow::DeleteOnFocusOut))
|
||||||
|
{
|
||||||
|
auto app = getApp();
|
||||||
|
|
||||||
|
auto layout = util::LayoutCreator<UserInfoPopup>(this).setLayoutType<QVBoxLayout>();
|
||||||
|
|
||||||
|
// first line
|
||||||
|
auto head = layout.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
// avatar
|
||||||
|
// auto avatar = head.emplace<QLabel>("Avatar").assign(&this->ui_.avatarButtoAn);
|
||||||
|
auto avatar = head.emplace<RippleEffectButton>(nullptr).assign(&this->ui_.avatarButton);
|
||||||
|
avatar->setFixedSize(100, 100);
|
||||||
|
QObject::connect(*avatar, &RippleEffectButton::clicked, [this] {
|
||||||
|
QDesktopServices::openUrl(QUrl("https://twitch.tv/" + this->userName_));
|
||||||
|
});
|
||||||
|
|
||||||
|
// items on the right
|
||||||
|
auto vbox = head.emplace<QVBoxLayout>();
|
||||||
|
{
|
||||||
|
auto name = vbox.emplace<QLabel>().assign(&this->ui_.nameLabel);
|
||||||
|
|
||||||
|
auto font = name->font();
|
||||||
|
font.setBold(true);
|
||||||
|
name->setFont(font);
|
||||||
|
vbox.emplace<QLabel>("Loading...").assign(&this->ui_.viewCountLabel);
|
||||||
|
vbox.emplace<QLabel>().assign(&this->ui_.followerCountLabel);
|
||||||
|
vbox.emplace<QLabel>().assign(&this->ui_.createdDateLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.emplace<Line>(false);
|
||||||
|
|
||||||
|
// second line
|
||||||
|
auto user = layout.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
user->addStretch(1);
|
||||||
|
|
||||||
|
auto ignore = user.emplace<QCheckBox>("Ignore").assign(&this->ui_.ignore);
|
||||||
|
// ignore->setEnabled(false);
|
||||||
|
|
||||||
|
auto ignoreHighlights =
|
||||||
|
user.emplace<QCheckBox>("Ignore highlights").assign(&this->ui_.ignoreHighlights);
|
||||||
|
// ignoreHighlights->setEnabled(false);
|
||||||
|
|
||||||
|
auto mod = user.emplace<RippleEffectButton>(this);
|
||||||
|
mod->setPixmap(app->resources->buttons.mod);
|
||||||
|
mod->setScaleIndependantSize(30, 30);
|
||||||
|
auto unmod = user.emplace<RippleEffectLabel>();
|
||||||
|
unmod->setPixmap(app->resources->buttons.unmod);
|
||||||
|
unmod->setScaleIndependantSize(30, 30);
|
||||||
|
|
||||||
|
user->addStretch(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.emplace<Line>(false);
|
||||||
|
|
||||||
|
// third line
|
||||||
|
auto moderation = layout.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
moderation.emplace<TimeoutWidget>();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->setStyleSheet("font-size: 11pt;");
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInfoPopup::setData(const QString &name, const ChannelPtr &channel)
|
||||||
|
{
|
||||||
|
this->userName_ = name;
|
||||||
|
this->channel_ = channel;
|
||||||
|
|
||||||
|
this->ui_.nameLabel->setText(name);
|
||||||
|
|
||||||
|
this->updateUserData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInfoPopup::updateUserData()
|
||||||
|
{
|
||||||
|
util::twitch::get("https://api.twitch.tv/kraken/channels/" + this->userName_, this,
|
||||||
|
[=](const QJsonObject &obj) {
|
||||||
|
this->ui_.followerCountLabel->setText(
|
||||||
|
"Followers: " + QString::number(obj.value("followers").toInt()));
|
||||||
|
this->ui_.viewCountLabel->setText(
|
||||||
|
"Views: " + QString::number(obj.value("views").toInt()));
|
||||||
|
this->ui_.createdDateLabel->setText(
|
||||||
|
"Created: " + obj.value("created_at").toString().section("T", 0, 0));
|
||||||
|
|
||||||
|
this->loadAvatar(QUrl(obj.value("logo").toString()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInfoPopup::loadAvatar(const QUrl &url)
|
||||||
|
{
|
||||||
|
QNetworkRequest req(url);
|
||||||
|
static auto manager = new QNetworkAccessManager();
|
||||||
|
auto *reply = manager->get(req);
|
||||||
|
|
||||||
|
QObject::connect(reply, &QNetworkReply::finished, this, [=] {
|
||||||
|
if (reply->error() == QNetworkReply::NoError) {
|
||||||
|
const auto data = reply->readAll();
|
||||||
|
|
||||||
|
// might want to cache the avatar image
|
||||||
|
QPixmap avatar;
|
||||||
|
avatar.loadFromData(data);
|
||||||
|
this->ui_.avatarButton->setPixmap(avatar);
|
||||||
|
} else {
|
||||||
|
this->ui_.avatarButton->setPixmap(QPixmap());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TimeoutWidget
|
||||||
|
//
|
||||||
|
UserInfoPopup::TimeoutWidget::TimeoutWidget()
|
||||||
|
: BaseWidget(nullptr)
|
||||||
|
{
|
||||||
|
auto layout =
|
||||||
|
util::LayoutCreator<TimeoutWidget>(this).setLayoutType<QHBoxLayout>().withoutMargin();
|
||||||
|
|
||||||
|
QColor color1(255, 255, 255, 80);
|
||||||
|
QColor color2(255, 255, 255, 0);
|
||||||
|
|
||||||
|
int buttonWidth = 40;
|
||||||
|
int buttonWidth2 = 24;
|
||||||
|
int buttonHeight = 32;
|
||||||
|
|
||||||
|
layout->setSpacing(16);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
title->addStretch(1);
|
||||||
|
title.emplace<QLabel>("unban");
|
||||||
|
title->addStretch(1);
|
||||||
|
|
||||||
|
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
hbox->setSpacing(0);
|
||||||
|
{
|
||||||
|
auto unban = hbox.emplace<RippleEffectButton>(nullptr);
|
||||||
|
unban->setPixmap(getApp()->resources->buttons.unban);
|
||||||
|
unban->setScaleIndependantSize(buttonHeight, buttonHeight);
|
||||||
|
unban->setBorderColor(QColor(255, 255, 255, 127));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
title->addStretch(1);
|
||||||
|
title.emplace<QLabel>("sec");
|
||||||
|
title->addStretch(1);
|
||||||
|
|
||||||
|
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
hbox->setSpacing(0);
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("1");
|
||||||
|
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
title->addStretch(1);
|
||||||
|
title.emplace<QLabel>("min");
|
||||||
|
title->addStretch(1);
|
||||||
|
|
||||||
|
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
hbox->setSpacing(0);
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("1");
|
||||||
|
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("5");
|
||||||
|
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("10");
|
||||||
|
a->setScaleIndependantSize(buttonWidth, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
title->addStretch(1);
|
||||||
|
title.emplace<QLabel>("hour");
|
||||||
|
title->addStretch(1);
|
||||||
|
|
||||||
|
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
hbox->setSpacing(0);
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("1");
|
||||||
|
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("4");
|
||||||
|
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
title->addStretch(1);
|
||||||
|
title.emplace<QLabel>("week");
|
||||||
|
title->addStretch(1);
|
||||||
|
|
||||||
|
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
hbox->setSpacing(0);
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("1");
|
||||||
|
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto a = hbox.emplace<RippleEffectLabel>();
|
||||||
|
a->getLabel().setText("2");
|
||||||
|
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||||
|
a->setBorderColor(color1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||||
|
{
|
||||||
|
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
title->addStretch(1);
|
||||||
|
title.emplace<QLabel>("ban");
|
||||||
|
title->addStretch(1);
|
||||||
|
|
||||||
|
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||||
|
hbox->setSpacing(0);
|
||||||
|
{
|
||||||
|
auto ban = hbox.emplace<RippleEffectButton>(nullptr);
|
||||||
|
ban->setPixmap(getApp()->resources->buttons.ban);
|
||||||
|
ban->setScaleIndependantSize(buttonHeight, buttonHeight);
|
||||||
|
ban->setBorderColor(QColor(255, 255, 255, 127));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInfoPopup::TimeoutWidget::paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
|
// QPainter painter(this);
|
||||||
|
|
||||||
|
// painter.setPen(QColor(255, 255, 255, 63));
|
||||||
|
|
||||||
|
// painter.drawLine(0, this->height() / 2, this->width(), this->height() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
||||||
|
} // namespace chatterino
|
56
src/widgets/userinfopopup.hpp
Normal file
56
src/widgets/userinfopopup.hpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "channel.hpp"
|
||||||
|
#include "widgets/basewindow.hpp"
|
||||||
|
|
||||||
|
#include <pajlada/signals/signal.hpp>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QCheckBox;
|
||||||
|
|
||||||
|
namespace chatterino {
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
class UserInfoPopup final : public BaseWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UserInfoPopup();
|
||||||
|
|
||||||
|
void setData(const QString &name, const ChannelPtr &channel);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isMod_;
|
||||||
|
bool isBroadcaster_;
|
||||||
|
|
||||||
|
QString userName_;
|
||||||
|
ChannelPtr channel_;
|
||||||
|
|
||||||
|
pajlada::Signals::NoArgSignal userStateChanged;
|
||||||
|
|
||||||
|
void updateUserData();
|
||||||
|
void loadAvatar(const QUrl &url);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
RippleEffectButton *avatarButton = nullptr;
|
||||||
|
|
||||||
|
QLabel *nameLabel = nullptr;
|
||||||
|
QLabel *viewCountLabel = nullptr;
|
||||||
|
QLabel *followerCountLabel = nullptr;
|
||||||
|
QLabel *createdDateLabel = nullptr;
|
||||||
|
|
||||||
|
QCheckBox *ignore = nullptr;
|
||||||
|
QCheckBox *ignoreHighlights = nullptr;
|
||||||
|
} ui_;
|
||||||
|
|
||||||
|
class TimeoutWidget : public BaseWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TimeoutWidget();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace widgets
|
||||||
|
} // namespace chatterino
|
Loading…
Reference in a new issue