moved menu code to ripple effect button

This commit is contained in:
fourtf 2018-08-07 23:46:00 +02:00
parent e1b8faacc9
commit 7a9af4ae84
13 changed files with 198 additions and 170 deletions

View file

@ -2,11 +2,12 @@
#include "Application.hpp"
#include "common/NetworkManager.hpp"
#include "debug/Log.hpp"
#include "providers/twitch/TwitchCommon.hpp"
#include "singletons/Paths.hpp"
#include "util/DebugCount.hpp"
#include <QFile>
#include <cassert>
namespace chatterino {
@ -165,6 +166,8 @@ Outcome NetworkRequest::tryLoadCachedFile()
void NetworkRequest::doRequest()
{
DebugCount::increase("http request started");
NetworkRequester requester;
NetworkWorker *worker = new NetworkWorker;
@ -223,6 +226,8 @@ void NetworkRequest::doRequest()
data->writeToCache(bytes);
NetworkResult result(bytes);
DebugCount::increase("http request success");
data->onSuccess_(result);
reply->deleteLater();

View file

@ -6,6 +6,8 @@
#include <QApplication>
#include <QStringList>
#include <messages/Image.hpp>
using namespace chatterino;
int main(int argc, char **argv)

View file

@ -96,8 +96,6 @@ void TwitchServer::privateMessageReceived(Communi::IrcPrivateMessage *message)
void TwitchServer::messageReceived(Communi::IrcMessage *message)
{
qDebug() << message->toData();
// this->readConnection
if (message->type() == Communi::IrcMessage::Type::Private) {
// We already have a handler for private messages

View file

@ -220,8 +220,8 @@ void Theme::actuallyUpdate(double hue, double multiplier)
this->scrollbars.background = QColor(0, 0, 0, 0);
// this->scrollbars.background = splits.background;
// this->scrollbars.background.setAlphaF(qreal(0.2));
this->scrollbars.thumb = getColor(0, sat, 0.80);
this->scrollbars.thumbSelected = getColor(0, sat, 0.7);
this->scrollbars.thumb = getColor(0, sat, 0.70);
this->scrollbars.thumbSelected = getColor(0, sat, 0.65);
// tooltip
this->tooltip.background = QColor(0, 0, 0);

View file

@ -147,8 +147,8 @@ void LogsPopup::getOverrustleLogs()
NetworkRequest req(url);
req.setCaller(QThread::currentThread());
req.onError([this, channelName](int errorCode) {
this->close();
req.onError([channelName](int errorCode) {
// this->close();
auto box = new QMessageBox(
QMessageBox::Information, "Error getting logs",
"No logs could be found for channel " + channelName);

View file

@ -83,7 +83,7 @@ UserInfoPopup::UserInfoPopup()
user.emplace<QCheckBox>("Ignore highlights")
.assign(&this->ui_.ignoreHighlights);
auto viewLogs = user.emplace<RippleEffectLabel2>(this);
viewLogs->getLabel().setText("Logs");
viewLogs->getLabel().setText("Online logs");
auto mod = user.emplace<RippleEffectButton>(this);
mod->setPixmap(app->resources->buttons.mod);

View file

@ -1,9 +1,12 @@
#include "RippleEffectButton.hpp"
#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include <QPainter>
#include "singletons/Theme.hpp"
#include "util/FunctionEventFilter.hpp"
namespace chatterino {
@ -76,6 +79,20 @@ const QColor &RippleEffectButton::getBorderColor() const
return this->borderColor_;
}
void RippleEffectButton::setMenu(std::unique_ptr<QMenu> menu)
{
this->menu_ = std::move(menu);
this->menu_->installEventFilter(
new FunctionEventFilter(this, [this](QObject *, QEvent *event) {
if (event->type() == QEvent::Hide) {
QTimer::singleShot(20, this,
[this] { this->menuVisible_ = false; });
}
return false;
}));
}
void RippleEffectButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
@ -177,6 +194,10 @@ void RippleEffectButton::mousePressEvent(QMouseEvent *event)
this->mouseDown_ = true;
emit this->leftMousePress();
if (this->menu_ && !this->menuVisible_) {
QTimer::singleShot(80, this, [this] { this->showMenu(); });
}
}
void RippleEffectButton::mouseReleaseEvent(QMouseEvent *event)
@ -251,4 +272,26 @@ void RippleEffectButton::onMouseEffectTimeout()
}
}
void RippleEffectButton::showMenu()
{
if (!this->menu_) return;
auto point = [this] {
auto bounds = QApplication::desktop()->availableGeometry(this);
auto point = this->mapToGlobal(
QPoint(this->width() - this->menu_->width(), this->height()));
if (point.y() + this->menu_->height() > bounds.bottom()) {
point.setY(point.y() - this->menu_->height() - this->height());
}
return point;
};
this->menu_->popup(point());
this->menu_->move(point());
this->menuVisible_ = true;
}
} // namespace chatterino

View file

@ -4,6 +4,7 @@
#include "widgets/BaseWidget.hpp"
#include <QMenu>
#include <QMouseEvent>
#include <QPainter>
#include <QPoint>
@ -43,6 +44,8 @@ public:
void setBorderColor(const QColor &color);
const QColor &getBorderColor() const;
void setMenu(std::unique_ptr<QMenu> menu);
signals:
void clicked();
void leftMousePress();
@ -57,22 +60,25 @@ protected:
void fancyPaint(QPainter &painter);
bool enabled_ = true;
bool selected_ = false;
bool mouseOver_ = false;
bool mouseDown_ = false;
bool enabled_{true};
bool selected_{false};
bool mouseOver_{false};
bool mouseDown_{false};
bool menuVisible_{false};
private:
void onMouseEffectTimeout();
void showMenu();
QColor borderColor_;
QPixmap pixmap_;
bool dimPixmap_ = true;
QPoint mousePos_;
double hoverMultiplier_ = 0.0;
QTimer effectTimer_;
std::vector<ClickEffect> clickEffects_;
boost::optional<QColor> mouseEffectColor_ = boost::none;
QColor borderColor_{};
QPixmap pixmap_{};
bool dimPixmap_{true};
QPoint mousePos_{};
double hoverMultiplier_{0.0};
QTimer effectTimer_{};
std::vector<ClickEffect> clickEffects_{};
boost::optional<QColor> mouseEffectColor_{};
std::unique_ptr<QMenu> menu_{};
};
} // namespace chatterino

View file

@ -1140,9 +1140,13 @@ void SplitContainer::ResizeHandle::paintEvent(QPaintEvent *)
}
}
void SplitContainer::ResizeHandle::mousePressEvent(QMouseEvent *)
void SplitContainer::ResizeHandle::mousePressEvent(QMouseEvent *event)
{
this->isMouseDown_ = true;
if (event->button() == Qt::RightButton) {
this->resetFlex();
}
}
void SplitContainer::ResizeHandle::mouseReleaseEvent(QMouseEvent *)
@ -1211,6 +1215,11 @@ void SplitContainer::ResizeHandle::mouseDoubleClickEvent(QMouseEvent *event)
{
event->accept();
this->resetFlex();
}
void SplitContainer::ResizeHandle::resetFlex()
{
for (auto &sibling : this->node->getParent()->getChildren()) {
sibling->flexH_ = 1;
sibling->flexV_ = 1;

View file

@ -161,6 +161,8 @@ private:
friend class SplitContainer;
private:
void resetFlex();
bool vertical_;
bool isMouseDown_ = false;
};

View file

@ -6,7 +6,6 @@
#include "providers/twitch/TwitchServer.hpp"
#include "singletons/Resources.hpp"
#include "singletons/Theme.hpp"
#include "util/FunctionEventFilter.hpp"
#include "util/LayoutCreator.hpp"
#include "widgets/Label.hpp"
#include "widgets/TooltipWidget.hpp"
@ -17,6 +16,7 @@
#include <QDesktopWidget>
#include <QDrag>
#include <QInputDialog>
#include <QMenu>
#include <QMimeData>
#include <QPainter>
@ -55,15 +55,7 @@ SplitHeader::SplitHeader(Split *_split)
this->setupModeLabel(*mode);
QObject::connect(
mode.getElement(), &RippleEffectLabel::clicked, this, [this] {
QTimer::singleShot(80, this, [&, this] {
ChannelPtr _channel = this->split_->getChannel();
if (_channel->hasModRights()) {
this->modeMenu_.popup(QCursor::pos());
}
});
});
mode->setMenu(this->createChatModeMenu());
// moderation mode
auto moderator = layout.emplace<RippleEffectButton>(this).assign(
@ -86,14 +78,9 @@ SplitHeader::SplitHeader(Split *_split)
dropdown->setMouseTracking(true);
// dropdown->setPixmap(*app->resources->splitHeaderContext->getPixmap());
// dropdown->setScaleIndependantSize(23, 23);
this->addDropdownItems(dropdown.getElement());
dropdown->setMenu(this->createMainMenu());
QObject::connect(dropdown.getElement(),
&RippleEffectButton::leftMousePress, this, [this] {
if (!this->menuVisible_) {
QTimer::singleShot(
80, this, [this] { this->showMenu(); });
}
});
&RippleEffectButton::leftMousePress, this, [this] {});
}
// ---- misc
@ -111,8 +98,6 @@ SplitHeader::SplitHeader(Split *_split)
this->managedConnect(app->accounts->twitch.currentUserChanged,
[this] { this->updateModerationModeIcon(); });
this->addModeActions(this->modeMenu_);
this->setMouseTracking(true);
// Update title on title-settings-change
@ -128,15 +113,6 @@ SplitHeader::SplitHeader(Split *_split)
getSettings()->showUptime.connect(
[this](const auto &, const auto &) { this->updateChannelText(); },
this->managedConnections_);
this->dropdownMenu_.installEventFilter(
new FunctionEventFilter(this, [this](QObject *, QEvent *event) {
if (event->type() == QEvent::Hide) {
QTimer::singleShot(20, this,
[this] { this->menuVisible_ = false; });
}
return false;
}));
}
SplitHeader::~SplitHeader()
@ -144,63 +120,129 @@ SplitHeader::~SplitHeader()
this->onlineStatusChangedConnection_.disconnect();
}
void SplitHeader::addDropdownItems(RippleEffectButton *)
std::unique_ptr<QMenu> SplitHeader::createMainMenu()
{
// clang-format off
this->dropdownMenu_.addAction("New split", this->split_, &Split::doAddSplit, QKeySequence(tr("Ctrl+T")));
this->dropdownMenu_.addAction("Close split", this->split_, &Split::doCloseSplit, QKeySequence(tr("Ctrl+W")));
this->dropdownMenu_.addAction("Change channel", this->split_, &Split::doChangeChannel, QKeySequence(tr("Ctrl+R")));
this->dropdownMenu_.addSeparator();
this->dropdownMenu_.addAction("Viewer list", this->split_, &Split::showViewerList);
this->dropdownMenu_.addAction("Search", this->split_, &Split::showSearchPopup, QKeySequence(tr("Ctrl+F")));
this->dropdownMenu_.addSeparator();
this->dropdownMenu_.addAction("Popup", this->split_, &Split::doPopup);
auto menu = std::make_unique<QMenu>();
menu->addAction("New split", this->split_, &Split::doAddSplit,
QKeySequence(tr("Ctrl+T")));
menu->addAction("Close split", this->split_, &Split::doCloseSplit,
QKeySequence(tr("Ctrl+W")));
menu->addAction("Change channel", this->split_, &Split::doChangeChannel,
QKeySequence(tr("Ctrl+R")));
menu->addSeparator();
menu->addAction("Viewer list", this->split_, &Split::showViewerList);
menu->addAction("Search", this->split_, &Split::showSearchPopup,
QKeySequence(tr("Ctrl+F")));
menu->addSeparator();
menu->addAction("Popup", this->split_, &Split::doPopup);
#ifdef USEWEBENGINE
this->dropdownMenu.addAction("Start watching", this, [this]{
this->dropdownMenu.addAction("Start watching", this, [this] {
ChannelPtr _channel = this->split->getChannel();
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_channel.get());
if (tc != nullptr) {
StreamView *view = new StreamView(_channel, "https://player.twitch.tv/?channel=" + tc->name);
StreamView *view = new StreamView(
_channel, "https://player.twitch.tv/?channel=" + tc->name);
view->setAttribute(Qt::WA_DeleteOnClose, true);
view->show();
}
});
#endif
this->dropdownMenu_.addAction("Open browser", this->split_, &Split::openInBrowser);
menu->addAction("Open in browser", this->split_, &Split::openInBrowser);
#ifndef USEWEBENGINE
this->dropdownMenu_.addAction("Open browser popup", this->split_, &Split::openInPopupPlayer);
menu->addAction("Open player in browser", this->split_,
&Split::openInPopupPlayer);
#endif
this->dropdownMenu_.addAction("Open streamlink", this->split_, &Split::openInStreamlink);
this->dropdownMenu_.addSeparator();
this->dropdownMenu_.addAction("Reload channel emotes", this, SLOT(menuReloadChannelEmotes()));
this->dropdownMenu_.addAction("Reconnect", this, SLOT(menuManualReconnect()));
this->dropdownMenu_.addAction("Clear messages", this->split_, &Split::doClearChat);
// this->dropdownMenu.addSeparator();
// this->dropdownMenu.addAction("Show changelog", this, SLOT(menuShowChangelog()));
// clang-format on
menu->addAction("Open streamlink", this->split_, &Split::openInStreamlink);
menu->addSeparator();
menu->addAction("Reload channel emotes", this,
SLOT(menuReloadChannelEmotes()));
menu->addAction("Reconnect", this, SLOT(menuManualReconnect()));
// menu->addAction("Clear messages", this->split_, &Split::doClearChat);
// menu->addSeparator();
// menu->addAction("Show changelog", this, SLOT(menuShowChangelog()));
return menu;
}
void SplitHeader::showMenu()
std::unique_ptr<QMenu> SplitHeader::createChatModeMenu()
{
auto point = [this] {
auto bounds = QApplication::desktop()->availableGeometry(this);
auto menu = std::make_unique<QMenu>();
auto point = this->dropdownButton_->mapToGlobal(
QPoint(this->dropdownButton_->width() - this->dropdownMenu_.width(),
this->dropdownButton_->height()));
auto setSub = new QAction("Subscriber only", this);
auto setEmote = new QAction("Emote only", this);
auto setSlow = new QAction("Slow", this);
auto setR9k = new QAction("R9K", this);
if (point.y() + this->dropdownMenu_.height() > bounds.bottom()) {
point.setY(point.y() - this->dropdownMenu_.height() -
this->dropdownButton_->height());
}
setSub->setCheckable(true);
setEmote->setCheckable(true);
setSlow->setCheckable(true);
setR9k->setCheckable(true);
return point;
menu->addAction(setEmote);
menu->addAction(setSub);
menu->addAction(setSlow);
menu->addAction(setR9k);
this->managedConnections_.push_back(this->modeUpdateRequested_.connect( //
[this, setSub, setEmote, setSlow, setR9k]() {
auto twitchChannel =
dynamic_cast<TwitchChannel *>(this->split_->getChannel().get());
if (twitchChannel == nullptr) {
this->modeButton_->hide();
return;
}
auto roomModes = twitchChannel->accessRoomModes();
setR9k->setChecked(roomModes->r9k);
setSlow->setChecked(roomModes->slowMode);
setEmote->setChecked(roomModes->emoteOnly);
setSub->setChecked(roomModes->submode);
}));
auto toggle = [this](const QString &_command, QAction *action) mutable {
QString command = _command;
if (!action->isChecked()) {
command += "off";
};
action->setChecked(!action->isChecked());
qDebug() << command;
this->split_->getChannel().get()->sendMessage(command);
};
this->dropdownMenu_.popup(point());
this->dropdownMenu_.move(point());
this->menuVisible_ = true;
QObject::connect(
setSub, &QAction::triggered, this,
[setSub, toggle]() mutable { toggle("/subscribers", setSub); });
QObject::connect(
setEmote, &QAction::triggered, this,
[setEmote, toggle]() mutable { toggle("/emoteonly", setEmote); });
QObject::connect(setSlow, &QAction::triggered, this, [setSlow, this]() {
if (!setSlow->isChecked()) {
this->split_->getChannel().get()->sendMessage("/slowoff");
setSlow->setChecked(false);
return;
};
bool ok;
int slowSec = QInputDialog::getInt(this, "", "Seconds:", 10, 0, 500, 1,
&ok, Qt::FramelessWindowHint);
if (ok) {
this->split_->getChannel().get()->sendMessage(
QString("/slow %1").arg(slowSec));
} else {
setSlow->setChecked(false);
}
});
QObject::connect(
setR9k, &QAction::triggered, this,
[setR9k, toggle]() mutable { toggle("/r9kbeta", setR9k); });
return menu;
}
void SplitHeader::updateRoomModes()
@ -263,82 +305,6 @@ void SplitHeader::setupModeLabel(RippleEffectLabel &label)
}));
}
void SplitHeader::addModeActions(QMenu &menu)
{
auto setSub = new QAction("Subscriber only", this);
auto setEmote = new QAction("Emote only", this);
auto setSlow = new QAction("Slow", this);
auto setR9k = new QAction("R9K", this);
setSub->setCheckable(true);
setEmote->setCheckable(true);
setSlow->setCheckable(true);
setR9k->setCheckable(true);
menu.addAction(setEmote);
menu.addAction(setSub);
menu.addAction(setSlow);
menu.addAction(setR9k);
this->managedConnections_.push_back(this->modeUpdateRequested_.connect( //
[this, setSub, setEmote, setSlow, setR9k]() {
auto twitchChannel =
dynamic_cast<TwitchChannel *>(this->split_->getChannel().get());
if (twitchChannel == nullptr) {
this->modeButton_->hide();
return;
}
auto roomModes = twitchChannel->accessRoomModes();
setR9k->setChecked(roomModes->r9k);
setSlow->setChecked(roomModes->slowMode);
setEmote->setChecked(roomModes->emoteOnly);
setSub->setChecked(roomModes->submode);
}));
auto toggle = [this](const QString &_command, QAction *action) mutable {
QString command = _command;
if (!action->isChecked()) {
command += "off";
};
action->setChecked(!action->isChecked());
qDebug() << command;
this->split_->getChannel().get()->sendMessage(command);
};
QObject::connect(
setSub, &QAction::triggered, this,
[setSub, toggle]() mutable { toggle("/subscribers", setSub); });
QObject::connect(
setEmote, &QAction::triggered, this,
[setEmote, toggle]() mutable { toggle("/emoteonly", setEmote); });
QObject::connect(setSlow, &QAction::triggered, this, [setSlow, this]() {
if (!setSlow->isChecked()) {
this->split_->getChannel().get()->sendMessage("/slowoff");
setSlow->setChecked(false);
return;
};
bool ok;
int slowSec = QInputDialog::getInt(this, "", "Seconds:", 10, 0, 500, 1,
&ok, Qt::FramelessWindowHint);
if (ok) {
this->split_->getChannel().get()->sendMessage(
QString("/slow %1").arg(slowSec));
} else {
setSlow->setChecked(false);
}
});
QObject::connect(
setR9k, &QAction::triggered, this,
[setR9k, toggle]() mutable { toggle("/r9kbeta", setR9k); });
}
void SplitHeader::initializeChannelSignals()
{
// Disconnect any previous signal first
@ -438,9 +404,9 @@ void SplitHeader::updateModerationModeIcon()
bool modButtonVisible = false;
ChannelPtr channel = this->split_->getChannel();
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(channel.get());
auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
if (tc != nullptr && tc->hasModRights()) {
if (twitchChannel != nullptr && twitchChannel->hasModRights()) {
modButtonVisible = true;
}

View file

@ -51,12 +51,11 @@ protected:
private:
void rightButtonClicked();
void initializeChannelSignals();
void addModeActions(QMenu &menu);
void setupModeLabel(RippleEffectLabel &label);
void addDropdownItems(RippleEffectButton *label);
void showMenu();
std::unique_ptr<QMenu> createMainMenu();
std::unique_ptr<QMenu> createChatModeMenu();
Split *const split_;
Split *split_;
QPoint dragStart_;
bool dragging_ = false;
@ -71,9 +70,6 @@ private:
RippleEffectLabel *modeButton_{};
RippleEffectButton *moderationButton_{};
QMenu dropdownMenu_;
QMenu modeMenu_;
bool menuVisible_{};
pajlada::Signals::NoArgSignal modeUpdateRequested_;

View file

@ -0,0 +1 @@
find . -not -path "*.git*" -exec fsutil.exe file setCaseSensitiveInfo {} disable \;