|
|
|
@@ -21,9 +21,9 @@ namespace chatterino {
|
|
|
|
|
namespace messages {
|
|
|
|
|
namespace layouts {
|
|
|
|
|
|
|
|
|
|
MessageLayout::MessageLayout(MessagePtr _message)
|
|
|
|
|
: message(_message)
|
|
|
|
|
, buffer(nullptr)
|
|
|
|
|
MessageLayout::MessageLayout(MessagePtr message)
|
|
|
|
|
: m_message(message)
|
|
|
|
|
, m_buffer(nullptr)
|
|
|
|
|
{
|
|
|
|
|
util::DebugCount::increase("message layout");
|
|
|
|
|
}
|
|
|
|
@@ -35,13 +35,13 @@ MessageLayout::~MessageLayout()
|
|
|
|
|
|
|
|
|
|
Message *MessageLayout::getMessage()
|
|
|
|
|
{
|
|
|
|
|
return this->message.get();
|
|
|
|
|
return this->m_message.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Height
|
|
|
|
|
int MessageLayout::getHeight() const
|
|
|
|
|
{
|
|
|
|
|
return container.getHeight();
|
|
|
|
|
return m_container.getHeight();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Layout
|
|
|
|
@@ -55,28 +55,28 @@ bool MessageLayout::layout(int width, float scale, MessageElement::Flags flags)
|
|
|
|
|
bool layoutRequired = false;
|
|
|
|
|
|
|
|
|
|
// check if width changed
|
|
|
|
|
bool widthChanged = width != this->currentLayoutWidth;
|
|
|
|
|
bool widthChanged = width != this->m_currentLayoutWidth;
|
|
|
|
|
layoutRequired |= widthChanged;
|
|
|
|
|
this->currentLayoutWidth = width;
|
|
|
|
|
this->m_currentLayoutWidth = width;
|
|
|
|
|
|
|
|
|
|
// check if emotes changed
|
|
|
|
|
bool imagesChanged = this->emoteGeneration != app->emotes->getGeneration();
|
|
|
|
|
bool imagesChanged = this->m_emoteGeneration != app->emotes->getGeneration();
|
|
|
|
|
layoutRequired |= imagesChanged;
|
|
|
|
|
this->emoteGeneration = app->emotes->getGeneration();
|
|
|
|
|
this->m_emoteGeneration = app->emotes->getGeneration();
|
|
|
|
|
|
|
|
|
|
// check if text changed
|
|
|
|
|
bool textChanged = this->fontGeneration != app->fonts->getGeneration();
|
|
|
|
|
bool textChanged = this->m_fontGeneration != app->fonts->getGeneration();
|
|
|
|
|
layoutRequired |= textChanged;
|
|
|
|
|
this->fontGeneration = app->fonts->getGeneration();
|
|
|
|
|
this->m_fontGeneration = app->fonts->getGeneration();
|
|
|
|
|
|
|
|
|
|
// check if work mask changed
|
|
|
|
|
bool wordMaskChanged = this->currentWordFlags != flags; // app->settings->getWordTypeMask();
|
|
|
|
|
bool wordMaskChanged = this->m_currentWordFlags != flags; // app->settings->getWordTypeMask();
|
|
|
|
|
layoutRequired |= wordMaskChanged;
|
|
|
|
|
this->currentWordFlags = flags; // app->settings->getWordTypeMask();
|
|
|
|
|
this->m_currentWordFlags = flags; // app->settings->getWordTypeMask();
|
|
|
|
|
|
|
|
|
|
// check if timestamp format changed
|
|
|
|
|
bool timestampFormatChanged = this->timestampFormat != app->settings->timestampFormat;
|
|
|
|
|
this->timestampFormat = app->settings->timestampFormat.getValue();
|
|
|
|
|
bool timestampFormatChanged = this->m_timestampFormat != app->settings->timestampFormat;
|
|
|
|
|
this->m_timestampFormat = app->settings->timestampFormat.getValue();
|
|
|
|
|
|
|
|
|
|
layoutRequired |= timestampFormatChanged;
|
|
|
|
|
|
|
|
|
@@ -85,9 +85,9 @@ bool MessageLayout::layout(int width, float scale, MessageElement::Flags flags)
|
|
|
|
|
this->flags &= ~RequiresLayout;
|
|
|
|
|
|
|
|
|
|
// check if dpi changed
|
|
|
|
|
bool scaleChanged = this->scale != scale;
|
|
|
|
|
bool scaleChanged = this->m_scale != scale;
|
|
|
|
|
layoutRequired |= scaleChanged;
|
|
|
|
|
this->scale = scale;
|
|
|
|
|
this->m_scale = scale;
|
|
|
|
|
imagesChanged |= scaleChanged;
|
|
|
|
|
textChanged |= scaleChanged;
|
|
|
|
|
|
|
|
|
@@ -121,30 +121,30 @@ bool MessageLayout::layout(int width, float scale, MessageElement::Flags flags)
|
|
|
|
|
|
|
|
|
|
void MessageLayout::actuallyLayout(int width, MessageElement::Flags _flags)
|
|
|
|
|
{
|
|
|
|
|
auto messageFlags = this->message->flags.value;
|
|
|
|
|
auto messageFlags = this->m_message->flags.value;
|
|
|
|
|
|
|
|
|
|
if (this->flags & MessageLayout::Expanded ||
|
|
|
|
|
(_flags & MessageElement::ModeratorTools &&
|
|
|
|
|
!(this->message->flags & Message::MessageFlags::Disabled))) {
|
|
|
|
|
!(this->m_message->flags & Message::MessageFlags::Disabled))) {
|
|
|
|
|
messageFlags = Message::MessageFlags(messageFlags & ~Message::MessageFlags::Collapsed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->container.begin(width, this->scale, messageFlags);
|
|
|
|
|
this->m_container.begin(width, this->m_scale, messageFlags);
|
|
|
|
|
|
|
|
|
|
for (const std::unique_ptr<MessageElement> &element : this->message->getElements()) {
|
|
|
|
|
element->addToContainer(this->container, _flags);
|
|
|
|
|
for (const std::unique_ptr<MessageElement> &element : this->m_message->getElements()) {
|
|
|
|
|
element->addToContainer(this->m_container, _flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this->height != this->container.getHeight()) {
|
|
|
|
|
if (this->m_height != this->m_container.getHeight()) {
|
|
|
|
|
this->deleteBuffer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->container.end();
|
|
|
|
|
this->height = this->container.getHeight();
|
|
|
|
|
this->m_container.end();
|
|
|
|
|
this->m_height = this->m_container.getHeight();
|
|
|
|
|
|
|
|
|
|
// collapsed state
|
|
|
|
|
this->flags &= ~Flags::Collapsed;
|
|
|
|
|
if (this->container.isCollapsed()) {
|
|
|
|
|
if (this->m_container.isCollapsed()) {
|
|
|
|
|
this->flags |= Flags::Collapsed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -154,7 +154,7 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
|
|
|
|
|
bool isLastReadMessage, bool isWindowFocused)
|
|
|
|
|
{
|
|
|
|
|
auto app = getApp();
|
|
|
|
|
QPixmap *pixmap = this->buffer.get();
|
|
|
|
|
QPixmap *pixmap = this->m_buffer.get();
|
|
|
|
|
|
|
|
|
|
// create new buffer if required
|
|
|
|
|
if (!pixmap) {
|
|
|
|
@@ -164,15 +164,16 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
|
|
|
|
|
(int)(this->container.getHeight() * painter.device()->devicePixelRatioF()));
|
|
|
|
|
pixmap->setDevicePixelRatio(painter.device()->devicePixelRatioF());
|
|
|
|
|
#else
|
|
|
|
|
pixmap = new QPixmap(this->container.getWidth(), std::max(16, this->container.getHeight()));
|
|
|
|
|
pixmap =
|
|
|
|
|
new QPixmap(this->m_container.getWidth(), std::max(16, this->m_container.getHeight()));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
this->buffer = std::shared_ptr<QPixmap>(pixmap);
|
|
|
|
|
this->bufferValid = false;
|
|
|
|
|
this->m_buffer = std::shared_ptr<QPixmap>(pixmap);
|
|
|
|
|
this->m_bufferValid = false;
|
|
|
|
|
util::DebugCount::increase("message drawing buffers");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!this->bufferValid || !selection.isEmpty()) {
|
|
|
|
|
if (!this->m_bufferValid || !selection.isEmpty()) {
|
|
|
|
|
this->updateBuffer(pixmap, messageIndex, selection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -181,21 +182,21 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
|
|
|
|
|
// painter.drawPixmap(0, y, this->container.width, this->container.getHeight(), *pixmap);
|
|
|
|
|
|
|
|
|
|
// draw gif emotes
|
|
|
|
|
this->container.paintAnimatedElements(painter, y);
|
|
|
|
|
this->m_container.paintAnimatedElements(painter, y);
|
|
|
|
|
|
|
|
|
|
// draw disabled
|
|
|
|
|
if (this->message->flags.HasFlag(Message::Disabled)) {
|
|
|
|
|
if (this->m_message->flags.HasFlag(Message::Disabled)) {
|
|
|
|
|
painter.fillRect(0, y, pixmap->width(), pixmap->height(), app->themes->messages.disabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// draw selection
|
|
|
|
|
if (!selection.isEmpty()) {
|
|
|
|
|
this->container.paintSelection(painter, messageIndex, selection, y);
|
|
|
|
|
this->m_container.paintSelection(painter, messageIndex, selection, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// draw message seperation line
|
|
|
|
|
if (app->settings->seperateMessages.getValue()) {
|
|
|
|
|
painter.fillRect(0, y + this->container.getHeight() - 1, this->container.getWidth(), 1,
|
|
|
|
|
painter.fillRect(0, y + this->m_container.getHeight() - 1, this->m_container.getWidth(), 1,
|
|
|
|
|
app->themes->splits.messageSeperator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -206,11 +207,11 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection
|
|
|
|
|
|
|
|
|
|
QBrush brush(color, Qt::VerPattern);
|
|
|
|
|
|
|
|
|
|
painter.fillRect(0, y + this->container.getHeight() - 1, this->container.getWidth(), 1,
|
|
|
|
|
painter.fillRect(0, y + this->m_container.getHeight() - 1, this->m_container.getWidth(), 1,
|
|
|
|
|
brush);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->bufferValid = true;
|
|
|
|
|
this->m_bufferValid = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MessageLayout::updateBuffer(QPixmap *buffer, int /*messageIndex*/, Selection & /*selection*/)
|
|
|
|
@@ -223,7 +224,7 @@ void MessageLayout::updateBuffer(QPixmap *buffer, int /*messageIndex*/, Selectio
|
|
|
|
|
|
|
|
|
|
// draw background
|
|
|
|
|
QColor backgroundColor;
|
|
|
|
|
if (this->message->flags & Message::Highlighted) {
|
|
|
|
|
if (this->m_message->flags & Message::Highlighted) {
|
|
|
|
|
backgroundColor = app->themes->messages.backgrounds.highlighted;
|
|
|
|
|
} else if (app->settings->alternateMessageBackground.getValue() &&
|
|
|
|
|
this->flags & MessageLayout::AlternateBackground) {
|
|
|
|
@@ -234,7 +235,7 @@ void MessageLayout::updateBuffer(QPixmap *buffer, int /*messageIndex*/, Selectio
|
|
|
|
|
painter.fillRect(buffer->rect(), backgroundColor);
|
|
|
|
|
|
|
|
|
|
// draw message
|
|
|
|
|
this->container.paintElements(painter);
|
|
|
|
|
this->m_container.paintElements(painter);
|
|
|
|
|
|
|
|
|
|
#ifdef FOURTF
|
|
|
|
|
// debug
|
|
|
|
@@ -252,15 +253,15 @@ void MessageLayout::updateBuffer(QPixmap *buffer, int /*messageIndex*/, Selectio
|
|
|
|
|
|
|
|
|
|
void MessageLayout::invalidateBuffer()
|
|
|
|
|
{
|
|
|
|
|
this->bufferValid = false;
|
|
|
|
|
this->m_bufferValid = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MessageLayout::deleteBuffer()
|
|
|
|
|
{
|
|
|
|
|
if (this->buffer != nullptr) {
|
|
|
|
|
if (this->m_buffer != nullptr) {
|
|
|
|
|
util::DebugCount::decrease("message drawing buffers");
|
|
|
|
|
|
|
|
|
|
this->buffer = nullptr;
|
|
|
|
|
this->m_buffer = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -269,7 +270,7 @@ void MessageLayout::deleteCache()
|
|
|
|
|
this->deleteBuffer();
|
|
|
|
|
|
|
|
|
|
#ifdef XD
|
|
|
|
|
this->container.clear();
|
|
|
|
|
this->m_container.clear();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -282,22 +283,22 @@ void MessageLayout::deleteCache()
|
|
|
|
|
const MessageLayoutElement *MessageLayout::getElementAt(QPoint point)
|
|
|
|
|
{
|
|
|
|
|
// go through all words and return the first one that contains the point.
|
|
|
|
|
return this->container.getElementAt(point);
|
|
|
|
|
return this->m_container.getElementAt(point);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int MessageLayout::getLastCharacterIndex() const
|
|
|
|
|
{
|
|
|
|
|
return this->container.getLastCharacterIndex();
|
|
|
|
|
return this->m_container.getLastCharacterIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int MessageLayout::getSelectionIndex(QPoint position)
|
|
|
|
|
{
|
|
|
|
|
return this->container.getSelectionIndex(position);
|
|
|
|
|
return this->m_container.getSelectionIndex(position);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MessageLayout::addSelectionText(QString &str, int from, int to)
|
|
|
|
|
{
|
|
|
|
|
this->container.addSelectionText(str, from, to);
|
|
|
|
|
this->m_container.addSelectionText(str, from, to);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace layouts
|
|
|
|
|