mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Further removal of WordParts, TwitchMessageBuilder parts etc.
This commit is contained in:
parent
a03ead6ac8
commit
bfaf08745e
4 changed files with 0 additions and 568 deletions
|
@ -1,334 +0,0 @@
|
||||||
#include "messages/messageref.hpp"
|
|
||||||
#include "emotemanager.hpp"
|
|
||||||
#include "settingsmanager.hpp"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#define MARGIN_LEFT 8
|
|
||||||
#define MARGIN_RIGHT 8
|
|
||||||
#define MARGIN_TOP 4
|
|
||||||
#define MARGIN_BOTTOM 4
|
|
||||||
|
|
||||||
using namespace chatterino::messages;
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
namespace messages {
|
|
||||||
|
|
||||||
MessageRef::MessageRef(SharedMessage _message)
|
|
||||||
: message(_message)
|
|
||||||
, wordParts()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Message *MessageRef::getMessage()
|
|
||||||
{
|
|
||||||
return this->message.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
int MessageRef::getHeight() const
|
|
||||||
{
|
|
||||||
return this->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MessageRef::layout(int width, bool enableEmoteMargins)
|
|
||||||
{
|
|
||||||
auto &settings = SettingsManager::getInstance();
|
|
||||||
|
|
||||||
bool sizeChanged = width != this->currentLayoutWidth;
|
|
||||||
bool redraw = width != this->currentLayoutWidth;
|
|
||||||
int spaceWidth = 4;
|
|
||||||
|
|
||||||
int mediumTextLineHeight =
|
|
||||||
FontManager::getInstance().getFontMetrics(FontManager::Medium).height();
|
|
||||||
|
|
||||||
/* TODO(pajlada): Re-implement
|
|
||||||
bool recalculateImages = this->emoteGeneration != EmoteManager::getInstance().getGeneration();
|
|
||||||
*/
|
|
||||||
bool recalculateImages = true;
|
|
||||||
|
|
||||||
bool recalculateText = this->fontGeneration != FontManager::getInstance().getGeneration();
|
|
||||||
bool newWordTypes = this->currentWordTypes != SettingsManager::getInstance().getWordTypeMask();
|
|
||||||
|
|
||||||
qreal emoteScale = settings.emoteScale.get();
|
|
||||||
bool scaleEmotesByLineHeight = settings.scaleEmotesByLineHeight.get();
|
|
||||||
|
|
||||||
// calculate word sizes
|
|
||||||
if (!redraw && !recalculateImages && !recalculateText && !newWordTypes) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this->emoteGeneration = EmoteManager::getInstance().getGeneration();
|
|
||||||
this->fontGeneration = FontManager::getInstance().getGeneration();
|
|
||||||
|
|
||||||
for (auto &word : this->message->getWords()) {
|
|
||||||
if (word.isImage()) {
|
|
||||||
if (!recalculateImages) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &image = word.getImage();
|
|
||||||
|
|
||||||
qreal w = image.getWidth();
|
|
||||||
qreal h = image.getHeight();
|
|
||||||
|
|
||||||
if (scaleEmotesByLineHeight) {
|
|
||||||
word.setSize(w * mediumTextLineHeight / h * emoteScale,
|
|
||||||
mediumTextLineHeight * emoteScale);
|
|
||||||
} else {
|
|
||||||
word.setSize(w * image.getScale() * emoteScale, h * image.getScale() * emoteScale);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!recalculateText) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFontMetrics &metrics = word.getFontMetrics();
|
|
||||||
word.setSize(metrics.width(word.getText()), metrics.height());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newWordTypes) {
|
|
||||||
this->currentWordTypes = settings.getWordTypeMask();
|
|
||||||
}
|
|
||||||
|
|
||||||
// layout
|
|
||||||
this->currentLayoutWidth = width;
|
|
||||||
|
|
||||||
int x = MARGIN_LEFT;
|
|
||||||
int y = MARGIN_TOP;
|
|
||||||
|
|
||||||
int right = width - MARGIN_RIGHT;
|
|
||||||
|
|
||||||
int lineNumber = 0;
|
|
||||||
int lineStart = 0;
|
|
||||||
int lineHeight = 0;
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
this->wordParts.clear();
|
|
||||||
|
|
||||||
uint32_t flags = settings.getWordTypeMask();
|
|
||||||
|
|
||||||
for (auto it = this->message->getWords().begin(); it != this->message->getWords().end(); ++it) {
|
|
||||||
Word &word = *it;
|
|
||||||
|
|
||||||
// Check if given word is supposed to be rendered by comparing it to the current setting
|
|
||||||
if ((word.getType() & flags) == Word::None) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xOffset = 0, yOffset = 0;
|
|
||||||
|
|
||||||
if (enableEmoteMargins) {
|
|
||||||
if (word.isImage() && word.getImage().isHat()) {
|
|
||||||
xOffset = -word.getWidth() + 2;
|
|
||||||
} else {
|
|
||||||
xOffset = word.getXOffset();
|
|
||||||
yOffset = word.getYOffset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// word wrapping
|
|
||||||
if (word.isText() && word.getWidth() + MARGIN_LEFT > right) {
|
|
||||||
alignWordParts(lineStart, lineHeight, width);
|
|
||||||
|
|
||||||
y += lineHeight;
|
|
||||||
|
|
||||||
const QString &text = word.getText();
|
|
||||||
|
|
||||||
int start = 0;
|
|
||||||
QFontMetrics &metrics = word.getFontMetrics();
|
|
||||||
|
|
||||||
int width = 0;
|
|
||||||
|
|
||||||
std::vector<short> &charWidths = word.getCharacterWidthCache();
|
|
||||||
int charOffset = 0;
|
|
||||||
|
|
||||||
for (int i = 2; i <= text.length(); i++) {
|
|
||||||
if ((width = width + charWidths[i - 1]) + MARGIN_LEFT > right) {
|
|
||||||
QString mid = text.mid(start, i - start - 1);
|
|
||||||
|
|
||||||
this->wordParts.push_back(WordPart(word, MARGIN_LEFT, y, width,
|
|
||||||
word.getHeight(), lineNumber, mid, mid,
|
|
||||||
false, charOffset));
|
|
||||||
|
|
||||||
charOffset = i;
|
|
||||||
|
|
||||||
y += metrics.height();
|
|
||||||
|
|
||||||
start = i - 1;
|
|
||||||
|
|
||||||
width = 0;
|
|
||||||
lineNumber++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString mid(text.mid(start));
|
|
||||||
width = metrics.width(mid);
|
|
||||||
|
|
||||||
this->wordParts.push_back(WordPart(word, MARGIN_LEFT, y - word.getHeight(), width,
|
|
||||||
word.getHeight(), lineNumber, mid, mid, charOffset));
|
|
||||||
x = width + MARGIN_LEFT + spaceWidth;
|
|
||||||
|
|
||||||
lineHeight = word.getHeight();
|
|
||||||
|
|
||||||
lineStart = this->wordParts.size() - 1;
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
} else if (first || x + word.getWidth() + xOffset <= right) {
|
|
||||||
// fits in the line
|
|
||||||
this->wordParts.push_back(
|
|
||||||
WordPart(word, x, y - word.getHeight(), lineNumber, word.getCopyText()));
|
|
||||||
|
|
||||||
x += word.getWidth() + xOffset;
|
|
||||||
x += spaceWidth;
|
|
||||||
|
|
||||||
lineHeight = std::max(word.getHeight(), lineHeight);
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
// doesn't fit in the line
|
|
||||||
alignWordParts(lineStart, lineHeight, width);
|
|
||||||
|
|
||||||
y += lineHeight;
|
|
||||||
|
|
||||||
lineNumber++;
|
|
||||||
|
|
||||||
this->wordParts.push_back(
|
|
||||||
WordPart(word, MARGIN_LEFT, y - word.getHeight(), lineNumber, word.getCopyText()));
|
|
||||||
|
|
||||||
lineStart = this->wordParts.size() - 1;
|
|
||||||
|
|
||||||
lineHeight = word.getHeight();
|
|
||||||
|
|
||||||
x = word.getWidth() + MARGIN_LEFT;
|
|
||||||
x += spaceWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
alignWordParts(lineStart, lineHeight, width);
|
|
||||||
|
|
||||||
if (this->height != y + lineHeight) {
|
|
||||||
sizeChanged = true;
|
|
||||||
this->height = y + lineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->height += MARGIN_BOTTOM;
|
|
||||||
|
|
||||||
if (sizeChanged) {
|
|
||||||
buffer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateBuffer = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<WordPart> &MessageRef::getWordParts() const
|
|
||||||
{
|
|
||||||
return this->wordParts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageRef::alignWordParts(int lineStart, int lineHeight, int width)
|
|
||||||
{
|
|
||||||
int xOffset = 0;
|
|
||||||
|
|
||||||
if (this->message->centered && this->wordParts.size() > 0) {
|
|
||||||
xOffset = (width - this->wordParts.at(this->wordParts.size() - 1).getRight()) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = lineStart; i < this->wordParts.size(); i++) {
|
|
||||||
WordPart &wordPart2 = this->wordParts.at(i);
|
|
||||||
|
|
||||||
wordPart2.setPosition(wordPart2.getX() + xOffset, wordPart2.getY() + lineHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Word *MessageRef::tryGetWordPart(QPoint point)
|
|
||||||
{
|
|
||||||
// go through all words and return the first one that contains the point.
|
|
||||||
for (WordPart &wordPart : this->wordParts) {
|
|
||||||
if (wordPart.getRect().contains(point)) {
|
|
||||||
return &wordPart.getWord();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MessageRef::getSelectionIndex(QPoint position)
|
|
||||||
{
|
|
||||||
if (this->wordParts.size() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find out in which line the cursor is
|
|
||||||
int lineNumber = 0, lineStart = 0, lineEnd = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < this->wordParts.size(); i++) {
|
|
||||||
WordPart &part = this->wordParts[i];
|
|
||||||
|
|
||||||
if (part.getLineNumber() != 0 && position.y() < part.getY()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (part.getLineNumber() != lineNumber) {
|
|
||||||
lineStart = i;
|
|
||||||
lineNumber = part.getLineNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
lineEnd = i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// count up to the cursor
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < lineStart; i++) {
|
|
||||||
WordPart &part = this->wordParts[i];
|
|
||||||
|
|
||||||
index += part.getWord().isImage() ? 2 : part.getText().length() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = lineStart; i < lineEnd; i++) {
|
|
||||||
WordPart &part = this->wordParts[i];
|
|
||||||
|
|
||||||
// curser is left of the word part
|
|
||||||
if (position.x() < part.getX()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cursor is right of the word part
|
|
||||||
if (position.x() > part.getX() + part.getWidth()) {
|
|
||||||
index += part.getCharacterLength();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cursor is over the word part
|
|
||||||
if (part.getWord().isImage()) {
|
|
||||||
if (position.x() - part.getX() > part.getWidth() / 2) {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: use word.getCharacterWidthCache();
|
|
||||||
|
|
||||||
auto text = part.getText();
|
|
||||||
|
|
||||||
int x = part.getX();
|
|
||||||
|
|
||||||
for (int j = 0; j < text.length(); j++) {
|
|
||||||
if (x > position.x()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
x = part.getX() + part.getWord().getFontMetrics().width(text, j + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace messages
|
|
||||||
} // namespace chatterino
|
|
|
@ -1,55 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "messages/message.hpp"
|
|
||||||
#include "messages/wordpart.hpp"
|
|
||||||
|
|
||||||
#include <QPixmap>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
namespace messages {
|
|
||||||
|
|
||||||
class MessageRef;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<MessageRef> SharedMessageRef;
|
|
||||||
|
|
||||||
class MessageRef
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MessageRef(SharedMessage message);
|
|
||||||
|
|
||||||
Message *getMessage();
|
|
||||||
int getHeight() const;
|
|
||||||
|
|
||||||
bool layout(int width, bool enableEmoteMargins = true);
|
|
||||||
|
|
||||||
const std::vector<WordPart> &getWordParts() const;
|
|
||||||
|
|
||||||
std::shared_ptr<QPixmap> buffer = nullptr;
|
|
||||||
bool updateBuffer = false;
|
|
||||||
|
|
||||||
const Word *tryGetWordPart(QPoint point);
|
|
||||||
|
|
||||||
int getSelectionIndex(QPoint position);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// variables
|
|
||||||
SharedMessage message;
|
|
||||||
std::vector<WordPart> wordParts;
|
|
||||||
|
|
||||||
int height = 0;
|
|
||||||
|
|
||||||
int currentLayoutWidth = -1;
|
|
||||||
int fontGeneration = -1;
|
|
||||||
/* TODO(pajlada): Re-implement
|
|
||||||
int emoteGeneration = -1;
|
|
||||||
*/
|
|
||||||
Word::Type currentWordTypes = Word::None;
|
|
||||||
|
|
||||||
// methods
|
|
||||||
void alignWordParts(int lineStart, int lineHeight, int width);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace messages
|
|
||||||
} // namespace chatterino
|
|
|
@ -1,123 +0,0 @@
|
||||||
#include "messages/wordpart.hpp"
|
|
||||||
#include "messages/word.hpp"
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
namespace messages {
|
|
||||||
|
|
||||||
WordPart::WordPart(Word &_word, int _x, int _y, int _lineNumber, const QString &_copyText,
|
|
||||||
bool _allowTrailingSpace)
|
|
||||||
: word(_word)
|
|
||||||
, copyText(_copyText)
|
|
||||||
, text(_word.isText() ? _word.getText() : QString())
|
|
||||||
, x(_x)
|
|
||||||
, y(_y)
|
|
||||||
, width(_word.getWidth())
|
|
||||||
, height(_word.getHeight())
|
|
||||||
, lineNumber(_lineNumber)
|
|
||||||
, _trailingSpace(!_word.getCopyText().isEmpty() &&
|
|
||||||
_word.hasTrailingSpace() & _allowTrailingSpace)
|
|
||||||
, wordCharOffset(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WordPart::WordPart(Word &_word, int _x, int _y, int _width, int _height, int _lineNumber,
|
|
||||||
const QString &_copyText, const QString &_customText, bool _allowTrailingSpace,
|
|
||||||
int _wordCharOffset)
|
|
||||||
: word(_word)
|
|
||||||
, copyText(_copyText)
|
|
||||||
, text(_customText)
|
|
||||||
, x(_x)
|
|
||||||
, y(_y)
|
|
||||||
, width(_width)
|
|
||||||
, height(_height)
|
|
||||||
, lineNumber(_lineNumber)
|
|
||||||
, _trailingSpace(!_word.getCopyText().isEmpty() &&
|
|
||||||
_word.hasTrailingSpace() & _allowTrailingSpace)
|
|
||||||
, wordCharOffset(_wordCharOffset)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const Word &WordPart::getWord() const
|
|
||||||
{
|
|
||||||
return this->word;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getWidth() const
|
|
||||||
{
|
|
||||||
return this->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getHeight() const
|
|
||||||
{
|
|
||||||
return this->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getX() const
|
|
||||||
{
|
|
||||||
return this->x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getY() const
|
|
||||||
{
|
|
||||||
return this->y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordPart::setPosition(int x, int y)
|
|
||||||
{
|
|
||||||
this->x = x;
|
|
||||||
this->y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordPart::setY(int y)
|
|
||||||
{
|
|
||||||
this->y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getRight() const
|
|
||||||
{
|
|
||||||
return this->x + this->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getBottom() const
|
|
||||||
{
|
|
||||||
return this->y + this->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect WordPart::getRect() const
|
|
||||||
{
|
|
||||||
return QRect(this->x, this->y, this->width, this->height - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString WordPart::getCopyText() const
|
|
||||||
{
|
|
||||||
return this->copyText;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::hasTrailingSpace() const
|
|
||||||
{
|
|
||||||
return this->_trailingSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString &WordPart::getText() const
|
|
||||||
{
|
|
||||||
return this->text;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getLineNumber() const
|
|
||||||
{
|
|
||||||
return this->lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WordPart::getCharacterLength() const
|
|
||||||
{
|
|
||||||
// return (this->getWord().isImage() ? 1 : this->getText().length()) + (_trailingSpace ? 1 :
|
|
||||||
// 0);
|
|
||||||
return this->getWord().isImage() ? 2 : this->getText().length() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
short WordPart::getCharacterWidth(int index) const
|
|
||||||
{
|
|
||||||
return this->getWord().getCharacterWidthCache().at(index + this->wordCharOffset);
|
|
||||||
}
|
|
||||||
} // namespace messages
|
|
||||||
} // namespace chatterino
|
|
|
@ -1,56 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QRect>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
namespace messages {
|
|
||||||
|
|
||||||
class Word;
|
|
||||||
|
|
||||||
class WordPart
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WordPart(Word &getWord, int getX, int getY, int _lineNumber, const QString &getCopyText,
|
|
||||||
bool allowTrailingSpace = true);
|
|
||||||
|
|
||||||
WordPart(Word &getWord, int getX, int getY, int getWidth, int getHeight, int _lineNumber,
|
|
||||||
const QString &getCopyText, const QString &customText, bool allowTrailingSpace = true,
|
|
||||||
int wordCharOffset = 0);
|
|
||||||
|
|
||||||
const Word &getWord() const;
|
|
||||||
int getWidth() const;
|
|
||||||
int getHeight() const;
|
|
||||||
int getX() const;
|
|
||||||
int getY() const;
|
|
||||||
void setPosition(int _x, int _y);
|
|
||||||
void setY(int _y);
|
|
||||||
int getRight() const;
|
|
||||||
int getBottom() const;
|
|
||||||
QRect getRect() const;
|
|
||||||
const QString getCopyText() const;
|
|
||||||
int hasTrailingSpace() const;
|
|
||||||
const QString &getText() const;
|
|
||||||
int getLineNumber() const;
|
|
||||||
int getCharacterLength() const;
|
|
||||||
short getCharacterWidth(int index) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Word &word;
|
|
||||||
|
|
||||||
QString copyText;
|
|
||||||
QString text;
|
|
||||||
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
int lineNumber;
|
|
||||||
|
|
||||||
bool _trailingSpace;
|
|
||||||
int wordCharOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace messages
|
|
||||||
} // namespace chatterino
|
|
Loading…
Reference in a new issue