refactor: buttons and friends (#6102)
This commit is contained in:
@@ -52,6 +52,7 @@
|
||||
- Dev: Simplified string literals to be a re-export of Qt functions. (#6175)
|
||||
- Dev: Fixed incorrect lua generation of static methods for typescript plugins. (#6190, #6223)
|
||||
- Dev: Merged top/bottom and left/right notebook layouts. (#6215)
|
||||
- Dev: Refactored `Button` and friends. (#6102)
|
||||
|
||||
## 2.5.3
|
||||
|
||||
|
||||
+21
-14
@@ -523,8 +523,6 @@ set(SOURCE_FILES
|
||||
util/Helpers.hpp
|
||||
util/IncognitoBrowser.cpp
|
||||
util/IncognitoBrowser.hpp
|
||||
util/InitUpdateButton.cpp
|
||||
util/InitUpdateButton.hpp
|
||||
util/IpcQueue.cpp
|
||||
util/IpcQueue.hpp
|
||||
util/IrcHelpers.cpp
|
||||
@@ -602,6 +600,27 @@ set(SOURCE_FILES
|
||||
widgets/Window.cpp
|
||||
widgets/Window.hpp
|
||||
|
||||
widgets/buttons/Button.cpp
|
||||
widgets/buttons/Button.hpp
|
||||
widgets/buttons/DimButton.cpp
|
||||
widgets/buttons/DimButton.hpp
|
||||
widgets/buttons/InitUpdateButton.cpp
|
||||
widgets/buttons/InitUpdateButton.hpp
|
||||
widgets/buttons/LabelButton.cpp
|
||||
widgets/buttons/LabelButton.hpp
|
||||
widgets/buttons/NotebookButton.cpp
|
||||
widgets/buttons/NotebookButton.hpp
|
||||
widgets/buttons/PixmapButton.cpp
|
||||
widgets/buttons/PixmapButton.hpp
|
||||
widgets/buttons/SignalLabel.cpp
|
||||
widgets/buttons/SignalLabel.hpp
|
||||
widgets/buttons/SvgButton.cpp
|
||||
widgets/buttons/SvgButton.hpp
|
||||
widgets/buttons/TitlebarButton.cpp
|
||||
widgets/buttons/TitlebarButton.hpp
|
||||
widgets/buttons/TitlebarButtons.cpp
|
||||
widgets/buttons/TitlebarButtons.hpp
|
||||
|
||||
widgets/dialogs/BadgePickerDialog.cpp
|
||||
widgets/dialogs/BadgePickerDialog.hpp
|
||||
widgets/dialogs/ChannelFilterEditorDialog.cpp
|
||||
@@ -660,8 +679,6 @@ set(SOURCE_FILES
|
||||
widgets/helper/color/SBCanvas.cpp
|
||||
widgets/helper/color/SBCanvas.hpp
|
||||
|
||||
widgets/helper/Button.cpp
|
||||
widgets/helper/Button.hpp
|
||||
widgets/helper/ChannelView.cpp
|
||||
widgets/helper/ChannelView.hpp
|
||||
widgets/helper/ComboBoxItemDelegate.cpp
|
||||
@@ -670,16 +687,12 @@ set(SOURCE_FILES
|
||||
widgets/helper/DebugPopup.hpp
|
||||
widgets/helper/EditableModelView.cpp
|
||||
widgets/helper/EditableModelView.hpp
|
||||
widgets/helper/EffectLabel.cpp
|
||||
widgets/helper/EffectLabel.hpp
|
||||
widgets/helper/IconDelegate.cpp
|
||||
widgets/helper/IconDelegate.hpp
|
||||
widgets/helper/InvisibleSizeGrip.cpp
|
||||
widgets/helper/InvisibleSizeGrip.hpp
|
||||
widgets/helper/MessageView.cpp
|
||||
widgets/helper/MessageView.hpp
|
||||
widgets/helper/NotebookButton.cpp
|
||||
widgets/helper/NotebookButton.hpp
|
||||
widgets/helper/NotebookTab.cpp
|
||||
widgets/helper/NotebookTab.hpp
|
||||
widgets/helper/OverlayInteraction.cpp
|
||||
@@ -694,14 +707,8 @@ set(SOURCE_FILES
|
||||
widgets/helper/SearchPopup.hpp
|
||||
widgets/helper/SettingsDialogTab.cpp
|
||||
widgets/helper/SettingsDialogTab.hpp
|
||||
widgets/helper/SignalLabel.cpp
|
||||
widgets/helper/SignalLabel.hpp
|
||||
widgets/helper/TableStyles.cpp
|
||||
widgets/helper/TableStyles.hpp
|
||||
widgets/helper/TitlebarButton.cpp
|
||||
widgets/helper/TitlebarButton.hpp
|
||||
widgets/helper/TitlebarButtons.cpp
|
||||
widgets/helper/TitlebarButtons.hpp
|
||||
widgets/helper/TrimRegExpValidator.cpp
|
||||
widgets/helper/TrimRegExpValidator.hpp
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace pajlada {
|
||||
namespace Signals {
|
||||
class SignalHolder;
|
||||
}
|
||||
} // namespace pajlada
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class Button;
|
||||
class UpdateDialog;
|
||||
|
||||
void initUpdateButton(Button &button,
|
||||
pajlada::Signals::SignalHolder &signalHolder);
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -8,8 +8,9 @@
|
||||
#include "util/DebugCount.hpp"
|
||||
#include "util/PostToThread.hpp"
|
||||
#include "util/WindowsHelper.hpp"
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
#include "widgets/helper/TitlebarButtons.hpp"
|
||||
#include "widgets/buttons/LabelButton.hpp"
|
||||
#include "widgets/buttons/TitlebarButton.hpp"
|
||||
#include "widgets/buttons/TitlebarButtons.hpp"
|
||||
#include "widgets/Label.hpp"
|
||||
#include "widgets/Window.hpp"
|
||||
|
||||
@@ -35,8 +36,6 @@
|
||||
# include <QOperatingSystemVersion>
|
||||
#endif
|
||||
|
||||
#include "widgets/helper/TitlebarButton.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace chatterino;
|
||||
@@ -672,34 +671,21 @@ void BaseWindow::focusOutEvent(QFocusEvent *event)
|
||||
BaseWidget::focusOutEvent(event);
|
||||
}
|
||||
|
||||
TitleBarButton *BaseWindow::addTitleBarButton(const TitleBarButtonStyle &style,
|
||||
std::function<void()> onClicked)
|
||||
void BaseWindow::appendTitlebarButton(Button *button)
|
||||
{
|
||||
TitleBarButton *button = new TitleBarButton;
|
||||
button->setScaleIndependentSize(30, 30);
|
||||
|
||||
this->ui_.buttons.push_back(button);
|
||||
this->ui_.titlebarBox->insertWidget(1, button);
|
||||
button->setButtonStyle(style);
|
||||
|
||||
QObject::connect(button, &TitleBarButton::leftClicked, this, [onClicked] {
|
||||
onClicked();
|
||||
});
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
EffectLabel *BaseWindow::addTitleBarLabel(std::function<void()> onClicked)
|
||||
LabelButton *BaseWindow::addTitleBarLabel(std::function<void()> onClicked)
|
||||
{
|
||||
EffectLabel *button = new EffectLabel;
|
||||
auto *button = new LabelButton;
|
||||
button->setScaleIndependentHeight(30);
|
||||
|
||||
this->ui_.buttons.push_back(button);
|
||||
this->ui_.titlebarBox->insertWidget(1, button);
|
||||
this->appendTitlebarButton(button);
|
||||
|
||||
QObject::connect(button, &EffectLabel::leftClicked, this, [onClicked] {
|
||||
onClicked();
|
||||
});
|
||||
QObject::connect(button, &LabelButton::leftClicked, this,
|
||||
std::move(onClicked));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,11 @@ typedef struct tagMSG MSG;
|
||||
namespace chatterino {
|
||||
|
||||
class Button;
|
||||
class EffectLabel;
|
||||
class LabelButton;
|
||||
class PixmapButton;
|
||||
class TitleBarButton;
|
||||
class TitleBarButtons;
|
||||
enum class TitleBarButtonStyle;
|
||||
enum class TitleBarButtonStyle : std::uint8_t;
|
||||
|
||||
class BaseWindow : public BaseWidget
|
||||
{
|
||||
@@ -52,9 +53,20 @@ public:
|
||||
|
||||
QWidget *getLayoutContainer();
|
||||
bool hasCustomWindowFrame() const;
|
||||
TitleBarButton *addTitleBarButton(const TitleBarButtonStyle &style,
|
||||
std::function<void()> onClicked);
|
||||
EffectLabel *addTitleBarLabel(std::function<void()> onClicked);
|
||||
|
||||
template <typename T>
|
||||
T *addTitleBarButton(std::function<void()> onClicked, auto &&...args)
|
||||
{
|
||||
auto *button = new T(std::forward<decltype(args)>(args)...);
|
||||
button->setScaleIndependentSize(30, 30);
|
||||
this->appendTitlebarButton(button);
|
||||
|
||||
QObject::connect(button, &T::leftClicked, this, std::move(onClicked));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
LabelButton *addTitleBarLabel(std::function<void()> onClicked);
|
||||
|
||||
void moveTo(QPoint point, widgets::BoundsChecking mode);
|
||||
|
||||
@@ -169,6 +181,8 @@ private:
|
||||
bool handleNCHITTEST(MSG *msg, long *result);
|
||||
#endif
|
||||
|
||||
void appendTitlebarButton(Button *button);
|
||||
|
||||
bool enableCustomFrame_;
|
||||
bool frameless_;
|
||||
bool shown_ = false;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "singletons/Resources.hpp"
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/buttons/PixmapButton.hpp"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
@@ -119,7 +119,7 @@ void DraggablePopup::togglePinned()
|
||||
}
|
||||
Button *DraggablePopup::createPinButton()
|
||||
{
|
||||
this->pinButton_ = new Button(this);
|
||||
this->pinButton_ = new PixmapButton(this);
|
||||
this->pinButton_->setPixmap(getTheme()->buttons.pin);
|
||||
this->pinButton_->setScaleIndependentSize(18, 18);
|
||||
this->pinButton_->setToolTip("Pin Window");
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class PixmapButton;
|
||||
|
||||
class DraggablePopup : public BaseWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -60,7 +62,7 @@ private:
|
||||
// dragTimer_ is called ~60 times per second once the user has initiated dragging
|
||||
QTimer dragTimer_;
|
||||
|
||||
Button *pinButton_ = nullptr;
|
||||
PixmapButton *pinButton_ = nullptr;
|
||||
bool isPinned_ = false;
|
||||
};
|
||||
|
||||
|
||||
+11
-21
@@ -10,10 +10,11 @@
|
||||
#include "singletons/StreamerMode.hpp"
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/InitUpdateButton.hpp"
|
||||
#include "widgets/buttons/InitUpdateButton.hpp"
|
||||
#include "widgets/buttons/NotebookButton.hpp"
|
||||
#include "widgets/buttons/PixmapButton.hpp"
|
||||
#include "widgets/dialogs/SettingsDialog.hpp"
|
||||
#include "widgets/helper/ChannelView.hpp"
|
||||
#include "widgets/helper/NotebookButton.hpp"
|
||||
#include "widgets/helper/NotebookTab.hpp"
|
||||
#include "widgets/splits/Split.hpp"
|
||||
#include "widgets/splits/SplitContainer.hpp"
|
||||
@@ -1162,16 +1163,6 @@ NotebookButton *Notebook::getAddButton()
|
||||
return this->addButton_;
|
||||
}
|
||||
|
||||
NotebookButton *Notebook::addCustomButton()
|
||||
{
|
||||
NotebookButton *btn = new NotebookButton(this);
|
||||
|
||||
this->customButtons_.push_back(btn);
|
||||
|
||||
this->performLayout();
|
||||
return btn;
|
||||
}
|
||||
|
||||
NotebookTab *Notebook::getTabFromPage(QWidget *page)
|
||||
{
|
||||
for (auto &it : this->items_)
|
||||
@@ -1416,7 +1407,7 @@ void SplitNotebook::showEvent(QShowEvent * /*event*/)
|
||||
void SplitNotebook::addCustomButtons()
|
||||
{
|
||||
// settings
|
||||
auto *settingsBtn = this->addCustomButton();
|
||||
auto *settingsBtn = this->addCustomButton<NotebookButton>();
|
||||
|
||||
// This is to ensure you can't lock yourself out of the settings
|
||||
if (getApp()->getArgs().safeMode)
|
||||
@@ -1442,7 +1433,7 @@ void SplitNotebook::addCustomButtons()
|
||||
});
|
||||
|
||||
// account
|
||||
auto *userBtn = this->addCustomButton();
|
||||
auto *userBtn = this->addCustomButton<NotebookButton>();
|
||||
userBtn->setVisible(!getSettings()->hideUserButton.getValue());
|
||||
getSettings()->hideUserButton.connect(
|
||||
[userBtn](bool hide, auto) {
|
||||
@@ -1457,17 +1448,16 @@ void SplitNotebook::addCustomButtons()
|
||||
});
|
||||
|
||||
// updates
|
||||
auto *updateBtn = this->addCustomButton();
|
||||
auto *updateBtn = this->addCustomButton<PixmapButton>();
|
||||
|
||||
initUpdateButton(*updateBtn, this->signalHolder_);
|
||||
|
||||
// streamer mode
|
||||
this->streamerModeIcon_ = this->addCustomButton();
|
||||
QObject::connect(this->streamerModeIcon_, &NotebookButton::leftClicked,
|
||||
[this] {
|
||||
getApp()->getWindows()->showSettingsDialog(
|
||||
this, SettingsDialogPreference::StreamerMode);
|
||||
});
|
||||
this->streamerModeIcon_ = this->addCustomButton<PixmapButton>();
|
||||
QObject::connect(this->streamerModeIcon_, &Button::leftClicked, [this] {
|
||||
getApp()->getWindows()->showSettingsDialog(
|
||||
this, SettingsDialogPreference::StreamerMode);
|
||||
});
|
||||
QObject::connect(getApp()->getStreamerMode(), &IStreamerMode::changed, this,
|
||||
&SplitNotebook::updateStreamerModeIcon);
|
||||
this->updateStreamerModeIcon();
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class Button;
|
||||
class PixmapButton;
|
||||
class SvgButton;
|
||||
class Window;
|
||||
class UpdateDialog;
|
||||
class NotebookButton;
|
||||
@@ -131,7 +134,16 @@ protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
|
||||
NotebookButton *getAddButton();
|
||||
NotebookButton *addCustomButton();
|
||||
|
||||
template <typename T>
|
||||
T *addCustomButton(auto &&...args)
|
||||
{
|
||||
auto *btn = new T(std::forward<decltype(args)>(args)..., this);
|
||||
this->customButtons_.push_back(btn);
|
||||
this->performLayout();
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
struct Item {
|
||||
NotebookTab *tab{};
|
||||
@@ -206,7 +218,7 @@ private:
|
||||
QWidget *selectedPage_ = nullptr;
|
||||
|
||||
NotebookButton *addButton_;
|
||||
std::vector<NotebookButton *> customButtons_;
|
||||
std::vector<Button *> customButtons_;
|
||||
|
||||
bool allowUserTabManagement_ = false;
|
||||
bool showTabs_ = true;
|
||||
@@ -261,7 +273,7 @@ private:
|
||||
pajlada::Signals::SignalHolder signalHolder_;
|
||||
|
||||
// Main window on Windows has basically a duplicate of this in Window
|
||||
NotebookButton *streamerModeIcon_{};
|
||||
PixmapButton *streamerModeIcon_{};
|
||||
void updateStreamerModeIcon();
|
||||
};
|
||||
|
||||
|
||||
+13
-10
@@ -17,16 +17,17 @@
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "singletons/Updates.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/InitUpdateButton.hpp"
|
||||
#include "util/RapidJsonSerializeQSize.hpp"
|
||||
#include "widgets/AccountSwitchPopup.hpp"
|
||||
#include "widgets/buttons/InitUpdateButton.hpp"
|
||||
#include "widgets/buttons/LabelButton.hpp"
|
||||
#include "widgets/buttons/PixmapButton.hpp"
|
||||
#include "widgets/buttons/TitlebarButton.hpp"
|
||||
#include "widgets/dialogs/SettingsDialog.hpp"
|
||||
#include "widgets/dialogs/switcher/QuickSwitcherPopup.hpp"
|
||||
#include "widgets/dialogs/UpdateDialog.hpp"
|
||||
#include "widgets/dialogs/WelcomeDialog.hpp"
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
#include "widgets/helper/NotebookTab.hpp"
|
||||
#include "widgets/helper/TitlebarButton.hpp"
|
||||
#include "widgets/Notebook.hpp"
|
||||
#include "widgets/splits/ClosedSplits.hpp"
|
||||
#include "widgets/splits/Split.hpp"
|
||||
@@ -202,12 +203,14 @@ void Window::addCustomTitlebarButtons()
|
||||
}
|
||||
|
||||
// settings
|
||||
this->addTitleBarButton(TitleBarButtonStyle::Settings, [this] {
|
||||
getApp()->getWindows()->showSettingsDialog(this);
|
||||
});
|
||||
this->addTitleBarButton<TitleBarButton>(
|
||||
[this] {
|
||||
getApp()->getWindows()->showSettingsDialog(this);
|
||||
},
|
||||
TitleBarButtonStyle::Settings);
|
||||
|
||||
// updates
|
||||
auto *update = this->addTitleBarButton(TitleBarButtonStyle::None, [] {});
|
||||
auto *update = this->addTitleBarButton<PixmapButton>([] {});
|
||||
|
||||
initUpdateButton(*update, this->signalHolder_);
|
||||
|
||||
@@ -221,7 +224,7 @@ void Window::addCustomTitlebarButtons()
|
||||
|
||||
// streamer mode
|
||||
this->streamerModeTitlebarIcon_ =
|
||||
this->addTitleBarButton(TitleBarButtonStyle::StreamerMode, [this] {
|
||||
this->addTitleBarButton<PixmapButton>([this] {
|
||||
getApp()->getWindows()->showSettingsDialog(
|
||||
this, SettingsDialogPreference::StreamerMode);
|
||||
});
|
||||
@@ -796,11 +799,11 @@ void Window::onAccountSelected()
|
||||
{
|
||||
if (user->isAnon())
|
||||
{
|
||||
this->userLabel_->getLabel().setText("anonymous");
|
||||
this->userLabel_->setText("anonymous");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->userLabel_->getLabel().setText(user->getUserName());
|
||||
this->userLabel_->setText(user->getUserName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class PixmapButton;
|
||||
class LabelButton;
|
||||
class Theme;
|
||||
class UpdateDialog;
|
||||
class SplitNotebook;
|
||||
@@ -46,14 +48,14 @@ private:
|
||||
WindowType type_;
|
||||
|
||||
SplitNotebook *notebook_;
|
||||
EffectLabel *userLabel_ = nullptr;
|
||||
LabelButton *userLabel_ = nullptr;
|
||||
std::shared_ptr<UpdateDialog> updateDialogHandle_;
|
||||
|
||||
pajlada::Signals::SignalHolder signalHolder_;
|
||||
std::vector<boost::signals2::scoped_connection> bSignals_;
|
||||
|
||||
// this is only used on Windows and only on the main window, for the one used otherwise, see SplitNotebook in Notebook.hpp
|
||||
TitleBarButton *streamerModeTitlebarIcon_ = nullptr;
|
||||
PixmapButton *streamerModeTitlebarIcon_ = nullptr;
|
||||
void updateStreamerModeIcon();
|
||||
|
||||
friend class Notebook;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/buttons/Button.hpp"
|
||||
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "util/FunctionEventFilter.hpp"
|
||||
@@ -8,42 +8,6 @@
|
||||
#include <QPainter>
|
||||
#include <QScreen>
|
||||
|
||||
namespace {
|
||||
|
||||
QSizeF deviceIndependentSize(const QPixmap &pixmap)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 2, 0)
|
||||
return QSizeF(pixmap.width(), pixmap.height()) / pixmap.devicePixelRatio();
|
||||
#else
|
||||
return pixmap.deviceIndependentSize();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes a pixmap to a desired size.
|
||||
* Does nothing if the target pixmap is already sized correctly.
|
||||
*
|
||||
* @param target The target pixmap.
|
||||
* @param source The unscaled pixmap.
|
||||
* @param size The desired device independent size.
|
||||
* @param dpr The device pixel ratio of the target area. The size of the target in pixels will be `size * dpr`.
|
||||
*/
|
||||
void resizePixmap(QPixmap &target, const QPixmap &source, const QSize &size,
|
||||
qreal dpr)
|
||||
{
|
||||
if (deviceIndependentSize(target) == size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QPixmap resized = source;
|
||||
resized.setDevicePixelRatio(dpr);
|
||||
target = resized.scaled(size * dpr, Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
Button::Button(BaseWidget *parent)
|
||||
@@ -58,98 +22,36 @@ Button::Button(BaseWidget *parent)
|
||||
this->setMouseTracking(true);
|
||||
}
|
||||
|
||||
void Button::setMouseEffectColor(std::optional<QColor> color)
|
||||
{
|
||||
this->mouseEffectColor_ = std::move(color);
|
||||
}
|
||||
|
||||
void Button::setPixmap(const QPixmap &_pixmap)
|
||||
{
|
||||
// Avoid updates if the pixmap didn't change
|
||||
if (_pixmap.cacheKey() == this->pixmap_.cacheKey())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->pixmap_ = _pixmap;
|
||||
this->resizedPixmap_ = {};
|
||||
this->update();
|
||||
}
|
||||
|
||||
void Button::setSvgResource(const QString &resourcePath)
|
||||
{
|
||||
if (resourcePath == this->svgResourcePath)
|
||||
{
|
||||
// Same resource path as before - nothing changed
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->svgRenderer)
|
||||
{
|
||||
this->svgRenderer->deleteLater();
|
||||
}
|
||||
this->svgRenderer = new QSvgRenderer(resourcePath, this);
|
||||
this->svgRenderer->setAspectRatioMode(Qt::KeepAspectRatio);
|
||||
this->svgResourcePath = resourcePath;
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
const QPixmap &Button::getPixmap() const
|
||||
{
|
||||
return this->pixmap_;
|
||||
}
|
||||
|
||||
void Button::setDim(Dim value)
|
||||
{
|
||||
this->dimPixmap_ = value;
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
Button::Dim Button::getDim() const
|
||||
{
|
||||
return this->dimPixmap_;
|
||||
}
|
||||
|
||||
void Button::setEnable(bool value)
|
||||
{
|
||||
this->enabled_ = value;
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
bool Button::getEnable() const
|
||||
bool Button::enabled() const noexcept
|
||||
{
|
||||
return this->enabled_;
|
||||
}
|
||||
|
||||
void Button::setEnableMargin(bool value)
|
||||
void Button::setEnabled(bool enabled)
|
||||
{
|
||||
this->enableMargin_ = value;
|
||||
this->enabled_ = enabled;
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
bool Button::getEnableMargin() const
|
||||
bool Button::mouseOver() const noexcept
|
||||
{
|
||||
return this->enableMargin_;
|
||||
return this->mouseOver_;
|
||||
}
|
||||
|
||||
qreal Button::getCurrentDimAmount() const
|
||||
bool Button::mouseDown() const noexcept
|
||||
{
|
||||
if (this->dimPixmap_ == Dim::None || this->mouseOver_)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (this->dimPixmap_ == Dim::Some)
|
||||
{
|
||||
return 0.7;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.15;
|
||||
}
|
||||
return this->mouseDown_;
|
||||
}
|
||||
|
||||
bool Button::menuVisible() const noexcept
|
||||
{
|
||||
return this->menuVisible_;
|
||||
}
|
||||
|
||||
QColor Button::borderColor() const noexcept
|
||||
{
|
||||
return this->borderColor_;
|
||||
}
|
||||
|
||||
void Button::setBorderColor(const QColor &color)
|
||||
@@ -159,9 +61,19 @@ void Button::setBorderColor(const QColor &color)
|
||||
this->update();
|
||||
}
|
||||
|
||||
const QColor &Button::getBorderColor() const
|
||||
std::optional<QColor> Button::mouseEffectColor() const
|
||||
{
|
||||
return this->borderColor_;
|
||||
return this->mouseEffectColor_;
|
||||
}
|
||||
|
||||
void Button::setMouseEffectColor(std::optional<QColor> color)
|
||||
{
|
||||
this->mouseEffectColor_ = color;
|
||||
}
|
||||
|
||||
QMenu *Button::menu() const
|
||||
{
|
||||
return this->menu_.get();
|
||||
}
|
||||
|
||||
void Button::setMenu(std::unique_ptr<QMenu> menu)
|
||||
@@ -185,104 +97,45 @@ void Button::setMenu(std::unique_ptr<QMenu> menu)
|
||||
}));
|
||||
}
|
||||
|
||||
void Button::paintEvent(QPaintEvent *)
|
||||
void Button::paintEvent(QPaintEvent * /*event*/)
|
||||
{
|
||||
QPainter painter(this);
|
||||
this->paintButton(painter);
|
||||
}
|
||||
|
||||
void Button::paintButton(QPainter &painter)
|
||||
void Button::invalidateContent()
|
||||
{
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
if (this->svgRenderer != nullptr)
|
||||
{
|
||||
painter.setOpacity(this->getCurrentDimAmount());
|
||||
|
||||
auto rect = this->rect();
|
||||
|
||||
if (this->enableMargin_)
|
||||
{
|
||||
auto s = this->getMargin();
|
||||
rect = {{s, s}, rect.size() - QSize{2 * s, 2 * s}};
|
||||
}
|
||||
|
||||
this->svgRenderer->render(&painter, rect);
|
||||
}
|
||||
else if (!this->pixmap_.isNull())
|
||||
{
|
||||
painter.setOpacity(this->getCurrentDimAmount());
|
||||
|
||||
QRect rect = this->rect();
|
||||
|
||||
resizePixmap(this->resizedPixmap_, this->pixmap_, rect.size(),
|
||||
this->devicePixelRatio());
|
||||
|
||||
if (this->enableMargin_)
|
||||
{
|
||||
auto s = this->getMargin();
|
||||
rect.moveLeft(s);
|
||||
rect.setRight(rect.right() - s - s);
|
||||
rect.moveTop(s);
|
||||
rect.setBottom(rect.bottom() - s - s);
|
||||
}
|
||||
|
||||
painter.drawPixmap(rect, this->resizedPixmap_);
|
||||
|
||||
painter.setOpacity(1);
|
||||
}
|
||||
|
||||
this->fancyPaint(painter);
|
||||
|
||||
if (this->borderColor_.isValid())
|
||||
{
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
painter.setPen(this->borderColor_);
|
||||
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
|
||||
}
|
||||
this->pixmapValid_ = false;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void Button::fancyPaint(QPainter &painter)
|
||||
bool Button::contentCacheEnabled() const noexcept
|
||||
{
|
||||
if (!this->enabled_)
|
||||
return this->cachePixmap_;
|
||||
}
|
||||
|
||||
void Button::setContentCacheEnabled(bool enabled)
|
||||
{
|
||||
if (this->cachePixmap_ == enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QColor c;
|
||||
|
||||
if (this->mouseEffectColor_)
|
||||
if (!enabled)
|
||||
{
|
||||
c = *this->mouseEffectColor_;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = this->theme->isLightTheme() ? QColor(0, 0, 0)
|
||||
: QColor(255, 255, 255);
|
||||
this->cachedPixmap_ = {};
|
||||
}
|
||||
this->cachePixmap_ = enabled;
|
||||
}
|
||||
|
||||
if (this->hoverMultiplier_ > 0)
|
||||
{
|
||||
QRadialGradient gradient(QPointF(mousePos_), this->width() / 2);
|
||||
bool Button::opaqueContent() const noexcept
|
||||
{
|
||||
return this->opaqueContent_;
|
||||
}
|
||||
|
||||
gradient.setColorAt(0, QColor(c.red(), c.green(), c.blue(),
|
||||
int(50 * this->hoverMultiplier_)));
|
||||
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(),
|
||||
int(40 * this->hoverMultiplier_)));
|
||||
|
||||
painter.fillRect(this->rect(), gradient);
|
||||
}
|
||||
|
||||
for (auto effect : this->clickEffects_)
|
||||
{
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QColor(c.red(), c.green(), c.blue(),
|
||||
int((1 - effect.progress) * 95)));
|
||||
painter.drawEllipse(QPointF(effect.position),
|
||||
effect.progress * qreal(width()) * 2,
|
||||
effect.progress * qreal(width()) * 2);
|
||||
}
|
||||
void Button::setOpaqueContent(bool opaqueContent)
|
||||
{
|
||||
this->opaqueContent_ = opaqueContent;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
@@ -319,7 +172,7 @@ void Button::mousePressEvent(QMouseEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
this->clickEffects_.push_back(ClickEffect(event->pos()));
|
||||
this->clickEffects_.emplace_back(event->pos());
|
||||
|
||||
this->mouseDown_ = true;
|
||||
|
||||
@@ -374,16 +227,7 @@ void Button::onMouseEffectTimeout()
|
||||
{
|
||||
bool performUpdate = false;
|
||||
|
||||
if (selected_)
|
||||
{
|
||||
if (this->hoverMultiplier_ != 0)
|
||||
{
|
||||
this->hoverMultiplier_ =
|
||||
std::max(0.0, this->hoverMultiplier_ - 0.1);
|
||||
performUpdate = true;
|
||||
}
|
||||
}
|
||||
else if (mouseOver_)
|
||||
if (mouseOver_)
|
||||
{
|
||||
if (this->hoverMultiplier_ != 1)
|
||||
{
|
||||
@@ -402,7 +246,7 @@ void Button::onMouseEffectTimeout()
|
||||
}
|
||||
}
|
||||
|
||||
if (this->clickEffects_.size() != 0)
|
||||
if (!this->clickEffects_.empty())
|
||||
{
|
||||
performUpdate = true;
|
||||
|
||||
@@ -456,13 +300,93 @@ void Button::showMenu()
|
||||
this->menuVisible_ = true;
|
||||
}
|
||||
|
||||
int Button::getMargin() const
|
||||
void Button::paintButton(QPainter &painter)
|
||||
{
|
||||
assert(this->enableMargin_);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
int baseMargin = this->height() < 22 * this->scale() ? 3 : 6;
|
||||
if (this->cachePixmap_)
|
||||
{
|
||||
if (this->cachedPixmap_.size() != this->size())
|
||||
{
|
||||
this->cachedPixmap_ = QPixmap(this->size());
|
||||
this->cachedPixmap_.setDevicePixelRatio(this->devicePixelRatio());
|
||||
this->pixmapValid_ = false;
|
||||
}
|
||||
|
||||
return static_cast<int>(baseMargin * this->scale());
|
||||
if (!this->pixmapValid_)
|
||||
{
|
||||
if (!this->opaqueContent_)
|
||||
{
|
||||
this->cachedPixmap_.fill(Qt::transparent);
|
||||
}
|
||||
|
||||
{
|
||||
QPainter pixmapPainter(&this->cachedPixmap_);
|
||||
this->paintContent(pixmapPainter);
|
||||
}
|
||||
|
||||
this->pixmapValid_ = true;
|
||||
}
|
||||
painter.drawPixmap(this->rect(), this->cachedPixmap_,
|
||||
{{}, this->cachedPixmap_.size()});
|
||||
}
|
||||
else
|
||||
{
|
||||
this->paintContent(painter);
|
||||
}
|
||||
|
||||
this->fancyPaint(painter);
|
||||
|
||||
if (this->borderColor_.isValid())
|
||||
{
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
painter.setPen(this->borderColor_);
|
||||
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Button::fancyPaint(QPainter &painter)
|
||||
{
|
||||
if (!this->enabled_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QColor c;
|
||||
|
||||
if (this->mouseEffectColor_)
|
||||
{
|
||||
c = *this->mouseEffectColor_;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = this->theme->isLightTheme() ? QColor(0, 0, 0)
|
||||
: QColor(255, 255, 255);
|
||||
}
|
||||
|
||||
if (this->hoverMultiplier_ > 0)
|
||||
{
|
||||
QRadialGradient gradient(QPointF(mousePos_),
|
||||
static_cast<qreal>(this->width()) / 2.0);
|
||||
|
||||
gradient.setColorAt(0, QColor(c.red(), c.green(), c.blue(),
|
||||
int(50 * this->hoverMultiplier_)));
|
||||
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(),
|
||||
int(40 * this->hoverMultiplier_)));
|
||||
|
||||
painter.fillRect(this->rect(), gradient);
|
||||
}
|
||||
|
||||
for (auto effect : this->clickEffects_)
|
||||
{
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QColor(c.red(), c.green(), c.blue(),
|
||||
int((1 - effect.progress) * 95)));
|
||||
painter.drawEllipse(QPointF(effect.position),
|
||||
effect.progress * qreal(width()) * 2,
|
||||
effect.progress * qreal(width()) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,211 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/BaseWidget.hpp"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPoint>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/// @brief A generic button with click and hover effects.
|
||||
///
|
||||
/// This button doesn't display anything - subclasses add content to the button.
|
||||
///
|
||||
/// To add content in a derived class, implement #paintContent(). This gets
|
||||
/// called before the click and hover effects are drawn.+
|
||||
///
|
||||
/// Subclasses can enable caching of the content drawn in #paintContent(), as
|
||||
/// the button often repaints due to mouse movement (and the hover effects).
|
||||
/// When updating the button, subclasses can invalidate the cache with
|
||||
/// #invalidateContent(). Alternatively, a subclass opt out of this by calling
|
||||
/// #setContentCacheEnabled().
|
||||
class Button : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
struct ClickEffect {
|
||||
double progress = 0.0;
|
||||
QPoint position;
|
||||
|
||||
ClickEffect(QPoint _position)
|
||||
: position(_position)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
Button(BaseWidget *parent = nullptr);
|
||||
|
||||
/// @brief Returns true if the button is enabled
|
||||
///
|
||||
/// An enabled button will emit interaction events and show mouse effects.
|
||||
/// When disabled, only the content and border is shown.
|
||||
///
|
||||
/// By default, a button is enabled.
|
||||
[[nodiscard]] bool enabled() const noexcept;
|
||||
|
||||
/// Setter for #enabled()
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
/// Returns true if the user is hovering over the button
|
||||
[[nodiscard]] bool mouseOver() const noexcept;
|
||||
|
||||
/// Returns true if the left mouse button is held down
|
||||
[[nodiscard]] bool mouseDown() const noexcept;
|
||||
|
||||
/// @brief Returns true if the menu is visible
|
||||
///
|
||||
/// @sa #menu(), #setMenu()
|
||||
[[nodiscard]] bool menuVisible() const noexcept;
|
||||
|
||||
/// @brief Returns the current border color
|
||||
///
|
||||
/// If no color is set, this will return an invalid color.
|
||||
///
|
||||
/// The border is shown with a width of 1 above all other content if the
|
||||
/// border color is valid.
|
||||
///
|
||||
/// By default, no border color is set.
|
||||
[[nodiscard]] QColor borderColor() const noexcept;
|
||||
|
||||
/// Setter for #borderColor()
|
||||
void setBorderColor(const QColor &color);
|
||||
|
||||
/// @brief Returns the current mouse effect color (if set)
|
||||
///
|
||||
/// The mouse effect color is used for hover and click effects.
|
||||
///
|
||||
/// By default, the color is based on the selected theme.
|
||||
[[nodiscard]] std::optional<QColor> mouseEffectColor() const;
|
||||
|
||||
/// Setter for #mouseEffectColor()
|
||||
void setMouseEffectColor(std::optional<QColor> color);
|
||||
|
||||
/// @brief Returns the menu associated with this button.
|
||||
///
|
||||
/// The menu is shown when pressing the left mouse button.
|
||||
///
|
||||
/// The return value is non-owned.
|
||||
/// If no menu is associated, `nullptr` is returned.
|
||||
///
|
||||
/// @sa #menuVisible(), #leftMousePress()
|
||||
[[nodiscard]] QMenu *menu() const;
|
||||
|
||||
/// Setter for #menu()
|
||||
void setMenu(std::unique_ptr<QMenu> menu);
|
||||
|
||||
Q_SIGNALS:
|
||||
/// @brief Emitted after the user left-clicked the button.
|
||||
///
|
||||
/// A click is only emitted if the user released the mouse above the button
|
||||
/// and the button is enabled.
|
||||
void leftClicked();
|
||||
|
||||
/// @brief Emitted after the user clicked the button with any mouse-button
|
||||
///
|
||||
/// A click is only emitted if the user released the mouse above the button
|
||||
/// and the button is enabled.
|
||||
///
|
||||
/// @sa #leftClicked()
|
||||
void clicked(Qt::MouseButton button);
|
||||
|
||||
/// @brief Emitted when the user presses the left mouse button.
|
||||
///
|
||||
/// Avoid using this event where possible and use #leftClicked().
|
||||
void leftMousePress();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent * /*event*/) override;
|
||||
|
||||
/// @brief Paint the contents to be shown below the button
|
||||
///
|
||||
/// First, the content is painted, then hover and click effects and finally
|
||||
/// the border.
|
||||
/// The content is cached by default as it's assumed to be expensive to
|
||||
/// repaint and repaints can occur frequently.
|
||||
///
|
||||
/// @sa #contentCacheEnabled()
|
||||
virtual void paintContent(QPainter &painter) = 0;
|
||||
|
||||
/// @brief Paint hover and click effects.
|
||||
///
|
||||
/// This is provided for custom setups that override #paintEvent().
|
||||
/// When possible, prefer #paintContent().
|
||||
void fancyPaint(QPainter &painter);
|
||||
|
||||
/// @brief Indicate that the cache is invalid and needs to be repainted.
|
||||
///
|
||||
/// This calls update().
|
||||
void invalidateContent();
|
||||
|
||||
/// @brief Returns true if the content drawn in #paintContent() should be
|
||||
/// cached.
|
||||
///
|
||||
/// For complex static content, this makes sense, as the button is often
|
||||
/// repainted when the user is hovering over it.
|
||||
///
|
||||
/// By default, the cache is disabled.
|
||||
[[nodiscard]] bool contentCacheEnabled() const noexcept;
|
||||
|
||||
/// @brief Setter for #contentCacheEnabled()
|
||||
///
|
||||
/// When disabling the content-cache, the cached pixmap is destroyed.
|
||||
void setContentCacheEnabled(bool enabled);
|
||||
|
||||
/// @brief Returns true if the content drawn in #paintContent() is fully
|
||||
/// opaque.
|
||||
///
|
||||
/// If the content is fully opaque, the cached pixmap isn't filled with a
|
||||
/// transparent color, but left in the default state.
|
||||
///
|
||||
/// @sa #setOpaqueContent()
|
||||
[[nodiscard]] bool opaqueContent() const noexcept;
|
||||
|
||||
/// Setter for #opaqueContent()
|
||||
void setOpaqueContent(bool opaqueContent);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
void enterEvent(QEnterEvent * /*event*/) override;
|
||||
#else
|
||||
void enterEvent(QEvent * /*event*/) override;
|
||||
#endif
|
||||
void leaveEvent(QEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void onMouseEffectTimeout();
|
||||
void showMenu();
|
||||
|
||||
void paintButton(QPainter &painter);
|
||||
|
||||
QColor borderColor_;
|
||||
|
||||
QPoint mousePos_;
|
||||
double hoverMultiplier_ = 0.0;
|
||||
|
||||
std::unique_ptr<QMenu> menu_;
|
||||
|
||||
QTimer effectTimer_;
|
||||
std::vector<ClickEffect> clickEffects_;
|
||||
std::optional<QColor> mouseEffectColor_;
|
||||
|
||||
bool enabled_ = true;
|
||||
bool mouseOver_ = false;
|
||||
bool mouseDown_ = false;
|
||||
bool menuVisible_ = false;
|
||||
|
||||
QPixmap cachedPixmap_;
|
||||
bool pixmapValid_ = false;
|
||||
bool cachePixmap_ = false;
|
||||
bool opaqueContent_ = false;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "widgets/buttons/DimButton.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
DimButton::DimButton(BaseWidget *parent)
|
||||
: Button(parent)
|
||||
{
|
||||
}
|
||||
|
||||
DimButton::Dim DimButton::dim() const noexcept
|
||||
{
|
||||
return this->dim_;
|
||||
}
|
||||
|
||||
void DimButton::setDim(Dim value)
|
||||
{
|
||||
this->dim_ = value;
|
||||
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
qreal DimButton::currentContentOpacity() const noexcept
|
||||
{
|
||||
if (this->dim_ == Dim::None || this->mouseOver())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (this->dim_ == Dim::Some)
|
||||
{
|
||||
return 0.7;
|
||||
}
|
||||
|
||||
return 0.15;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/buttons/Button.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/// @brief A button with a #dim() setting for controlling the opacity of its
|
||||
/// content.
|
||||
///
|
||||
/// This button doesn't paint anything.
|
||||
///
|
||||
/// @sa #currentContentOpacity()
|
||||
class DimButton : public Button
|
||||
{
|
||||
public:
|
||||
enum class Dim : std::uint8_t {
|
||||
/// Fully opaque (100% opcaity)
|
||||
None,
|
||||
/// Slightly transparent (70% opacity)
|
||||
Some,
|
||||
/// Almost transparent (15% opacity)
|
||||
Lots,
|
||||
};
|
||||
|
||||
DimButton(BaseWidget *parent = nullptr);
|
||||
|
||||
/// Returns the current dim level.
|
||||
[[nodiscard]] Dim dim() const noexcept;
|
||||
|
||||
/// Setter for #dim()
|
||||
void setDim(Dim value);
|
||||
|
||||
/// Returns the current opacity based on the current dim level.
|
||||
[[nodiscard]] qreal currentContentOpacity() const noexcept;
|
||||
|
||||
private:
|
||||
Dim dim_ = Dim::Some;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,12 +1,12 @@
|
||||
#include "util/InitUpdateButton.hpp"
|
||||
#include "widgets/buttons/InitUpdateButton.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "widgets/buttons/PixmapButton.hpp"
|
||||
#include "widgets/dialogs/UpdateDialog.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
void initUpdateButton(Button &button,
|
||||
void initUpdateButton(PixmapButton &button,
|
||||
pajlada::Signals::SignalHolder &signalHolder)
|
||||
{
|
||||
button.hide();
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
namespace pajlada::Signals {
|
||||
class SignalHolder;
|
||||
} // namespace pajlada::Signals
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class PixmapButton;
|
||||
class UpdateDialog;
|
||||
|
||||
void initUpdateButton(PixmapButton &button,
|
||||
pajlada::Signals::SignalHolder &signalHolder);
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "widgets/buttons/LabelButton.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
LabelButton::LabelButton(const QString &text, BaseWidget *parent, QSize padding)
|
||||
: Button(parent)
|
||||
, layout_(this)
|
||||
, label_(text)
|
||||
, padding_(padding)
|
||||
{
|
||||
this->layout_.setContentsMargins(0, 0, 0, 0);
|
||||
this->layout_.addWidget(&this->label_);
|
||||
this->label_.setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
this->label_.setAlignment(Qt::AlignCenter);
|
||||
|
||||
this->updatePadding();
|
||||
}
|
||||
|
||||
void LabelButton::setText(const QString &text)
|
||||
{
|
||||
this->label_.setText(text);
|
||||
}
|
||||
|
||||
QSize LabelButton::padding() const noexcept
|
||||
{
|
||||
return this->padding_;
|
||||
}
|
||||
|
||||
void LabelButton::setPadding(QSize padding)
|
||||
{
|
||||
if (this->padding_ == padding)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->padding_ = padding;
|
||||
this->updatePadding();
|
||||
}
|
||||
|
||||
void LabelButton::enableRichText()
|
||||
{
|
||||
this->label_.setTextFormat(Qt::RichText);
|
||||
}
|
||||
|
||||
void LabelButton::paintContent(QPainter &painter)
|
||||
{
|
||||
}
|
||||
|
||||
void LabelButton::updatePadding()
|
||||
{
|
||||
auto x = this->padding_.width();
|
||||
auto y = this->padding_.height();
|
||||
this->label_.setContentsMargins(x, y, x, y);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/buttons/Button.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/// @brief A button with a label on top.
|
||||
///
|
||||
/// The content can be set with #setText(), #setPixmap(), and #setMovie().
|
||||
class LabelButton : public Button
|
||||
{
|
||||
public:
|
||||
LabelButton(const QString &text = {}, BaseWidget *parent = nullptr,
|
||||
QSize padding = {6, 0});
|
||||
|
||||
/// @brief Returns the current text
|
||||
///
|
||||
/// If no text has been set this will return an empty string.
|
||||
[[nodiscard]] QString text() const;
|
||||
|
||||
/// @brief Sets the label's text to @a text.
|
||||
///
|
||||
/// Any previous content is cleared.
|
||||
/// Supports Qt's HTML subset.
|
||||
void setText(const QString &text);
|
||||
|
||||
/// @brief Returns the padding inside the button.
|
||||
///
|
||||
/// `width` is the padding applied horizontally (left and right).
|
||||
/// `height` is the padding applied vertically (top and bottom).
|
||||
///
|
||||
/// By default, the button has no vertical padding and a horizontal padding of 6.
|
||||
[[nodiscard]] QSize padding() const noexcept;
|
||||
|
||||
/// Setter for #padding()
|
||||
void setPadding(QSize padding);
|
||||
|
||||
/// Sets the label to display rich text (Qt's HTML subset)
|
||||
void enableRichText();
|
||||
|
||||
protected:
|
||||
void paintContent(QPainter &painter) override;
|
||||
|
||||
private:
|
||||
void updatePadding();
|
||||
|
||||
QHBoxLayout layout_;
|
||||
QLabel label_;
|
||||
QSize padding_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "widgets/helper/NotebookButton.hpp"
|
||||
#include "widgets/buttons/NotebookButton.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "common/QLogging.hpp"
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/Notebook.hpp"
|
||||
#include "widgets/splits/DraggedSplit.hpp"
|
||||
#include "widgets/splits/Split.hpp"
|
||||
@@ -41,14 +40,12 @@ void NotebookButton::themeChangedEvent()
|
||||
this->setMouseEffectColor(this->theme->tabs.regular.text);
|
||||
}
|
||||
|
||||
void NotebookButton::paintEvent(QPaintEvent *event)
|
||||
void NotebookButton::paintContent(QPainter &painter)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
QColor background;
|
||||
QColor foreground;
|
||||
|
||||
if (mouseDown_ || mouseOver_)
|
||||
if (this->mouseDown() || this->mouseOver())
|
||||
{
|
||||
background = this->theme->tabs.regular.backgrounds.hover;
|
||||
foreground = this->theme->tabs.regular.text;
|
||||
@@ -72,7 +69,7 @@ void NotebookButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
tmp = this->theme->tabs.selected.line.regular;
|
||||
}
|
||||
else if (!this->mouseOver_)
|
||||
else if (!this->mouseOver())
|
||||
{
|
||||
tmp.setAlpha(180);
|
||||
}
|
||||
@@ -136,22 +133,6 @@ void NotebookButton::paintEvent(QPaintEvent *event)
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
this->paintButton(painter);
|
||||
}
|
||||
|
||||
void NotebookButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
mouseDown_ = false;
|
||||
|
||||
update();
|
||||
|
||||
leftClicked();
|
||||
}
|
||||
|
||||
Button::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void NotebookButton::dragEnterEvent(QDragEnterEvent *event)
|
||||
@@ -173,7 +154,6 @@ void NotebookButton::dragEnterEvent(QDragEnterEvent *event)
|
||||
|
||||
void NotebookButton::dragLeaveEvent(QDragLeaveEvent *)
|
||||
{
|
||||
this->mouseDown_ = true;
|
||||
this->update();
|
||||
|
||||
auto *e =
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/buttons/Button.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
@@ -21,9 +21,9 @@ public:
|
||||
Icon getIcon() const;
|
||||
|
||||
protected:
|
||||
void paintContent(QPainter &painter) override;
|
||||
|
||||
void themeChangedEvent() override;
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
void dragEnterEvent(QDragEnterEvent *) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *) override;
|
||||
void dropEvent(QDropEvent *) override;
|
||||
@@ -31,9 +31,6 @@ protected:
|
||||
void hideEvent(QHideEvent *) override;
|
||||
void showEvent(QShowEvent *) override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void leftClicked();
|
||||
|
||||
private:
|
||||
Notebook *parent_ = nullptr;
|
||||
QPoint mousePos_;
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "widgets/buttons/PixmapButton.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Resizes a pixmap to a desired size.
|
||||
* Does nothing if the target pixmap is already sized correctly.
|
||||
*
|
||||
* @param target The target pixmap.
|
||||
* @param source The unscaled pixmap.
|
||||
* @param size The desired device independent size.
|
||||
* @param dpr The device pixel ratio of the target area. The size of the target in pixels will be `size * dpr`.
|
||||
*/
|
||||
void resizePixmap(QPixmap &target, const QPixmap &source, const QSize &size,
|
||||
qreal dpr)
|
||||
{
|
||||
if (target.deviceIndependentSize() == size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QPixmap resized = source;
|
||||
resized.setDevicePixelRatio(dpr);
|
||||
target = resized.scaled(size * dpr, Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
PixmapButton::PixmapButton(BaseWidget *parent)
|
||||
: DimButton(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QPixmap PixmapButton::pixmap() const
|
||||
{
|
||||
return this->pixmap_;
|
||||
}
|
||||
|
||||
void PixmapButton::setPixmap(const QPixmap &pixmap)
|
||||
{
|
||||
// Avoid updates if the pixmap didn't change
|
||||
if (pixmap.cacheKey() == this->pixmap_.cacheKey())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->pixmap_ = pixmap;
|
||||
this->resizedPixmap_ = {};
|
||||
this->update();
|
||||
}
|
||||
|
||||
bool PixmapButton::marginEnabled() const noexcept
|
||||
{
|
||||
return this->marginEnabled_;
|
||||
}
|
||||
|
||||
void PixmapButton::setMarginEnabled(bool enableMargin)
|
||||
{
|
||||
this->marginEnabled_ = enableMargin;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void PixmapButton::paintContent(QPainter &painter)
|
||||
{
|
||||
if (this->pixmap_.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
painter.setOpacity(this->currentContentOpacity());
|
||||
|
||||
QRect rect = this->rect();
|
||||
|
||||
int shift = 0;
|
||||
if (this->marginEnabled_)
|
||||
{
|
||||
int margin =
|
||||
this->height() < static_cast<int>(22 * this->scale()) ? 3 : 6;
|
||||
|
||||
shift = static_cast<int>(static_cast<float>(margin) * this->scale());
|
||||
}
|
||||
|
||||
rect.moveLeft(shift);
|
||||
rect.setRight(rect.right() - (2 * shift));
|
||||
rect.moveTop(shift);
|
||||
rect.setBottom(rect.bottom() - (2 * shift));
|
||||
|
||||
resizePixmap(this->resizedPixmap_, this->pixmap_, rect.size(),
|
||||
this->devicePixelRatio());
|
||||
|
||||
painter.drawPixmap(rect, this->resizedPixmap_);
|
||||
|
||||
painter.setOpacity(1);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/buttons/DimButton.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/// @brief A (dimmable) button displaying a pixmap.
|
||||
///
|
||||
/// The pixmap is scaled to fit the button, ignoring any aspect ratio.
|
||||
///
|
||||
/// By default, a margin is added to the button (@see #marginEnabled()).
|
||||
///
|
||||
/// When possible, prefer using a `SvgButton` as it can scale its contents
|
||||
/// to any size without blur and supports scaling and themeing.
|
||||
///
|
||||
/// @sa #setPixmap()
|
||||
class PixmapButton : public DimButton
|
||||
{
|
||||
public:
|
||||
PixmapButton(BaseWidget *parent = nullptr);
|
||||
|
||||
/// Returns the current, non-scaled pixmap
|
||||
[[nodiscard]] QPixmap pixmap() const;
|
||||
|
||||
/// Setter for #pixmap()
|
||||
void setPixmap(const QPixmap &pixmap);
|
||||
|
||||
/// @brief Returns true if this button has margin.
|
||||
///
|
||||
/// The margin is dynamically calculated based on the UI-scale
|
||||
/// and the size of the pixmap.
|
||||
[[nodiscard]] bool marginEnabled() const noexcept;
|
||||
|
||||
/// Setter for #marginEnabled()
|
||||
void setMarginEnabled(bool enableMargin);
|
||||
|
||||
protected:
|
||||
void paintContent(QPainter &painter) override;
|
||||
|
||||
private:
|
||||
QPixmap pixmap_;
|
||||
QPixmap resizedPixmap_;
|
||||
bool marginEnabled_ = true;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "widgets/helper/SignalLabel.hpp"
|
||||
#include "widgets/buttons/SignalLabel.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "widgets/buttons/SvgButton.hpp"
|
||||
|
||||
#include "singletons/Theme.hpp"
|
||||
|
||||
#include <QSvgRenderer>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
SvgButton::SvgButton(Src source, BaseWidget *parent, QSize padding)
|
||||
: Button(parent)
|
||||
, source_(std::move(source))
|
||||
, svg_(new QSvgRenderer(this->currentSvgPath(), this))
|
||||
, padding_(padding)
|
||||
{
|
||||
this->svg_->setAspectRatioMode(Qt::KeepAspectRatio);
|
||||
this->setContentCacheEnabled(true);
|
||||
}
|
||||
|
||||
void SvgButton::setSource(Src source)
|
||||
{
|
||||
this->source_ = std::move(source);
|
||||
this->svg_->load(this->currentSvgPath());
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
void SvgButton::setPadding(QSize padding)
|
||||
{
|
||||
if (this->padding_ == padding)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->padding_ = padding;
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
void SvgButton::themeChangedEvent()
|
||||
{
|
||||
Button::themeChangedEvent();
|
||||
|
||||
if (this->source_.dark == this->source_.light)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->svg_->load(this->currentSvgPath());
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
void SvgButton::scaleChangedEvent(float scale)
|
||||
{
|
||||
Button::scaleChangedEvent(scale);
|
||||
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
void SvgButton::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
Button::resizeEvent(e);
|
||||
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
void SvgButton::paintContent(QPainter &painter)
|
||||
{
|
||||
QSize actualPadding = this->scale() * this->padding_;
|
||||
QPoint topLeft{actualPadding.width(), actualPadding.height()};
|
||||
QSize contentSize = this->size() - 2 * actualPadding;
|
||||
this->svg_->render(&painter, {topLeft, contentSize});
|
||||
}
|
||||
|
||||
QString SvgButton::currentSvgPath() const
|
||||
{
|
||||
if (this->theme->isLightTheme())
|
||||
{
|
||||
return this->source_.light;
|
||||
}
|
||||
return this->source_.dark;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/buttons/Button.hpp"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QSvgRenderer;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/// @brief A button displaying SVGs.
|
||||
///
|
||||
/// The source can be specified per theme (dark/light)
|
||||
/// and will get automatically updated when the theme changes.
|
||||
///
|
||||
/// To set the size, use #setInnerHeight(). The width is adjusted according
|
||||
/// to the aspect ratio of the SVG. If the button should scale with the UI,
|
||||
/// turn on auto-scaling (@see #setAutoScale()), which will scale the button
|
||||
/// and padding according to the current UI-scale (linearly).
|
||||
///
|
||||
/// The button has #padding() around the SVG.
|
||||
class SvgButton : public Button
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Source configuration for the button
|
||||
struct Src {
|
||||
/// Source to load in a dark theme
|
||||
QString dark;
|
||||
/// Source to load in a light theme
|
||||
QString light;
|
||||
};
|
||||
|
||||
[[nodiscard]] SvgButton(Src source, BaseWidget *parent = nullptr,
|
||||
QSize padding = {6, 3});
|
||||
|
||||
/// Returns the current source configuration.
|
||||
[[nodiscard]] Src source() const;
|
||||
|
||||
/// Setter for #source()
|
||||
void setSource(Src source);
|
||||
|
||||
/// @brief Returns the padding inside the button.
|
||||
///
|
||||
/// `width` is the padding applied horizontally (left and right).
|
||||
/// `height` is the padding applied vertically (top and bottom).
|
||||
///
|
||||
/// By default, the button has a vertical padding of 3 and a horizontal padding of 6.
|
||||
[[nodiscard]] QSize padding() const;
|
||||
|
||||
/// Setter for #padding()
|
||||
void setPadding(QSize padding);
|
||||
|
||||
protected:
|
||||
void themeChangedEvent() override;
|
||||
void scaleChangedEvent(float scale) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
void paintContent(QPainter &painter) override;
|
||||
|
||||
private:
|
||||
[[nodiscard]] QString currentSvgPath() const;
|
||||
|
||||
Src source_;
|
||||
QSvgRenderer *svg_;
|
||||
QSize padding_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "widgets/helper/TitlebarButton.hpp"
|
||||
#include "widgets/buttons/TitlebarButton.hpp"
|
||||
|
||||
#include "singletons/Theme.hpp"
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
TitleBarButton::TitleBarButton()
|
||||
: Button(nullptr)
|
||||
TitleBarButton::TitleBarButton(TitleBarButtonStyle style)
|
||||
: DimButton(nullptr)
|
||||
, style_(style)
|
||||
{
|
||||
this->setContentCacheEnabled(true);
|
||||
}
|
||||
|
||||
TitleBarButtonStyle TitleBarButton::getButtonStyle() const
|
||||
@@ -16,17 +18,20 @@ TitleBarButtonStyle TitleBarButton::getButtonStyle() const
|
||||
return this->style_;
|
||||
}
|
||||
|
||||
void TitleBarButton::setButtonStyle(TitleBarButtonStyle _style)
|
||||
void TitleBarButton::setButtonStyle(TitleBarButtonStyle style)
|
||||
{
|
||||
this->style_ = _style;
|
||||
this->update();
|
||||
this->style_ = style;
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
void TitleBarButton::paintEvent(QPaintEvent *event)
|
||||
void TitleBarButton::themeChangedEvent()
|
||||
{
|
||||
QPainter painter(this);
|
||||
this->invalidateContent();
|
||||
}
|
||||
|
||||
painter.setOpacity(this->getCurrentDimAmount());
|
||||
void TitleBarButton::paintContent(QPainter &painter)
|
||||
{
|
||||
painter.setOpacity(this->currentContentOpacity());
|
||||
|
||||
QColor color = this->theme->window.text;
|
||||
QColor background = this->theme->window.background;
|
||||
@@ -65,32 +70,8 @@ void TitleBarButton::paintEvent(QPaintEvent *event)
|
||||
painter.drawLine(rect.topRight(), rect.bottomLeft());
|
||||
break;
|
||||
}
|
||||
case TitleBarButtonStyle::User: {
|
||||
color = "#999";
|
||||
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
auto a = xD / 3;
|
||||
QPainterPath path;
|
||||
|
||||
painter.save();
|
||||
painter.translate(3, 3);
|
||||
|
||||
path.arcMoveTo(a, 4 * a, 6 * a, 6 * a, 0);
|
||||
path.arcTo(a, 4 * a, 6 * a, 6 * a, 0, 180);
|
||||
|
||||
painter.fillPath(path, color);
|
||||
|
||||
painter.setBrush(background);
|
||||
painter.drawEllipse(2 * a, 1 * a, 4 * a, 4 * a);
|
||||
|
||||
painter.setBrush(color);
|
||||
painter.drawEllipse(2.5 * a, 1.5 * a, 3 * a + 1, 3 * a);
|
||||
painter.restore();
|
||||
|
||||
break;
|
||||
}
|
||||
case TitleBarButtonStyle::Settings: {
|
||||
painter.setPen(color);
|
||||
color = "#999";
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
@@ -121,7 +102,7 @@ void TitleBarButton::paintEvent(QPaintEvent *event)
|
||||
default:;
|
||||
}
|
||||
|
||||
this->paintButton(painter);
|
||||
painter.setOpacity(1.0);
|
||||
}
|
||||
|
||||
void TitleBarButton::ncEnter()
|
||||
@@ -1,27 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/buttons/DimButton.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
enum class TitleBarButtonStyle {
|
||||
None = 0,
|
||||
Minimize = 1,
|
||||
Maximize = 2,
|
||||
Unmaximize = 4,
|
||||
Close = 8,
|
||||
User = 16,
|
||||
Settings = 32,
|
||||
StreamerMode = 64,
|
||||
enum class TitleBarButtonStyle : std::uint8_t {
|
||||
None,
|
||||
Minimize,
|
||||
Maximize,
|
||||
Unmaximize,
|
||||
Close,
|
||||
Settings,
|
||||
};
|
||||
|
||||
class TitleBarButton : public Button
|
||||
class TitleBarButton : public DimButton
|
||||
{
|
||||
public:
|
||||
TitleBarButton();
|
||||
TitleBarButton(TitleBarButtonStyle style = {});
|
||||
|
||||
TitleBarButtonStyle getButtonStyle() const;
|
||||
void setButtonStyle(TitleBarButtonStyle style_);
|
||||
void setButtonStyle(TitleBarButtonStyle style);
|
||||
|
||||
/// Simulate a `mouseEnter` event.
|
||||
void ncEnter();
|
||||
@@ -42,7 +40,9 @@ public:
|
||||
void ncMouseRelease(QPoint at);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void themeChangedEvent() override;
|
||||
|
||||
void paintContent(QPainter &painter) override;
|
||||
|
||||
private:
|
||||
TitleBarButtonStyle style_{};
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "widgets/helper/TitlebarButtons.hpp"
|
||||
#include "widgets/buttons/TitlebarButtons.hpp"
|
||||
|
||||
#ifdef USEWINSDK
|
||||
|
||||
# include "widgets/helper/TitlebarButton.hpp"
|
||||
# include "widgets/buttons/TitlebarButton.hpp"
|
||||
|
||||
# include <Windows.h>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "providers/twitch/TwitchChannel.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/buttons/Button.hpp"
|
||||
#include "widgets/helper/ChannelView.hpp"
|
||||
#include "widgets/helper/InvisibleSizeGrip.hpp"
|
||||
#include "widgets/Scrollbar.hpp"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "widgets/BaseWindow.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/helper/SettingsDialogTab.hpp"
|
||||
#include "widgets/settingspages/AboutPage.hpp"
|
||||
#include "widgets/settingspages/AccountsPage.hpp"
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
#include "util/Helpers.hpp"
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "util/PostToThread.hpp"
|
||||
#include "widgets/buttons/LabelButton.hpp"
|
||||
#include "widgets/buttons/PixmapButton.hpp"
|
||||
#include "widgets/dialogs/EditUserNotesDialog.hpp"
|
||||
#include "widgets/helper/ChannelView.hpp"
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
#include "widgets/helper/InvisibleSizeGrip.hpp"
|
||||
#include "widgets/helper/Line.hpp"
|
||||
#include "widgets/Label.hpp"
|
||||
@@ -47,7 +48,6 @@
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr QStringView TEXT_FOLLOWERS = u"Followers: %1";
|
||||
constexpr QStringView TEXT_CREATED = u"Created: %1";
|
||||
constexpr QStringView TEXT_TITLE = u"%1's Usercard - #%2";
|
||||
@@ -61,17 +61,17 @@ constexpr qsizetype NOTES_PREVIEW_LENGTH = 80;
|
||||
using namespace chatterino;
|
||||
|
||||
Label *addCopyableLabel(LayoutCreator<QHBoxLayout> box, const char *tooltip,
|
||||
Button **copyButton = nullptr)
|
||||
PixmapButton **copyButton = nullptr)
|
||||
{
|
||||
auto label = box.emplace<Label>();
|
||||
auto button = box.emplace<Button>();
|
||||
auto button = box.emplace<PixmapButton>();
|
||||
if (copyButton != nullptr)
|
||||
{
|
||||
button.assign(copyButton);
|
||||
}
|
||||
button->setPixmap(getApp()->getThemes()->buttons.copy);
|
||||
button->setScaleIndependentSize(18, 18);
|
||||
button->setDim(Button::Dim::Lots);
|
||||
button->setDim(DimButton::Dim::Lots);
|
||||
button->setToolTip(tooltip);
|
||||
QObject::connect(
|
||||
button.getElement(), &Button::leftClicked,
|
||||
@@ -272,9 +272,9 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, Split *split)
|
||||
{
|
||||
// avatar
|
||||
auto avatar =
|
||||
head.emplace<Button>(nullptr).assign(&this->ui_.avatarButton);
|
||||
head.emplace<PixmapButton>(nullptr).assign(&this->ui_.avatarButton);
|
||||
avatar->setScaleIndependentSize(100, 100);
|
||||
avatar->setDim(Button::Dim::None);
|
||||
avatar->setDim(DimButton::Dim::None);
|
||||
QObject::connect(
|
||||
avatar.getElement(), &Button::clicked,
|
||||
[this](Qt::MouseButton button) {
|
||||
@@ -409,22 +409,20 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, Split *split)
|
||||
.assign(&this->ui_.ignoreHighlights);
|
||||
// visibility of this is updated in setData
|
||||
|
||||
auto notesAdd =
|
||||
user.emplace<EffectLabel2>(this).assign(&this->ui_.notesAdd);
|
||||
notesAdd->getLabel().setText("Add notes");
|
||||
auto usercard =
|
||||
user.emplace<EffectLabel2>(this).assign(&this->ui_.usercardLabel);
|
||||
usercard->getLabel().setText("Usercard");
|
||||
auto mod = user.emplace<Button>(this);
|
||||
user.emplace<LabelButton>("Add notes", this)
|
||||
.assign(&this->ui_.notesAdd);
|
||||
auto usercard = user.emplace<LabelButton>("Usercard", this)
|
||||
.assign(&this->ui_.usercardLabel);
|
||||
auto mod = user.emplace<PixmapButton>(this);
|
||||
mod->setPixmap(getResources().buttons.mod);
|
||||
mod->setScaleIndependentSize(30, 30);
|
||||
auto unmod = user.emplace<Button>(this);
|
||||
auto unmod = user.emplace<PixmapButton>(this);
|
||||
unmod->setPixmap(getResources().buttons.unmod);
|
||||
unmod->setScaleIndependentSize(30, 30);
|
||||
auto vip = user.emplace<Button>(this);
|
||||
auto vip = user.emplace<PixmapButton>(this);
|
||||
vip->setPixmap(getResources().buttons.vip);
|
||||
vip->setScaleIndependentSize(30, 30);
|
||||
auto unvip = user.emplace<Button>(this);
|
||||
auto unvip = user.emplace<PixmapButton>(this);
|
||||
unvip->setPixmap(getResources().buttons.unvip);
|
||||
unvip->setScaleIndependentSize(30, 30);
|
||||
|
||||
@@ -762,7 +760,7 @@ void UserInfoPopup::installEvents()
|
||||
|
||||
// user notes
|
||||
QObject::connect(
|
||||
this->ui_.notesAdd, &EffectLabel2::clicked, [this]() mutable {
|
||||
this->ui_.notesAdd, &LabelButton::clicked, [this]() mutable {
|
||||
if (this->editUserNotesDialog_.isNull())
|
||||
{
|
||||
this->editUserNotesDialog_ = new EditUserNotesDialog(this);
|
||||
@@ -1185,7 +1183,7 @@ UserInfoPopup::TimeoutWidget::TimeoutWidget()
|
||||
|
||||
const auto addButton = [&](Action action, const QString &title,
|
||||
const QPixmap &pixmap) {
|
||||
auto button = addLayout(title).emplace<Button>(nullptr);
|
||||
auto button = addLayout(title).emplace<PixmapButton>(nullptr);
|
||||
button->setPixmap(pixmap);
|
||||
button->setScaleIndependentSize(buttonHeight, buttonHeight);
|
||||
button->setBorderColor(QColor(255, 255, 255, 127));
|
||||
@@ -1201,8 +1199,9 @@ UserInfoPopup::TimeoutWidget::TimeoutWidget()
|
||||
|
||||
for (const auto &item : getSettings()->timeoutButtons.getValue())
|
||||
{
|
||||
auto a = hbox.emplace<EffectLabel2>();
|
||||
a->getLabel().setText(QString::number(item.second) + item.first);
|
||||
auto a = hbox.emplace<LabelButton>();
|
||||
a->setPadding({0, 0});
|
||||
a->setText(QString::number(item.second) + item.first);
|
||||
|
||||
a->setScaleIndependentSize(buttonWidth, buttonHeight);
|
||||
a->setBorderColor(borderColor);
|
||||
@@ -1210,7 +1209,7 @@ UserInfoPopup::TimeoutWidget::TimeoutWidget()
|
||||
const auto pair =
|
||||
std::make_pair(Action::Timeout, calculateTimeoutDuration(item));
|
||||
|
||||
QObject::connect(a.getElement(), &EffectLabel2::leftClicked,
|
||||
QObject::connect(a.getElement(), &LabelButton::leftClicked,
|
||||
[this, pair] {
|
||||
this->buttonClicked.invoke(pair);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/DraggablePopup.hpp"
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
|
||||
#include <pajlada/signals/scoped-connection.hpp>
|
||||
#include <pajlada/signals/signal.hpp>
|
||||
@@ -17,6 +16,8 @@ class Label;
|
||||
class EditUserNotesDialog;
|
||||
class ChannelView;
|
||||
class Split;
|
||||
class LabelButton;
|
||||
class PixmapButton;
|
||||
|
||||
class UserInfoPopup final : public DraggablePopup
|
||||
{
|
||||
@@ -72,8 +73,8 @@ private:
|
||||
const bool closeAutomatically_;
|
||||
|
||||
struct {
|
||||
Button *avatarButton = nullptr;
|
||||
Button *localizedNameCopyButton = nullptr;
|
||||
PixmapButton *avatarButton = nullptr;
|
||||
PixmapButton *localizedNameCopyButton = nullptr;
|
||||
|
||||
Label *nameLabel = nullptr;
|
||||
Label *localizedNameLabel = nullptr;
|
||||
@@ -87,12 +88,12 @@ private:
|
||||
QCheckBox *block = nullptr;
|
||||
QCheckBox *ignoreHighlights = nullptr;
|
||||
Label *notesPreview = nullptr;
|
||||
EffectLabel2 *notesAdd = nullptr;
|
||||
LabelButton *notesAdd = nullptr;
|
||||
|
||||
Label *noMessagesLabel = nullptr;
|
||||
ChannelView *latestMessages = nullptr;
|
||||
|
||||
EffectLabel2 *usercardLabel = nullptr;
|
||||
LabelButton *usercardLabel = nullptr;
|
||||
} ui_;
|
||||
|
||||
QPointer<EditUserNotesDialog> editUserNotesDialog_;
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/BaseWidget.hpp"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPoint>
|
||||
#include <QSvgRenderer>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class Button : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
struct ClickEffect {
|
||||
double progress = 0.0;
|
||||
QPoint position;
|
||||
|
||||
ClickEffect(QPoint _position)
|
||||
: position(_position)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
enum class Dim { None, Some, Lots };
|
||||
|
||||
Button(BaseWidget *parent = nullptr);
|
||||
|
||||
void setMouseEffectColor(std::optional<QColor> color);
|
||||
void setPixmap(const QPixmap &pixmap_);
|
||||
void setSvgResource(const QString &resourcePath);
|
||||
const QPixmap &getPixmap() const;
|
||||
|
||||
void setDim(Dim value);
|
||||
Dim getDim() const;
|
||||
qreal getCurrentDimAmount() const;
|
||||
|
||||
void setEnable(bool value);
|
||||
bool getEnable() const;
|
||||
|
||||
void setEnableMargin(bool value);
|
||||
bool getEnableMargin() const;
|
||||
|
||||
void setBorderColor(const QColor &color);
|
||||
const QColor &getBorderColor() const;
|
||||
|
||||
void setMenu(std::unique_ptr<QMenu> menu);
|
||||
|
||||
Q_SIGNALS:
|
||||
void leftClicked();
|
||||
void clicked(Qt::MouseButton button);
|
||||
void leftMousePress();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent * /*event*/) override;
|
||||
|
||||
/// Paint this button.
|
||||
/// This is intended for child classes that may want to paint the overlay.
|
||||
/// This function should be used after rendering the custom button,
|
||||
/// because the painter's state will be modified by this function.
|
||||
void paintButton(QPainter &painter);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
void enterEvent(QEnterEvent * /*event*/) override;
|
||||
#else
|
||||
void enterEvent(QEvent * /*event*/) override;
|
||||
#endif
|
||||
void leaveEvent(QEvent *) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
void fancyPaint(QPainter &painter);
|
||||
|
||||
bool enabled_{true};
|
||||
bool selected_{false};
|
||||
bool mouseOver_{false};
|
||||
bool mouseDown_{false};
|
||||
bool menuVisible_{false};
|
||||
|
||||
private:
|
||||
void onMouseEffectTimeout();
|
||||
void showMenu();
|
||||
|
||||
int getMargin() const;
|
||||
|
||||
QColor borderColor_{};
|
||||
QPixmap pixmap_{};
|
||||
QSvgRenderer *svgRenderer{};
|
||||
QString svgResourcePath;
|
||||
QPixmap resizedPixmap_{};
|
||||
Dim dimPixmap_{Dim::Some};
|
||||
bool enableMargin_{true};
|
||||
QPoint mousePos_{};
|
||||
double hoverMultiplier_{0.0};
|
||||
QTimer effectTimer_{};
|
||||
std::vector<ClickEffect> clickEffects_{};
|
||||
std::optional<QColor> mouseEffectColor_{};
|
||||
std::unique_ptr<QMenu> menu_{};
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -35,10 +35,10 @@
|
||||
#include "util/IncognitoBrowser.hpp"
|
||||
#include "util/QMagicEnum.hpp"
|
||||
#include "util/Twitch.hpp"
|
||||
#include "widgets/buttons/LabelButton.hpp"
|
||||
#include "widgets/dialogs/ReplyThreadPopup.hpp"
|
||||
#include "widgets/dialogs/SettingsDialog.hpp"
|
||||
#include "widgets/dialogs/UserInfoPopup.hpp"
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
#include "widgets/helper/ScrollbarHighlight.hpp"
|
||||
#include "widgets/helper/SearchPopup.hpp"
|
||||
#include "widgets/Notebook.hpp"
|
||||
@@ -372,19 +372,17 @@ ChannelView::ChannelView(InternalCtor /*tag*/, QWidget *parent, Split *split,
|
||||
|
||||
void ChannelView::initializeLayout()
|
||||
{
|
||||
this->goToBottom_ = new EffectLabel(this, 0);
|
||||
this->goToBottom_ = new LabelButton("More messages below", this);
|
||||
this->goToBottom_->setStyleSheet(
|
||||
"background-color: rgba(0,0,0,0.66); color: #FFF;");
|
||||
this->goToBottom_->getLabel().setText("More messages below");
|
||||
this->goToBottom_->setVisible(false);
|
||||
|
||||
QObject::connect(
|
||||
this->goToBottom_, &EffectLabel::leftClicked, this, [this] {
|
||||
QTimer::singleShot(180, this, [this] {
|
||||
this->scrollBar_->scrollToBottom(
|
||||
getSettings()->enableSmoothScrollingNewMessages.getValue());
|
||||
});
|
||||
QObject::connect(this->goToBottom_, &Button::leftClicked, this, [this] {
|
||||
QTimer::singleShot(180, this, [this] {
|
||||
this->scrollBar_->scrollToBottom(
|
||||
getSettings()->enableSmoothScrollingNewMessages.getValue());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ChannelView::initializeScrollbar()
|
||||
@@ -624,7 +622,7 @@ void ChannelView::scaleChangedEvent(float scale)
|
||||
std::max<float>(
|
||||
0.01, this->logicalDpiX() * this->devicePixelRatioF());
|
||||
#endif
|
||||
this->goToBottom_->getLabel().setFont(
|
||||
this->goToBottom_->setFont(
|
||||
getApp()->getFonts()->getFont(FontStyle::UiMedium, factor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ enum class MessageElementFlag : int64_t;
|
||||
using MessageElementFlags = FlagsEnum<MessageElementFlag>;
|
||||
|
||||
class Scrollbar;
|
||||
class EffectLabel;
|
||||
class LabelButton;
|
||||
struct Link;
|
||||
class MessageLayoutElement;
|
||||
class Split;
|
||||
@@ -381,7 +381,7 @@ private:
|
||||
Split *split_;
|
||||
|
||||
Scrollbar *scrollBar_;
|
||||
EffectLabel *goToBottom_{};
|
||||
LabelButton *goToBottom_{};
|
||||
bool showScrollBar_ = false;
|
||||
|
||||
FilterSetPtr channelFilters_;
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QPainter>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
EffectLabel::EffectLabel(BaseWidget *parent, int spacing)
|
||||
: Button(parent)
|
||||
, label_(this)
|
||||
{
|
||||
setLayout(&this->hbox_);
|
||||
|
||||
this->label_.setAlignment(Qt::AlignCenter);
|
||||
|
||||
this->hbox_.setContentsMargins(0, 0, 0, 0);
|
||||
this->hbox_.addSpacing(spacing);
|
||||
this->hbox_.addWidget(&this->label_);
|
||||
this->hbox_.addSpacing(spacing);
|
||||
}
|
||||
|
||||
EffectLabel2::EffectLabel2(BaseWidget *parent, int padding)
|
||||
: Button(parent)
|
||||
, label_(this)
|
||||
{
|
||||
auto *hbox = new QHBoxLayout(this);
|
||||
this->setLayout(hbox);
|
||||
|
||||
// this->label_.setAlignment(Qt::AlignCenter);
|
||||
this->label_.setCentered(true);
|
||||
|
||||
hbox->setContentsMargins(0, 0, 0, 0);
|
||||
// hbox.addSpacing(spacing);
|
||||
hbox->addWidget(&this->label_);
|
||||
// hbox.addSpacing(spacing);
|
||||
}
|
||||
|
||||
Label &EffectLabel2::getLabel()
|
||||
{
|
||||
return this->label_;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/helper/SignalLabel.hpp"
|
||||
#include "widgets/Label.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPaintEvent>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class EffectLabel : public Button
|
||||
{
|
||||
public:
|
||||
explicit EffectLabel(BaseWidget *parent = nullptr, int spacing = 6);
|
||||
|
||||
SignalLabel &getLabel()
|
||||
{
|
||||
return this->label_;
|
||||
}
|
||||
|
||||
private:
|
||||
QHBoxLayout hbox_;
|
||||
SignalLabel label_;
|
||||
};
|
||||
|
||||
class EffectLabel2 : public Button
|
||||
{
|
||||
public:
|
||||
explicit EffectLabel2(BaseWidget *parent = nullptr, int padding = 6);
|
||||
|
||||
Label &getLabel();
|
||||
|
||||
private:
|
||||
Label label_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -87,6 +87,7 @@ NotebookTab::NotebookTab(Notebook *notebook)
|
||||
, notebook_(notebook)
|
||||
, menu_(this)
|
||||
{
|
||||
this->setContentCacheEnabled(false);
|
||||
this->setAcceptDrops(true);
|
||||
|
||||
this->positionChangedAnimation_.setEasingCurve(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/Common.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
#include "widgets/buttons/Button.hpp"
|
||||
#include "widgets/helper/ChannelView.hpp"
|
||||
#include "widgets/Notebook.hpp"
|
||||
|
||||
@@ -91,6 +91,9 @@ protected:
|
||||
void themeChangedEvent() override;
|
||||
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void paintContent(QPainter &painter) override
|
||||
{
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "widgets/helper/TitlebarButton.hpp"
|
||||
#include "widgets/buttons/TitlebarButton.hpp"
|
||||
|
||||
#include <QPropertyAnimation>
|
||||
#include <QWidget>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "util/RemoveScrollAreaBackground.hpp"
|
||||
#include "widgets/BasePopup.hpp"
|
||||
#include "widgets/buttons/SignalLabel.hpp"
|
||||
#include "widgets/layout/FlowLayout.hpp"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "Application.hpp"
|
||||
#include "common/ChatterinoSetting.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "widgets/helper/SignalLabel.hpp"
|
||||
#include "widgets/buttons/SignalLabel.hpp"
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <pajlada/signals/signalholder.hpp>
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/Helpers.hpp"
|
||||
#include "util/LayoutHelper.hpp"
|
||||
#include "widgets/buttons/LabelButton.hpp"
|
||||
#include "widgets/buttons/PixmapButton.hpp"
|
||||
#include "widgets/dialogs/SettingsDialog.hpp"
|
||||
#include "widgets/helper/CommonTexts.hpp"
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
#include "widgets/Label.hpp"
|
||||
#include "widgets/splits/Split.hpp"
|
||||
#include "widgets/splits/SplitContainer.hpp"
|
||||
@@ -296,13 +297,13 @@ void SplitHeader::initializeLayout()
|
||||
w->setScaleIndependentSize(8, 4);
|
||||
}),
|
||||
// mode
|
||||
this->modeButton_ = makeWidget<EffectLabel>([&](auto w) {
|
||||
this->modeButton_ = makeWidget<LabelButton>([&](auto w) {
|
||||
w->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
w->hide();
|
||||
w->setMenu(this->createChatModeMenu());
|
||||
}),
|
||||
// moderator
|
||||
this->moderationButton_ = makeWidget<Button>([&](auto w) {
|
||||
this->moderationButton_ = makeWidget<PixmapButton>([&](auto w) {
|
||||
QObject::connect(
|
||||
w, &Button::clicked, this,
|
||||
[this, w](Qt::MouseButton button) mutable {
|
||||
@@ -323,7 +324,9 @@ void SplitHeader::initializeLayout()
|
||||
|
||||
this->split_->setModerationMode(
|
||||
!moderationMode);
|
||||
w->setDim(Button::Dim(moderationMode));
|
||||
w->setDim(moderationMode
|
||||
? DimButton::Dim::Some
|
||||
: DimButton::Dim::None);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -337,22 +340,22 @@ void SplitHeader::initializeLayout()
|
||||
});
|
||||
}),
|
||||
// chatter list
|
||||
this->chattersButton_ = makeWidget<Button>([&](auto w) {
|
||||
this->chattersButton_ = makeWidget<PixmapButton>([&](auto w) {
|
||||
QObject::connect(w, &Button::leftClicked, this, [this]() {
|
||||
this->split_->showChatterList();
|
||||
});
|
||||
}),
|
||||
// dropdown
|
||||
this->dropdownButton_ = makeWidget<Button>([&](auto w) {
|
||||
this->dropdownButton_ = makeWidget<PixmapButton>([&](auto w) {
|
||||
/// XXX: this never gets disconnected
|
||||
QObject::connect(w, &Button::leftMousePress, this, [this] {
|
||||
this->dropdownButton_->setMenu(this->createMainMenu());
|
||||
});
|
||||
}),
|
||||
// add split
|
||||
this->addButton_ = makeWidget<Button>([&](auto w) {
|
||||
this->addButton_ = makeWidget<PixmapButton>([&](auto w) {
|
||||
w->setPixmap(getResources().buttons.addSplitDark);
|
||||
w->setEnableMargin(false);
|
||||
w->setMarginEnabled(false);
|
||||
|
||||
QObject::connect(w, &Button::leftClicked, this, [this]() {
|
||||
this->split_->addSibling();
|
||||
@@ -725,7 +728,7 @@ void SplitHeader::updateRoomModes()
|
||||
if (auto *twitchChannel =
|
||||
dynamic_cast<TwitchChannel *>(this->split_->getChannel().get()))
|
||||
{
|
||||
this->modeButton_->setEnable(twitchChannel->hasModRights());
|
||||
this->modeButton_->setEnabled(twitchChannel->hasModRights());
|
||||
|
||||
QString text;
|
||||
{
|
||||
@@ -746,7 +749,7 @@ void SplitHeader::updateRoomModes()
|
||||
|
||||
if (!text.isEmpty())
|
||||
{
|
||||
this->modeButton_->getLabel().setText(text);
|
||||
this->modeButton_->setText(text);
|
||||
this->modeButton_->show();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class Button;
|
||||
class EffectLabel;
|
||||
class PixmapButton;
|
||||
class LabelButton;
|
||||
class Label;
|
||||
class Split;
|
||||
|
||||
@@ -54,7 +54,6 @@ protected:
|
||||
|
||||
private:
|
||||
void initializeLayout();
|
||||
void initializeModeSignals(EffectLabel &label);
|
||||
std::unique_ptr<QMenu> createMainMenu();
|
||||
std::unique_ptr<QMenu> createChatModeMenu();
|
||||
|
||||
@@ -76,19 +75,19 @@ private:
|
||||
std::chrono::steady_clock::time_point lastReloadedSubEmotes_;
|
||||
|
||||
// ui
|
||||
Button *dropdownButton_{};
|
||||
PixmapButton *dropdownButton_{};
|
||||
Label *titleLabel_{};
|
||||
|
||||
EffectLabel *modeButton_{};
|
||||
LabelButton *modeButton_{};
|
||||
QAction *modeActionSetEmote{};
|
||||
QAction *modeActionSetSub{};
|
||||
QAction *modeActionSetSlow{};
|
||||
QAction *modeActionSetR9k{};
|
||||
QAction *modeActionSetFollowers{};
|
||||
|
||||
Button *moderationButton_{};
|
||||
Button *chattersButton_{};
|
||||
Button *addButton_{};
|
||||
PixmapButton *moderationButton_{};
|
||||
PixmapButton *chattersButton_{};
|
||||
PixmapButton *addButton_{};
|
||||
|
||||
// states
|
||||
QPoint dragStart_{};
|
||||
|
||||
@@ -10,13 +10,15 @@
|
||||
#include "providers/twitch/TwitchChannel.hpp"
|
||||
#include "providers/twitch/TwitchCommon.hpp"
|
||||
#include "providers/twitch/TwitchIrcServer.hpp"
|
||||
#include "singletons/Fonts.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "util/Helpers.hpp"
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "widgets/buttons/LabelButton.hpp"
|
||||
#include "widgets/buttons/SvgButton.hpp"
|
||||
#include "widgets/dialogs/EmotePopup.hpp"
|
||||
#include "widgets/helper/ChannelView.hpp"
|
||||
#include "widgets/helper/EffectLabel.hpp"
|
||||
#include "widgets/helper/MessageView.hpp"
|
||||
#include "widgets/helper/ResizingTextEdit.hpp"
|
||||
#include "widgets/Notebook.hpp"
|
||||
@@ -112,8 +114,14 @@ void SplitInput::initLayout()
|
||||
|
||||
replyHbox->addStretch(1);
|
||||
|
||||
auto replyCancelButton =
|
||||
replyHbox.emplace<Button>().assign(&this->ui_.cancelReplyButton);
|
||||
auto replyCancelButton = replyHbox
|
||||
.emplace<SvgButton>(
|
||||
SvgButton::Src{
|
||||
.dark = ":/buttons/cancel.svg",
|
||||
.light = ":/buttons/cancelDark.svg",
|
||||
},
|
||||
nullptr, QSize{4, 0})
|
||||
.assign(&this->ui_.cancelReplyButton);
|
||||
|
||||
replyCancelButton->hide();
|
||||
replyLabel->hide();
|
||||
@@ -133,11 +141,10 @@ void SplitInput::initLayout()
|
||||
connect(textEdit.getElement(), &ResizingTextEdit::textChanged, this,
|
||||
&SplitInput::editTextChanged);
|
||||
|
||||
hboxLayout.emplace<EffectLabel>().assign(&this->ui_.sendButton);
|
||||
this->ui_.sendButton->getLabel().setText("SEND");
|
||||
hboxLayout.emplace<LabelButton>("SEND").assign(&this->ui_.sendButton);
|
||||
this->ui_.sendButton->hide();
|
||||
|
||||
QObject::connect(this->ui_.sendButton, &EffectLabel::leftClicked, [this] {
|
||||
QObject::connect(this->ui_.sendButton, &Button::leftClicked, [this] {
|
||||
std::vector<QString> arguments;
|
||||
this->handleSendMessage(arguments);
|
||||
});
|
||||
@@ -164,7 +171,13 @@ void SplitInput::initLayout()
|
||||
textEditLength->setAlignment(Qt::AlignRight);
|
||||
|
||||
box->addStretch(1);
|
||||
box.emplace<Button>().assign(&this->ui_.emoteButton);
|
||||
box.emplace<SvgButton>(
|
||||
SvgButton::Src{
|
||||
.dark = ":/buttons/emote.svg",
|
||||
.light = ":/buttons/emoteDark.svg",
|
||||
},
|
||||
nullptr, QSize{6, 3})
|
||||
.assign(&this->ui_.emoteButton);
|
||||
}
|
||||
|
||||
// ---- misc
|
||||
@@ -186,15 +199,14 @@ void SplitInput::initLayout()
|
||||
});
|
||||
|
||||
// open emote popup
|
||||
QObject::connect(this->ui_.emoteButton, &EffectLabel::leftClicked, [this] {
|
||||
QObject::connect(this->ui_.emoteButton, &Button::leftClicked, [this] {
|
||||
this->openEmotePopup();
|
||||
});
|
||||
|
||||
// remove reply target
|
||||
QObject::connect(this->ui_.cancelReplyButton, &EffectLabel::leftClicked,
|
||||
[this] {
|
||||
this->setReply(nullptr);
|
||||
});
|
||||
// clear input and remove reply thread
|
||||
QObject::connect(this->ui_.cancelReplyButton, &Button::leftClicked, [this] {
|
||||
this->setReply(nullptr);
|
||||
});
|
||||
|
||||
// Forward selection change signal
|
||||
QObject::connect(this->ui_.textEdit, &QTextEdit::copyAvailable,
|
||||
@@ -256,8 +268,6 @@ void SplitInput::themeChangedEvent()
|
||||
QPalette::PlaceholderText,
|
||||
this->theme->messages.textColors.chatPlaceholder);
|
||||
|
||||
this->updateEmoteButton();
|
||||
this->updateCancelReplyButton();
|
||||
this->ui_.textEditLength->setPalette(palette);
|
||||
|
||||
this->ui_.textEdit->setStyleSheet(this->theme->splits.input.styleSheet);
|
||||
@@ -284,15 +294,6 @@ void SplitInput::updateEmoteButton()
|
||||
{
|
||||
auto scale = this->scale();
|
||||
|
||||
if (this->theme->isLightTheme())
|
||||
{
|
||||
this->ui_.emoteButton->setSvgResource(":/buttons/emoteDark.svg");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ui_.emoteButton->setSvgResource(":/buttons/emote.svg");
|
||||
}
|
||||
|
||||
this->ui_.emoteButton->setFixedHeight(int(18 * scale));
|
||||
// Make button slightly wider so it's easier to click
|
||||
this->ui_.emoteButton->setFixedWidth(int(24 * scale));
|
||||
@@ -302,15 +303,6 @@ void SplitInput::updateCancelReplyButton()
|
||||
{
|
||||
float scale = this->scale();
|
||||
|
||||
if (this->theme->isLightTheme())
|
||||
{
|
||||
this->ui_.cancelReplyButton->setSvgResource(":/buttons/cancelDark.svg");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ui_.cancelReplyButton->setSvgResource(":/buttons/cancel.svg");
|
||||
}
|
||||
this->ui_.cancelReplyButton->setEnableMargin(false);
|
||||
this->ui_.cancelReplyButton->setFixedHeight(int(12 * scale));
|
||||
this->ui_.cancelReplyButton->setFixedWidth(int(20 * scale));
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "messages/Message.hpp"
|
||||
#include "widgets/BaseWidget.hpp"
|
||||
#include "widgets/helper/Button.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
@@ -20,10 +19,11 @@ namespace chatterino {
|
||||
class Split;
|
||||
class EmotePopup;
|
||||
class InputCompletionPopup;
|
||||
class EffectLabel;
|
||||
class MessageView;
|
||||
class LabelButton;
|
||||
class ResizingTextEdit;
|
||||
class ChannelView;
|
||||
class SvgButton;
|
||||
enum class CompletionKind;
|
||||
|
||||
class SplitInput : public BaseWidget
|
||||
@@ -144,15 +144,15 @@ protected:
|
||||
QHBoxLayout *replyHbox;
|
||||
MessageView *replyMessage;
|
||||
QLabel *replyLabel;
|
||||
Button *cancelReplyButton;
|
||||
SvgButton *cancelReplyButton;
|
||||
|
||||
// input widgets
|
||||
QWidget *inputWrapper;
|
||||
QHBoxLayout *inputHbox;
|
||||
ResizingTextEdit *textEdit;
|
||||
QLabel *textEditLength;
|
||||
EffectLabel *sendButton;
|
||||
Button *emoteButton;
|
||||
LabelButton *sendButton;
|
||||
SvgButton *emoteButton;
|
||||
} ui_;
|
||||
|
||||
MessagePtr replyTarget_ = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user