updated messages

This commit is contained in:
fourtf 2017-01-15 16:38:30 +01:00
parent 4dbe2b0254
commit 801e7b8a1e
32 changed files with 698 additions and 148 deletions

View file

@ -61,7 +61,10 @@ SOURCES += main.cpp\
appsettings.cpp \
emojis.cpp \
wordpart.cpp \
resources.cpp
resources.cpp \
windows.cpp \
chatwidgetheaderbutton.cpp \
chatwidgetheaderbuttonlabel.cpp
HEADERS += mainwindow.h \
chatwidget.h \
@ -96,7 +99,10 @@ HEADERS += mainwindow.h \
emojis.h \
wordpart.h \
common.h \
resources.h
resources.h \
windows.h \
chatwidgetheaderbutton.h \
chatwidgetheaderbuttonlabel.h
PRECOMPILED_HEADER =

View file

@ -1,16 +1,82 @@
#include "chatwidgetheader.h"
#include "QByteArray"
#include "QDrag"
#include "QMimeData"
#include "QPainter"
#include "chatwidget.h"
#include "colorscheme.h"
#include "notebookpage.h"
#include <QByteArray>
#include <QDrag>
#include <QMimeData>
#include <QPainter>
ChatWidgetHeader::ChatWidgetHeader()
: QWidget()
, m_dragStart()
, m_dragging(false)
, leftLabel()
, middleLabel()
, rightLabel()
, leftMenu(this)
, rightMenu(this)
{
setFixedHeight(32);
updateColors();
setLayout(&hbox);
hbox.setMargin(0);
hbox.addWidget(&leftLabel);
hbox.addWidget(&middleLabel, 1);
hbox.addWidget(&rightLabel);
// left
leftLabel.label().setTextFormat(Qt::RichText);
leftLabel.label().setText(
"<img src=':/images/tool_moreCollapser_off16.png' />");
QObject::connect(&leftLabel, ChatWidgetHeaderButton::clicked, this,
leftButtonClicked);
leftMenu.addAction("Add new split", this, ChatWidgetHeader::menuAddSplit,
QKeySequence(tr("Ctrl+T")));
leftMenu.addAction("Close split", this, ChatWidgetHeader::menuCloseSplit,
QKeySequence(tr("Ctrl+W")));
leftMenu.addAction("Move split", this, ChatWidgetHeader::menuMoveSplit);
leftMenu.addSeparator();
leftMenu.addAction("Change channel", this,
ChatWidgetHeader::menuChangeChannel,
QKeySequence(tr("Ctrl+R")));
leftMenu.addAction("Clear chat", this, ChatWidgetHeader::menuClearChat);
leftMenu.addAction("Open channel", this, ChatWidgetHeader::menuOpenChannel);
leftMenu.addAction("Open pop-out player", this,
ChatWidgetHeader::menuPopupPlayer);
leftMenu.addSeparator();
leftMenu.addAction("Reload channel emotes", this,
ChatWidgetHeader::menuReloadChannelEmotes);
leftMenu.addAction("Manual reconnect", this,
ChatWidgetHeader::menuManualReconnect);
leftMenu.addSeparator();
leftMenu.addAction("Show changelog", this,
ChatWidgetHeader::menuShowChangelog);
// middle
middleLabel.setAlignment(Qt::AlignCenter);
middleLabel.setText("textString");
// right
rightLabel.setMinimumWidth(height());
rightLabel.label().setTextFormat(Qt::RichText);
rightLabel.label().setText("ayy");
}
void
ChatWidgetHeader::updateColors()
{
QPalette palette;
palette.setColor(QPalette::Foreground, ColorScheme::instance().Text);
leftLabel.setPalette(palette);
middleLabel.setPalette(palette);
rightLabel.setPalette(palette);
}
void
@ -26,17 +92,17 @@ ChatWidgetHeader::paintEvent(QPaintEvent *)
void
ChatWidgetHeader::mousePressEvent(QMouseEvent *event)
{
dragging = true;
m_dragging = true;
dragStart = event->pos();
m_dragStart = event->pos();
}
void
ChatWidgetHeader::mouseMoveEvent(QMouseEvent *event)
{
if (dragging) {
if (std::abs(dragStart.x() - event->pos().x()) > 12 ||
std::abs(dragStart.y() - event->pos().y()) > 12) {
if (m_dragging) {
if (std::abs(m_dragStart.x() - event->pos().x()) > 12 ||
std::abs(m_dragStart.y() - event->pos().y()) > 12) {
auto chatWidget = getChatWidget();
auto page = static_cast<NotebookPage *>(chatWidget->parentWidget());
@ -72,3 +138,56 @@ ChatWidgetHeader::getChatWidget()
{
return static_cast<ChatWidget *>(parentWidget());
}
void
ChatWidgetHeader::leftButtonClicked()
{
leftMenu.move(leftLabel.mapToGlobal(QPoint(0, leftLabel.height())));
leftMenu.show();
}
void
ChatWidgetHeader::rightButtonClicked()
{
}
void
ChatWidgetHeader::menuAddSplit()
{
}
void
ChatWidgetHeader::menuCloseSplit()
{
}
void
ChatWidgetHeader::menuMoveSplit()
{
}
void
ChatWidgetHeader::menuChangeChannel()
{
}
void
ChatWidgetHeader::menuClearChat()
{
}
void
ChatWidgetHeader::menuOpenChannel()
{
}
void
ChatWidgetHeader::menuPopupPlayer()
{
}
void
ChatWidgetHeader::menuReloadChannelEmotes()
{
}
void
ChatWidgetHeader::menuManualReconnect()
{
}
void
ChatWidgetHeader::menuShowChangelog()
{
}

View file

@ -1,10 +1,16 @@
#ifndef CHATWIDGETHEADER_H
#define CHATWIDGETHEADER_H
#include "QMouseEvent"
#include "QPaintEvent"
#include "QPoint"
#include "QWidget"
#include "chatwidgetheaderbutton.h"
#include <QAction>
#include <QHBoxLayout>
#include <QLabel>
#include <QMenu>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPoint>
#include <QWidget>
class ChatWidget;
@ -15,6 +21,7 @@ class ChatWidgetHeader : public QWidget
public:
ChatWidgetHeader();
ChatWidget *getChatWidget();
void updateColors();
protected:
void paintEvent(QPaintEvent *);
@ -22,8 +29,31 @@ protected:
void mouseMoveEvent(QMouseEvent *event);
private:
QPoint dragStart;
bool dragging = false;
QPoint m_dragStart;
bool m_dragging;
QHBoxLayout hbox;
ChatWidgetHeaderButton leftLabel;
QLabel middleLabel;
ChatWidgetHeaderButton rightLabel;
QMenu leftMenu;
QMenu rightMenu;
void leftButtonClicked();
void rightButtonClicked();
void menuAddSplit();
void menuCloseSplit();
void menuMoveSplit();
void menuChangeChannel();
void menuClearChat();
void menuOpenChannel();
void menuPopupPlayer();
void menuReloadChannelEmotes();
void menuManualReconnect();
void menuShowChangelog();
};
#endif // CHATWIDGETHEADER_H

View file

@ -0,0 +1,99 @@
#include "chatwidgetheaderbutton.h"
#include "colorscheme.h"
#include <QBrush>
#include <QPainter>
ChatWidgetHeaderButton::ChatWidgetHeaderButton()
: QWidget()
, hbox()
, m_label()
, m_mouseOver(false)
, m_mouseDown(false)
{
setLayout(&hbox);
hbox.setMargin(0);
hbox.addSpacing(6);
hbox.addWidget(&m_label);
hbox.addSpacing(6);
QObject::connect(&m_label, ChatWidgetHeaderButtonLabel::mouseUp, this,
labelMouseUp);
QObject::connect(&m_label, ChatWidgetHeaderButtonLabel::mouseDown, this,
labelMouseDown);
}
void
ChatWidgetHeaderButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QBrush brush(ColorScheme::instance().IsLightTheme
? QColor(0, 0, 0, 32)
: QColor(255, 255, 255, 32));
if (m_mouseDown) {
painter.fillRect(rect(), brush);
}
if (m_mouseOver) {
painter.fillRect(rect(), brush);
}
}
void
ChatWidgetHeaderButton::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
m_mouseDown = true;
repaint();
}
}
void
ChatWidgetHeaderButton::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
m_mouseDown = false;
repaint();
emit clicked();
}
}
void
ChatWidgetHeaderButton::enterEvent(QEvent *)
{
m_mouseOver = true;
repaint();
}
void
ChatWidgetHeaderButton::leaveEvent(QEvent *)
{
m_mouseOver = false;
repaint();
}
void
ChatWidgetHeaderButton::labelMouseUp()
{
m_mouseDown = false;
repaint();
emit clicked();
}
void
ChatWidgetHeaderButton::labelMouseDown()
{
m_mouseDown = true;
repaint();
}

