mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
0acbc0d2c3
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
318 lines
7.4 KiB
C++
318 lines
7.4 KiB
C++
#include "widgets/TooltipWidget.hpp"
|
|
|
|
#include "Application.hpp"
|
|
#include "messages/Image.hpp"
|
|
#include "singletons/Fonts.hpp"
|
|
#include "singletons/WindowManager.hpp"
|
|
|
|
#include <QPainter>
|
|
|
|
// number of columns in grid mode
|
|
#define GRID_NUM_COLS 3
|
|
|
|
namespace chatterino {
|
|
|
|
TooltipWidget *TooltipWidget::instance()
|
|
{
|
|
static TooltipWidget *tooltipWidget = new TooltipWidget();
|
|
return tooltipWidget;
|
|
}
|
|
|
|
TooltipWidget::TooltipWidget(BaseWidget *parent)
|
|
: BaseWindow({BaseWindow::TopMost, BaseWindow::DontFocus,
|
|
BaseWindow::DisableLayoutSave},
|
|
parent)
|
|
{
|
|
this->setStyleSheet("color: #fff; background: rgba(11, 11, 11, 0.8)");
|
|
this->setAttribute(Qt::WA_TranslucentBackground);
|
|
this->setWindowFlag(Qt::WindowStaysOnTopHint, true);
|
|
|
|
this->setStayInScreenRect(true);
|
|
|
|
// Default to using vertical layout
|
|
this->initializeVLayout();
|
|
this->setLayout(this->vLayout_);
|
|
this->currentStyle_ = TooltipStyle::Vertical;
|
|
|
|
this->connections_.managedConnect(getFonts()->fontChanged, [this] {
|
|
this->updateFont();
|
|
});
|
|
this->updateFont();
|
|
|
|
auto windows = getApp()->windows;
|
|
this->connections_.managedConnect(windows->gifRepaintRequested, [this] {
|
|
for (int i = 0; i < this->visibleEntries_; ++i)
|
|
{
|
|
auto entry = this->entryAt(i);
|
|
if (entry && entry->animated())
|
|
{
|
|
entry->refreshPixmap();
|
|
}
|
|
}
|
|
});
|
|
|
|
this->connections_.managedConnect(windows->miscUpdate, [this] {
|
|
bool needSizeAdjustment = false;
|
|
for (int i = 0; i < this->visibleEntries_; ++i)
|
|
{
|
|
auto entry = this->entryAt(i);
|
|
if (entry->hasImage() && entry->attemptRefresh())
|
|
{
|
|
bool successfullyUpdated = entry->refreshPixmap();
|
|
needSizeAdjustment |= successfullyUpdated;
|
|
}
|
|
}
|
|
|
|
if (needSizeAdjustment)
|
|
{
|
|
this->adjustSize();
|
|
}
|
|
});
|
|
}
|
|
|
|
void TooltipWidget::setOne(const TooltipEntry &entry, TooltipStyle style)
|
|
{
|
|
this->set({entry}, style);
|
|
}
|
|
|
|
void TooltipWidget::set(const std::vector<TooltipEntry> &entries,
|
|
TooltipStyle style)
|
|
{
|
|
this->setCurrentStyle(style);
|
|
|
|
int delta = entries.size() - this->currentLayoutCount();
|
|
if (delta > 0)
|
|
{
|
|
// Need to add more TooltipEntry instances
|
|
int base = this->currentLayoutCount();
|
|
for (int i = 0; i < delta; ++i)
|
|
{
|
|
this->addNewEntry(base + i);
|
|
}
|
|
}
|
|
|
|
this->setVisibleEntries(entries.size());
|
|
|
|
for (int i = 0; i < entries.size(); ++i)
|
|
{
|
|
if (auto entryWidget = this->entryAt(i))
|
|
{
|
|
auto &entry = entries[i];
|
|
entryWidget->setImage(entry.image);
|
|
entryWidget->setText(entry.text);
|
|
entryWidget->setImageScale(entry.customWidth, entry.customHeight);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TooltipWidget::setVisibleEntries(int n)
|
|
{
|
|
for (int i = 0; i < this->currentLayoutCount(); ++i)
|
|
{
|
|
auto *entry = this->entryAt(i);
|
|
if (entry == nullptr)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (i >= n)
|
|
{
|
|
entry->hide();
|
|
entry->clearImage();
|
|
}
|
|
else
|
|
{
|
|
entry->show();
|
|
}
|
|
}
|
|
this->visibleEntries_ = n;
|
|
}
|
|
|
|
void TooltipWidget::addNewEntry(int absoluteIndex)
|
|
{
|
|
switch (this->currentStyle_)
|
|
{
|
|
case TooltipStyle::Vertical:
|
|
this->vLayout_->addWidget(new TooltipEntryWidget(),
|
|
Qt::AlignHCenter);
|
|
return;
|
|
case TooltipStyle::Grid:
|
|
if (absoluteIndex == 0)
|
|
{
|
|
// Top row spans all columns
|
|
this->gLayout_->addWidget(new TooltipEntryWidget(), 0, 0, 1,
|
|
GRID_NUM_COLS, Qt::AlignCenter);
|
|
}
|
|
else
|
|
{
|
|
int row = ((absoluteIndex - 1) / GRID_NUM_COLS) + 1;
|
|
int col = (absoluteIndex - 1) % GRID_NUM_COLS;
|
|
this->gLayout_->addWidget(new TooltipEntryWidget(), row, col,
|
|
Qt::AlignHCenter | Qt::AlignBottom);
|
|
}
|
|
return;
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
// May be nullptr
|
|
QLayout *TooltipWidget::currentLayout() const
|
|
{
|
|
switch (this->currentStyle_)
|
|
{
|
|
case TooltipStyle::Vertical:
|
|
return this->vLayout_;
|
|
case TooltipStyle::Grid:
|
|
return this->gLayout_;
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
int TooltipWidget::currentLayoutCount() const
|
|
{
|
|
if (auto *layout = this->currentLayout())
|
|
{
|
|
return layout->count();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// May be nullptr
|
|
TooltipEntryWidget *TooltipWidget::entryAt(int n)
|
|
{
|
|
if (auto *layout = this->currentLayout())
|
|
{
|
|
return dynamic_cast<TooltipEntryWidget *>(layout->itemAt(n)->widget());
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void TooltipWidget::setCurrentStyle(TooltipStyle style)
|
|
{
|
|
if (this->currentStyle_ == style)
|
|
{
|
|
// Nothing to update
|
|
return;
|
|
}
|
|
|
|
this->clearEntries();
|
|
this->deleteCurrentLayout();
|
|
|
|
switch (style)
|
|
{
|
|
case TooltipStyle::Vertical:
|
|
this->initializeVLayout();
|
|
this->setLayout(this->vLayout_);
|
|
break;
|
|
case TooltipStyle::Grid:
|
|
this->initializeGLayout();
|
|
this->setLayout(this->gLayout_);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
this->currentStyle_ = style;
|
|
}
|
|
|
|
void TooltipWidget::deleteCurrentLayout()
|
|
{
|
|
auto *currentLayout = this->layout();
|
|
delete currentLayout;
|
|
|
|
switch (this->currentStyle_)
|
|
{
|
|
case TooltipStyle::Vertical:
|
|
this->vLayout_ = nullptr;
|
|
break;
|
|
case TooltipStyle::Grid:
|
|
this->gLayout_ = nullptr;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void TooltipWidget::initializeVLayout()
|
|
{
|
|
auto *vLayout = new QVBoxLayout(this);
|
|
vLayout->setSizeConstraint(QLayout::SetFixedSize);
|
|
vLayout->setContentsMargins(10, 5, 10, 5);
|
|
vLayout->setSpacing(10);
|
|
this->vLayout_ = vLayout;
|
|
}
|
|
|
|
void TooltipWidget::initializeGLayout()
|
|
{
|
|
auto *gLayout = new QGridLayout(this);
|
|
gLayout->setSizeConstraint(QLayout::SetFixedSize);
|
|
gLayout->setContentsMargins(10, 5, 10, 5);
|
|
gLayout->setHorizontalSpacing(8);
|
|
gLayout->setVerticalSpacing(10);
|
|
this->gLayout_ = gLayout;
|
|
}
|
|
|
|
void TooltipWidget::themeChangedEvent()
|
|
{
|
|
// this->setStyleSheet("color: #fff; background: #000");
|
|
}
|
|
|
|
void TooltipWidget::paintEvent(QPaintEvent *)
|
|
{
|
|
QPainter painter(this);
|
|
|
|
painter.fillRect(this->rect(), QColor(0, 0, 0, int(0.8 * 255)));
|
|
}
|
|
|
|
void TooltipWidget::scaleChangedEvent(float)
|
|
{
|
|
this->updateFont();
|
|
}
|
|
|
|
void TooltipWidget::updateFont()
|
|
{
|
|
this->setFont(
|
|
getFonts()->getFont(FontStyle::ChatMediumSmall, this->scale()));
|
|
}
|
|
|
|
void TooltipWidget::setWordWrap(bool wrap)
|
|
{
|
|
for (int i = 0; i < this->visibleEntries_; ++i)
|
|
{
|
|
auto entry = this->entryAt(i);
|
|
if (entry)
|
|
{
|
|
entry->setWordWrap(wrap);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TooltipWidget::clearEntries()
|
|
{
|
|
this->setVisibleEntries(0);
|
|
}
|
|
|
|
void TooltipWidget::hideEvent(QHideEvent *)
|
|
{
|
|
this->clearEntries();
|
|
}
|
|
|
|
void TooltipWidget::showEvent(QShowEvent *)
|
|
{
|
|
this->adjustSize();
|
|
}
|
|
|
|
void TooltipWidget::changeEvent(QEvent *)
|
|
{
|
|
// clear parents event
|
|
}
|
|
|
|
void TooltipWidget::leaveEvent(QEvent *)
|
|
{
|
|
// clear parents event
|
|
}
|
|
|
|
} // namespace chatterino
|