mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
added some code for collapsing messages
This commit is contained in:
parent
5c6411b50b
commit
c950e9c58a
11 changed files with 109 additions and 21 deletions
BIN
resources/images/collapse.png
Normal file
BIN
resources/images/collapse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 236 B |
|
@ -33,6 +33,7 @@
|
|||
<file>images/VSO_Link_blue_16x.png</file>
|
||||
<file>sounds/ping2.wav</file>
|
||||
<file>images/subscriber.png</file>
|
||||
<file>images/collapse.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qt/etc">
|
||||
<file>qt.conf</file>
|
||||
|
|
|
@ -61,6 +61,16 @@ const QString &Message::getId() const
|
|||
return this->id;
|
||||
}
|
||||
|
||||
bool Message::getCollapsedDefault() const
|
||||
{
|
||||
return this->collapsedDefault;
|
||||
}
|
||||
|
||||
void Message::setCollapsedDefault(bool value)
|
||||
{
|
||||
this->collapsedDefault = value;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void AddCurrentTimestamp(Message *message)
|
||||
|
|
|
@ -27,6 +27,8 @@ public:
|
|||
std::vector<Word> &getWords();
|
||||
bool isDisabled() const;
|
||||
const QString &getId() const;
|
||||
bool getCollapsedDefault() const;
|
||||
void setCollapsedDefault(bool value);
|
||||
|
||||
QString loginName;
|
||||
QString displayName;
|
||||
|
@ -57,6 +59,9 @@ private:
|
|||
QString timeoutUser = "";
|
||||
int timeoutCount = 0;
|
||||
bool disabled = false;
|
||||
|
||||
bool collapsedDefault = false;
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> parseTime;
|
||||
|
||||
QString content;
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
#include <QDebug>
|
||||
|
||||
#define MARGIN_LEFT 8
|
||||
#define MARGIN_RIGHT 8
|
||||
#define MARGIN_TOP 4
|
||||
#define MARGIN_BOTTOM 4
|
||||
#define MARGIN_LEFT (int)(8 * this->dpiMultiplier)
|
||||
#define MARGIN_RIGHT (int)(8 * this->dpiMultiplier)
|
||||
#define MARGIN_TOP (int)(4 * this->dpiMultiplier)
|
||||
#define MARGIN_BOTTOM (int)(4 * this->dpiMultiplier)
|
||||
|
||||
using namespace chatterino::messages;
|
||||
|
||||
|
@ -17,6 +17,7 @@ namespace messages {
|
|||
MessageRef::MessageRef(SharedMessage _message)
|
||||
: message(_message)
|
||||
, wordParts()
|
||||
, collapsed(_message->getCollapsedDefault())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -59,9 +60,9 @@ bool MessageRef::layout(int width, float dpiMultiplyer)
|
|||
this->currentWordTypes = SettingsManager::getInstance().getWordTypeMask();
|
||||
|
||||
// check if dpi changed
|
||||
bool dpiChanged = this->dpiMultiplyer != dpiMultiplyer;
|
||||
bool dpiChanged = this->dpiMultiplier != dpiMultiplyer;
|
||||
layoutRequired |= dpiChanged;
|
||||
this->dpiMultiplyer = dpiMultiplyer;
|
||||
this->dpiMultiplier = dpiMultiplyer;
|
||||
imagesChanged |= dpiChanged;
|
||||
textChanged |= dpiChanged;
|
||||
|
||||
|
@ -105,9 +106,13 @@ void MessageRef::actuallyLayout(int width)
|
|||
int lineNumber = 0;
|
||||
int lineStart = 0;
|
||||
int lineHeight = 0;
|
||||
int firstLineHeight = -1;
|
||||
bool first = true;
|
||||
|
||||
uint32_t flags = settings.getWordTypeMask();
|
||||
if (this->collapsed) {
|
||||
flags |= Word::Collapsed;
|
||||
}
|
||||
|
||||
// loop throught all the words and add them when a line is full
|
||||
for (auto it = this->message->getWords().begin(); it != this->message->getWords().end(); ++it) {
|
||||
|
@ -132,7 +137,7 @@ void MessageRef::actuallyLayout(int width)
|
|||
// word wrapping
|
||||
if (word.isText() && word.getWidth() + MARGIN_LEFT > right) {
|
||||
// align and end the current line
|
||||
alignWordParts(lineStart, lineHeight, width);
|
||||
alignWordParts(lineStart, lineHeight, width, firstLineHeight);
|
||||
y += lineHeight;
|
||||
|
||||
int currentPartStart = 0;
|
||||
|
@ -187,7 +192,7 @@ void MessageRef::actuallyLayout(int width)
|
|||
// doesn't fit in the line
|
||||
else {
|
||||
// align and end the current line
|
||||
alignWordParts(lineStart, lineHeight, width);
|
||||
alignWordParts(lineStart, lineHeight, width, firstLineHeight);
|
||||
|
||||
y += lineHeight;
|
||||
|
||||
|
@ -206,11 +211,19 @@ void MessageRef::actuallyLayout(int width)
|
|||
}
|
||||
|
||||
// align and end the current line
|
||||
alignWordParts(lineStart, lineHeight, width);
|
||||
alignWordParts(lineStart, lineHeight, width, firstLineHeight);
|
||||
|
||||
this->collapsedHeight = firstLineHeight == -1 ? (int)(24 * dpiMultiplier)
|
||||
: firstLineHeight + MARGIN_TOP + MARGIN_BOTTOM;
|
||||
|
||||
// update height
|
||||
int oldHeight = this->height;
|
||||
|
||||
if (this->isCollapsed()) {
|
||||
this->height = this->collapsedHeight;
|
||||
} else {
|
||||
this->height = y + lineHeight + MARGIN_BOTTOM;
|
||||
}
|
||||
|
||||
// invalidate buffer if height changed
|
||||
if (oldHeight != this->height) {
|
||||
|
@ -227,8 +240,8 @@ void MessageRef::updateTextSizes()
|
|||
continue;
|
||||
|
||||
QFontMetrics &metrics = word.getFontMetrics();
|
||||
word.setSize((int)(metrics.width(word.getText()) * this->dpiMultiplyer),
|
||||
(int)(metrics.height() * this->dpiMultiplyer));
|
||||
word.setSize((int)(metrics.width(word.getText()) * this->dpiMultiplier),
|
||||
(int)(metrics.height() * this->dpiMultiplier));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,7 +249,7 @@ void MessageRef::updateImageSizes()
|
|||
{
|
||||
const int mediumTextLineHeight =
|
||||
FontManager::getInstance().getFontMetrics(FontManager::Medium).height();
|
||||
const qreal emoteScale = SettingsManager::getInstance().emoteScale.get() * this->dpiMultiplyer;
|
||||
const qreal emoteScale = SettingsManager::getInstance().emoteScale.get() * this->dpiMultiplier;
|
||||
const bool scaleEmotesByLineHeight = SettingsManager::getInstance().scaleEmotesByLineHeight;
|
||||
|
||||
for (auto &word : this->message->getWords()) {
|
||||
|
@ -262,8 +275,12 @@ const std::vector<WordPart> &MessageRef::getWordParts() const
|
|||
return this->wordParts;
|
||||
}
|
||||
|
||||
void MessageRef::alignWordParts(int lineStart, int lineHeight, int width)
|
||||
void MessageRef::alignWordParts(int lineStart, int lineHeight, int width, int &firstLineHeight)
|
||||
{
|
||||
if (firstLineHeight == -1) {
|
||||
firstLineHeight = lineHeight;
|
||||
}
|
||||
|
||||
int xOffset = 0;
|
||||
|
||||
if (this->message->centered && this->wordParts.size() > 0) {
|
||||
|
@ -399,5 +416,22 @@ int MessageRef::getSelectionIndex(QPoint position)
|
|||
return index;
|
||||
}
|
||||
|
||||
bool MessageRef::isCollapsed() const
|
||||
{
|
||||
return this->collapsed;
|
||||
}
|
||||
|
||||
void MessageRef::setCollapsed(bool value)
|
||||
{
|
||||
if (this->collapsed != value) {
|
||||
this->currentLayoutWidth = 0;
|
||||
this->collapsed = value;
|
||||
}
|
||||
}
|
||||
|
||||
int MessageRef::getCollapsedHeight() const
|
||||
{
|
||||
return this->collapsedHeight;
|
||||
}
|
||||
} // namespace messages
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
Message *getMessage();
|
||||
int getHeight() const;
|
||||
|
||||
bool layout(int width, float dpiMultiplyer);
|
||||
bool layout(int width, float dpiMultiplier);
|
||||
|
||||
const std::vector<WordPart> &getWordParts() const;
|
||||
|
||||
|
@ -33,6 +33,10 @@ public:
|
|||
int getLastCharacterIndex() const;
|
||||
int getSelectionIndex(QPoint position);
|
||||
|
||||
bool isCollapsed() const;
|
||||
void setCollapsed(bool value);
|
||||
int getCollapsedHeight() const;
|
||||
|
||||
private:
|
||||
// variables
|
||||
SharedMessage message;
|
||||
|
@ -43,13 +47,16 @@ private:
|
|||
int currentLayoutWidth = -1;
|
||||
int fontGeneration = -1;
|
||||
int emoteGeneration = -1;
|
||||
float dpiMultiplyer = -1;
|
||||
float dpiMultiplier = -1;
|
||||
|
||||
Word::Type currentWordTypes = Word::None;
|
||||
|
||||
bool collapsed;
|
||||
int collapsedHeight = 32;
|
||||
|
||||
// methods
|
||||
void actuallyLayout(int width);
|
||||
void alignWordParts(int lineStart, int lineHeight, int width);
|
||||
void alignWordParts(int lineStart, int lineHeight, int width, int &firstLineHeight);
|
||||
void updateTextSizes();
|
||||
void updateImageSizes();
|
||||
};
|
||||
|
|
|
@ -80,6 +80,9 @@ public:
|
|||
|
||||
AlwaysShow = (1 << 25),
|
||||
|
||||
// used in the ChannelView class to make the collapse buttons visible if needed
|
||||
Collapsed = (1 << 26),
|
||||
|
||||
Default = TimestampNoSeconds | Badges | Username | BitsStatic | FfzEmoteImage |
|
||||
BttvEmoteImage | BttvGifEmoteImage | TwitchEmoteImage | BitsAmount | Text |
|
||||
ButtonBan | ButtonTimeout | AlwaysShow
|
||||
|
|
|
@ -26,6 +26,7 @@ Resources::Resources()
|
|||
, badgePremium(lli(":/images/twitchprime_bg.png"))
|
||||
, badgeVerified(lli(":/images/verified.png", 0.25))
|
||||
, badgeSubscriber(lli(":/images/subscriber.png", 0.25))
|
||||
, badgeCollapsed(lli(":/images/collapse.png"))
|
||||
, cheerBadge100000(lli(":/images/cheer100000"))
|
||||
, cheerBadge10000(lli(":/images/cheer10000"))
|
||||
, cheerBadge5000(lli(":/images/cheer5000"))
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
messages::LazyLoadedImage *badgePremium;
|
||||
messages::LazyLoadedImage *badgeVerified;
|
||||
messages::LazyLoadedImage *badgeSubscriber;
|
||||
messages::LazyLoadedImage *badgeCollapsed;
|
||||
|
||||
messages::LazyLoadedImage *cheerBadge100000;
|
||||
messages::LazyLoadedImage *cheerBadge10000;
|
||||
|
|
|
@ -41,6 +41,10 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
|
||||
this->parseUsername();
|
||||
|
||||
// this->message->setCollapsedDefault(true);
|
||||
// this->appendWord(Word(this->resources.badgeCollapsed, Word::Collapsed, QString(),
|
||||
// QString()));
|
||||
|
||||
// The timestamp is always appended to the builder
|
||||
// Whether or not will be rendered is decided/checked later
|
||||
this->appendTimestamp();
|
||||
|
|
|
@ -729,11 +729,19 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
|
|||
QPoint relativePos;
|
||||
int messageIndex;
|
||||
|
||||
// no message under cursor
|
||||
if (!tryGetMessageAt(event->pos(), message, relativePos, messageIndex)) {
|
||||
setCursor(Qt::ArrowCursor);
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
return;
|
||||
}
|
||||
|
||||
// message under cursor is collapsed
|
||||
if (message->isCollapsed()) {
|
||||
this->setCursor(Qt::PointingHandCursor);
|
||||
return;
|
||||
}
|
||||
|
||||
// is selecting
|
||||
if (this->selecting) {
|
||||
int index = message->getSelectionIndex(relativePos);
|
||||
|
||||
|
@ -742,16 +750,18 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
|
|||
this->repaint();
|
||||
}
|
||||
|
||||
// check if word underneath cursor
|
||||
const messages::Word *hoverWord;
|
||||
if ((hoverWord = message->tryGetWordPart(relativePos)) == nullptr) {
|
||||
setCursor(Qt::ArrowCursor);
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if word has a link
|
||||
if (hoverWord->getLink().isValid()) {
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
this->setCursor(Qt::PointingHandCursor);
|
||||
} else {
|
||||
setCursor(Qt::ArrowCursor);
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -787,6 +797,11 @@ void ChannelView::mousePressEvent(QMouseEvent *event)
|
|||
return;
|
||||
}
|
||||
|
||||
// check if message is collapsed
|
||||
if (message->isCollapsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = message->getSelectionIndex(relativePos);
|
||||
|
||||
auto selectionItem = SelectionItem(messageIndex, index);
|
||||
|
@ -831,6 +846,13 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event)
|
|||
return;
|
||||
}
|
||||
|
||||
// message under cursor is collapsed
|
||||
if (message->isCollapsed()) {
|
||||
message->setCollapsed(false);
|
||||
this->layoutMessages();
|
||||
return;
|
||||
}
|
||||
|
||||
const messages::Word *hoverWord;
|
||||
|
||||
if ((hoverWord = message->tryGetWordPart(relativePos)) == nullptr) {
|
||||
|
|
Loading…
Reference in a new issue