47
chatwidgetheaderbutton.h Normal file
View file

@ -0,0 +1,47 @@
#ifndef CHATWIDGETHEADERBUTTON_H
#define CHATWIDGETHEADERBUTTON_H
#include "chatwidgetheaderbuttonlabel.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QPaintEvent>
#include <QWidget>
class ChatWidgetHeaderButton : public QWidget
{
Q_OBJECT
public:
ChatWidgetHeaderButton();
ChatWidgetHeaderButtonLabel &
label()
{
return m_label;
}
signals:
void clicked();
protected:
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
void enterEvent(QEvent *) Q_DECL_OVERRIDE;
void leaveEvent(QEvent *) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private:
QHBoxLayout hbox;
ChatWidgetHeaderButtonLabel m_label;
bool m_mouseOver;
bool m_mouseDown;
void labelMouseUp();
void labelMouseDown();
};
#endif // CHATWIDGETHEADERBUTTON_H

View file

@ -0,0 +1,21 @@
#include "chatwidgetheaderbuttonlabel.h"
ChatWidgetHeaderButtonLabel::ChatWidgetHeaderButtonLabel()
{
}
void
ChatWidgetHeaderButtonLabel::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
emit mouseDown();
}
}
void
ChatWidgetHeaderButtonLabel::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
emit mouseUp();
}
}

