mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
A lot of changes
Remove unused constructor of messages::Message Fixed LimitedQueueSnapshot _-prefixes Changed LimitedQueueSnapshot's usage of int to std::size_t ColorScheme is no longer a singleton Created a "BaseWidget" class which is pretty much a QWidget except it has a reference of ColorScheme since most widgets will need a reference to the style they should use. BaseWidget can be implemented either with a BaseWidget parent (which will copy the ColorScheme reference from the parent) or with a normal QWidget parent and an explicit ColorScheme reference. Save main window geometry on close Fix font changing in the Settings Dialog Update settings library version
This commit is contained in:
parent
c2e67e4b90
commit
7df7da70cb
56 changed files with 933 additions and 650 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 4bf19ff04c77c51883886af2586753df0638ffa4
|
||||
Subproject commit c05bec45f3ccb829d5014b46b6a02ee9e9c6b81f
|
|
@ -1,18 +1,25 @@
|
|||
#include "application.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "logging/loggingmanager.hpp"
|
||||
#include "settingsmanager.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
// this class is responsible for handling the workflow of Chatterino
|
||||
// It will create the instances of the major classes, and connect their signals to each other
|
||||
|
||||
Application::Application()
|
||||
: windowManager(this->channelManager)
|
||||
: windowManager(this->channelManager, this->colorScheme)
|
||||
, colorScheme(this->windowManager)
|
||||
, emoteManager(this->windowManager, this->resources)
|
||||
, resources(this->emoteManager, this->windowManager)
|
||||
, channelManager(this->windowManager, this->emoteManager, this->ircManager)
|
||||
, ircManager(this->channelManager, this->resources, this->emoteManager, this->windowManager)
|
||||
, messageFactory(this->resources, this->emoteManager, this->windowManager)
|
||||
{
|
||||
// TODO(pajlada): Get rid of all singletons
|
||||
ColorScheme::getInstance().init(this->windowManager);
|
||||
logging::init();
|
||||
SettingsManager::getInstance().load();
|
||||
|
||||
// Initialize everything we need
|
||||
this->emoteManager.loadGlobalEmotes();
|
||||
|
@ -21,11 +28,28 @@ Application::Application()
|
|||
SettingsManager::getInstance().updateWordTypeMask();
|
||||
|
||||
this->windowManager.load();
|
||||
|
||||
this->ircManager.onPrivateMessage.connect([=](Communi::IrcPrivateMessage *message) {
|
||||
QString channelName = message->target().mid(1);
|
||||
|
||||
auto channel = this->channelManager.getChannel(channelName);
|
||||
|
||||
if (channel == nullptr) {
|
||||
// The message doesn't have a channel we listen to
|
||||
return;
|
||||
}
|
||||
|
||||
messages::MessageParseArgs args;
|
||||
|
||||
this->messageFactory.buildMessage(message, *channel.get(), args);
|
||||
});
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
this->windowManager.save();
|
||||
|
||||
chatterino::SettingsManager::getInstance().save();
|
||||
}
|
||||
|
||||
int Application::run(QApplication &qtApp)
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "channelmanager.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "emotemanager.hpp"
|
||||
#include "ircmanager.hpp"
|
||||
#include "messagefactory.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "windowmanager.hpp"
|
||||
|
||||
|
@ -19,10 +21,12 @@ public:
|
|||
int run(QApplication &qtApp);
|
||||
|
||||
WindowManager windowManager;
|
||||
ColorScheme colorScheme;
|
||||
EmoteManager emoteManager;
|
||||
Resources resources;
|
||||
ChannelManager channelManager;
|
||||
IrcManager ircManager;
|
||||
MessageFactory messageFactory;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -8,62 +8,65 @@
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
void ColorScheme::init(WindowManager &windowManager)
|
||||
namespace detail {
|
||||
|
||||
double getMultiplierByTheme(const std::string &themeName)
|
||||
{
|
||||
static bool initiated = false;
|
||||
|
||||
if (!initiated) {
|
||||
initiated = true;
|
||||
ColorScheme::getInstance().update();
|
||||
|
||||
SettingsManager::getInstance().theme.valueChanged.connect([](const QString &) {
|
||||
ColorScheme::getInstance().update(); //
|
||||
});
|
||||
|
||||
SettingsManager::getInstance().themeHue.valueChanged.connect([](const float &) {
|
||||
ColorScheme::getInstance().update(); //
|
||||
});
|
||||
|
||||
ColorScheme::getInstance().updated.connect([&windowManager] {
|
||||
windowManager.repaintVisibleChatWidgets(); //
|
||||
});
|
||||
if (themeName == "Light") {
|
||||
return 0.8;
|
||||
} else if (themeName == "White") {
|
||||
return 1.0;
|
||||
} else if (themeName == "Black") {
|
||||
return -1.0;
|
||||
} else if (themeName == "Dark") {
|
||||
return -0.8;
|
||||
}
|
||||
|
||||
return -0.8;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
ColorScheme::ColorScheme(WindowManager &windowManager)
|
||||
{
|
||||
this->update();
|
||||
|
||||
SettingsManager::getInstance().themeName.getValueChangedSignal().connect([=](const auto &) {
|
||||
this->update(); //
|
||||
});
|
||||
|
||||
SettingsManager::getInstance().themeHue.getValueChangedSignal().connect([=](const auto &) {
|
||||
this->update(); //
|
||||
});
|
||||
|
||||
this->updated.connect([&windowManager] {
|
||||
windowManager.repaintVisibleChatWidgets(); //
|
||||
});
|
||||
}
|
||||
|
||||
void ColorScheme::update()
|
||||
{
|
||||
QString theme = SettingsManager::getInstance().theme.get();
|
||||
theme = theme.toLower();
|
||||
SettingsManager &settings = SettingsManager::getInstance();
|
||||
|
||||
qreal hue = SettingsManager::getInstance().themeHue.get();
|
||||
|
||||
if (theme == "light") {
|
||||
setColors(hue, 0.8);
|
||||
} else if (theme == "white") {
|
||||
setColors(hue, 1);
|
||||
} else if (theme == "black") {
|
||||
setColors(hue, -1);
|
||||
} else {
|
||||
setColors(hue, -0.8);
|
||||
}
|
||||
this->setColors(settings.themeHue, detail::getMultiplierByTheme(settings.themeName));
|
||||
}
|
||||
|
||||
// hue: theme color (0 - 1)
|
||||
// multiplyer: 1 = white, 0.8 = light, -0.8 dark, -1 black
|
||||
void ColorScheme::setColors(float hue, float multiplyer)
|
||||
// multiplier: 1 = white, 0.8 = light, -0.8 dark, -1 black
|
||||
void ColorScheme::setColors(double hue, double multiplier)
|
||||
{
|
||||
IsLightTheme = multiplyer > 0;
|
||||
lightTheme = multiplier > 0;
|
||||
bool hasDarkBorder = false;
|
||||
|
||||
SystemMessageColor = QColor(140, 127, 127);
|
||||
|
||||
auto getColor = [multiplyer](qreal h, qreal s, qreal l, qreal a = 1.0) {
|
||||
return QColor::fromHslF(h, s, (((l - 0.5) * multiplyer) + 0.5), a);
|
||||
auto getColor = [multiplier](double h, double s, double l, double a = 1.0) {
|
||||
return QColor::fromHslF(h, s, (((l - 0.5) * multiplier) + 0.5), a);
|
||||
};
|
||||
|
||||
DropPreviewBackground = getColor(hue, 0.5, 0.5, 0.6);
|
||||
|
||||
Text = TextCaret = IsLightTheme ? QColor(0, 0, 0) : QColor(255, 255, 255);
|
||||
Text = TextCaret = lightTheme ? QColor(0, 0, 0) : QColor(255, 255, 255);
|
||||
|
||||
// tab
|
||||
if (hasDarkBorder) {
|
||||
|
@ -119,26 +122,26 @@ void ColorScheme::setColors(float hue, float multiplyer)
|
|||
updated();
|
||||
}
|
||||
|
||||
void ColorScheme::fillLookupTableValues(qreal (&array)[360], qreal from, qreal to, qreal fromValue,
|
||||
qreal toValue)
|
||||
void ColorScheme::fillLookupTableValues(double (&array)[360], double from, double to,
|
||||
double fromValue, double toValue)
|
||||
{
|
||||
qreal diff = toValue - fromValue;
|
||||
double diff = toValue - fromValue;
|
||||
|
||||
int start = from * LOOKUP_COLOR_COUNT;
|
||||
int end = to * LOOKUP_COLOR_COUNT;
|
||||
int length = end - start;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[start + i] = fromValue + (diff * ((qreal)i / length));
|
||||
array[start + i] = fromValue + (diff * ((double)i / length));
|
||||
}
|
||||
}
|
||||
|
||||
void ColorScheme::normalizeColor(QColor &color)
|
||||
{
|
||||
// qreal l = color.lightnessF();
|
||||
// qreal s = color.saturationF();
|
||||
// qreal x = this->colorLookupTable[std::max(0, color.hue())];
|
||||
// qreal newL = (l - 1) * x + 1;
|
||||
// double l = color.lightnessF();
|
||||
// double s = color.saturationF();
|
||||
// double x = this->colorLookupTable[std::max(0, color.hue())];
|
||||
// double newL = (l - 1) * x + 1;
|
||||
|
||||
// newL = s * newL + (1 - s) * l;
|
||||
|
||||
|
@ -146,16 +149,16 @@ void ColorScheme::normalizeColor(QColor &color)
|
|||
|
||||
// color.setHslF(color.hueF(), s, newL);
|
||||
|
||||
qreal l = color.lightnessF();
|
||||
qreal s = color.saturationF();
|
||||
double l = color.lightnessF();
|
||||
double s = color.saturationF();
|
||||
int h = std::max(0, color.hue());
|
||||
qreal x = this->middleLookupTable[h];
|
||||
double x = this->middleLookupTable[h];
|
||||
x = s * 0.5 + (1 - s) * x;
|
||||
|
||||
qreal min = this->minLookupTable[h];
|
||||
double min = this->minLookupTable[h];
|
||||
min = (1 - s) * 0.5 + s * min;
|
||||
|
||||
qreal newL;
|
||||
double newL;
|
||||
|
||||
if (l < x) {
|
||||
newL = l * ((x - min) / x) + min;
|
||||
|
@ -168,7 +171,7 @@ void ColorScheme::normalizeColor(QColor &color)
|
|||
|
||||
color.setHslF(color.hueF(), s, newL);
|
||||
|
||||
// qreal newL = (l - 1) * x + 1;
|
||||
// double newL = (l - 1) * x + 1;
|
||||
|
||||
// newL = s * newL + (1 - s) * l;
|
||||
|
||||
|
|
|
@ -11,7 +11,12 @@ class WindowManager;
|
|||
class ColorScheme
|
||||
{
|
||||
public:
|
||||
bool IsLightTheme;
|
||||
explicit ColorScheme(WindowManager &windowManager);
|
||||
|
||||
inline bool isLightTheme() const
|
||||
{
|
||||
return this->lightTheme;
|
||||
}
|
||||
|
||||
QString InputStyleSheet;
|
||||
|
||||
|
@ -62,13 +67,6 @@ public:
|
|||
const int HighlightColorCount = 3;
|
||||
QColor HighlightColors[3];
|
||||
|
||||
static ColorScheme &getInstance()
|
||||
{
|
||||
static ColorScheme instance;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void init(WindowManager &windowManager);
|
||||
void normalizeColor(QColor &color);
|
||||
|
||||
|
@ -77,18 +75,15 @@ public:
|
|||
boost::signals2::signal<void()> updated;
|
||||
|
||||
private:
|
||||
ColorScheme()
|
||||
: updated()
|
||||
{
|
||||
}
|
||||
void setColors(double hue, double multiplier);
|
||||
|
||||
void setColors(float hue, float multiplyer);
|
||||
double middleLookupTable[360] = {};
|
||||
double minLookupTable[360] = {};
|
||||
|
||||
qreal middleLookupTable[360] = {};
|
||||
qreal minLookupTable[360] = {};
|
||||
void fillLookupTableValues(double (&array)[360], double from, double to, double fromValue,
|
||||
double toValue);
|
||||
|
||||
void fillLookupTableValues(qreal (&array)[360], qreal from, qreal to, qreal fromValue,
|
||||
qreal toValue);
|
||||
bool lightTheme;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
112
src/emojis.cpp
112
src/emojis.cpp
|
@ -9,116 +9,4 @@ namespace chatterino {
|
|||
|
||||
QRegularExpression Emojis::findShortCodesRegex(":([-+\\w]+):");
|
||||
|
||||
QMap<QString, Emojis::EmojiData> Emojis::shortCodeToEmoji;
|
||||
QMap<QString, QString> Emojis::emojiToShortCode;
|
||||
QMap<QChar, QMap<QString, QString>> Emojis::firstEmojiChars;
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> Emojis::imageCache;
|
||||
|
||||
QString Emojis::replaceShortCodes(const QString &text)
|
||||
{
|
||||
// TODO: Implement this xD
|
||||
return text;
|
||||
}
|
||||
|
||||
void Emojis::parseEmojis(std::vector<std::tuple<messages::LazyLoadedImage *, QString>> &vector,
|
||||
const QString &text)
|
||||
{
|
||||
long lastSlice = 0;
|
||||
|
||||
for (auto i = 0; i < text.length() - 1; i++) {
|
||||
if (!text.at(i).isLowSurrogate()) {
|
||||
auto iter = firstEmojiChars.find(text.at(i));
|
||||
|
||||
if (iter != firstEmojiChars.end()) {
|
||||
for (auto j = std::min(8, text.length() - i); j > 0; j--) {
|
||||
QString emojiString = text.mid(i, 2);
|
||||
auto emojiIter = iter.value().find(emojiString);
|
||||
|
||||
if (emojiIter != iter.value().end()) {
|
||||
QString url = "https://cdnjs.cloudflare.com/ajax/libs/"
|
||||
"emojione/2.2.6/assets/png/" +
|
||||
emojiIter.value() + ".png";
|
||||
|
||||
if (i - lastSlice != 0) {
|
||||
vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>(
|
||||
nullptr, text.mid(lastSlice, i - lastSlice)));
|
||||
}
|
||||
|
||||
vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>(
|
||||
imageCache.getOrAdd(url,
|
||||
[/*&url*/] {
|
||||
/* TODO: re-implement
|
||||
return new messages::LazyLoadedImage(url,
|
||||
0.35); //
|
||||
*/
|
||||
return nullptr;
|
||||
}),
|
||||
QString()));
|
||||
|
||||
i += j - 1;
|
||||
|
||||
lastSlice = i + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastSlice < text.length()) {
|
||||
vector.push_back(
|
||||
std::tuple<messages::LazyLoadedImage *, QString>(nullptr, text.mid(lastSlice)));
|
||||
}
|
||||
}
|
||||
|
||||
void Emojis::loadEmojis()
|
||||
{
|
||||
QFile file(":/emojidata.txt");
|
||||
file.open(QFile::ReadOnly);
|
||||
QTextStream in(&file);
|
||||
|
||||
uint emotes[4];
|
||||
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
|
||||
if (line.length() < 3 || line.at(0) == '#')
|
||||
continue;
|
||||
|
||||
QStringList a = line.split(' ');
|
||||
if (a.length() < 2)
|
||||
continue;
|
||||
|
||||
QStringList b = a.at(1).split('-');
|
||||
if (b.length() < 1)
|
||||
continue;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (const QString &item : b) {
|
||||
emotes[i++] = QString(item).toUInt(nullptr, 16);
|
||||
}
|
||||
|
||||
shortCodeToEmoji.insert(a.at(0), Emojis::EmojiData{QString::fromUcs4(emotes, i), a.at(1)});
|
||||
}
|
||||
|
||||
for (auto const &emoji : shortCodeToEmoji.toStdMap()) {
|
||||
emojiToShortCode.insert(emoji.second.value, emoji.first);
|
||||
}
|
||||
|
||||
for (auto const &emoji : shortCodeToEmoji.toStdMap()) {
|
||||
auto iter = firstEmojiChars.find(emoji.first.at(0));
|
||||
|
||||
if (iter != firstEmojiChars.end()) {
|
||||
iter.value().insert(emoji.second.value, emoji.second.value);
|
||||
continue;
|
||||
}
|
||||
|
||||
firstEmojiChars.insert(emoji.first.at(0),
|
||||
QMap<QString, QString>{{emoji.second.value, emoji.second.code}});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -11,33 +11,18 @@
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
struct EmojiData {
|
||||
QString value;
|
||||
QString code;
|
||||
};
|
||||
|
||||
class Emojis
|
||||
{
|
||||
public:
|
||||
static void parseEmojis(std::vector<std::tuple<messages::LazyLoadedImage *, QString>> &vector,
|
||||
const QString &text);
|
||||
|
||||
static void loadEmojis();
|
||||
|
||||
static QString replaceShortCodes(const QString &text);
|
||||
|
||||
struct EmojiData {
|
||||
QString value;
|
||||
QString code;
|
||||
};
|
||||
|
||||
private:
|
||||
static QRegularExpression findShortCodesRegex;
|
||||
|
||||
static QMap<QString, EmojiData> shortCodeToEmoji;
|
||||
static QMap<QString, QString> emojiToShortCode;
|
||||
static QMap<QChar, QMap<QString, QString>> firstEmojiChars;
|
||||
|
||||
static ConcurrentMap<QString, messages::LazyLoadedImage *> imageCache;
|
||||
|
||||
Emojis()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -29,6 +29,7 @@ EmoteManager::EmoteManager(WindowManager &_windowManager, Resources &_resources)
|
|||
|
||||
void EmoteManager::loadGlobalEmotes()
|
||||
{
|
||||
this->loadEmojis();
|
||||
this->loadBTTVEmotes();
|
||||
this->loadFFZEmotes();
|
||||
}
|
||||
|
@ -39,7 +40,7 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName,
|
|||
printf("[EmoteManager] Reload BTTV Channel Emotes for channel %s\n", qPrintable(channelName));
|
||||
|
||||
QString url("https://api.betterttv.net/2/channels/" + channelName);
|
||||
util::urlJsonFetch(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
|
||||
util::urlFetchJSON(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
|
||||
channelEmoteMap.clear();
|
||||
|
||||
auto emotesNode = rootNode.value("emotes").toArray();
|
||||
|
@ -77,7 +78,7 @@ void EmoteManager::reloadFFZChannelEmotes(
|
|||
|
||||
QString url("http://api.frankerfacez.com/v1/room/" + channelName);
|
||||
|
||||
util::urlJsonFetch(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
|
||||
util::urlFetchJSON(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
|
||||
channelEmoteMap.clear();
|
||||
|
||||
auto setsNode = rootNode.value("sets").toObject();
|
||||
|
@ -148,6 +149,116 @@ ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getMiscImageF
|
|||
return _miscImageFromCache;
|
||||
}
|
||||
|
||||
void EmoteManager::loadEmojis()
|
||||
{
|
||||
QFile file(":/emojidata.txt");
|
||||
file.open(QFile::ReadOnly);
|
||||
QTextStream in(&file);
|
||||
|
||||
uint unicodeBytes[4];
|
||||
|
||||
while (!in.atEnd()) {
|
||||
// Line example: sunglasses 1f60e
|
||||
QString line = in.readLine();
|
||||
|
||||
if (line.at(0) == '#') {
|
||||
// Ignore lines starting with # (comments)
|
||||
continue;
|
||||
}
|
||||
|
||||
QStringList parts = line.split(' ');
|
||||
if (parts.length() < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString shortCode = parts[0];
|
||||
QString code = parts[1];
|
||||
|
||||
QStringList unicodeCharacters = code.split('-');
|
||||
if (unicodeCharacters.length() < 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int numUnicodeBytes = 0;
|
||||
|
||||
for (const QString &unicodeCharacter : unicodeCharacters) {
|
||||
unicodeBytes[numUnicodeBytes++] = QString(unicodeCharacter).toUInt(nullptr, 16);
|
||||
}
|
||||
|
||||
EmojiData emojiData{
|
||||
QString::fromUcs4(unicodeBytes, numUnicodeBytes), //
|
||||
code, //
|
||||
};
|
||||
|
||||
shortCodeToEmoji.insert(shortCode, emojiData);
|
||||
emojiToShortCode.insert(emojiData.value, shortCode);
|
||||
}
|
||||
|
||||
/*
|
||||
for (auto const &emoji : shortCodeToEmoji.toStdMap()) {
|
||||
auto iter = firstEmojiChars.find(emoji.first.at(0));
|
||||
|
||||
if (iter != firstEmojiChars.end()) {
|
||||
iter.value().insert(emoji.second.value, emoji.second.value);
|
||||
continue;
|
||||
}
|
||||
|
||||
firstEmojiChars.insert(emoji.first.at(0),
|
||||
QMap<QString, QString>{{emoji.second.value, emoji.second.code}});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void EmoteManager::parseEmojis(
|
||||
std::vector<std::tuple<messages::LazyLoadedImage *, QString>> &vector, const QString &text)
|
||||
{
|
||||
// TODO(pajlada): Add this method to EmoteManager instead
|
||||
long lastSlice = 0;
|
||||
|
||||
for (auto i = 0; i < text.length() - 1; i++) {
|
||||
if (!text.at(i).isLowSurrogate()) {
|
||||
auto iter = firstEmojiChars.find(text.at(i));
|
||||
|
||||
if (iter != firstEmojiChars.end()) {
|
||||
for (auto j = std::min(8, text.length() - i); j > 0; j--) {
|
||||
QString emojiString = text.mid(i, 2);
|
||||
auto emojiIter = iter.value().find(emojiString);
|
||||
|
||||
if (emojiIter != iter.value().end()) {
|
||||
QString url = "https://cdnjs.cloudflare.com/ajax/libs/"
|
||||
"emojione/2.2.6/assets/png/" +
|
||||
emojiIter.value() + ".png";
|
||||
|
||||
if (i - lastSlice != 0) {
|
||||
vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>(
|
||||
nullptr, text.mid(lastSlice, i - lastSlice)));
|
||||
}
|
||||
|
||||
vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>(
|
||||
emojis.getOrAdd(url,
|
||||
[this, &url] {
|
||||
return new LazyLoadedImage(
|
||||
*this, this->windowManager, url, 0.35); //
|
||||
}),
|
||||
QString()));
|
||||
|
||||
i += j - 1;
|
||||
|
||||
lastSlice = i + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastSlice < text.length()) {
|
||||
vector.push_back(
|
||||
std::tuple<messages::LazyLoadedImage *, QString>(nullptr, text.mid(lastSlice)));
|
||||
}
|
||||
}
|
||||
|
||||
void EmoteManager::loadBTTVEmotes()
|
||||
{
|
||||
// bttv
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
#define GIF_FRAME_LENGTH 33
|
||||
|
||||
#include "concurrentmap.hpp"
|
||||
#include "emojis.hpp"
|
||||
#include "messages/lazyloadedimage.hpp"
|
||||
#include "twitch/emotevalue.hpp"
|
||||
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
|
@ -60,16 +62,47 @@ private:
|
|||
WindowManager &windowManager;
|
||||
Resources &resources;
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> bttvChannelEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> ffzChannelEmotes;
|
||||
// Emojis
|
||||
// shortCodeToEmoji maps strings like ":sunglasses:" to the unicode character
|
||||
QMap<QString, EmojiData> shortCodeToEmoji;
|
||||
|
||||
// emojiToShortCode maps the unicode character to the shortcode like ":sunglasses:"
|
||||
QMap<QString, QString> emojiToShortCode;
|
||||
|
||||
// TODO(pajlada): Figure out what this is for
|
||||
QMap<QChar, QMap<QString, QString>> firstEmojiChars;
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> emojis;
|
||||
|
||||
void loadEmojis();
|
||||
|
||||
public:
|
||||
void parseEmojis(std::vector<std::tuple<messages::LazyLoadedImage *, QString>> &vector,
|
||||
const QString &text);
|
||||
|
||||
private:
|
||||
// Twitch emotes
|
||||
ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _ffzEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _chatterinoEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvChannelEmoteFromCaches;
|
||||
ConcurrentMap<int, messages::LazyLoadedImage *> _ffzChannelEmoteFromCaches;
|
||||
ConcurrentMap<long, messages::LazyLoadedImage *> _twitchEmoteFromCache;
|
||||
|
||||
// BTTV emotes
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> bttvChannelEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvChannelEmoteFromCaches;
|
||||
|
||||
void loadBTTVEmotes();
|
||||
|
||||
// FFZ emotes
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> ffzChannelEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _ffzEmotes;
|
||||
ConcurrentMap<int, messages::LazyLoadedImage *> _ffzChannelEmoteFromCaches;
|
||||
|
||||
void loadFFZEmotes();
|
||||
|
||||
// Chatterino emotes
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _chatterinoEmotes;
|
||||
|
||||
// ???
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _miscImageFromCache;
|
||||
|
||||
boost::signals2::signal<void()> _gifUpdateTimerSignal;
|
||||
|
@ -80,9 +113,6 @@ private:
|
|||
|
||||
// methods
|
||||
static QString getTwitchEmoteLink(long id, qreal &scale);
|
||||
|
||||
void loadFFZEmotes();
|
||||
void loadBTTVEmotes();
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -9,10 +9,10 @@ FontManager::FontManager()
|
|||
, currentFontSize("/appearance/currentFontSize", 14)
|
||||
, currentFont(this->currentFontFamily.getValue().c_str(), currentFontSize.getValue())
|
||||
{
|
||||
this->currentFontFamily.valueChanged.connect([this](const std::string &newValue) {
|
||||
this->currentFontFamily.getValueChangedSignal().connect([this](const std::string &newValue) {
|
||||
this->currentFont.setFamily(newValue.c_str()); //
|
||||
});
|
||||
this->currentFontSize.valueChanged.connect([this](const int &newValue) {
|
||||
this->currentFontSize.getValueChangedSignal().connect([this](const int &newValue) {
|
||||
this->currentFont.setSize(newValue); //
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "twitch/twitchmessagebuilder.hpp"
|
||||
#include "twitch/twitchparsemessage.hpp"
|
||||
#include "twitch/twitchuser.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
#include "windowmanager.hpp"
|
||||
|
||||
#include <irccommand.h>
|
||||
|
@ -132,28 +133,29 @@ void IrcManager::refreshIgnoredUsers(const QString &username, const QString &oau
|
|||
void IrcManager::refreshTwitchEmotes(const QString &username, const QString &oauthClient,
|
||||
const QString &oauthToken)
|
||||
{
|
||||
QNetworkRequest req(QUrl("https://api.twitch.tv/kraken/users/" + username +
|
||||
"/emotes?oauth_token=" + oauthToken + "&client_id=" + oauthClient));
|
||||
QNetworkReply *reply = _accessManager.get(req);
|
||||
QString url("https://api.twitch.tv/kraken/users/" + username +
|
||||
"/emotes?oauth_token=" + oauthToken + "&client_id=" + oauthClient);
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=] {
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
QJsonObject root = jsonDoc.object();
|
||||
if (true) {
|
||||
util::urlFetchJSONTimeout(url,
|
||||
[=](QJsonObject &root) {
|
||||
// nextLink =
|
||||
// root.value("_links").toObject().value("next").toString();
|
||||
|
||||
// nextLink =
|
||||
// root.value("_links").toObject().value("next").toString();
|
||||
auto blocks = root.value("blocks").toArray();
|
||||
|
||||
auto blocks = root.value("blocks").toArray();
|
||||
|
||||
_twitchBlockedUsersMutex.lock();
|
||||
for (QJsonValue block : blocks) {
|
||||
QJsonObject user = block.toObject().value("user").toObject();
|
||||
// display_name
|
||||
_twitchBlockedUsers.insert(user.value("name").toString().toLower(), true);
|
||||
}
|
||||
_twitchBlockedUsersMutex.unlock();
|
||||
});
|
||||
_twitchBlockedUsersMutex.lock();
|
||||
for (QJsonValue block : blocks) {
|
||||
QJsonObject user = block.toObject().value("user").toObject();
|
||||
// display_name
|
||||
_twitchBlockedUsers.insert(
|
||||
user.value("name").toString().toLower(), true);
|
||||
}
|
||||
_twitchBlockedUsersMutex.unlock();
|
||||
qDebug() << "XD";
|
||||
},
|
||||
3000, &this->_accessManager);
|
||||
}
|
||||
}
|
||||
|
||||
void IrcManager::beginConnecting()
|
||||
|
@ -209,14 +211,13 @@ void IrcManager::sendMessage(const QString &channelName, const QString &message)
|
|||
this->connectionMutex.unlock();
|
||||
|
||||
// DEBUGGING
|
||||
#if 0
|
||||
/*
|
||||
Communi::IrcPrivateMessage msg(this->readConnection.get());
|
||||
|
||||
QStringList params{"#pajlada", message};
|
||||
|
||||
qDebug() << params;
|
||||
|
||||
/*
|
||||
if (message == "COMIC SANS LOL") {
|
||||
FontManager::getInstance().currentFontFamily = "Comic Sans MS";
|
||||
} else if (message == "ARIAL LOL") {
|
||||
|
@ -224,14 +225,13 @@ void IrcManager::sendMessage(const QString &channelName, const QString &message)
|
|||
} else if (message == "WINGDINGS LOL") {
|
||||
FontManager::getInstance().currentFontFamily = "Wingdings";
|
||||
}
|
||||
*/
|
||||
|
||||
msg.setParameters(params);
|
||||
|
||||
msg.setPrefix("pajlada!pajlada@pajlada");
|
||||
|
||||
this->privateMessageReceived(&msg);
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
void IrcManager::joinChannel(const QString &channelName)
|
||||
|
@ -260,6 +260,7 @@ void IrcManager::partChannel(const QString &channelName)
|
|||
|
||||
void IrcManager::privateMessageReceived(Communi::IrcPrivateMessage *message)
|
||||
{
|
||||
this->onPrivateMessage.invoke(message);
|
||||
auto c = this->channelManager.getChannel(message->target().mid(1));
|
||||
|
||||
if (c != nullptr) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <QMutex>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QString>
|
||||
#include <pajlada/signals/signal.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
@ -50,6 +51,8 @@ public:
|
|||
const twitch::TwitchUser &getUser() const;
|
||||
void setUser(const twitch::TwitchUser &account);
|
||||
|
||||
pajlada::Signals::Signal<Communi::IrcPrivateMessage *> onPrivateMessage;
|
||||
|
||||
private:
|
||||
ChannelManager &channelManager;
|
||||
Resources &resources;
|
||||
|
|
18
src/main.cpp
18
src/main.cpp
|
@ -1,20 +1,8 @@
|
|||
#include "application.hpp"
|
||||
#include "channelmanager.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "emojis.hpp"
|
||||
#include "emotemanager.hpp"
|
||||
#include "ircmanager.hpp"
|
||||
#include "logging/loggingmanager.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "settingsmanager.hpp"
|
||||
#include "widgets/mainwindow.hpp"
|
||||
#include "windowmanager.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <boost/signals2.hpp>
|
||||
#include <pajlada/settings/settingmanager.hpp>
|
||||
|
||||
namespace {
|
||||
|
@ -67,10 +55,6 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
chatterino::logging::init();
|
||||
chatterino::SettingsManager::getInstance().load();
|
||||
chatterino::Emojis::loadEmojis();
|
||||
|
||||
int ret = 0;
|
||||
|
||||
{
|
||||
|
@ -83,8 +67,6 @@ int main(int argc, char *argv[])
|
|||
// Application will go out of scope here and deinitialize itself
|
||||
}
|
||||
|
||||
chatterino::SettingsManager::getInstance().save();
|
||||
|
||||
// Save settings
|
||||
pajlada::Settings::SettingManager::save();
|
||||
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
#include "messagefactory.hpp"
|
||||
|
||||
MessageFactory::MessageFactory()
|
||||
{
|
||||
|
||||
}
|
||||
#include "messagefactory.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
MessageFactory::MessageFactory(Resources &_resources, EmoteManager &_emoteManager,
|
||||
WindowManager &_windowManager)
|
||||
: resources(_resources)
|
||||
, emoteManager(_emoteManager)
|
||||
, windowManager(_windowManager)
|
||||
{
|
||||
}
|
||||
|
||||
messages::SharedMessage MessageFactory::buildMessage(Communi::IrcPrivateMessage *message,
|
||||
Channel &channel,
|
||||
const messages::MessageParseArgs &args)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -1,11 +1,26 @@
|
|||
#ifndef MESSAGEFACTORY_HPP
|
||||
#define MESSAGEFACTORY_HPP
|
||||
|
||||
|
||||
class MessageFactory
|
||||
{
|
||||
public:
|
||||
MessageFactory();
|
||||
};
|
||||
|
||||
#endif // MESSAGEFACTORY_HPP
|
||||
#pragma once
|
||||
|
||||
#include "messages/message.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class Resources;
|
||||
class EmoteManager;
|
||||
class WindowManager;
|
||||
|
||||
class MessageFactory
|
||||
{
|
||||
public:
|
||||
explicit MessageFactory(Resources &_resources, EmoteManager &_emoteManager,
|
||||
WindowManager &_windowManager);
|
||||
|
||||
messages::SharedMessage buildMessage(Communi::IrcPrivateMessage *message, Channel &channel,
|
||||
const messages::MessageParseArgs &args);
|
||||
|
||||
private:
|
||||
Resources &resources;
|
||||
EmoteManager &emoteManager;
|
||||
WindowManager &windowManager;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -10,28 +10,29 @@ template <typename T>
|
|||
class LimitedQueueSnapshot
|
||||
{
|
||||
public:
|
||||
LimitedQueueSnapshot(std::shared_ptr<std::vector<T>> vector, int offset, int size)
|
||||
: _vector(vector)
|
||||
, _offset(offset)
|
||||
, _length(size)
|
||||
LimitedQueueSnapshot(std::shared_ptr<std::vector<T>> _vector, std::size_t _offset,
|
||||
std::size_t _size)
|
||||
: vector(_vector)
|
||||
, offset(_offset)
|
||||
, length(_size)
|
||||
{
|
||||
}
|
||||
|
||||
int getSize()
|
||||
std::size_t getLength()
|
||||
{
|
||||
return _length;
|
||||
return length;
|
||||
}
|
||||
|
||||
T const &operator[](int index) const
|
||||
T const &operator[](std::size_t index) const
|
||||
{
|
||||
return _vector->at(index + _offset);
|
||||
return vector->at(index + offset);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::vector<T>> _vector;
|
||||
std::shared_ptr<std::vector<T>> vector;
|
||||
|
||||
int _offset;
|
||||
int _length;
|
||||
std::size_t offset;
|
||||
std::size_t length;
|
||||
};
|
||||
|
||||
} // namespace messages
|
||||
|
|
|
@ -20,12 +20,14 @@
|
|||
namespace chatterino {
|
||||
namespace messages {
|
||||
|
||||
/*
|
||||
Message::Message(const QString &text)
|
||||
: text(text)
|
||||
{
|
||||
this->words.push_back(
|
||||
Word(text, Word::Text, ColorScheme::getInstance().SystemMessageColor, text, QString()));
|
||||
}
|
||||
*/
|
||||
|
||||
Message::Message(const QString &text, const std::vector<Word> &words)
|
||||
: text(text)
|
||||
|
|
|
@ -23,7 +23,7 @@ typedef std::shared_ptr<Message> SharedMessage;
|
|||
class Message
|
||||
{
|
||||
public:
|
||||
explicit Message(const QString &text);
|
||||
// explicit Message(const QString &text);
|
||||
explicit Message(const QString &text, const std::vector<messages::Word> &words);
|
||||
|
||||
bool getCanHighlightTab() const;
|
||||
|
|
|
@ -33,17 +33,21 @@ void MessageBuilder::appendTimestamp(time_t time)
|
|||
{
|
||||
char timeStampBuffer[69];
|
||||
|
||||
// TODO(pajlada): Fix this
|
||||
QColor systemMessageColor(140, 127, 127);
|
||||
// QColor &systemMessageColor = ColorScheme::getInstance().SystemMessageColor;
|
||||
|
||||
// Add word for timestamp with no seconds
|
||||
strftime(timeStampBuffer, 69, "%H:%M", localtime(&time));
|
||||
QString timestampNoSeconds(timeStampBuffer);
|
||||
appendWord(Word(timestampNoSeconds, Word::TimestampNoSeconds,
|
||||
ColorScheme::getInstance().SystemMessageColor, QString(), QString()));
|
||||
appendWord(Word(timestampNoSeconds, Word::TimestampNoSeconds, systemMessageColor, QString(),
|
||||
QString()));
|
||||
|
||||
// Add word for timestamp with seconds
|
||||
strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&time));
|
||||
QString timestampWithSeconds(timeStampBuffer);
|
||||
appendWord(Word(timestampWithSeconds, Word::TimestampWithSeconds,
|
||||
ColorScheme::getInstance().SystemMessageColor, QString(), QString()));
|
||||
appendWord(Word(timestampWithSeconds, Word::TimestampWithSeconds, systemMessageColor, QString(),
|
||||
QString()));
|
||||
}
|
||||
|
||||
QString MessageBuilder::matchLink(const QString &string)
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
ButtonTimeout = (1 << 22),
|
||||
|
||||
EmojiImage = (1 << 23),
|
||||
EmojiText = (1 << 34),
|
||||
EmojiText = (1 << 24),
|
||||
|
||||
Default = TimestampNoSeconds | Badges | Username | BitsStatic | FfzEmoteImage |
|
||||
BttvEmoteImage | BttvGifEmoteImage | TwitchEmoteImage | BitsAmount | Text |
|
||||
|
@ -85,6 +85,7 @@ public:
|
|||
Word()
|
||||
{
|
||||
}
|
||||
|
||||
explicit Word(LazyLoadedImage *_image, Type getType, const QString ©text,
|
||||
const QString &getTooltip, const Link &getLink = Link());
|
||||
explicit Word(const QString &_text, Type getType, const QColor &getColor,
|
||||
|
|
|
@ -40,7 +40,7 @@ Resources::Resources(EmoteManager &em, WindowManager &wm)
|
|||
{
|
||||
QString badgesUrl("https://badges.twitch.tv/v1/badges/global/display?language=en");
|
||||
|
||||
util::urlJsonFetch(badgesUrl, [this](QJsonObject &root) {
|
||||
util::urlFetchJSON(badgesUrl, [this](QJsonObject &root) {
|
||||
QJsonObject sets = root.value("badge_sets").toObject();
|
||||
|
||||
for (QJsonObject::iterator it = sets.begin(); it != sets.end(); ++it) {
|
||||
|
@ -86,7 +86,7 @@ void Resources::loadChannelData(const std::string &roomID, bool bypassCache)
|
|||
QString url = "https://badges.twitch.tv/v1/badges/channels/" + QString::fromStdString(roomID) +
|
||||
"/display?language=en";
|
||||
|
||||
util::urlJsonFetch(url, [this](QJsonObject &root) {
|
||||
util::urlFetchJSON(url, [this](QJsonObject &root) {
|
||||
QJsonObject sets = root.value("badge_sets").toObject();
|
||||
|
||||
for (QJsonObject::iterator it = sets.begin(); it != sets.end(); ++it) {
|
||||
|
|
|
@ -11,15 +11,15 @@ namespace chatterino {
|
|||
|
||||
SettingsManager::SettingsManager()
|
||||
: _settings(Path::getAppdataPath() + "settings.ini", QSettings::IniFormat)
|
||||
, theme(_settingsItems, "theme", "dark")
|
||||
, themeHue(_settingsItems, "themeHue", 0)
|
||||
, showTimestamps("/appearance/messages/showTimestamps", true)
|
||||
, showTimestampSeconds("/appearance/messages/showTimestampSeconds", true)
|
||||
, showBadges("/appearance/messages/showBadges", true)
|
||||
, themeName("/appearance/theme/name", "Dark")
|
||||
, themeHue("/appearance/theme/hue", 0.0)
|
||||
, selectedUser(_settingsItems, "selectedUser", "")
|
||||
, emoteScale(_settingsItems, "emoteScale", 1.0)
|
||||
, mouseScrollMultiplier(_settingsItems, "mouseScrollMultiplier", 1.0)
|
||||
, scaleEmotesByLineHeight(_settingsItems, "scaleEmotesByLineHeight", false)
|
||||
, showTimestamps("/appearance/messages/showTimestamps", true)
|
||||
, showTimestampSeconds("/appearance/messages/showTimestampSeconds", true)
|
||||
, showBadges("/appearance/messages/showBadges", true)
|
||||
, showLastMessageIndicator(_settingsItems, "showLastMessageIndicator", false)
|
||||
, allowDouplicateMessages(_settingsItems, "allowDouplicateMessages", true)
|
||||
, linksDoubleClickOnly(_settingsItems, "linksDoubleClickOnly", false)
|
||||
|
|
|
@ -42,10 +42,10 @@ public:
|
|||
pajlada::Settings::Setting<bool> showTimestamps;
|
||||
pajlada::Settings::Setting<bool> showTimestampSeconds;
|
||||
pajlada::Settings::Setting<bool> showBadges;
|
||||
pajlada::Settings::Setting<std::string> themeName;
|
||||
pajlada::Settings::Setting<double> themeHue;
|
||||
|
||||
// Settings
|
||||
Setting<QString> theme;
|
||||
Setting<float> themeHue;
|
||||
Setting<QString> selectedUser;
|
||||
Setting<float> emoteScale;
|
||||
Setting<float> mouseScrollMultiplier;
|
||||
|
|
|
@ -60,6 +60,8 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
|
|||
// badges
|
||||
iterator = tags.find("badges");
|
||||
|
||||
ColorScheme &colorScheme = windowManager.colorScheme;
|
||||
|
||||
const auto &channelResources = resources.channels[roomID];
|
||||
|
||||
if (iterator != tags.end()) {
|
||||
|
@ -69,7 +71,7 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
|
|||
}
|
||||
|
||||
// color
|
||||
QColor usernameColor = ColorScheme::getInstance().SystemMessageColor;
|
||||
QColor &usernameColor = colorScheme.SystemMessageColor;
|
||||
|
||||
iterator = tags.find("color");
|
||||
if (iterator != tags.end()) {
|
||||
|
@ -79,7 +81,7 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
|
|||
// channel name
|
||||
if (args.includeChannelName) {
|
||||
QString channelName("#" + channel->getName());
|
||||
b.appendWord(Word(channelName, Word::Misc, ColorScheme::getInstance().SystemMessageColor,
|
||||
b.appendWord(Word(channelName, Word::Misc, colorScheme.SystemMessageColor,
|
||||
QString(channelName), QString(),
|
||||
Link(Link::Url, channel->getName() + "\n" + b.messageId)));
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
|
|||
auto currentTwitchEmote = twitchEmotes.begin();
|
||||
|
||||
// words
|
||||
QColor textColor = ircMessage->isAction() ? usernameColor : ColorScheme::getInstance().Text;
|
||||
QColor textColor = ircMessage->isAction() ? usernameColor : colorScheme.Text;
|
||||
|
||||
const QString &originalMessage = ircMessage->content();
|
||||
b.originalMessage = originalMessage;
|
||||
|
@ -184,7 +186,7 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
|
|||
// split words
|
||||
std::vector<std::tuple<LazyLoadedImage *, QString>> parsed;
|
||||
|
||||
Emojis::parseEmojis(parsed, split);
|
||||
emoteManager.parseEmojis(parsed, split);
|
||||
|
||||
for (const std::tuple<LazyLoadedImage *, QString> &tuple : parsed) {
|
||||
LazyLoadedImage *image = std::get<0>(tuple);
|
||||
|
@ -257,7 +259,11 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
|
|||
// bttv / ffz emotes
|
||||
LazyLoadedImage *bttvEmote;
|
||||
|
||||
// TODO: Implement this (ignored emotes)
|
||||
// TODO: Implement ignored emotes
|
||||
// Format of ignored emotes:
|
||||
// Emote name: "forsenPuke" - if string in ignoredEmotes
|
||||
// Will match emote regardless of source (i.e. bttv, ffz)
|
||||
// Emote source + name: "bttv:nyanPls"
|
||||
if (emoteManager.getBTTVEmotes().tryGet(string, bttvEmote) ||
|
||||
channel->getBttvChannelEmotes().tryGet(string, bttvEmote) ||
|
||||
emoteManager.getFFZEmotes().tryGet(string, bttvEmote) ||
|
||||
|
|
|
@ -1,4 +1,34 @@
|
|||
#ifndef BASEWIDGET_HPP
|
||||
#define BASEWIDGET_HPP
|
||||
#pragma once
|
||||
|
||||
#endif // BASEWIDGET_HPP
|
||||
#include "colorscheme.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class BaseWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BaseWidget(ColorScheme &_colorScheme, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, colorScheme(_colorScheme)
|
||||
{
|
||||
}
|
||||
|
||||
explicit BaseWidget(BaseWidget *parent)
|
||||
: QWidget(parent)
|
||||
, colorScheme(parent->colorScheme)
|
||||
{
|
||||
}
|
||||
|
||||
ColorScheme &colorScheme;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -30,8 +30,8 @@ inline void ezShortcut(ChatWidget *w, const char *key, T t)
|
|||
|
||||
} // namespace
|
||||
|
||||
ChatWidget::ChatWidget(ChannelManager &_channelManager, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
ChatWidget::ChatWidget(ChannelManager &_channelManager, NotebookPage *parent)
|
||||
: BaseWidget(parent)
|
||||
, channelManager(_channelManager)
|
||||
, channel(_channelManager.getEmpty())
|
||||
, vbox(this)
|
||||
|
@ -142,7 +142,7 @@ void ChatWidget::setChannel(std::shared_ptr<Channel> _newChannel)
|
|||
|
||||
auto snapshot = this->channel->getMessageSnapshot();
|
||||
|
||||
for (int i = 0; i < snapshot.getSize(); i++) {
|
||||
for (int i = 0; i < snapshot.getLength(); i++) {
|
||||
SharedMessageRef deleted;
|
||||
|
||||
auto messageRef = new MessageRef(snapshot[i]);
|
||||
|
@ -199,7 +199,7 @@ void ChatWidget::paintEvent(QPaintEvent *)
|
|||
// color the background of the chat
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(this->rect(), ColorScheme::getInstance().ChatBackground);
|
||||
painter.fillRect(this->rect(), this->colorScheme.ChatBackground);
|
||||
}
|
||||
|
||||
void ChatWidget::load(const boost::property_tree::ptree &tree)
|
||||
|
@ -241,7 +241,8 @@ void ChatWidget::doChangeChannel()
|
|||
void ChatWidget::doPopup()
|
||||
{
|
||||
// TODO: Copy signals and stuff too
|
||||
auto widget = new ChatWidget(this->channelManager);
|
||||
auto widget =
|
||||
new ChatWidget(this->channelManager, static_cast<NotebookPage *>(this->parentWidget()));
|
||||
widget->setChannelName(this->getChannelName());
|
||||
widget->show();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "messages/messageref.hpp"
|
||||
#include "messages/word.hpp"
|
||||
#include "messages/wordpart.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/chatwidgetheader.hpp"
|
||||
#include "widgets/chatwidgetinput.hpp"
|
||||
#include "widgets/chatwidgetview.hpp"
|
||||
|
@ -19,9 +20,12 @@
|
|||
namespace chatterino {
|
||||
|
||||
class ChannelManager;
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class NotebookPage;
|
||||
|
||||
// Each ChatWidget consists of three sub-elements that handle their own part of the chat widget:
|
||||
// ChatWidgetHeader
|
||||
// - Responsible for rendering which channel the ChatWidget is in, and the menu in the top-left of
|
||||
|
@ -32,12 +36,12 @@ namespace widgets {
|
|||
// - Responsible for rendering and handling user text input
|
||||
//
|
||||
// Each sub-element has a reference to the parent Chat Widget
|
||||
class ChatWidget : public QWidget
|
||||
class ChatWidget : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatWidget(ChannelManager &_channelManager, QWidget *parent = nullptr);
|
||||
ChatWidget(ChannelManager &_channelManager, NotebookPage *parent);
|
||||
~ChatWidget();
|
||||
|
||||
std::shared_ptr<Channel> getChannel() const;
|
||||
|
|
|
@ -12,9 +12,11 @@ namespace chatterino {
|
|||
namespace widgets {
|
||||
|
||||
ChatWidgetHeader::ChatWidgetHeader(ChatWidget *_chatWidget)
|
||||
: QWidget(_chatWidget)
|
||||
: BaseWidget(_chatWidget)
|
||||
, chatWidget(_chatWidget)
|
||||
, leftLabel(this)
|
||||
, leftMenu(this)
|
||||
, rightLabel(this)
|
||||
, rightMenu(this)
|
||||
{
|
||||
this->setFixedHeight(32);
|
||||
|
@ -68,7 +70,7 @@ ChatWidgetHeader::ChatWidgetHeader(ChatWidget *_chatWidget)
|
|||
void ChatWidgetHeader::updateColors()
|
||||
{
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Foreground, ColorScheme::getInstance().Text);
|
||||
palette.setColor(QPalette::Foreground, this->colorScheme.Text);
|
||||
|
||||
this->leftLabel.setPalette(palette);
|
||||
this->channelNameLabel.setPalette(palette);
|
||||
|
@ -86,8 +88,8 @@ void ChatWidgetHeader::paintEvent(QPaintEvent *)
|
|||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(rect(), ColorScheme::getInstance().ChatHeaderBackground);
|
||||
painter.setPen(ColorScheme::getInstance().ChatHeaderBorder);
|
||||
painter.fillRect(rect(), this->colorScheme.ChatHeaderBackground);
|
||||
painter.setPen(this->colorScheme.ChatHeaderBorder);
|
||||
painter.drawRect(0, 0, width() - 1, height() - 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "signallabel.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/chatwidgetheaderbutton.hpp"
|
||||
|
||||
#include <QAction>
|
||||
|
@ -13,10 +14,14 @@
|
|||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class ChatWidget;
|
||||
|
||||
class ChatWidgetHeader : public QWidget
|
||||
class ChatWidgetHeader : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "widgets/chatwidgetheaderbutton.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "widgets/chatwidgetheader.hpp"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QPainter>
|
||||
|
@ -7,24 +8,23 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetHeaderButton::ChatWidgetHeaderButton(int spacing)
|
||||
: QWidget()
|
||||
, _hbox()
|
||||
, _label()
|
||||
, _mouseOver(false)
|
||||
, _mouseDown(false)
|
||||
ChatWidgetHeaderButton::ChatWidgetHeaderButton(BaseWidget *parent, int spacing)
|
||||
: BaseWidget(parent)
|
||||
, mouseOver(false)
|
||||
, mouseDown(false)
|
||||
{
|
||||
setLayout(&_hbox);
|
||||
setLayout(&this->ui.hbox);
|
||||
|
||||
_label.setAlignment(Qt::AlignCenter);
|
||||
this->ui.label.setAlignment(Qt::AlignCenter);
|
||||
|
||||
_hbox.setMargin(0);
|
||||
_hbox.addSpacing(spacing);
|
||||
_hbox.addWidget(&_label);
|
||||
_hbox.addSpacing(spacing);
|
||||
this->ui.hbox.setMargin(0);
|
||||
this->ui.hbox.addSpacing(spacing);
|
||||
this->ui.hbox.addWidget(&this->ui.label);
|
||||
this->ui.hbox.addSpacing(spacing);
|
||||
|
||||
QObject::connect(&_label, &SignalLabel::mouseUp, this, &ChatWidgetHeaderButton::labelMouseUp);
|
||||
QObject::connect(&_label, &SignalLabel::mouseDown, this,
|
||||
QObject::connect(&this->ui.label, &SignalLabel::mouseUp, this,
|
||||
&ChatWidgetHeaderButton::labelMouseUp);
|
||||
QObject::connect(&this->ui.label, &SignalLabel::mouseDown, this,
|
||||
&ChatWidgetHeaderButton::labelMouseDown);
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,14 @@ void ChatWidgetHeaderButton::paintEvent(QPaintEvent *)
|
|||
{
|
||||
QPainter painter(this);
|
||||
|
||||
QBrush brush(ColorScheme::getInstance().IsLightTheme ? QColor(0, 0, 0, 32)
|
||||
: QColor(255, 255, 255, 32));
|
||||
QBrush brush(this->colorScheme.isLightTheme() ? QColor(0, 0, 0, 32)
|
||||
: QColor(255, 255, 255, 32));
|
||||
|
||||
if (_mouseDown) {
|
||||
if (mouseDown) {
|
||||
painter.fillRect(rect(), brush);
|
||||
}
|
||||
|
||||
if (_mouseOver) {
|
||||
if (mouseOver) {
|
||||
painter.fillRect(rect(), brush);
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ void ChatWidgetHeaderButton::paintEvent(QPaintEvent *)
|
|||
void ChatWidgetHeaderButton::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
_mouseDown = true;
|
||||
mouseDown = true;
|
||||
|
||||
update();
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ void ChatWidgetHeaderButton::mousePressEvent(QMouseEvent *event)
|
|||
void ChatWidgetHeaderButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
_mouseDown = false;
|
||||
mouseDown = false;
|
||||
|
||||
update();
|
||||
|
||||
|
@ -66,21 +66,21 @@ void ChatWidgetHeaderButton::mouseReleaseEvent(QMouseEvent *event)
|
|||
|
||||
void ChatWidgetHeaderButton::enterEvent(QEvent *)
|
||||
{
|
||||
_mouseOver = true;
|
||||
mouseOver = true;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ChatWidgetHeaderButton::leaveEvent(QEvent *)
|
||||
{
|
||||
_mouseOver = false;
|
||||
mouseOver = false;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ChatWidgetHeaderButton::labelMouseUp()
|
||||
{
|
||||
_mouseDown = false;
|
||||
mouseDown = false;
|
||||
|
||||
update();
|
||||
|
||||
|
@ -89,7 +89,7 @@ void ChatWidgetHeaderButton::labelMouseUp()
|
|||
|
||||
void ChatWidgetHeaderButton::labelMouseDown()
|
||||
{
|
||||
_mouseDown = true;
|
||||
mouseDown = true;
|
||||
|
||||
update();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/signallabel.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
@ -8,38 +9,45 @@
|
|||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class ChatWidgetHeaderButton : public QWidget
|
||||
class ChatWidgetHeader;
|
||||
|
||||
class ChatWidgetHeaderButton : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChatWidgetHeaderButton(int spacing = 6);
|
||||
explicit ChatWidgetHeaderButton(BaseWidget *parent, int spacing = 6);
|
||||
|
||||
SignalLabel &getLabel()
|
||||
{
|
||||
return _label;
|
||||
return this->ui.label;
|
||||
}
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
|
||||
void enterEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
void leaveEvent(QEvent *) Q_DECL_OVERRIDE;
|
||||
virtual void enterEvent(QEvent *) override;
|
||||
virtual void leaveEvent(QEvent *) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
QHBoxLayout _hbox;
|
||||
SignalLabel _label;
|
||||
struct {
|
||||
QHBoxLayout hbox;
|
||||
SignalLabel label;
|
||||
} ui;
|
||||
|
||||
bool _mouseOver;
|
||||
bool _mouseDown;
|
||||
bool mouseOver = false;
|
||||
bool mouseDown = false;
|
||||
|
||||
void labelMouseUp();
|
||||
void labelMouseDown();
|
||||
|
|
|
@ -12,8 +12,9 @@ namespace chatterino {
|
|||
namespace widgets {
|
||||
|
||||
ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget)
|
||||
: QWidget(_chatWidget)
|
||||
: BaseWidget(_chatWidget)
|
||||
, chatWidget(_chatWidget)
|
||||
, emotesLabel(this)
|
||||
{
|
||||
this->setMaximumHeight(150);
|
||||
|
||||
|
@ -93,11 +94,11 @@ void ChatWidgetInput::refreshTheme()
|
|||
{
|
||||
QPalette palette;
|
||||
|
||||
palette.setColor(QPalette::Foreground, ColorScheme::getInstance().Text);
|
||||
palette.setColor(QPalette::Foreground, this->colorScheme.Text);
|
||||
|
||||
this->textLengthLabel.setPalette(palette);
|
||||
|
||||
this->textInput.setStyleSheet(ColorScheme::getInstance().InputStyleSheet);
|
||||
this->textInput.setStyleSheet(this->colorScheme.InputStyleSheet);
|
||||
}
|
||||
|
||||
void ChatWidgetInput::editTextChanged()
|
||||
|
@ -118,8 +119,8 @@ void ChatWidgetInput::paintEvent(QPaintEvent *)
|
|||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(this->rect(), ColorScheme::getInstance().ChatInputBackground);
|
||||
painter.setPen(ColorScheme::getInstance().ChatInputBorder);
|
||||
painter.fillRect(this->rect(), this->colorScheme.ChatInputBackground);
|
||||
painter.setPen(this->colorScheme.ChatInputBorder);
|
||||
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "resizingtextedit.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/chatwidgetheaderbutton.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
@ -16,7 +17,7 @@ namespace widgets {
|
|||
|
||||
class ChatWidget;
|
||||
|
||||
class ChatWidgetInput : public QWidget
|
||||
class ChatWidgetInput : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace chatterino {
|
|||
namespace widgets {
|
||||
|
||||
ChatWidgetView::ChatWidgetView(ChatWidget *_chatWidget)
|
||||
: QWidget(_chatWidget)
|
||||
: BaseWidget(_chatWidget)
|
||||
, chatWidget(_chatWidget)
|
||||
, scrollBar(this)
|
||||
, userPopupWidget(_chatWidget->getChannelRef())
|
||||
|
@ -47,7 +47,7 @@ bool ChatWidgetView::layoutMessages()
|
|||
{
|
||||
auto messages = this->chatWidget->getMessagesSnapshot();
|
||||
|
||||
if (messages.getSize() == 0) {
|
||||
if (messages.getLength() == 0) {
|
||||
this->scrollBar.setVisible(false);
|
||||
return false;
|
||||
}
|
||||
|
@ -65,10 +65,10 @@ bool ChatWidgetView::layoutMessages()
|
|||
int layoutWidth = this->scrollBar.isVisible() ? width() - this->scrollBar.width() : width();
|
||||
|
||||
// layout the visible messages in the view
|
||||
if (messages.getSize() > start) {
|
||||
if (messages.getLength() > start) {
|
||||
int y = -(messages[start]->getHeight() * (fmod(this->scrollBar.getCurrentValue(), 1)));
|
||||
|
||||
for (int i = start; i < messages.getSize(); ++i) {
|
||||
for (int i = start; i < messages.getLength(); ++i) {
|
||||
auto message = messages[i];
|
||||
|
||||
redraw |= message->layout(layoutWidth, true);
|
||||
|
@ -84,7 +84,7 @@ bool ChatWidgetView::layoutMessages()
|
|||
// layout the messages at the bottom to determine the scrollbar thumb size
|
||||
int h = height() - 8;
|
||||
|
||||
for (int i = messages.getSize() - 1; i >= 0; i--) {
|
||||
for (std::size_t i = messages.getLength() - 1; i > 0; i--) {
|
||||
auto *message = messages[i].get();
|
||||
|
||||
message->layout(layoutWidth, true);
|
||||
|
@ -92,7 +92,7 @@ bool ChatWidgetView::layoutMessages()
|
|||
h -= message->getHeight();
|
||||
|
||||
if (h < 0) {
|
||||
this->scrollBar.setLargeChange((messages.getSize() - i) +
|
||||
this->scrollBar.setLargeChange((messages.getLength() - i) +
|
||||
(qreal)h / message->getHeight());
|
||||
this->scrollBar.setDesiredValue(this->scrollBar.getDesiredValue());
|
||||
|
||||
|
@ -107,7 +107,7 @@ bool ChatWidgetView::layoutMessages()
|
|||
this->scrollBar.setDesiredValue(0);
|
||||
}
|
||||
|
||||
this->scrollBar.setMaximum(messages.getSize());
|
||||
this->scrollBar.setMaximum(messages.getLength());
|
||||
|
||||
if (this->showingLatestMessages && showScrollbar) {
|
||||
// If we were showing the latest messages and the scrollbar now wants to be rendered, scroll
|
||||
|
@ -148,14 +148,12 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
|
||||
_painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
ColorScheme &scheme = ColorScheme::getInstance();
|
||||
|
||||
// only update gif emotes
|
||||
if (this->onlyUpdateEmotes) {
|
||||
this->onlyUpdateEmotes = false;
|
||||
|
||||
for (const GifEmoteData &item : this->gifEmotes) {
|
||||
_painter.fillRect(item.rect, scheme.ChatBackground);
|
||||
_painter.fillRect(item.rect, this->colorScheme.ChatBackground);
|
||||
|
||||
_painter.drawPixmap(item.rect, *item.image->getPixmap());
|
||||
}
|
||||
|
@ -166,7 +164,7 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
// update all messages
|
||||
this->gifEmotes.clear();
|
||||
|
||||
_painter.fillRect(rect(), scheme.ChatBackground);
|
||||
_painter.fillRect(rect(), this->colorScheme.ChatBackground);
|
||||
|
||||
// code for tesing colors
|
||||
/*
|
||||
|
@ -205,13 +203,13 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
|
||||
int start = this->scrollBar.getCurrentValue();
|
||||
|
||||
if (start >= messages.getSize()) {
|
||||
if (start >= messages.getLength()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int y = -(messages[start].get()->getHeight() * (fmod(this->scrollBar.getCurrentValue(), 1)));
|
||||
|
||||
for (int i = start; i < messages.getSize(); ++i) {
|
||||
for (int i = start; i < messages.getLength(); ++i) {
|
||||
messages::MessageRef *messageRef = messages[i].get();
|
||||
|
||||
std::shared_ptr<QPixmap> bufferPtr = messageRef->buffer;
|
||||
|
@ -228,7 +226,7 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
// update messages that have been changed
|
||||
if (updateBuffer) {
|
||||
QPainter painter(buffer);
|
||||
painter.fillRect(buffer->rect(), scheme.ChatBackground);
|
||||
painter.fillRect(buffer->rect(), this->colorScheme.ChatBackground);
|
||||
|
||||
for (messages::WordPart const &wordPart : messageRef->getWordParts()) {
|
||||
// image
|
||||
|
@ -247,7 +245,7 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
else {
|
||||
QColor color = wordPart.getWord().getColor();
|
||||
|
||||
ColorScheme::getInstance().normalizeColor(color);
|
||||
this->colorScheme.normalizeColor(color);
|
||||
|
||||
painter.setPen(color);
|
||||
painter.setFont(wordPart.getWord().getFont());
|
||||
|
@ -266,14 +264,14 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
messages::LazyLoadedImage &lli = wordPart.getWord().getImage();
|
||||
|
||||
if (lli.getAnimated()) {
|
||||
GifEmoteData data;
|
||||
data.image = &lli;
|
||||
GifEmoteData gifEmoteData;
|
||||
gifEmoteData.image = &lli;
|
||||
QRect rect(wordPart.getX(), wordPart.getY() + y, wordPart.getWidth(),
|
||||
wordPart.getHeight());
|
||||
|
||||
data.rect = rect;
|
||||
gifEmoteData.rect = rect;
|
||||
|
||||
this->gifEmotes.push_back(data);
|
||||
this->gifEmotes.push_back(gifEmoteData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +288,7 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
}
|
||||
|
||||
for (GifEmoteData &item : this->gifEmotes) {
|
||||
_painter.fillRect(item.rect, scheme.ChatBackground);
|
||||
_painter.fillRect(item.rect, this->colorScheme.ChatBackground);
|
||||
|
||||
_painter.drawPixmap(item.rect, *item.image->getPixmap());
|
||||
}
|
||||
|
@ -401,13 +399,13 @@ bool ChatWidgetView::tryGetMessageAt(QPoint p, std::shared_ptr<messages::Message
|
|||
|
||||
int start = this->scrollBar.getCurrentValue();
|
||||
|
||||
if (start >= messages.getSize()) {
|
||||
if (start >= messages.getLength()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int y = -(messages[start]->getHeight() * (fmod(this->scrollBar.getCurrentValue(), 1)));
|
||||
|
||||
for (int i = start; i < messages.getSize(); ++i) {
|
||||
for (int i = start; i < messages.getLength(); ++i) {
|
||||
auto message = messages[i];
|
||||
|
||||
if (p.y() < y + message->getHeight()) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "messages/messageref.hpp"
|
||||
#include "messages/word.hpp"
|
||||
#include "widgets/accountpopup.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/scrollbar.hpp"
|
||||
|
||||
#include <QPaintEvent>
|
||||
|
@ -17,7 +18,7 @@ namespace widgets {
|
|||
|
||||
class ChatWidget;
|
||||
|
||||
class ChatWidgetView : public QWidget
|
||||
class ChatWidgetView : public BaseWidget
|
||||
{
|
||||
public:
|
||||
explicit ChatWidgetView(ChatWidget *_chatWidget);
|
||||
|
|
|
@ -6,49 +6,42 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
FancyButton::FancyButton(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, _selected()
|
||||
, _mouseOver()
|
||||
, _mouseDown()
|
||||
, _mousePos()
|
||||
, _hoverMultiplier()
|
||||
, _effectTimer()
|
||||
, _mouseEffectColor(QColor(255, 255, 255))
|
||||
FancyButton::FancyButton(BaseWidget *parent)
|
||||
: BaseWidget(parent)
|
||||
|
||||
{
|
||||
connect(&_effectTimer, &QTimer::timeout, this, &FancyButton::onMouseEffectTimeout);
|
||||
connect(&effectTimer, &QTimer::timeout, this, &FancyButton::onMouseEffectTimeout);
|
||||
|
||||
_effectTimer.setInterval(20);
|
||||
_effectTimer.start();
|
||||
this->effectTimer.setInterval(20);
|
||||
this->effectTimer.start();
|
||||
}
|
||||
|
||||
void FancyButton::setMouseEffectColor(QColor color)
|
||||
{
|
||||
_mouseEffectColor = color;
|
||||
this->mouseEffectColor = color;
|
||||
}
|
||||
|
||||
void FancyButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter;
|
||||
|
||||
fancyPaint(painter);
|
||||
this->fancyPaint(painter);
|
||||
}
|
||||
|
||||
void FancyButton::fancyPaint(QPainter &painter)
|
||||
{
|
||||
QColor &c = _mouseEffectColor;
|
||||
QColor &c = this->mouseEffectColor;
|
||||
|
||||
if (_hoverMultiplier > 0) {
|
||||
QRadialGradient gradient(_mousePos.x(), _mousePos.y(), 50, _mousePos.x(), _mousePos.y());
|
||||
if (this->hoverMultiplier > 0) {
|
||||
QRadialGradient gradient(mousePos.x(), mousePos.y(), 50, mousePos.x(), mousePos.y());
|
||||
|
||||
gradient.setColorAt(0, QColor(c.red(), c.green(), c.blue(), (int)(24 * _hoverMultiplier)));
|
||||
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(), (int)(12 * _hoverMultiplier)));
|
||||
gradient.setColorAt(0, QColor(c.red(), c.green(), c.blue(), (int)(24 * this->hoverMultiplier)));
|
||||
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(), (int)(12 * this->hoverMultiplier)));
|
||||
|
||||
painter.fillRect(this->rect(), gradient);
|
||||
}
|
||||
|
||||
for (auto effect : _clickEffects) {
|
||||
for (auto effect : this->clickEffects) {
|
||||
QRadialGradient gradient(effect.position.x(), effect.position.y(),
|
||||
effect.progress * (float)width() * 2, effect.position.x(),
|
||||
effect.position.y());
|
||||
|
@ -65,12 +58,12 @@ void FancyButton::fancyPaint(QPainter &painter)
|
|||
|
||||
void FancyButton::enterEvent(QEvent *)
|
||||
{
|
||||
_mouseOver = true;
|
||||
this->mouseOver = true;
|
||||
}
|
||||
|
||||
void FancyButton::leaveEvent(QEvent *)
|
||||
{
|
||||
_mouseOver = false;
|
||||
this->mouseOver = false;
|
||||
}
|
||||
|
||||
void FancyButton::mousePressEvent(QMouseEvent *event)
|
||||
|
@ -79,9 +72,9 @@ void FancyButton::mousePressEvent(QMouseEvent *event)
|
|||
return;
|
||||
}
|
||||
|
||||
_clickEffects.push_back(ClickEffect(event->pos()));
|
||||
this->clickEffects.push_back(ClickEffect(event->pos()));
|
||||
|
||||
_mouseDown = true;
|
||||
this->mouseDown = true;
|
||||
}
|
||||
|
||||
void FancyButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
@ -90,43 +83,43 @@ void FancyButton::mouseReleaseEvent(QMouseEvent *event)
|
|||
return;
|
||||
}
|
||||
|
||||
_mouseDown = false;
|
||||
this->mouseDown = false;
|
||||
}
|
||||
|
||||
void FancyButton::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
_mousePos = event->pos();
|
||||
this->mousePos = event->pos();
|
||||
}
|
||||
|
||||
void FancyButton::onMouseEffectTimeout()
|
||||
{
|
||||
bool performUpdate = false;
|
||||
|
||||
if (_selected) {
|
||||
if (_hoverMultiplier != 0) {
|
||||
_hoverMultiplier = std::max(0.0, _hoverMultiplier - 0.1);
|
||||
if (selected) {
|
||||
if (this->hoverMultiplier != 0) {
|
||||
this->hoverMultiplier = std::max(0.0, this->hoverMultiplier - 0.1);
|
||||
performUpdate = true;
|
||||
}
|
||||
} else if (_mouseOver) {
|
||||
if (_hoverMultiplier != 1) {
|
||||
_hoverMultiplier = std::min(1.0, _hoverMultiplier + 0.5);
|
||||
} else if (mouseOver) {
|
||||
if (this->hoverMultiplier != 1) {
|
||||
this->hoverMultiplier = std::min(1.0, this->hoverMultiplier + 0.5);
|
||||
performUpdate = true;
|
||||
}
|
||||
} else {
|
||||
if (_hoverMultiplier != 0) {
|
||||
_hoverMultiplier = std::max(0.0, _hoverMultiplier - 0.3);
|
||||
if (this->hoverMultiplier != 0) {
|
||||
this->hoverMultiplier = std::max(0.0, this->hoverMultiplier - 0.3);
|
||||
performUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_clickEffects.size() != 0) {
|
||||
if (this->clickEffects.size() != 0) {
|
||||
performUpdate = true;
|
||||
|
||||
for (auto it = _clickEffects.begin(); it != _clickEffects.end();) {
|
||||
(*it).progress += _mouseDown ? 0.02 : 0.07;
|
||||
for (auto it = this->clickEffects.begin(); it != this->clickEffects.end();) {
|
||||
(*it).progress += mouseDown ? 0.02 : 0.07;
|
||||
|
||||
if ((*it).progress >= 1.0) {
|
||||
it = _clickEffects.erase(it);
|
||||
it = this->clickEffects.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/basewidget.hpp"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPoint>
|
||||
|
@ -9,43 +11,42 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class FancyButton : public QWidget
|
||||
class FancyButton : public BaseWidget
|
||||
{
|
||||
struct ClickEffect {
|
||||
float progress;
|
||||
double progress = 0.0;
|
||||
QPoint position;
|
||||
|
||||
ClickEffect(QPoint position)
|
||||
: progress()
|
||||
, position(position)
|
||||
ClickEffect(QPoint _position)
|
||||
: position(_position)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
FancyButton(QWidget *parent = nullptr);
|
||||
FancyButton(BaseWidget *parent);
|
||||
|
||||
void setMouseEffectColor(QColor color);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void enterEvent(QEvent *) override;
|
||||
void leaveEvent(QEvent *) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
virtual void enterEvent(QEvent *) override;
|
||||
virtual void leaveEvent(QEvent *) override;
|
||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
void fancyPaint(QPainter &painter);
|
||||
|
||||
private:
|
||||
bool _selected;
|
||||
bool _mouseOver;
|
||||
bool _mouseDown;
|
||||
QPoint _mousePos;
|
||||
float _hoverMultiplier;
|
||||
QTimer _effectTimer;
|
||||
std::vector<ClickEffect> _clickEffects;
|
||||
QColor _mouseEffectColor;
|
||||
bool selected = false;
|
||||
bool mouseOver = false;
|
||||
bool mouseDown = false;
|
||||
QPoint mousePos;
|
||||
double hoverMultiplier = 0.0;
|
||||
QTimer effectTimer;
|
||||
std::vector<ClickEffect> clickEffects;
|
||||
QColor mouseEffectColor = {255, 255, 255};
|
||||
|
||||
void onMouseEffectTimeout();
|
||||
};
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
MainWindow::MainWindow(ChannelManager &_channelManager, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
MainWindow::MainWindow(ChannelManager &_channelManager, ColorScheme &_colorScheme)
|
||||
: BaseWidget(_colorScheme, nullptr)
|
||||
, channelManager(_channelManager)
|
||||
, colorScheme(_colorScheme)
|
||||
, notebook(this->channelManager, this)
|
||||
, _loaded(false)
|
||||
, _titleBar()
|
||||
, windowGeometry("/windows/0/geometry")
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
|
@ -44,10 +44,17 @@ MainWindow::MainWindow(ChannelManager &_channelManager, QWidget *parent)
|
|||
// }
|
||||
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Background, ColorScheme::getInstance().TabPanelBackground);
|
||||
palette.setColor(QPalette::Background, this->colorScheme.TabPanelBackground);
|
||||
setPalette(palette);
|
||||
|
||||
resize(1280, 800);
|
||||
if (this->windowGeometry->isFilled()) {
|
||||
// Load geometry from settings file
|
||||
this->setGeometry(this->windowGeometry.getValueRef());
|
||||
} else {
|
||||
// Set default geometry
|
||||
// Default position is in the middle of the current monitor or the primary monitor
|
||||
this->resize(1280, 800);
|
||||
}
|
||||
|
||||
// Initialize program-wide hotkeys
|
||||
{
|
||||
|
@ -122,7 +129,7 @@ void MainWindow::load(const boost::property_tree::ptree &tree)
|
|||
{
|
||||
this->notebook.load(tree);
|
||||
|
||||
_loaded = true;
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
boost::property_tree::ptree MainWindow::save()
|
||||
|
@ -140,12 +147,12 @@ void MainWindow::loadDefaults()
|
|||
{
|
||||
this->notebook.loadDefaults();
|
||||
|
||||
_loaded = true;
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
bool MainWindow::isLoaded() const
|
||||
{
|
||||
return _loaded;
|
||||
return loaded;
|
||||
}
|
||||
|
||||
Notebook &MainWindow::getNotebook()
|
||||
|
@ -153,5 +160,11 @@ Notebook &MainWindow::getNotebook()
|
|||
return this->notebook;
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
// Save closing window position
|
||||
this->windowGeometry = this->geometry();
|
||||
}
|
||||
|
||||
} // namespace widgets
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/notebook.hpp"
|
||||
#include "widgets/titlebar.hpp"
|
||||
|
||||
|
@ -9,19 +10,22 @@
|
|||
|
||||
#include <QMainWindow>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <pajlada/settings/serialize.hpp>
|
||||
#include <pajlada/settings/settingdata.hpp>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ChannelManager;
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class MainWindow : public QWidget
|
||||
class MainWindow : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(ChannelManager &_channelManager, QWidget *parent = nullptr);
|
||||
explicit MainWindow(ChannelManager &_channelManager, ColorScheme &_colorScheme);
|
||||
~MainWindow();
|
||||
|
||||
void layoutVisibleChatWidgets(Channel *channel = nullptr);
|
||||
|
@ -36,12 +40,108 @@ public:
|
|||
|
||||
Notebook &getNotebook();
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
ChannelManager &channelManager;
|
||||
ColorScheme &colorScheme;
|
||||
|
||||
Notebook notebook;
|
||||
bool _loaded;
|
||||
TitleBar _titleBar;
|
||||
bool loaded = false;
|
||||
TitleBar titleBar;
|
||||
|
||||
class QRectWrapper : public pajlada::Settings::ISettingData, public QRect
|
||||
{
|
||||
public:
|
||||
QRectWrapper()
|
||||
: QRect(-1, -1, -1, -1)
|
||||
{
|
||||
}
|
||||
|
||||
pajlada::Signals::Signal<const QRectWrapper &> valueChanged;
|
||||
|
||||
/*
|
||||
operator const QRect &() const
|
||||
{
|
||||
return static_cast<const QRect &>(*this);
|
||||
// return this->getValue();
|
||||
}
|
||||
*/
|
||||
|
||||
const QRectWrapper &getValueRef() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual rapidjson::Value marshalInto(rapidjson::Document &d) override
|
||||
{
|
||||
using namespace pajlada::Settings;
|
||||
|
||||
rapidjson::Value obj(rapidjson::kObjectType);
|
||||
|
||||
auto _x = serializeToJSON<int>::serialize(this->x(), d.GetAllocator());
|
||||
auto _y = serializeToJSON<int>::serialize(this->y(), d.GetAllocator());
|
||||
auto _width = serializeToJSON<int>::serialize(this->width(), d.GetAllocator());
|
||||
auto _height = serializeToJSON<int>::serialize(this->height(), d.GetAllocator());
|
||||
|
||||
obj.AddMember("x", _x, d.GetAllocator());
|
||||
obj.AddMember("y", _y, d.GetAllocator());
|
||||
obj.AddMember("width", _width, d.GetAllocator());
|
||||
obj.AddMember("height", _height, d.GetAllocator());
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
virtual bool unmarshalFrom(rapidjson::Document &document) override
|
||||
{
|
||||
using namespace pajlada::Settings;
|
||||
|
||||
auto vXp = this->getValueWithSuffix("/x", document);
|
||||
auto vYp = this->getValueWithSuffix("/y", document);
|
||||
auto vWidthp = this->getValueWithSuffix("/width", document);
|
||||
auto vHeightp = this->getValueWithSuffix("/height", document);
|
||||
if (vXp != nullptr) {
|
||||
this->setX(deserializeJSON<int>::deserialize(*vXp));
|
||||
this->filled = true;
|
||||
}
|
||||
if (vYp != nullptr) {
|
||||
this->setY(deserializeJSON<int>::deserialize(*vYp));
|
||||
this->filled = true;
|
||||
}
|
||||
if (vWidthp != nullptr) {
|
||||
this->setWidth(deserializeJSON<int>::deserialize(*vWidthp));
|
||||
this->filled = true;
|
||||
}
|
||||
if (vHeightp != nullptr) {
|
||||
this->setHeight(deserializeJSON<int>::deserialize(*vHeightp));
|
||||
this->filled = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void registerDocument(rapidjson::Document &d) override
|
||||
{
|
||||
this->valueChanged.connect([this, &d](const auto &) {
|
||||
this->marshalInto(d); //
|
||||
});
|
||||
}
|
||||
|
||||
QRectWrapper &operator=(const QRect &rhs)
|
||||
{
|
||||
static_cast<QRect &>(*this) = rhs;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void setValue(const QRect &rhs)
|
||||
{
|
||||
static_cast<QRect &>(*this) = rhs;
|
||||
}
|
||||
};
|
||||
|
||||
pajlada::Settings::Setting<QRectWrapper, QRectWrapper> windowGeometry;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
@ -18,26 +18,26 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
Notebook::Notebook(ChannelManager &_channelManager, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, channelManager(_channelManager)
|
||||
, _addButton(this)
|
||||
, _settingsButton(this)
|
||||
, _userButton(this)
|
||||
, _selectedPage(nullptr)
|
||||
Notebook::Notebook(ChannelManager &_channelManager, BaseWidget *parent)
|
||||
: BaseWidget(parent)
|
||||
, channelManager(_channelManager)
|
||||
, addButton(this)
|
||||
, settingsButton(this)
|
||||
, userButton(this)
|
||||
, selectedPage(nullptr)
|
||||
{
|
||||
connect(&_settingsButton, SIGNAL(clicked()), this, SLOT(settingsButtonClicked()));
|
||||
connect(&_userButton, SIGNAL(clicked()), this, SLOT(usersButtonClicked()));
|
||||
connect(&_addButton, SIGNAL(clicked()), this, SLOT(addPageButtonClicked()));
|
||||
connect(&settingsButton, SIGNAL(clicked()), this, SLOT(settingsButtonClicked()));
|
||||
connect(&userButton, SIGNAL(clicked()), this, SLOT(usersButtonClicked()));
|
||||
connect(&addButton, SIGNAL(clicked()), this, SLOT(addPageButtonClicked()));
|
||||
|
||||
_settingsButton.resize(24, 24);
|
||||
_settingsButton.icon = NotebookButton::IconSettings;
|
||||
settingsButton.resize(24, 24);
|
||||
settingsButton.icon = NotebookButton::IconSettings;
|
||||
|
||||
_userButton.resize(24, 24);
|
||||
_userButton.move(24, 0);
|
||||
_userButton.icon = NotebookButton::IconUser;
|
||||
userButton.resize(24, 24);
|
||||
userButton.move(24, 0);
|
||||
userButton.icon = NotebookButton::IconUser;
|
||||
|
||||
_addButton.resize(24, 24);
|
||||
addButton.resize(24, 24);
|
||||
|
||||
SettingsManager::getInstance().hidePreferencesButton.valueChanged.connect(
|
||||
[this](const bool &) { performLayout(); });
|
||||
|
@ -52,11 +52,11 @@ NotebookPage *Notebook::addPage(bool select)
|
|||
|
||||
tab->show();
|
||||
|
||||
if (select || _pages.count() == 0) {
|
||||
if (select || pages.count() == 0) {
|
||||
this->select(page);
|
||||
}
|
||||
|
||||
_pages.append(page);
|
||||
pages.append(page);
|
||||
|
||||
performLayout();
|
||||
|
||||
|
@ -65,22 +65,22 @@ NotebookPage *Notebook::addPage(bool select)
|
|||
|
||||
void Notebook::removePage(NotebookPage *page)
|
||||
{
|
||||
int index = _pages.indexOf(page);
|
||||
int index = pages.indexOf(page);
|
||||
|
||||
if (_pages.size() == 1) {
|
||||
if (pages.size() == 1) {
|
||||
select(nullptr);
|
||||
} else if (index == _pages.count() - 1) {
|
||||
select(_pages[index - 1]);
|
||||
} else if (index == pages.count() - 1) {
|
||||
select(pages[index - 1]);
|
||||
} else {
|
||||
select(_pages[index + 1]);
|
||||
select(pages[index + 1]);
|
||||
}
|
||||
|
||||
delete page->getTab();
|
||||
delete page;
|
||||
|
||||
_pages.removeOne(page);
|
||||
pages.removeOne(page);
|
||||
|
||||
if (_pages.size() == 0) {
|
||||
if (pages.size() == 0) {
|
||||
addPage();
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ void Notebook::removePage(NotebookPage *page)
|
|||
|
||||
void Notebook::select(NotebookPage *page)
|
||||
{
|
||||
if (page == _selectedPage)
|
||||
if (page == selectedPage)
|
||||
return;
|
||||
|
||||
if (page != nullptr) {
|
||||
|
@ -98,12 +98,12 @@ void Notebook::select(NotebookPage *page)
|
|||
page->getTab()->raise();
|
||||
}
|
||||
|
||||
if (_selectedPage != nullptr) {
|
||||
_selectedPage->setHidden(true);
|
||||
_selectedPage->getTab()->setSelected(false);
|
||||
if (selectedPage != nullptr) {
|
||||
selectedPage->setHidden(true);
|
||||
selectedPage->getTab()->setSelected(false);
|
||||
}
|
||||
|
||||
_selectedPage = page;
|
||||
selectedPage = page;
|
||||
|
||||
performLayout();
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ NotebookPage *Notebook::tabAt(QPoint point, int &index)
|
|||
{
|
||||
int i = 0;
|
||||
|
||||
for (auto *page : _pages) {
|
||||
for (auto *page : pages) {
|
||||
if (page->getTab()->getDesiredRect().contains(point)) {
|
||||
index = i;
|
||||
return page;
|
||||
|
@ -127,7 +127,7 @@ NotebookPage *Notebook::tabAt(QPoint point, int &index)
|
|||
|
||||
void Notebook::rearrangePage(NotebookPage *page, int index)
|
||||
{
|
||||
_pages.move(_pages.indexOf(page), index);
|
||||
pages.move(pages.indexOf(page), index);
|
||||
|
||||
performLayout();
|
||||
}
|
||||
|
@ -137,26 +137,26 @@ void Notebook::performLayout(bool animated)
|
|||
int x = 0, y = 0;
|
||||
|
||||
if (SettingsManager::getInstance().hidePreferencesButton.get()) {
|
||||
_settingsButton.hide();
|
||||
settingsButton.hide();
|
||||
} else {
|
||||
_settingsButton.show();
|
||||
settingsButton.show();
|
||||
x += 24;
|
||||
}
|
||||
if (SettingsManager::getInstance().hideUserButton.get()) {
|
||||
_userButton.hide();
|
||||
userButton.hide();
|
||||
} else {
|
||||
_userButton.move(x, 0);
|
||||
_userButton.show();
|
||||
userButton.move(x, 0);
|
||||
userButton.show();
|
||||
x += 24;
|
||||
}
|
||||
|
||||
int tabHeight = 16;
|
||||
bool first = true;
|
||||
|
||||
for (auto &i : _pages) {
|
||||
for (auto &i : pages) {
|
||||
tabHeight = i->getTab()->height();
|
||||
|
||||
if (!first && (i == _pages.last() ? tabHeight : 0) + x + i->getTab()->width() > width()) {
|
||||
if (!first && (i == pages.last() ? tabHeight : 0) + x + i->getTab()->width() > width()) {
|
||||
y += i->getTab()->height();
|
||||
i->getTab()->moveAnimated(QPoint(0, y), animated);
|
||||
x = i->getTab()->width();
|
||||
|
@ -168,11 +168,11 @@ void Notebook::performLayout(bool animated)
|
|||
first = false;
|
||||
}
|
||||
|
||||
_addButton.move(x, y);
|
||||
addButton.move(x, y);
|
||||
|
||||
if (_selectedPage != nullptr) {
|
||||
_selectedPage->move(0, y + tabHeight);
|
||||
_selectedPage->resize(width(), height() - y - tabHeight);
|
||||
if (selectedPage != nullptr) {
|
||||
selectedPage->move(0, y + tabHeight);
|
||||
selectedPage->resize(width(), height() - y - tabHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,7 @@ void Notebook::load(const boost::property_tree::ptree &tree)
|
|||
// can't read tabs
|
||||
}
|
||||
|
||||
if (_pages.size() == 0) {
|
||||
if (pages.size() == 0) {
|
||||
// No pages saved, show default stuff
|
||||
loadDefaults();
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ void Notebook::save(boost::property_tree::ptree &tree)
|
|||
boost::property_tree::ptree tabs;
|
||||
|
||||
// Iterate through all tabs and add them to our tabs property thing
|
||||
for (const auto &page : _pages) {
|
||||
for (const auto &page : pages) {
|
||||
boost::property_tree::ptree pTab = page->getTab()->save();
|
||||
|
||||
boost::property_tree::ptree pChats = page->save();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/notebookbutton.hpp"
|
||||
#include "widgets/notebookpage.hpp"
|
||||
#include "widgets/notebooktab.hpp"
|
||||
|
@ -11,17 +12,18 @@
|
|||
namespace chatterino {
|
||||
|
||||
class ChannelManager;
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class Notebook : public QWidget
|
||||
class Notebook : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum HighlightType { none, highlighted, newMessage };
|
||||
|
||||
Notebook(ChannelManager &_channelManager, QWidget *parent);
|
||||
explicit Notebook(ChannelManager &_channelManager, BaseWidget *parent);
|
||||
|
||||
NotebookPage *addPage(bool select = false);
|
||||
|
||||
|
@ -30,7 +32,7 @@ public:
|
|||
|
||||
NotebookPage *getSelectedPage()
|
||||
{
|
||||
return _selectedPage;
|
||||
return selectedPage;
|
||||
}
|
||||
|
||||
void performLayout(bool animate = true);
|
||||
|
@ -51,13 +53,13 @@ public slots:
|
|||
private:
|
||||
ChannelManager &channelManager;
|
||||
|
||||
QList<NotebookPage *> _pages;
|
||||
QList<NotebookPage *> pages;
|
||||
|
||||
NotebookButton _addButton;
|
||||
NotebookButton _settingsButton;
|
||||
NotebookButton _userButton;
|
||||
NotebookButton addButton;
|
||||
NotebookButton settingsButton;
|
||||
NotebookButton userButton;
|
||||
|
||||
NotebookPage *_selectedPage;
|
||||
NotebookPage *selectedPage;
|
||||
|
||||
public:
|
||||
void load(const boost::property_tree::ptree &tree);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
NotebookButton::NotebookButton(QWidget *parent)
|
||||
NotebookButton::NotebookButton(BaseWidget *parent)
|
||||
: FancyButton(parent)
|
||||
{
|
||||
setMouseEffectColor(QColor(0, 0, 0));
|
||||
|
@ -23,17 +23,15 @@ void NotebookButton::paintEvent(QPaintEvent *)
|
|||
QColor background;
|
||||
QColor foreground;
|
||||
|
||||
auto &colorScheme = ColorScheme::getInstance();
|
||||
|
||||
if (_mouseDown) {
|
||||
background = colorScheme.TabSelectedBackground;
|
||||
foreground = colorScheme.TabSelectedText;
|
||||
} else if (_mouseOver) {
|
||||
background = colorScheme.TabHoverBackground;
|
||||
foreground = colorScheme.TabSelectedBackground;
|
||||
if (mouseDown) {
|
||||
background = this->colorScheme.TabSelectedBackground;
|
||||
foreground = this->colorScheme.TabSelectedText;
|
||||
} else if (mouseOver) {
|
||||
background = this->colorScheme.TabHoverBackground;
|
||||
foreground = this->colorScheme.TabSelectedBackground;
|
||||
} else {
|
||||
background = colorScheme.TabPanelBackground;
|
||||
// foreground = colorScheme.TabSelectedBackground;
|
||||
background = this->colorScheme.TabPanelBackground;
|
||||
// foreground = this->colorScheme.TabSelectedBackground;
|
||||
foreground = QColor(230, 230, 230);
|
||||
}
|
||||
|
||||
|
@ -93,7 +91,7 @@ void NotebookButton::paintEvent(QPaintEvent *)
|
|||
void NotebookButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
_mouseDown = false;
|
||||
mouseDown = false;
|
||||
|
||||
update();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
|
||||
int icon = 0;
|
||||
|
||||
NotebookButton(QWidget *parent);
|
||||
NotebookButton(BaseWidget *parent);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
|
@ -28,9 +28,9 @@ signals:
|
|||
void clicked();
|
||||
|
||||
private:
|
||||
bool _mouseOver = false;
|
||||
bool _mouseDown = false;
|
||||
QPoint _mousePos;
|
||||
bool mouseOver = false;
|
||||
bool mouseDown = false;
|
||||
QPoint mousePos;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "widgets/notebookpage.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "widgets/chatwidget.hpp"
|
||||
#include "widgets/notebook.hpp"
|
||||
#include "widgets/notebooktab.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
@ -19,8 +20,8 @@ bool NotebookPage::isDraggingSplit = false;
|
|||
ChatWidget *NotebookPage::draggingSplit = nullptr;
|
||||
std::pair<int, int> NotebookPage::dropPosition = std::pair<int, int>(-1, -1);
|
||||
|
||||
NotebookPage::NotebookPage(ChannelManager &_channelManager, QWidget *parent, NotebookTab *_tab)
|
||||
: QWidget(parent)
|
||||
NotebookPage::NotebookPage(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab)
|
||||
: BaseWidget(parent->colorScheme, parent)
|
||||
, channelManager(_channelManager)
|
||||
, tab(_tab)
|
||||
, _parentbox(this)
|
||||
|
@ -52,7 +53,7 @@ NotebookTab *NotebookPage::getTab() const
|
|||
|
||||
void NotebookPage::addChat(bool openChannelNameDialog)
|
||||
{
|
||||
ChatWidget *w = new ChatWidget(this->channelManager);
|
||||
ChatWidget *w = this->createChatWidget();
|
||||
|
||||
if (openChannelNameDialog) {
|
||||
w->showChangeChannelPopup();
|
||||
|
@ -130,9 +131,9 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
|||
void NotebookPage::enterEvent(QEvent *)
|
||||
{
|
||||
if (_hbox.count() == 0) {
|
||||
setCursor(QCursor(Qt::PointingHandCursor));
|
||||
this->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
} else {
|
||||
setCursor(QCursor(Qt::ArrowCursor));
|
||||
this->setCursor(QCursor(Qt::ArrowCursor));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,9 +145,9 @@ void NotebookPage::mouseReleaseEvent(QMouseEvent *event)
|
|||
{
|
||||
if (_hbox.count() == 0 && event->button() == Qt::LeftButton) {
|
||||
// "Add Chat" was clicked
|
||||
addToLayout(new ChatWidget(this->channelManager), std::pair<int, int>(-1, -1));
|
||||
this->addToLayout(this->createChatWidget(), std::pair<int, int>(-1, -1));
|
||||
|
||||
setCursor(QCursor(Qt::ArrowCursor));
|
||||
this->setCursor(QCursor(Qt::ArrowCursor));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,16 +237,16 @@ void NotebookPage::paintEvent(QPaintEvent *)
|
|||
QPainter painter(this);
|
||||
|
||||
if (_hbox.count() == 0) {
|
||||
painter.fillRect(rect(), ColorScheme::getInstance().ChatBackground);
|
||||
painter.fillRect(rect(), this->colorScheme.ChatBackground);
|
||||
|
||||
painter.fillRect(0, 0, width(), 2, ColorScheme::getInstance().TabSelectedBackground);
|
||||
painter.fillRect(0, 0, width(), 2, this->colorScheme.TabSelectedBackground);
|
||||
|
||||
painter.setPen(ColorScheme::getInstance().Text);
|
||||
painter.setPen(this->colorScheme.Text);
|
||||
painter.drawText(rect(), "Add Chat", QTextOption(Qt::AlignCenter));
|
||||
} else {
|
||||
painter.fillRect(rect(), ColorScheme::getInstance().TabSelectedBackground);
|
||||
painter.fillRect(rect(), this->colorScheme.TabSelectedBackground);
|
||||
|
||||
painter.fillRect(0, 0, width(), 2, ColorScheme::getInstance().TabSelectedBackground);
|
||||
painter.fillRect(0, 0, width(), 2, this->colorScheme.TabSelectedBackground);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,6 +270,11 @@ std::pair<int, int> NotebookPage::getChatPosition(const ChatWidget *chatWidget)
|
|||
return getWidgetPositionInLayout(layout, chatWidget);
|
||||
}
|
||||
|
||||
ChatWidget *NotebookPage::createChatWidget()
|
||||
{
|
||||
return new ChatWidget(this->channelManager, this);
|
||||
}
|
||||
|
||||
void NotebookPage::load(const boost::property_tree::ptree &tree)
|
||||
{
|
||||
try {
|
||||
|
@ -276,7 +282,7 @@ void NotebookPage::load(const boost::property_tree::ptree &tree)
|
|||
for (const auto &v : tree.get_child("columns.")) {
|
||||
int row = 0;
|
||||
for (const auto &innerV : v.second.get_child("")) {
|
||||
auto widget = new ChatWidget(this->channelManager);
|
||||
auto widget = this->createChatWidget();
|
||||
widget->load(innerV.second);
|
||||
addToLayout(widget, std::pair<int, int>(column, row));
|
||||
++row;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/chatwidget.hpp"
|
||||
#include "widgets/notebookpage.hpp"
|
||||
#include "widgets/notebookpagedroppreview.hpp"
|
||||
|
@ -20,12 +21,14 @@ class ChannelManager;
|
|||
|
||||
namespace widgets {
|
||||
|
||||
class NotebookPage : public QWidget
|
||||
class NotebookPage : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NotebookPage(ChannelManager &_channelManager, QWidget *parent, NotebookTab *_tab);
|
||||
NotebookPage(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab);
|
||||
|
||||
ChannelManager &channelManager;
|
||||
|
||||
std::pair<int, int> removeFromLayout(ChatWidget *widget);
|
||||
void addToLayout(ChatWidget *widget, std::pair<int, int> position);
|
||||
|
@ -52,8 +55,6 @@ protected:
|
|||
void dropEvent(QDropEvent *event) override;
|
||||
|
||||
private:
|
||||
ChannelManager &channelManager;
|
||||
|
||||
struct DropRegion {
|
||||
QRect rect;
|
||||
std::pair<int, int> position;
|
||||
|
@ -79,6 +80,8 @@ private:
|
|||
|
||||
std::pair<int, int> getChatPosition(const ChatWidget *chatWidget);
|
||||
|
||||
ChatWidget *createChatWidget();
|
||||
|
||||
public:
|
||||
void load(const boost::property_tree::ptree &tree);
|
||||
boost::property_tree::ptree save();
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "widgets/notebookpagedroppreview.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
|
@ -7,11 +6,9 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
NotebookPageDropPreview::NotebookPageDropPreview(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
NotebookPageDropPreview::NotebookPageDropPreview(BaseWidget *parent)
|
||||
: BaseWidget(parent)
|
||||
, positionAnimation(this, "geometry")
|
||||
, desiredGeometry()
|
||||
, animate(false)
|
||||
{
|
||||
this->positionAnimation.setEasingCurve(QEasingCurve(QEasingCurve::InCubic));
|
||||
this->setHidden(true);
|
||||
|
@ -21,13 +18,12 @@ void NotebookPageDropPreview::paintEvent(QPaintEvent *)
|
|||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.fillRect(8, 8, width() - 17, height() - 17,
|
||||
ColorScheme::getInstance().DropPreviewBackground);
|
||||
painter.fillRect(8, 8, width() - 17, height() - 17, this->colorScheme.DropPreviewBackground);
|
||||
}
|
||||
|
||||
void NotebookPageDropPreview::hideEvent(QHideEvent *)
|
||||
{
|
||||
animate = false;
|
||||
this->animate = false;
|
||||
}
|
||||
|
||||
void NotebookPageDropPreview::setBounds(const QRect &rect)
|
||||
|
@ -36,7 +32,7 @@ void NotebookPageDropPreview::setBounds(const QRect &rect)
|
|||
return;
|
||||
}
|
||||
|
||||
if (animate) {
|
||||
if (this->animate) {
|
||||
this->positionAnimation.stop();
|
||||
this->positionAnimation.setDuration(50);
|
||||
this->positionAnimation.setStartValue(this->geometry());
|
||||
|
@ -48,7 +44,7 @@ void NotebookPageDropPreview::setBounds(const QRect &rect)
|
|||
|
||||
this->desiredGeometry = rect;
|
||||
|
||||
animate = true;
|
||||
this->animate = true;
|
||||
}
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/basewidget.hpp"
|
||||
|
||||
#include <QPropertyAnimation>
|
||||
#include <QWidget>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class NotebookPageDropPreview : public QWidget
|
||||
class NotebookPageDropPreview : public BaseWidget
|
||||
{
|
||||
public:
|
||||
NotebookPageDropPreview(QWidget *parent);
|
||||
NotebookPageDropPreview(BaseWidget *parent);
|
||||
|
||||
void setBounds(const QRect &rect);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
void hideEvent(QHideEvent *);
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
virtual void hideEvent(QHideEvent *) override;
|
||||
|
||||
QPropertyAnimation positionAnimation;
|
||||
QRect desiredGeometry;
|
||||
bool animate;
|
||||
bool animate = false;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
@ -10,17 +10,9 @@ namespace widgets {
|
|||
|
||||
NotebookTab::NotebookTab(Notebook *notebook)
|
||||
: QWidget(notebook)
|
||||
, colorScheme(notebook->colorScheme)
|
||||
, _posAnimation(this, "pos")
|
||||
, _posAnimated(false)
|
||||
, _posAnimationDesired()
|
||||
, _notebook(notebook)
|
||||
, _title("<no title>")
|
||||
, _selected(false)
|
||||
, _mouseOver(false)
|
||||
, _mouseDown(false)
|
||||
, _mouseOverX(false)
|
||||
, _mouseDownX(false)
|
||||
, _highlightStyle(HighlightNone)
|
||||
{
|
||||
this->calcSize();
|
||||
this->setAcceptDrops(true);
|
||||
|
@ -122,23 +114,21 @@ void NotebookTab::paintEvent(QPaintEvent *)
|
|||
|
||||
QColor fg = QColor(0, 0, 0);
|
||||
|
||||
auto &colorScheme = ColorScheme::getInstance();
|
||||
|
||||
if (_selected) {
|
||||
painter.fillRect(rect(), colorScheme.TabSelectedBackground);
|
||||
fg = colorScheme.TabSelectedText;
|
||||
painter.fillRect(rect(), this->colorScheme.TabSelectedBackground);
|
||||
fg = this->colorScheme.TabSelectedText;
|
||||
} else if (_mouseOver) {
|
||||
painter.fillRect(rect(), colorScheme.TabHoverBackground);
|
||||
fg = colorScheme.TabHoverText;
|
||||
painter.fillRect(rect(), this->colorScheme.TabHoverBackground);
|
||||
fg = this->colorScheme.TabHoverText;
|
||||
} else if (_highlightStyle == HighlightHighlighted) {
|
||||
painter.fillRect(rect(), colorScheme.TabHighlightedBackground);
|
||||
fg = colorScheme.TabHighlightedText;
|
||||
painter.fillRect(rect(), this->colorScheme.TabHighlightedBackground);
|
||||
fg = this->colorScheme.TabHighlightedText;
|
||||
} else if (_highlightStyle == HighlightNewMessage) {
|
||||
painter.fillRect(rect(), colorScheme.TabNewMessageBackground);
|
||||
fg = colorScheme.TabHighlightedText;
|
||||
painter.fillRect(rect(), this->colorScheme.TabNewMessageBackground);
|
||||
fg = this->colorScheme.TabHighlightedText;
|
||||
} else {
|
||||
painter.fillRect(rect(), colorScheme.TabBackground);
|
||||
fg = colorScheme.TabText;
|
||||
painter.fillRect(rect(), this->colorScheme.TabBackground);
|
||||
fg = this->colorScheme.TabText;
|
||||
}
|
||||
|
||||
painter.setPen(fg);
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#include <boost/signals2/connection.hpp>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class Notebook;
|
||||
|
@ -22,6 +25,8 @@ public:
|
|||
explicit NotebookTab(Notebook *_notebook);
|
||||
~NotebookTab();
|
||||
|
||||
ColorScheme &colorScheme;
|
||||
|
||||
void calcSize();
|
||||
|
||||
NotebookPage *page;
|
||||
|
@ -55,20 +60,20 @@ private:
|
|||
boost::signals2::connection _hideXConnection;
|
||||
|
||||
QPropertyAnimation _posAnimation;
|
||||
bool _posAnimated;
|
||||
bool _posAnimated = false;
|
||||
QPoint _posAnimationDesired;
|
||||
|
||||
Notebook *_notebook;
|
||||
|
||||
QString _title;
|
||||
QString _title = "<no title>";
|
||||
|
||||
bool _selected;
|
||||
bool _mouseOver;
|
||||
bool _mouseDown;
|
||||
bool _mouseOverX;
|
||||
bool _mouseDownX;
|
||||
bool _selected = false;
|
||||
bool _mouseOver = false;
|
||||
bool _mouseDown = false;
|
||||
bool _mouseOverX = false;
|
||||
bool _mouseDownX = false;
|
||||
|
||||
HighlightStyle _highlightStyle;
|
||||
HighlightStyle _highlightStyle = HighlightStyle::HighlightNone;
|
||||
|
||||
QRect getXRect()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "widgets/scrollbar.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "widgets/chatwidgetview.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMouseEvent>
|
||||
|
@ -10,8 +11,8 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ScrollBar::ScrollBar(QWidget *widget)
|
||||
: QWidget(widget)
|
||||
ScrollBar::ScrollBar(ChatWidgetView *parent)
|
||||
: BaseWidget(parent)
|
||||
, _currentValueAnimation(this, "currentValue")
|
||||
, _highlights(nullptr)
|
||||
{
|
||||
|
@ -197,7 +198,7 @@ void ScrollBar::printCurrentState(const QString &prefix) const
|
|||
void ScrollBar::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.fillRect(rect(), ColorScheme::getInstance().ScrollbarBG);
|
||||
painter.fillRect(rect(), this->colorScheme.ScrollbarBG);
|
||||
|
||||
painter.fillRect(QRect(0, 0, width(), _buttonHeight), QColor(255, 0, 0));
|
||||
painter.fillRect(QRect(0, height() - _buttonHeight, width(), _buttonHeight), QColor(255, 0, 0));
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/scrollbarhighlight.hpp"
|
||||
|
||||
#include <QMutex>
|
||||
|
@ -8,14 +9,19 @@
|
|||
#include <boost/signals2.hpp>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class ScrollBar : public QWidget
|
||||
class ChatWidgetView;
|
||||
|
||||
class ScrollBar : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScrollBar(QWidget *parent = 0);
|
||||
ScrollBar(ChatWidgetView *parent = 0);
|
||||
~ScrollBar();
|
||||
|
||||
void removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func);
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
#include "widgets/scrollbarhighlight.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "widgets/scrollbar.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ScrollBarHighlight::ScrollBarHighlight(float position, int colorIndex, Style style, QString tag)
|
||||
: _style(style)
|
||||
, _position(position)
|
||||
, _colorIndex(std::max(0, std::min(ColorScheme::getInstance().HighlightColorCount, colorIndex)))
|
||||
, _tag(tag)
|
||||
ScrollBarHighlight::ScrollBarHighlight(double _position, int _colorIndex, ScrollBar *parent,
|
||||
Style _style, QString _tag)
|
||||
: colorScheme(parent->colorScheme)
|
||||
, position(_position)
|
||||
, colorIndex(std::max(0, std::min(this->colorScheme.HighlightColorCount, _colorIndex)))
|
||||
, style(_style)
|
||||
, tag(_tag)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -3,43 +3,50 @@
|
|||
#include "QString"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ColorScheme;
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class ScrollBar;
|
||||
|
||||
class ScrollBarHighlight
|
||||
{
|
||||
public:
|
||||
enum Style { Default, Left, Right, SingleLine };
|
||||
|
||||
ScrollBarHighlight(float getPosition, int getColorIndex, Style getStyle = Default,
|
||||
ScrollBarHighlight(double _position, int _colorIndex, ScrollBar *parent, Style _style = Default,
|
||||
QString _tag = "");
|
||||
|
||||
Style getStyle()
|
||||
{
|
||||
return _style;
|
||||
}
|
||||
ColorScheme &colorScheme;
|
||||
|
||||
float getPosition()
|
||||
double getPosition()
|
||||
{
|
||||
return _position;
|
||||
return this->position;
|
||||
}
|
||||
|
||||
int getColorIndex()
|
||||
{
|
||||
return _colorIndex;
|
||||
return this->colorIndex;
|
||||
}
|
||||
|
||||
Style getStyle()
|
||||
{
|
||||
return this->style;
|
||||
}
|
||||
|
||||
QString getTag()
|
||||
{
|
||||
return _tag;
|
||||
return this->tag;
|
||||
}
|
||||
|
||||
ScrollBarHighlight *next = nullptr;
|
||||
|
||||
private:
|
||||
Style _style;
|
||||
float _position;
|
||||
int _colorIndex;
|
||||
QString _tag;
|
||||
double position;
|
||||
int colorIndex;
|
||||
Style style;
|
||||
QString tag;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
@ -108,10 +108,31 @@ void SettingsDialog::addTabs()
|
|||
|
||||
auto form = new QFormLayout();
|
||||
auto combo = new QComboBox();
|
||||
auto slider = new QSlider(Qt::Horizontal);
|
||||
|
||||
auto font = new QPushButton("select");
|
||||
font->connect(font, &QPushButton::clicked, []() {
|
||||
auto fontLayout = new QHBoxLayout();
|
||||
auto fontFamilyLabel = new QLabel("Current font family");
|
||||
auto fontSizeLabel = new QLabel("Current font size");
|
||||
auto fontButton = new QPushButton("Select");
|
||||
|
||||
fontLayout->addWidget(fontButton);
|
||||
fontLayout->addWidget(fontFamilyLabel);
|
||||
fontLayout->addWidget(fontSizeLabel);
|
||||
|
||||
{
|
||||
auto fontManager = FontManager::getInstance();
|
||||
|
||||
fontManager.currentFontFamily.getValueChangedSignal().connect(
|
||||
[fontFamilyLabel](const std::string &newValue) {
|
||||
fontFamilyLabel->setText(QString::fromStdString(newValue)); //
|
||||
});
|
||||
|
||||
fontManager.currentFontSize.getValueChangedSignal().connect(
|
||||
[fontSizeLabel](const int &newValue) {
|
||||
fontSizeLabel->setText(QString(QString::number(newValue))); //
|
||||
});
|
||||
}
|
||||
|
||||
fontButton->connect(fontButton, &QPushButton::clicked, []() {
|
||||
auto fontManager = FontManager::getInstance();
|
||||
QFontDialog dialog(fontManager.getFont(FontManager::Medium));
|
||||
|
||||
|
@ -131,48 +152,61 @@ void SettingsDialog::addTabs()
|
|||
auto hideUserButton = createCheckbox("Hide user button", settings.hideUserButton);
|
||||
|
||||
form->addRow("Theme:", combo);
|
||||
form->addRow("Theme color:", slider);
|
||||
form->addRow("Font:", font);
|
||||
form->addRow("Tabbar:", compactTabs);
|
||||
|
||||
{
|
||||
auto hbox = new QHBoxLayout();
|
||||
|
||||
auto slider = new QSlider(Qt::Horizontal);
|
||||
// Theme hue
|
||||
slider->setMinimum(0);
|
||||
slider->setMaximum(1000);
|
||||
|
||||
slider->setValue(std::min(std::max(settings.themeHue.getValue(), 0.0), 1.0) * 1000);
|
||||
|
||||
hbox->addWidget(slider);
|
||||
|
||||
auto button = new QPushButton();
|
||||
button->setFlat(true);
|
||||
|
||||
hbox->addWidget(button);
|
||||
|
||||
form->addRow("Theme color:", hbox);
|
||||
|
||||
QObject::connect(slider, &QSlider::valueChanged, this, [&settings, button](int value) {
|
||||
settings.themeHue.setValue(value / 1000.0);
|
||||
|
||||
QPalette pal = button->palette();
|
||||
QColor color;
|
||||
color.setHsvF(settings.themeHue.getValue(), 1.0, 1.0, 1.0);
|
||||
pal.setColor(QPalette::Button, color);
|
||||
button->setAutoFillBackground(true);
|
||||
button->setPalette(pal);
|
||||
button->update();
|
||||
|
||||
// TODO(pajlada): re-implement
|
||||
// this->windowManager.updateAll();
|
||||
});
|
||||
}
|
||||
|
||||
form->addRow("Font:", fontLayout);
|
||||
form->addRow("Tab bar:", compactTabs);
|
||||
form->addRow("", hidePreferencesButton);
|
||||
form->addRow("", hideUserButton);
|
||||
|
||||
// theme
|
||||
// Theme name
|
||||
combo->addItem("White");
|
||||
combo->addItem("Light");
|
||||
combo->addItem("Dark");
|
||||
combo->addItem("Black");
|
||||
|
||||
QString theme = settings.theme.get();
|
||||
theme = theme.toLower();
|
||||
auto xD = QString::fromStdString(settings.themeName);
|
||||
|
||||
if (theme == "light") {
|
||||
combo->setCurrentIndex(0);
|
||||
} else if (theme == "white") {
|
||||
combo->setCurrentIndex(1);
|
||||
} else if (theme == "black") {
|
||||
combo->setCurrentIndex(3);
|
||||
} else {
|
||||
combo->setCurrentIndex(2);
|
||||
}
|
||||
combo->setCurrentText(xD);
|
||||
|
||||
QObject::connect(combo, &QComboBox::currentTextChanged, this,
|
||||
[&settings](const QString &value) { settings.theme.set(value); });
|
||||
|
||||
// theme hue
|
||||
slider->setMinimum(0);
|
||||
slider->setMaximum(1000);
|
||||
|
||||
float hue = settings.themeHue.get();
|
||||
|
||||
slider->setValue(std::min(std::max(hue, (float)0.0), (float)1.0) * 1000);
|
||||
|
||||
QObject::connect(slider, &QSlider::valueChanged, this, [&settings](int value) {
|
||||
settings.themeHue.set(value / 1000.0);
|
||||
|
||||
// TODO(pajlada): re-implement
|
||||
// this->windowManager.updateAll();
|
||||
});
|
||||
[&settings](const QString &value) {
|
||||
settings.themeName.setValue(value.toStdString()); //
|
||||
});
|
||||
|
||||
group->setLayout(form);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "windowmanager.hpp"
|
||||
#include "appdatapath.hpp"
|
||||
#include "channelmanager.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QStandardPaths>
|
||||
|
@ -9,8 +10,9 @@
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
WindowManager::WindowManager(ChannelManager &_channelManager)
|
||||
WindowManager::WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme)
|
||||
: channelManager(_channelManager)
|
||||
, colorScheme(_colorScheme)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -54,7 +56,7 @@ widgets::MainWindow &WindowManager::getMainWindow()
|
|||
std::lock_guard<std::mutex> lock(this->windowMutex);
|
||||
|
||||
if (this->mainWindow == nullptr) {
|
||||
this->mainWindow = new widgets::MainWindow(this->channelManager);
|
||||
this->mainWindow = new widgets::MainWindow(this->channelManager, this->colorScheme);
|
||||
}
|
||||
|
||||
return *this->mainWindow;
|
||||
|
|
|
@ -7,11 +7,15 @@
|
|||
namespace chatterino {
|
||||
|
||||
class ChannelManager;
|
||||
class ColorScheme;
|
||||
|
||||
class WindowManager
|
||||
{
|
||||
public:
|
||||
explicit WindowManager(ChannelManager &_channelManager);
|
||||
explicit WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme);
|
||||
|
||||
ChannelManager &channelManager;
|
||||
ColorScheme &colorScheme;
|
||||
|
||||
void layoutVisibleChatWidgets(Channel *channel = nullptr);
|
||||
void repaintVisibleChatWidgets(Channel *channel = nullptr);
|
||||
|
@ -24,8 +28,6 @@ public:
|
|||
void save();
|
||||
|
||||
private:
|
||||
ChannelManager &channelManager;
|
||||
|
||||
std::mutex windowMutex;
|
||||
|
||||
// TODO(pajlada): Store as a value instead of a pointer
|
||||
|
|
Loading…
Reference in a new issue