Add transparent overlay window (#4746)

This commit is contained in:
nerix
2024-10-06 12:54:24 +02:00
committed by GitHub
parent 9ba7ef324d
commit afa8067a20
40 changed files with 1464 additions and 190 deletions
+58 -16
View File
@@ -362,7 +362,8 @@ ChannelView::ChannelView(InternalCtor /*tag*/, QWidget *parent, Split *split,
this->queueUpdate();
});
this->messageColors_.applyTheme(getTheme());
this->messageColors_.applyTheme(getTheme(), this->isOverlay_,
getSettings()->overlayBackgroundOpacity);
this->messagePreferences_.connectSettings(getSettings(),
this->signalHolder_);
}
@@ -450,6 +451,11 @@ void ChannelView::initializeSignals()
});
}
Scrollbar *ChannelView::scrollbar()
{
return this->scrollBar_;
}
bool ChannelView::pausable() const
{
return pausable_;
@@ -574,7 +580,19 @@ void ChannelView::themeChangedEvent()
this->setupHighlightAnimationColors();
this->queueLayout();
this->messageColors_.applyTheme(getTheme());
this->messageColors_.applyTheme(getTheme(), this->isOverlay_,
getSettings()->overlayBackgroundOpacity);
}
void ChannelView::updateColorTheme()
{
this->themeChangedEvent();
}
void ChannelView::setIsOverlay(bool isOverlay)
{
this->isOverlay_ = isOverlay;
this->themeChangedEvent();
}
void ChannelView::setupHighlightAnimationColors()
@@ -680,9 +698,15 @@ void ChannelView::layoutVisibleMessages(
const auto &message = messages[i];
redrawRequired |= message->layout(
layoutWidth, this->scale(),
this->scale() * static_cast<float>(this->devicePixelRatio()),
flags, this->bufferInvalidationQueued_);
{
.messageColors = this->messageColors_,
.flags = flags,
.width = layoutWidth,
.scale = this->scale(),
.imageScale = this->scale() *
static_cast<float>(this->devicePixelRatio()),
},
this->bufferInvalidationQueued_);
y += message->getHeight();
}
@@ -717,8 +741,14 @@ void ChannelView::updateScrollbar(
auto *message = messages[i].get();
message->layout(
layoutWidth, this->scale(),
this->scale() * static_cast<float>(this->devicePixelRatio()), flags,
{
.messageColors = this->messageColors_,
.flags = flags,
.width = layoutWidth,
.scale = this->scale(),
.imageScale = this->scale() *
static_cast<float>(this->devicePixelRatio()),
},
false);
h -= message->getHeight();
@@ -1486,7 +1516,7 @@ void ChannelView::paintEvent(QPaintEvent *event)
QPainter painter(this);
painter.fillRect(rect(), this->theme->splits.background);
painter.fillRect(rect(), this->messageColors_.channelBackground);
// draw messages
this->drawMessages(painter, event->rect());
@@ -1705,10 +1735,16 @@ void ChannelView::wheelEvent(QWheelEvent *event)
else
{
snapshot[i - 1]->layout(
this->getLayoutWidth(), this->scale(),
this->scale() *
static_cast<float>(this->devicePixelRatio()),
this->getFlags(), false);
{
.messageColors = this->messageColors_,
.flags = this->getFlags(),
.width = this->getLayoutWidth(),
.scale = this->scale(),
.imageScale =
this->scale() *
static_cast<float>(this->devicePixelRatio()),
},
false);
scrollFactor = 1;
currentScrollLeft = snapshot[i - 1]->getHeight();
}
@@ -1742,10 +1778,16 @@ void ChannelView::wheelEvent(QWheelEvent *event)
else
{
snapshot[i + 1]->layout(
this->getLayoutWidth(), this->scale(),
this->scale() *
static_cast<float>(this->devicePixelRatio()),
this->getFlags(), false);
{
.messageColors = this->messageColors_,
.flags = this->getFlags(),
.width = this->getLayoutWidth(),
.scale = this->scale(),
.imageScale =
this->scale() *
static_cast<float>(this->devicePixelRatio()),
},
false);
scrollFactor = 1;
currentScrollLeft = snapshot[i + 1]->getHeight();
+12
View File
@@ -202,6 +202,16 @@ public:
*/
bool mayContainMessage(const MessagePtr &message);
void updateColorTheme();
/// @brief Adjusts the colors this view uses
///
/// If @a isOverlay is true, the overlay colors (as specified in the theme)
/// will be used. Otherwise, regular message-colors will be used.
void setIsOverlay(bool isOverlay);
Scrollbar *scrollbar();
pajlada::Signals::Signal<QMouseEvent *> mouseDown;
pajlada::Signals::NoArgSignal selectionChanged;
pajlada::Signals::Signal<HighlightState> tabHighlightRequested;
@@ -377,6 +387,8 @@ private:
bool onlyUpdateEmotes_ = false;
bool isOverlay_ = false;
// Mouse event variables
bool isLeftMouseDown_ = false;
bool isRightMouseDown_ = false;
+11 -5
View File
@@ -97,8 +97,8 @@ void MessageView::paintEvent(QPaintEvent * /*event*/)
void MessageView::themeChangedEvent()
{
this->messageColors_.applyTheme(getTheme());
this->messageColors_.regular = getTheme()->splits.input.background;
this->messageColors_.applyTheme(getTheme(), false, 255);
this->messageColors_.regularBg = getTheme()->splits.input.background;
if (this->messageLayout_)
{
this->messageLayout_->invalidateBuffer();
@@ -120,9 +120,15 @@ void MessageView::layoutMessage()
}
bool updateRequired = this->messageLayout_->layout(
this->width_, this->scale(),
this->scale() * static_cast<float>(this->devicePixelRatio()),
MESSAGE_FLAGS, false);
{
.messageColors = this->messageColors_,
.flags = MESSAGE_FLAGS,
.width = this->width_,
.scale = this->scale(),
.imageScale =
this->scale() * static_cast<float>(this->devicePixelRatio()),
},
false);
if (updateRequired)
{
+123
View File
@@ -0,0 +1,123 @@
#include "widgets/helper/OverlayInteraction.hpp"
#include "common/Literals.hpp"
#include "widgets/OverlayWindow.hpp"
#include <QGridLayout>
namespace chatterino {
using namespace literals;
OverlayInteraction::OverlayInteraction(OverlayWindow *parent)
: QWidget(nullptr)
, interactAnimation_(this, "interactionProgress"_ba)
, window_(parent)
{
this->interactAnimation_.setStartValue(0.0);
this->interactAnimation_.setEndValue(1.0);
this->closeButton_.setButtonStyle(TitleBarButtonStyle::Close);
this->closeButton_.setScaleIndependantSize(46, 30);
this->closeButton_.hide();
this->closeButton_.setCursor(Qt::PointingHandCursor);
}
void OverlayInteraction::attach(QGridLayout *layout)
{
layout->addWidget(this, 0, 0);
layout->addWidget(&this->closeButton_, 0, 0, Qt::AlignTop | Qt::AlignRight);
layout->setContentsMargins(0, 0, 0, 0);
QObject::connect(&this->closeButton_, &TitleBarButton::leftClicked,
[this]() {
this->window_->close();
});
}
QWidget *OverlayInteraction::closeButton()
{
return &this->closeButton_;
}
void OverlayInteraction::startInteraction()
{
if (this->interacting_)
{
return;
}
this->interacting_ = true;
if (this->interactAnimation_.state() != QPropertyAnimation::Stopped)
{
this->interactAnimation_.stop();
}
this->interactAnimation_.setDirection(QPropertyAnimation::Forward);
this->interactAnimation_.setDuration(100);
this->interactAnimation_.start();
this->window_->setOverrideCursor(Qt::SizeAllCursor);
this->closeButton_.show();
}
void OverlayInteraction::endInteraction()
{
if (!this->interacting_)
{
return;
}
this->interacting_ = false;
if (this->interactAnimation_.state() != QPropertyAnimation::Stopped)
{
this->interactAnimation_.stop();
}
this->interactAnimation_.setDirection(QPropertyAnimation::Backward);
this->interactAnimation_.setDuration(200);
this->interactAnimation_.start();
this->window_->setOverrideCursor(Qt::ArrowCursor);
this->closeButton_.hide();
}
bool OverlayInteraction::isInteracting() const
{
return this->interacting_;
}
void OverlayInteraction::paintEvent(QPaintEvent * /*event*/)
{
QPainter painter(this);
QColor highlightColor(
255, 255, 255, std::max(int(255.0 * this->interactionProgress()), 50));
painter.setPen({highlightColor, 2});
// outline
auto bounds = this->rect();
painter.drawRect(bounds);
if (this->interactionProgress() <= 0.0)
{
return;
}
highlightColor.setAlpha(highlightColor.alpha() / 4);
painter.setBrush(highlightColor);
painter.setPen(Qt::transparent);
// close button
auto buttonSize = this->closeButton_.size();
painter.drawRect(
QRect{bounds.topRight() - QPoint{buttonSize.width(), 0}, buttonSize});
}
double OverlayInteraction::interactionProgress() const
{
return this->interactionProgress_;
}
void OverlayInteraction::setInteractionProgress(double progress)
{
this->interactionProgress_ = progress;
this->update();
}
} // namespace chatterino
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include "widgets/helper/TitlebarButton.hpp"
#include <QPropertyAnimation>
#include <QWidget>
class QGridLayout;
namespace chatterino {
class OverlayWindow;
class OverlayInteraction : public QWidget
{
Q_OBJECT
public:
OverlayInteraction(OverlayWindow *parent);
void attach(QGridLayout *layout);
QWidget *closeButton();
void startInteraction();
void endInteraction();
bool isInteracting() const;
protected:
void paintEvent(QPaintEvent *event) override;
private:
Q_PROPERTY(double interactionProgress READ interactionProgress WRITE
setInteractionProgress)
TitleBarButton closeButton_;
double interactionProgress() const;
void setInteractionProgress(double progress);
bool interacting_ = false;
double interactionProgress_ = 0.0;
QPropertyAnimation interactAnimation_;
OverlayWindow *window_;
};
} // namespace chatterino