View file

@ -0,0 +1,23 @@
#ifndef CHATWIDGETHEADERBUTTONLABEL_H
#define CHATWIDGETHEADERBUTTONLABEL_H
#include <QLabel>
#include <QMouseEvent>
class ChatWidgetHeaderButtonLabel : public QLabel
{
Q_OBJECT
public:
ChatWidgetHeaderButtonLabel();
signals:
void mouseDown();
void mouseUp();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
};
#endif // CHATWIDGETHEADERBUTTONLABEL_H

View file

@ -15,7 +15,7 @@ ChatWidgetView::ChatWidgetView()
scroll->scrollTo(QPointF(0, 100));
m_channel = Channel::getChannel("ian678");
m_channel = Channel::getChannel("fourtf");
}
void
@ -42,6 +42,8 @@ ChatWidgetView::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
auto c = channel();
if (c == NULL)
@ -49,7 +51,7 @@ ChatWidgetView::paintEvent(QPaintEvent *)
auto messages = c->getMessagesClone();
int y = 32;
int y = 0;
for (std::shared_ptr<Message> const &message : messages) {
for (WordPart const &wordPart : message.get()->wordParts()) {
@ -77,8 +79,7 @@ ChatWidgetView::paintEvent(QPaintEvent *)
painter.drawText(
QRectF(wordPart.x(), wordPart.y() + y, 10000, 10000),
wordPart.getText(),
QTextOption(Qt::AlignLeft | Qt::AlignTop));
wordPart.text(), QTextOption(Qt::AlignLeft | Qt::AlignTop));
}
}

View file

@ -13,6 +13,8 @@ ConcurrentMap<QString, LazyLoadedImage *> Emotes::m_ffzChannelEmoteFromCaches;
ConcurrentMap<long, LazyLoadedImage *> Emotes::m_twitchEmoteFromCache;
ConcurrentMap<QString, LazyLoadedImage *> Emotes::m_miscImageFromCache;
int Emotes::m_generation = 0;
Emotes::Emotes()
{
}

View file

@ -66,6 +66,18 @@ public:
static LazyLoadedImage *getTwitchEmoteById(const QString &name,
long int id);
static int
generation()
{
return m_generation;
}
static void
incGeneration()
{
m_generation++;
}
private:
Emotes();
@ -83,6 +95,8 @@ private:
static ConcurrentMap<QString, LazyLoadedImage *> m_miscImageFromCache;
static QString getTwitchEmoteLink(long id, qreal &scale);
static int m_generation;
};
#endif // EMOTES_H

View file

@ -5,7 +5,7 @@
QFont *Fonts::medium = new QFont(DEFAULT_FONT, 14);
QFont *Fonts::mediumBold = new QFont(DEFAULT_FONT, 14);
QFont *Fonts::mediumItalic = new QFont(DEFAULT_FONT, 14);
QFont *Fonts::small = new QFont(DEFAULT_FONT, 12);
QFont *Fonts::small = new QFont(DEFAULT_FONT, 10);
QFont *Fonts::large = new QFont(DEFAULT_FONT, 16);
QFont *Fonts::veryLarge = new QFont(DEFAULT_FONT, 18);
@ -16,6 +16,8 @@ QFontMetrics *Fonts::metricsSmall = new QFontMetrics(*small);
QFontMetrics *Fonts::metricsLarge = new QFontMetrics(*large);
QFontMetrics *Fonts::metricsVeryLarge = new QFontMetrics(*veryLarge);
int Fonts::m_generation = 0;
Fonts::Fonts()
{
}

