Add transparent overlay window (#4746)
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user