14
fonts.h
View file

@ -19,6 +19,18 @@ public:
static QFont &getFont(Type type);
static QFontMetrics &getFontMetrics(Type type);
static int
generation()
{
return m_generation;
}
static void
incGeneration()
{
m_generation++;
}
private:
Fonts();
@ -35,6 +47,8 @@ private:
static QFontMetrics *metricsSmall;
static QFontMetrics *metricsLarge;
static QFontMetrics *metricsVeryLarge;
static int m_generation;
};
#endif // FONTS_H

BIN
images/button_ban.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
images/button_timeout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

After

Width:  |  Height:  |  Size: 279 B

View file

@ -120,8 +120,6 @@ IrcManager::beginConnecting()
c->setNickName("justinfan123");
c->setRealName("justinfan123");
c->sendRaw("JOIN #fourtf");
c->sendRaw("JOIN #ian678");
c->sendRaw("JOIN #nuuls");
c->sendCommand(IrcCommand::createCapability("REQ", "twitch.tv/commands"));
c->sendCommand(IrcCommand::createCapability("REQ", "twitch.tv/tags"));

View file

@ -1,6 +1,7 @@
#include "lazyloadedimage.h"
#include "asyncexec.h"
#include "emotes.h"
#include "ircmanager.h"
#include <QNetworkAccessManager>
@ -56,6 +57,7 @@ LazyLoadedImage::loadImage()
}
m_pixmap = pixmap;
Emotes::incGeneration();
});
//}));
}

2
link.h
View file

@ -11,6 +11,8 @@ public:
Url,
CloseCurrentSplit,
UserInfo,
UserTimeout,
UserBan,
InsertText,
ShowMessage,
};

View file

@ -3,6 +3,7 @@
#include "ircmanager.h"
#include "mainwindow.h"
#include "resources.h"
#include "windows.h"
#include <QApplication>
#include <QClipboard>
@ -17,7 +18,7 @@ main(int argc, char *argv[])
ColorScheme::instance().setColors(0, -0.8);
MainWindow w;
MainWindow &w = Windows::mainWindow();
w.show();
Channel::addChannel("ian678");

View file

@ -23,14 +23,14 @@ QRegularExpression *Message::cheerRegex =
new QRegularExpression("cheer[1-9][0-9]*");
Message::Message(const QString &text)
: m_wordParts(new std::list<WordPart>())
: m_wordParts(new std::vector<WordPart>())
{
}
Message::Message(const IrcPrivateMessage &ircMessage, const Channel &channel,
bool enablePingSound, bool isReceivedWhisper,
bool isSentWhisper, bool includeChannel)
: m_wordParts(new std::list<WordPart>())
: m_wordParts(new std::vector<WordPart>())
{
m_parseTime = std::chrono::system_clock::now();
@ -70,6 +70,17 @@ Message::Message(const IrcPrivateMessage &ircMessage, const Channel &channel,
ColorScheme::instance().SystemMessageColor, QString(),
QString()));
// mod buttons
static QString buttonBanTooltip("Ban user");
static QString buttonTimeoutTooltip("Timeout user");
words.push_back(Word(Resources::buttonBan(), Word::ButtonBan, QString(),
buttonBanTooltip,
Link(Link::UserBan, ircMessage.account())));
words.push_back(Word(Resources::buttonTimeout(), Word::ButtonTimeout,
QString(), buttonTimeoutTooltip,
Link(Link::UserTimeout, ircMessage.account())));
// badges
iterator = tags.find("badges");
@ -239,10 +250,8 @@ Message::Message(const IrcPrivateMessage &ircMessage, const Channel &channel,
for (QString split : splits) {
// twitch emote
if (currentTwitchEmote == twitchEmotes.end())
break;
if (currentTwitchEmote->first == i) {
if (currentTwitchEmote != twitchEmotes.end() &&
currentTwitchEmote->first == i) {
words.push_back(Word(currentTwitchEmote->second,
Word::TwitchEmoteImage,
currentTwitchEmote->second->name(),
@ -264,10 +273,10 @@ Message::Message(const IrcPrivateMessage &ircMessage, const Channel &channel,
std::vector<std::tuple<LazyLoadedImage *, QString>> parsed;
Emojis::parseEmojis(parsed, split);
for (const std::tuple<LazyLoadedImage *, QString> &tuple : parsed) {
LazyLoadedImage *image = std::get<0>(tuple);
if (image == NULL) {
if (image == NULL) { // is text
QString string = std::get<1>(tuple);
// cheers
@ -344,7 +353,7 @@ Message::Message(const IrcPrivateMessage &ircMessage, const Channel &channel,
// bttv / ffz emotes
LazyLoadedImage *bttvEmote;
#pragma message WARN("xD ignored emotes")
#pragma message WARN("ignored emotes")
if (Emotes::bttvEmotes().tryGet(string, bttvEmote) ||
channel.bttvChannelEmotes().tryGet(string, bttvEmote) ||
Emotes::ffzEmotes().tryGet(string, bttvEmote) ||
@ -364,6 +373,13 @@ Message::Message(const IrcPrivateMessage &ircMessage, const Channel &channel,
words.push_back(
Word(string, Word::Text, textColor, string, QString(),
link.isEmpty() ? Link() : Link(Link::Url, link)));
} else { // is emoji
static QString emojiTooltip("Emoji");
words.push_back(
Word(image, Word::EmojiImage, image->name(), emojiTooltip));
Word(image->name(), Word::EmojiText, textColor, image->name(),
emojiTooltip);
}
}
@ -390,12 +406,18 @@ Message::layout(int width, bool enableEmoteMargins)
bool redraw = width != m_currentLayoutWidth || m_relayoutRequested;
if (m_recalculateImages || m_recalculateText) {
bool recalculateImages = m_emoteGeneration != Emotes::generation();
bool recalculateText = m_fontGeneration != Fonts::generation();
if (recalculateImages || recalculateText) {
m_emoteGeneration = Emotes::generation();
m_fontGeneration = Fonts::generation();
redraw = true;
for (auto &word : m_words) {
if (word.isImage()) {
if (m_recalculateImages) {
if (recalculateImages) {
auto &image = word.getImage();
qreal w = image.width();
@ -413,16 +435,13 @@ Message::layout(int width, bool enableEmoteMargins)
}
}
} else {
if (m_recalculateText) {
if (recalculateText) {
QFontMetrics &metrics = word.getFontMetrics();
word.setSize(metrics.width(word.getText()),
metrics.height());
}
}
}
m_recalculateImages = false;
m_recalculateText = false;
}
if (!redraw) {
@ -434,20 +453,17 @@ Message::layout(int width, bool enableEmoteMargins)
int right = width - MARGIN_RIGHT - MARGIN_LEFT;
std::list<WordPart> *parts = new std::list<WordPart>();
std::vector<WordPart> *parts = new std::vector<WordPart>();
auto lineStart = parts->begin();
int lineStart = 0;
int lineHeight = 0;
bool first = true;
auto alignParts = [&lineStart, &lineHeight, &parts, this] {
for (auto it2 = lineStart; true; it2++) {
WordPart &wordPart2 = *it2;
for (int i = lineStart; i < parts->size(); i++) {
WordPart &wordPart2 = parts->at(i);
wordPart2.setY(wordPart2.y() + lineHeight);
if (it2 == parts->end()) {
break;
}
}
};
@ -471,24 +487,70 @@ Message::layout(int width, bool enableEmoteMargins)
}
}
// word wrapping
if (word.isText() && word.width() + MARGIN_LEFT > right) {
alignParts();
y += lineHeight;
const QString &text = word.getText();
int start = 0;
QFontMetrics &metrics = word.getFontMetrics();
int width = 0;
std::vector<short> &charWidths = word.characterWidthCache();
if (charWidths.size() == 0) {
charWidths.reserve(text.length());
for (int i = 0; i < text.length(); i++) {
charWidths.push_back(metrics.charWidth(text, i));
}
}
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);
parts->push_back(WordPart(word, MARGIN_LEFT, y, width,
word.height(), mid, mid));
y += metrics.height();
start = i - 1;
width = 0;
}
}
QString mid(text.mid(start));
width = metrics.width(mid);
parts->push_back(WordPart(word, MARGIN_LEFT, y - word.height(),
width, word.height(), mid, mid));
x = width + MARGIN_LEFT + spaceWidth;
lineHeight = word.height();
lineStart = parts->size() - 1;
first = false;
}
// fits in the line
if (x + word.width() + xOffset <= right) {
else if (first || x + word.width() + xOffset <= right) {
parts->push_back(
WordPart(word, x, y - word.height(), word.copyText()));
x += word.width() + xOffset;
if (word.hasTrailingSpace()) {
x += spaceWidth;
}
x += spaceWidth;
lineHeight = std::max(word.height(), lineHeight);
}
// else if (word.isText() && word.getText().length()
// > 2)
// {
// }
first = false;
}
// doesn't fit in the line
else {
@ -499,15 +561,12 @@ Message::layout(int width, bool enableEmoteMargins)
parts->push_back(WordPart(word, MARGIN_LEFT, y - word.height(),
word.copyText()));
lineStart = parts->end();
lineStart = parts->size() - 1;
lineHeight = word.height();
x = word.width();
if (word.hasTrailingSpace()) {
x += spaceWidth;
}
x = word.width() + MARGIN_LEFT;
x += spaceWidth;
}
}

View file

@ -60,7 +60,7 @@ public:
return m_words;
}
const std::list<WordPart>
const std::vector<WordPart>
wordParts() const
{
return *m_wordParts;
@ -91,16 +91,6 @@ public:
{
m_relayoutRequested = true;
}
void
requestTextRecalculation()
{
m_recalculateText = true;
}
void
requestImageRecalculation()
{
m_recalculateImages = true;
}
private:
static LazyLoadedImage *badgeStaff;
@ -126,12 +116,12 @@ private:
int m_height = 0;
std::vector<Word> m_words;
std::list<WordPart> *m_wordParts;
std::vector<WordPart> *m_wordParts;
long m_currentLayoutWidth = -1;
bool m_relayoutRequested = true;
bool m_recalculateText = true;
bool m_recalculateImages = true;
int m_fontGeneration = -1;
int m_emoteGeneration = -1;
static QString matchLink(const QString &string);

View file

@ -1,49 +1,27 @@
#include "notebooktab.h"
#include <QPainter>
#include "colorscheme.h"
#include "notebook.h"
#include <QPainter>
NotebookTab::NotebookTab(Notebook *notebook)
: QWidget(notebook)
, m_notebook(notebook)
, m_text("<no title>")
, m_selected(false)
, m_mouseOver(false)
, m_mouseDown(false)
, m_highlightStyle(HighlightNone)
{
this->notebook = notebook;
text = "<no title>";
calcSize();
setAcceptDrops(true);
}
int
NotebookTab::getHighlightStyle()
{
return highlightStyle;
}
void
NotebookTab::setHighlightStyle(int style)
{
highlightStyle = style;
repaint();
}
void
NotebookTab::setSelected(bool value)
{
selected = value;
repaint();
}
bool
NotebookTab::getSelected()
{
return selected;
}
void
NotebookTab::calcSize()
{
resize(fontMetrics().width(text) + 8, 24);
resize(fontMetrics().width(m_text) + 8, 24);
}
void
@ -55,16 +33,16 @@ NotebookTab::paintEvent(QPaintEvent *)
auto colorScheme = ColorScheme::instance();
if (selected) {
if (m_selected) {
painter.fillRect(rect(), colorScheme.TabSelectedBackground);
fg = colorScheme.TabSelectedText;
} else if (mouseOver) {
} else if (m_mouseOver) {
painter.fillRect(rect(), colorScheme.TabHoverBackground);
fg = colorScheme.TabHoverText;
} else if (highlightStyle == HighlightHighlighted) {
} else if (m_highlightStyle == HighlightHighlighted) {
painter.fillRect(rect(), colorScheme.TabHighlightedBackground);
fg = colorScheme.TabHighlightedText;
} else if (highlightStyle == HighlightNewMessage) {
} else if (m_highlightStyle == HighlightNewMessage) {
painter.fillRect(rect(), colorScheme.TabNewMessageBackground);
fg = colorScheme.TabHighlightedText;
} else {
@ -73,23 +51,23 @@ NotebookTab::paintEvent(QPaintEvent *)
}
painter.setPen(fg);
painter.drawText(4, (height() + fontMetrics().height()) / 2, text);
painter.drawText(4, (height() + fontMetrics().height()) / 2, m_text);
}
void
NotebookTab::mousePressEvent(QMouseEvent *)
{
mouseDown = true;
m_mouseDown = true;
repaint();
notebook->select(page);
m_notebook->select(page);
}
void
NotebookTab::mouseReleaseEvent(QMouseEvent *)
{
mouseDown = false;
m_mouseDown = false;
repaint();
}
@ -97,7 +75,7 @@ NotebookTab::mouseReleaseEvent(QMouseEvent *)
void
NotebookTab::enterEvent(QEvent *)
{
mouseOver = true;
m_mouseOver = true;
repaint();
}
@ -105,7 +83,7 @@ NotebookTab::enterEvent(QEvent *)
void
NotebookTab::leaveEvent(QEvent *)
{
mouseOver = false;
m_mouseOver = false;
repaint();
}
@ -113,5 +91,5 @@ NotebookTab::leaveEvent(QEvent *)
void
NotebookTab::dragEnterEvent(QDragEnterEvent *event)
{
notebook->select(page);
m_notebook->select(page);
}

View file

@ -1,7 +1,7 @@
#ifndef NOTEBOOKTAB_H
#define NOTEBOOKTAB_H
#include "QWidget"
#include <QWidget>
class Notebook;
class NotebookPage;
@ -11,22 +11,55 @@ class NotebookTab : public QWidget
Q_OBJECT
public:
NotebookTab(Notebook *notebook);
enum HighlightStyle {
HighlightNone,
HighlightHighlighted,
HighlightNewMessage
};
NotebookTab(Notebook *m_notebook);
void calcSize();
NotebookPage *page;
QString text;
bool getSelected();
void setSelected(bool value);
const QString &
text() const
{
return m_text;
}
int getHighlightStyle();
void setHighlightStyle(int style);
void
setText(const QString &text)
{
m_text = text;
}
static const int HighlightNone = 0;
static const int HighlightHighlighted = 1;
static const int HighlightNewMessage = 2;
bool
selected()
{
return m_selected;
}
void
setSelected(bool value)
{
m_selected = value;
repaint();
}
HighlightStyle
highlightStyle() const
{
return m_highlightStyle;
}
void
setHighlightStyle(HighlightStyle style)
{
m_highlightStyle = style;
repaint();
}
protected:
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
@ -39,12 +72,14 @@ protected:
void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
private:
Notebook *notebook;
bool selected = false;
Notebook *m_notebook;
bool mouseOver = false;
bool mouseDown = false;
int highlightStyle;
QString m_text;
bool m_selected;
bool m_mouseOver;
bool m_mouseDown;
HighlightStyle m_highlightStyle;
};
#endif // NOTEBOOKTAB_H

View file

@ -16,6 +16,9 @@ LazyLoadedImage *Resources::m_cheerBadge1000;
LazyLoadedImage *Resources::m_cheerBadge100;
LazyLoadedImage *Resources::m_cheerBadge1;
LazyLoadedImage *Resources::m_buttonBan;
LazyLoadedImage *Resources::m_buttonTimeout;
Resources::Resources()
{
}
@ -37,10 +40,17 @@ Resources::load()
new LazyLoadedImage(new QPixmap(":/images/twitchprime_bg.png"));
// cheer badges
m_cheerBadge100000 = new LazyLoadedImage(new QPixmap(":/cheer100000"));
m_cheerBadge10000 = new LazyLoadedImage(new QPixmap(":/cheer10000"));
m_cheerBadge5000 = new LazyLoadedImage(new QPixmap(":/cheer5000"));
m_cheerBadge1000 = new LazyLoadedImage(new QPixmap(":/cheer1000"));
m_cheerBadge100 = new LazyLoadedImage(new QPixmap(":/cheer100"));
m_cheerBadge1 = new LazyLoadedImage(new QPixmap(":/cheer1"));
m_cheerBadge100000 =
new LazyLoadedImage(new QPixmap(":/images/cheer100000"));
m_cheerBadge10000 = new LazyLoadedImage(new QPixmap(":/images/cheer10000"));
m_cheerBadge5000 = new LazyLoadedImage(new QPixmap(":/images/cheer5000"));
m_cheerBadge1000 = new LazyLoadedImage(new QPixmap(":/images/cheer1000"));
m_cheerBadge100 = new LazyLoadedImage(new QPixmap(":/images/cheer100"));
m_cheerBadge1 = new LazyLoadedImage(new QPixmap(":/images/cheer1"));
// button
m_buttonBan =
new LazyLoadedImage(new QPixmap(":/images/button_ban.png"), 0.25);
m_buttonTimeout =
new LazyLoadedImage(new QPixmap(":/images/button_timeout.png"), 0.25);
}

View file

@ -88,6 +88,18 @@ public:
return m_cheerBadge1;
}
static LazyLoadedImage *
buttonBan()
{
return m_buttonBan;
}
static LazyLoadedImage *
buttonTimeout()
{
return m_buttonTimeout;
}
private:
Resources();
@ -105,6 +117,9 @@ private:
static LazyLoadedImage *m_cheerBadge1000;
static LazyLoadedImage *m_cheerBadge100;
static LazyLoadedImage *m_cheerBadge1;
static LazyLoadedImage *m_buttonBan;
static LazyLoadedImage *m_buttonTimeout;
};
#endif // RESOURCES_H

View file

@ -25,5 +25,7 @@
<file>images/staff_bg.png</file>
<file>images/turbo_bg.png</file>
<file>emojidata.txt</file>
<file>images/button_ban.png</file>
<file>images/button_timeout.png</file>
</qresource>
</RCC>

10
windows.cpp Normal file
View file

@ -0,0 +1,10 @@
#include "windows.h"
QMutex Windows::m_windowMutex;
MainWindow *Windows::m_mainWindow(NULL);
void
Windows::invalidateEmotes()
{
}

35
windows.h Normal file
View file

@ -0,0 +1,35 @@
#ifndef WINDOWS_H
#define WINDOWS_H
#include "mainwindow.h"
#include <QMutex>
class Windows
{
public:
static void invalidateEmotes();
static MainWindow &
mainWindow()
{
m_windowMutex.lock();
if (m_mainWindow == NULL) {
m_mainWindow = new MainWindow();
}
m_windowMutex.unlock();
return *m_mainWindow;
}
private:
Windows()
{
}
static QMutex m_windowMutex;
static MainWindow *m_mainWindow;
};
#endif // WINDOWS_H

View file

@ -5,12 +5,13 @@ Word::Word(LazyLoadedImage *image, Type type, const QString &copytext,
const QString &tooltip, const Link &link)
: m_image(image)
, m_text()
, m_color()
, m_isImage(true)
, m_type(type)
, m_copyText(copytext)
, m_tooltip(tooltip)
, m_color()
, m_link(link)
, m_characterWidthCache()
{
image->width(); // professional segfault test
}
@ -20,11 +21,12 @@ Word::Word(const QString &text, Type type, const QColor &color,
const QString &copytext, const QString &tooltip, const Link &link)
: m_image(NULL)
, m_text(text)
, m_color(color)
, m_isImage(false)
, m_type(type)
, m_copyText(copytext)
, m_tooltip(tooltip)
, m_color(color)
, m_link(link)
, m_characterWidthCache()
{
}

17
word.h
View file

@ -49,9 +49,16 @@ public:
Username = 0x800000,
BitsAmount = 0x1000000,
ButtonBan = 0x2000000,
ButtonTimeout = 0x4000000,
EmojiImage = 0x8000000,
EmojiText = 0x10000000,
Default = TimestampNoSeconds | Badges | Username | Bits |
FfzEmoteImage | BttvEmoteImage | BttvGifEmoteImage |
TwitchEmoteImage | BitsAmount | Text
TwitchEmoteImage | BitsAmount | Text | ButtonBan |
ButtonTimeout
};
explicit Word(LazyLoadedImage *m_image, Type type, const QString &copytext,
@ -170,6 +177,12 @@ public:
m_yOffset = std::max(0, yOffset);
}
std::vector<short> &
characterWidthCache()
{
return m_characterWidthCache;
}
private:
LazyLoadedImage *m_image;
QString m_text;
@ -188,6 +201,8 @@ private:
bool m_hasTrailingSpace;
Fonts::Type m_font = Fonts::Medium;
Link m_link;
std::vector<short> m_characterWidthCache;
};
#endif // WORD_H

View file

@ -10,11 +10,20 @@ WordPart::WordPart(Word &word, int x, int y, const QString &copyText,
, m_width(word.width())
, m_height(word.height())
, m_trailingSpace(word.hasTrailingSpace() & allowTrailingSpace)
, m_text(word.isText() ? m_word.getText() : QString())
{
}
const QString &
WordPart::getText() const
WordPart::WordPart(Word &word, int x, int y, int width, int height,
const QString &copyText, const QString &customText,
bool allowTrailingSpace)
: m_word(word)
, m_copyText(copyText)
, m_x(x)
, m_y(y)
, m_width(width)
, m_height(height)
, m_trailingSpace(word.hasTrailingSpace() & allowTrailingSpace)
, m_text(customText)
{
return m_word.getText();
}

View file

@ -12,6 +12,10 @@ public:
WordPart(Word &word, int x, int y, const QString &copyText,
bool allowTrailingSpace = true);
WordPart(Word &word, int x, int y, int width, int height,
const QString &copyText, const QString &customText,
bool allowTrailingSpace = true);
const Word &
word() const
{
@ -85,12 +89,17 @@ public:
return m_trailingSpace;
}
const QString &getText() const;
const QString &
text() const
{
return m_text;
}
private:
Word &m_word;
QString m_copyText;
QString m_text;
int m_x;
int m_y;