removed appbase directory

This commit is contained in:
fourtf
2019-10-07 15:46:08 +02:00
parent 9f52564b9c
commit b1cbf09427
52 changed files with 126 additions and 286 deletions
-3
View File
@@ -1,3 +0,0 @@
# include appbase
include($$PWD/appbase/main.pro)
INCLUDEPATH += $$PWD/appbase
-34
View File
@@ -1,34 +0,0 @@
Language: Cpp
AccessModifierOffset: -1
AccessModifierOffset: -4
AlignEscapedNewlinesLeft: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakBeforeMultilineStrings: false
BasedOnStyle: Google
BraceWrapping: {
AfterNamespace: 'false'
AfterClass: 'true'
BeforeElse: 'true'
AfterControlStatement: 'true'
AfterFunction: 'true'
BeforeCatch: 'true'
}
BreakBeforeBraces: Custom
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
FixNamespaceComments: true
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: true
IndentPPDirectives: AfterHash
NamespaceIndentation: Inner
PointerBindsToType: false
SpacesBeforeTrailingComments: 2
Standard: Auto
ReflowComments: false
-128
View File
@@ -1,128 +0,0 @@
#include "BaseSettings.hpp"
#include <QDebug>
#include "util/Clamp.hpp"
namespace AB_NAMESPACE {
std::vector<std::weak_ptr<pajlada::Settings::SettingData>> _settings;
AB_SETTINGS_CLASS *AB_SETTINGS_CLASS::instance = nullptr;
void _actuallyRegisterSetting(
std::weak_ptr<pajlada::Settings::SettingData> setting)
{
_settings.push_back(setting);
}
AB_SETTINGS_CLASS::AB_SETTINGS_CLASS(const QString &settingsDirectory)
{
AB_SETTINGS_CLASS::instance = this;
QString settingsPath = settingsDirectory + "/settings.json";
// get global instance of the settings library
auto settingsInstance = pajlada::Settings::SettingManager::getInstance();
settingsInstance->load(qPrintable(settingsPath));
settingsInstance->setBackupEnabled(true);
settingsInstance->setBackupSlots(9);
settingsInstance->saveMethod =
pajlada::Settings::SettingManager::SaveMethod::SaveOnExit;
}
void AB_SETTINGS_CLASS::saveSnapshot()
{
rapidjson::Document *d = new rapidjson::Document(rapidjson::kObjectType);
rapidjson::Document::AllocatorType &a = d->GetAllocator();
for (const auto &weakSetting : _settings)
{
auto setting = weakSetting.lock();
if (!setting)
{
continue;
}
rapidjson::Value key(setting->getPath().c_str(), a);
auto curVal = setting->unmarshalJSON();
if (curVal == nullptr)
{
continue;
}
rapidjson::Value val;
val.CopyFrom(*curVal, a);
d->AddMember(key.Move(), val.Move(), a);
}
// log("Snapshot state: {}", rj::stringify(*d));
this->snapshot_.reset(d);
}
void AB_SETTINGS_CLASS::restoreSnapshot()
{
if (!this->snapshot_)
{
return;
}
const auto &snapshot = *(this->snapshot_.get());
if (!snapshot.IsObject())
{
return;
}
for (const auto &weakSetting : _settings)
{
auto setting = weakSetting.lock();
if (!setting)
{
continue;
}
const char *path = setting->getPath().c_str();
if (!snapshot.HasMember(path))
{
continue;
}
setting->marshalJSON(snapshot[path]);
}
}
float AB_SETTINGS_CLASS::getClampedUiScale() const
{
return clamp<float>(this->uiScale.getValue(), 0.2f, 10);
}
void AB_SETTINGS_CLASS::setClampedUiScale(float value)
{
this->uiScale.setValue(clamp<float>(value, 0.2f, 10));
}
#ifndef AB_CUSTOM_SETTINGS
Settings *getSettings()
{
static_assert(std::is_same_v<AB_SETTINGS_CLASS, Settings>,
"`AB_SETTINGS_CLASS` must be the same as `Settings`");
assert(AB_SETTINGS_CLASS::instance);
return AB_SETTINGS_CLASS::instance;
}
#endif
AB_SETTINGS_CLASS *getABSettings()
{
assert(AB_SETTINGS_CLASS::instance);
return AB_SETTINGS_CLASS::instance;
}
} // namespace AB_NAMESPACE
-52
View File
@@ -1,52 +0,0 @@
#ifndef AB_SETTINGS_H
#define AB_SETTINGS_H
#include <rapidjson/document.h>
#include <QString>
#include <memory>
#include <pajlada/settings/settingdata.hpp>
#include "common/ChatterinoSetting.hpp"
#ifdef AB_CUSTOM_SETTINGS
# define AB_SETTINGS_CLASS ABSettings
#else
# define AB_SETTINGS_CLASS Settings
#endif
namespace AB_NAMESPACE {
class Settings;
void _actuallyRegisterSetting(
std::weak_ptr<pajlada::Settings::SettingData> setting);
class AB_SETTINGS_CLASS
{
public:
AB_SETTINGS_CLASS(const QString &settingsDirectory);
void saveSnapshot();
void restoreSnapshot();
static AB_SETTINGS_CLASS *instance;
FloatSetting uiScale = {"/appearance/uiScale2", 1};
BoolSetting windowTopMost = {"/appearance/windowAlwaysOnTop", false};
float getClampedUiScale() const;
void setClampedUiScale(float value);
private:
std::unique_ptr<rapidjson::Document> snapshot_;
};
Settings *getSettings();
AB_SETTINGS_CLASS *getABSettings();
} // namespace AB_NAMESPACE
#ifdef CHATTERINO
# include "singletons/Settings.hpp"
#endif
#endif
-225
View File
@@ -1,225 +0,0 @@
#include "BaseTheme.hpp"
namespace AB_NAMESPACE {
namespace {
double getMultiplierByTheme(const QString &themeName)
{
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;
}
/*
else if (themeName == "Custom")
{
return getSettings()->customThemeMultiplier.getValue();
}
*/
return -0.8;
}
} // namespace
bool AB_THEME_CLASS::isLightTheme() const
{
return this->isLight_;
}
void AB_THEME_CLASS::update()
{
this->actuallyUpdate(this->themeHue,
getMultiplierByTheme(this->themeName.getValue()));
this->updated.invoke();
}
void AB_THEME_CLASS::actuallyUpdate(double hue, double multiplier)
{
this->isLight_ = multiplier > 0;
bool lightWin = isLight_;
// QColor themeColor = QColor::fromHslF(hue, 0.43, 0.5);
QColor themeColor = QColor::fromHslF(hue, 0.8, 0.5);
QColor themeColorNoSat = QColor::fromHslF(hue, 0, 0.5);
qreal sat = 0;
// 0.05;
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);
};
/// WINDOW
{
#ifdef Q_OS_LINUX
this->window.background = lightWin ? "#fff" : QColor(61, 60, 56);
#else
this->window.background = lightWin ? "#fff" : "#111";
#endif
QColor fg = this->window.text = lightWin ? "#000" : "#eee";
this->window.borderFocused = lightWin ? "#ccc" : themeColor;
this->window.borderUnfocused = lightWin ? "#ccc" : themeColorNoSat;
// Ubuntu style
// TODO: add setting for this
// TabText = QColor(210, 210, 210);
// TabBackground = QColor(61, 60, 56);
// TabHoverText = QColor(210, 210, 210);
// TabHoverBackground = QColor(73, 72, 68);
// message (referenced later)
this->messages.textColors.caret = //
this->messages.textColors.regular = isLight_ ? "#000" : "#fff";
QColor highlighted = lightWin ? QColor("#ff0000") : QColor("#ee6166");
/// TABS
if (lightWin)
{
this->tabs.regular = {
QColor("#444"),
{QColor("#fff"), QColor("#eee"), QColor("#fff")},
{QColor("#fff"), QColor("#fff"), QColor("#fff")}};
this->tabs.newMessage = {
QColor("#222"),
{QColor("#fff"), QColor("#eee"), QColor("#fff")},
{QColor("#bbb"), QColor("#bbb"), QColor("#bbb")}};
this->tabs.highlighted = {
fg,
{QColor("#fff"), QColor("#eee"), QColor("#fff")},
{highlighted, highlighted, highlighted}};
this->tabs.selected = {
QColor("#000"),
{QColor("#b4d7ff"), QColor("#b4d7ff"), QColor("#b4d7ff")},
{QColor("#00aeef"), QColor("#00aeef"), QColor("#00aeef")}};
}
else
{
this->tabs.regular = {
QColor("#aaa"),
{QColor("#252525"), QColor("#252525"), QColor("#252525")},
{QColor("#444"), QColor("#444"), QColor("#444")}};
this->tabs.newMessage = {
fg,
{QColor("#252525"), QColor("#252525"), QColor("#252525")},
{QColor("#888"), QColor("#888"), QColor("#888")}};
this->tabs.highlighted = {
fg,
{QColor("#252525"), QColor("#252525"), QColor("#252525")},
{highlighted, highlighted, highlighted}};
this->tabs.selected = {
QColor("#fff"),
{QColor("#555555"), QColor("#555555"), QColor("#555555")},
{QColor("#00aeef"), QColor("#00aeef"), QColor("#00aeef")}};
}
// scrollbar
this->scrollbars.highlights.highlight = QColor("#ee6166");
this->scrollbars.highlights.subscription = QColor("#C466FF");
// this->tabs.newMessage = {
// fg,
// {QBrush(blendColors(themeColor, "#ccc", 0.9), Qt::FDiagPattern),
// QBrush(blendColors(themeColor, "#ccc", 0.9), Qt::FDiagPattern),
// QBrush(blendColors(themeColorNoSat, "#ccc", 0.9),
// Qt::FDiagPattern)}};
// this->tabs.newMessage = {
// fg,
// {QBrush(blendColors(themeColor, "#666", 0.7),
// Qt::FDiagPattern),
// QBrush(blendColors(themeColor, "#666", 0.5),
// Qt::FDiagPattern),
// QBrush(blendColors(themeColorNoSat, "#666", 0.7),
// Qt::FDiagPattern)}};
// this->tabs.highlighted = {fg, {QColor("#777"),
// QColor("#777"), QColor("#666")}};
this->tabs.bottomLine = this->tabs.selected.backgrounds.regular.color();
} // namespace AB_NAMESPACE
// Split
bool flat = isLight_;
// Message
this->messages.textColors.link =
isLight_ ? QColor(66, 134, 244) : QColor(66, 134, 244);
this->messages.textColors.system = QColor(140, 127, 127);
this->messages.backgrounds.regular = getColor(0, sat, 1);
this->messages.backgrounds.alternate = getColor(0, sat, 0.96);
if (isLight_)
{
this->messages.backgrounds.highlighted =
blendColors(themeColor, this->messages.backgrounds.regular, 0.8);
}
else
{
// REMOVED
// this->messages.backgrounds.highlighted =
// QColor(getSettings()->highlightColor);
}
this->messages.backgrounds.subscription =
blendColors(QColor("#C466FF"), this->messages.backgrounds.regular, 0.7);
// this->messages.backgrounds.resub
// this->messages.backgrounds.whisper
this->messages.disabled = getColor(0, sat, 1, 0.6);
// this->messages.seperator =
// this->messages.seperatorInner =
// Scrollbar
this->scrollbars.background = QColor(0, 0, 0, 0);
// this->scrollbars.background = splits.background;
// this->scrollbars.background.setAlphaF(qreal(0.2));
this->scrollbars.thumb = getColor(0, sat, 0.70);
this->scrollbars.thumbSelected = getColor(0, sat, 0.65);
// tooltip
this->tooltip.background = QColor(0, 0, 0);
this->tooltip.text = QColor(255, 255, 255);
// Selection
this->messages.selection =
isLightTheme() ? QColor(0, 0, 0, 64) : QColor(255, 255, 255, 64);
}
QColor AB_THEME_CLASS::blendColors(const QColor &color1, const QColor &color2,
qreal ratio)
{
int r = int(color1.red() * (1 - ratio) + color2.red() * ratio);
int g = int(color1.green() * (1 - ratio) + color2.green() * ratio);
int b = int(color1.blue() * (1 - ratio) + color2.blue() * ratio);
return QColor(r, g, b, 255);
}
#ifndef AB_CUSTOM_THEME
Theme *getTheme()
{
static auto theme = [] {
auto theme = new Theme();
theme->update();
return theme;
}();
return theme;
}
#endif
} // namespace AB_NAMESPACE
-117
View File
@@ -1,117 +0,0 @@
#ifndef AB_THEME_H
#define AB_THEME_H
#include <QBrush>
#include <QColor>
#include <common/ChatterinoSetting.hpp>
#ifdef AB_CUSTOM_THEME
# define AB_THEME_CLASS BaseTheme
#else
# define AB_THEME_CLASS Theme
#endif
namespace AB_NAMESPACE {
class Theme;
class AB_THEME_CLASS
{
public:
bool isLightTheme() const;
struct TabColors {
QColor text;
struct {
QBrush regular;
QBrush hover;
QBrush unfocused;
} backgrounds;
struct {
QColor regular;
QColor hover;
QColor unfocused;
} line;
};
/// WINDOW
struct {
QColor background;
QColor text;
QColor borderUnfocused;
QColor borderFocused;
} window;
/// TABS
struct {
TabColors regular;
TabColors newMessage;
TabColors highlighted;
TabColors selected;
QColor border;
QColor bottomLine;
} tabs;
/// MESSAGES
struct {
struct {
QColor regular;
QColor caret;
QColor link;
QColor system;
} textColors;
struct {
QColor regular;
QColor alternate;
QColor highlighted;
QColor subscription;
// QColor whisper;
} backgrounds;
QColor disabled;
// QColor seperator;
// QColor seperatorInner;
QColor selection;
} messages;
/// SCROLLBAR
struct {
QColor background;
QColor thumb;
QColor thumbSelected;
struct {
QColor highlight;
QColor subscription;
} highlights;
} scrollbars;
/// TOOLTIP
struct {
QColor text;
QColor background;
} tooltip;
void update();
virtual void actuallyUpdate(double hue, double multiplier);
QColor blendColors(const QColor &color1, const QColor &color2, qreal ratio);
pajlada::Signals::NoArgSignal updated;
QStringSetting themeName{"/appearance/theme/name", "Dark"};
DoubleSetting themeHue{"/appearance/theme/hue", 0.0};
private:
bool isLight_ = false;
};
// Implemented in parent project if AB_CUSTOM_THEME is set.
// Otherwise implemented in BaseThemecpp
Theme *getTheme();
} // namespace AB_NAMESPACE
#ifdef CHATTERINO
# include "singletons/Theme.hpp"
#endif
#endif
-36
View File
@@ -1,36 +0,0 @@
#pragma once
#include <QHash>
#include <QString>
#include <functional>
#define QStringAlias(name) \
namespace chatterino { \
struct name { \
QString string; \
bool operator==(const name &other) const \
{ \
return this->string == other.string; \
} \
bool operator!=(const name &other) const \
{ \
return this->string != other.string; \
} \
}; \
} /* namespace chatterino */ \
namespace std { \
template <> \
struct hash<chatterino::name> { \
size_t operator()(const chatterino::name &s) const \
{ \
return qHash(s.string); \
} \
}; \
} /* namespace std */
QStringAlias(UserName);
QStringAlias(UserId);
QStringAlias(Url);
QStringAlias(Tooltip);
QStringAlias(EmoteId);
QStringAlias(EmoteName);
-12
View File
@@ -1,12 +0,0 @@
#include "common/ChatterinoSetting.hpp"
#include "BaseSettings.hpp"
namespace AB_NAMESPACE {
void _registerSetting(std::weak_ptr<pajlada::Settings::SettingData> setting)
{
_actuallyRegisterSetting(setting);
}
} // namespace AB_NAMESPACE
-88
View File
@@ -1,88 +0,0 @@
#pragma once
#include <QString>
#include <pajlada/settings.hpp>
namespace AB_NAMESPACE {
void _registerSetting(std::weak_ptr<pajlada::Settings::SettingData> setting);
template <typename Type>
class ChatterinoSetting : public pajlada::Settings::Setting<Type>
{
public:
ChatterinoSetting(const std::string &path)
: pajlada::Settings::Setting<Type>(path)
{
_registerSetting(this->getData());
}
ChatterinoSetting(const std::string &path, const Type &defaultValue)
: pajlada::Settings::Setting<Type>(path, defaultValue)
{
_registerSetting(this->getData());
}
template <typename T2>
ChatterinoSetting &operator=(const T2 &newValue)
{
this->setValue(newValue);
return *this;
}
ChatterinoSetting &operator=(Type &&newValue) noexcept
{
pajlada::Settings::Setting<Type>::operator=(newValue);
return *this;
}
using pajlada::Settings::Setting<Type>::operator==;
using pajlada::Settings::Setting<Type>::operator!=;
using pajlada::Settings::Setting<Type>::operator Type;
};
using BoolSetting = ChatterinoSetting<bool>;
using FloatSetting = ChatterinoSetting<float>;
using DoubleSetting = ChatterinoSetting<double>;
using IntSetting = ChatterinoSetting<int>;
using StringSetting = ChatterinoSetting<std::string>;
using QStringSetting = ChatterinoSetting<QString>;
template <typename Enum>
class EnumSetting
: public ChatterinoSetting<typename std::underlying_type<Enum>::type>
{
using Underlying = typename std::underlying_type<Enum>::type;
public:
using ChatterinoSetting<Underlying>::ChatterinoSetting;
EnumSetting(const std::string &path, const Enum &defaultValue)
: ChatterinoSetting<Underlying>(path, Underlying(defaultValue))
{
_registerSetting(this->getData());
}
template <typename T2>
EnumSetting<Enum> &operator=(Enum newValue)
{
this->setValue(Underlying(newValue));
return *this;
}
operator Enum()
{
return Enum(this->getValue());
}
Enum getEnum()
{
return Enum(this->getValue());
}
};
} // namespace AB_NAMESPACE
-82
View File
@@ -1,82 +0,0 @@
#pragma once
#include <type_traits>
namespace chatterino {
template <typename T, typename Q = typename std::underlying_type<T>::type>
class FlagsEnum
{
public:
FlagsEnum()
: value_(static_cast<T>(0))
{
}
FlagsEnum(T value)
: value_(value)
{
}
FlagsEnum(std::initializer_list<T> flags)
{
for (auto flag : flags)
{
this->set(flag);
}
}
bool operator==(const FlagsEnum<T> &other)
{
return this->value_ == other.value_;
}
bool operator!=(const FlagsEnum &other)
{
return this->value_ != other.value_;
}
void set(T flag)
{
reinterpret_cast<Q &>(this->value_) |= static_cast<Q>(flag);
}
void unset(T flag)
{
reinterpret_cast<Q &>(this->value_) &= ~static_cast<Q>(flag);
}
void set(T flag, bool value)
{
if (value)
this->set(flag);
else
this->unset(flag);
}
bool has(T flag) const
{
return static_cast<Q>(this->value_) & static_cast<Q>(flag);
}
bool hasAny(FlagsEnum flags) const
{
return static_cast<Q>(this->value_) & static_cast<Q>(flags.value_);
}
bool hasAll(FlagsEnum<T> flags) const
{
return (static_cast<Q>(this->value_) & static_cast<Q>(flags.value_)) &&
static_cast<Q>(flags->value);
}
bool hasNone(std::initializer_list<T> flags) const
{
return !this->hasAny(flags);
}
private:
T value_{};
};
} // namespace chatterino
-51
View File
@@ -1,51 +0,0 @@
#pragma once
namespace chatterino {
struct SuccessTag {
};
struct FailureTag {
};
const SuccessTag Success{};
const FailureTag Failure{};
class Outcome
{
public:
Outcome(SuccessTag)
: success_(true)
{
}
Outcome(FailureTag)
: success_(false)
{
}
explicit operator bool() const
{
return this->success_;
}
bool operator!() const
{
return !this->success_;
}
bool operator==(const Outcome &other) const
{
return this->success_ == other.success_;
}
bool operator!=(const Outcome &other) const
{
return !this->operator==(other);
}
private:
bool success_;
};
} // namespace chatterino
-26
View File
@@ -1,26 +0,0 @@
#pragma once
#include <boost/noncopyable.hpp>
namespace AB_NAMESPACE {
class Settings;
class Paths;
class Singleton : boost::noncopyable
{
public:
virtual ~Singleton() = default;
virtual void initialize(Settings &settings, Paths &paths)
{
(void)(settings);
(void)(paths);
}
virtual void save()
{
}
};
} // namespace AB_NAMESPACE
-21
View File
@@ -1,21 +0,0 @@
#pragma once
#include <QCoreApplication>
#include <QThread>
#include <cassert>
namespace AB_NAMESPACE {
static bool isGuiThread()
{
return QCoreApplication::instance()->thread() == QThread::currentThread();
}
static void assertInGuiThread()
{
#ifdef _DEBUG
assert(isGuiThread());
#endif
}
} // namespace AB_NAMESPACE
-21
View File
@@ -1,21 +0,0 @@
#include "Benchmark.hpp"
namespace AB_NAMESPACE {
BenchmarkGuard::BenchmarkGuard(const QString &_name)
: name_(_name)
{
timer_.start();
}
BenchmarkGuard::~BenchmarkGuard()
{
log("{} {} ms", this->name_, float(timer_.nsecsElapsed()) / 1000000.0f);
}
qreal BenchmarkGuard::getElapsedMs()
{
return qreal(timer_.nsecsElapsed()) / 1000000.0;
}
} // namespace AB_NAMESPACE
-22
View File
@@ -1,22 +0,0 @@
#pragma once
#include "debug/Log.hpp"
#include <QElapsedTimer>
#include <boost/noncopyable.hpp>
namespace AB_NAMESPACE {
class BenchmarkGuard : boost::noncopyable
{
public:
BenchmarkGuard(const QString &_name);
~BenchmarkGuard();
qreal getElapsedMs();
private:
QElapsedTimer timer_;
QString name_;
};
} // namespace AB_NAMESPACE
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include "util/Helpers.hpp"
#include <QDebug>
#include <QTime>
namespace AB_NAMESPACE {
template <typename... Args>
inline void log(const std::string &formatString, Args &&... args)
{
qDebug().noquote() << QTime::currentTime().toString("hh:mm:ss.zzz")
<< fS(formatString, std::forward<Args>(args)...).c_str();
}
template <typename... Args>
inline void log(const char *formatString, Args &&... args)
{
log(std::string(formatString), std::forward<Args>(args)...);
}
template <typename... Args>
inline void log(const QString &formatString, Args &&... args)
{
log(formatString.toStdString(), std::forward<Args>(args)...);
}
} // namespace AB_NAMESPACE
-31
View File
@@ -1,31 +0,0 @@
#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QStandardPaths>
#include "ABSettings.hpp"
#include "ABTheme.hpp"
#include "singletons/Fonts.hpp"
#include "widgets/BaseWindow.hpp"
int main(int argc, char *argv[])
{
using namespace AB_NAMESPACE;
QApplication a(argc, argv);
auto path =
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
qDebug() << path;
QDir(path).mkdir(".");
new Settings(path);
new Fonts();
BaseWindow widget(nullptr, BaseWindow::EnableCustomFrame);
widget.setWindowTitle("asdf");
widget.show();
return a.exec();
}
-100
View File
@@ -1,100 +0,0 @@
#-------------------------------------------------
#
# Project created by QtCreator 2018-11-19T19:03:22
#
#-------------------------------------------------
!AB_NOT_STANDALONE {
message(appbase standalone)
QT += core gui widgets
TARGET = main
TEMPLATE = app
SOURCES += main.cpp
# https://bugreports.qt.io/browse/QTBUG-27018
equals(QMAKE_CXX, "clang++")|equals(QMAKE_CXX, "g++") {
TARGET = bin/appbase
}
}
#DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000
macx {
# osx (Tested on macOS Mojave and High Sierra)
CONFIG += c++17
} else {
CONFIG += c++17
win32-msvc* {
# win32 msvc
QMAKE_CXXFLAGS += /std:c++17
} else {
# clang/gcc on linux or win32
QMAKE_CXXFLAGS += -std=c++17
}
}
debug {
DEFINES += QT_DEBUG
}
linux {
LIBS += -lrt
QMAKE_LFLAGS += -lrt
}
macx {
INCLUDEPATH += /usr/local/include
INCLUDEPATH += /usr/local/opt/openssl/include
LIBS += -L/usr/local/opt/openssl/lib
}
SOURCES += \
$$PWD/BaseSettings.cpp \
$$PWD/BaseTheme.cpp \
$$PWD/common/ChatterinoSetting.cpp \
$$PWD/debug/Benchmark.cpp \
$$PWD/singletons/Fonts.cpp \
$$PWD/util/FunctionEventFilter.cpp \
$$PWD/util/FuzzyConvert.cpp \
$$PWD/util/Helpers.cpp \
$$PWD/util/WindowsHelper.cpp \
$$PWD/widgets/BaseWidget.cpp \
$$PWD/widgets/BaseWindow.cpp \
$$PWD/widgets/Label.cpp \
$$PWD/widgets/TooltipWidget.cpp \
$$PWD/widgets/helper/Button.cpp \
$$PWD/widgets/helper/EffectLabel.cpp \
$$PWD/widgets/helper/SignalLabel.cpp \
$$PWD/widgets/helper/TitlebarButton.cpp \
HEADERS += \
$$PWD/BaseSettings.hpp \
$$PWD/BaseTheme.hpp \
$$PWD/common/ChatterinoSetting.hpp \
$$PWD/common/FlagsEnum.hpp \
$$PWD/common/Outcome.hpp \
$$PWD/common/Singleton.hpp \
$$PWD/debug/AssertInGuiThread.hpp \
$$PWD/debug/Benchmark.hpp \
$$PWD/debug/Log.hpp \
$$PWD/singletons/Fonts.hpp \
$$PWD/util/Clamp.hpp \
$$PWD/util/CombinePath.hpp \
$$PWD/util/DistanceBetweenPoints.hpp \
$$PWD/util/FunctionEventFilter.hpp \
$$PWD/util/FuzzyConvert.hpp \
$$PWD/util/Helpers.hpp \
$$PWD/util/LayoutHelper.hpp \
$$PWD/util/PostToThread.hpp \
$$PWD/util/RapidJsonSerializeQString.hpp \
$$PWD/util/Shortcut.hpp \
$$PWD/util/WindowsHelper.hpp \
$$PWD/widgets/BaseWidget.hpp \
$$PWD/widgets/BaseWindow.hpp \
$$PWD/widgets/Label.hpp \
$$PWD/widgets/TooltipWidget.hpp \
$$PWD/widgets/helper/Button.hpp \
$$PWD/widgets/helper/EffectLabel.hpp \
$$PWD/widgets/helper/SignalLabel.hpp \
$$PWD/widgets/helper/TitlebarButton.hpp \
-181
View File
@@ -1,181 +0,0 @@
#include "singletons/Fonts.hpp"
#include "BaseSettings.hpp"
#include "debug/AssertInGuiThread.hpp"
#include <QDebug>
#include <QtGlobal>
#ifdef CHATTERINO
# include "Application.hpp"
# include "singletons/WindowManager.hpp"
#endif
#ifdef Q_OS_WIN32
# define DEFAULT_FONT_FAMILY "Segoe UI"
# define DEFAULT_FONT_SIZE 10
#else
# ifdef Q_OS_MACOS
# define DEFAULT_FONT_FAMILY "Helvetica Neue"
# define DEFAULT_FONT_SIZE 12
# else
# define DEFAULT_FONT_FAMILY "Arial"
# define DEFAULT_FONT_SIZE 11
# endif
#endif
namespace AB_NAMESPACE {
namespace {
int getBoldness()
{
#ifdef CHATTERINO
return getSettings()->boldScale.getValue();
#else
return QFont::Bold;
#endif
}
} // namespace
Fonts *Fonts::instance = nullptr;
Fonts::Fonts()
: chatFontFamily("/appearance/currentFontFamily", DEFAULT_FONT_FAMILY)
, chatFontSize("/appearance/currentFontSize", DEFAULT_FONT_SIZE)
{
Fonts::instance = this;
this->fontsByType_.resize(size_t(FontStyle::EndType));
}
void Fonts::initialize(Settings &, Paths &)
{
this->chatFontFamily.connect(
[this]() {
assertInGuiThread();
for (auto &map : this->fontsByType_)
{
map.clear();
}
this->fontChanged.invoke();
},
false);
this->chatFontSize.connect(
[this]() {
assertInGuiThread();
for (auto &map : this->fontsByType_)
{
map.clear();
}
this->fontChanged.invoke();
},
false);
#ifdef CHATTERINO
getSettings()->boldScale.connect(
[this]() {
assertInGuiThread();
// REMOVED
getApp()->windows->incGeneration();
for (auto &map : this->fontsByType_)
{
map.clear();
}
this->fontChanged.invoke();
},
false);
#endif
} // namespace AB_NAMESPACE
QFont Fonts::getFont(FontStyle type, float scale)
{
return this->getOrCreateFontData(type, scale).font;
}
QFontMetrics Fonts::getFontMetrics(FontStyle type, float scale)
{
return this->getOrCreateFontData(type, scale).metrics;
}
Fonts::FontData &Fonts::getOrCreateFontData(FontStyle type, float scale)
{
assertInGuiThread();
assert(type < FontStyle::EndType);
auto &map = this->fontsByType_[size_t(type)];
// find element
auto it = map.find(scale);
if (it != map.end())
{
// return if found
return it->second;
}
// emplace new element
auto result = map.emplace(scale, this->createFontData(type, scale));
assert(result.second);
return result.first->second;
}
Fonts::FontData Fonts::createFontData(FontStyle type, float scale)
{
// check if it's a chat (scale the setting)
if (type >= FontStyle::ChatStart && type <= FontStyle::ChatEnd)
{
static std::unordered_map<FontStyle, ChatFontData> sizeScale{
{FontStyle::ChatSmall, {0.6f, false, QFont::Normal}},
{FontStyle::ChatMediumSmall, {0.8f, false, QFont::Normal}},
{FontStyle::ChatMedium, {1, false, QFont::Normal}},
{FontStyle::ChatMediumBold,
{1, false, QFont::Weight(getBoldness())}},
{FontStyle::ChatMediumItalic, {1, true, QFont::Normal}},
{FontStyle::ChatLarge, {1.2f, false, QFont::Normal}},
{FontStyle::ChatVeryLarge, {1.4f, false, QFont::Normal}},
};
sizeScale[FontStyle::ChatMediumBold] = {1, false,
QFont::Weight(getBoldness())};
auto data = sizeScale[type];
return FontData(
QFont(this->chatFontFamily.getValue(),
int(this->chatFontSize.getValue() * data.scale * scale),
data.weight, data.italic));
}
// normal Ui font (use pt size)
{
#ifdef Q_OS_MAC
constexpr float multiplier = 0.8f;
#else
constexpr float multiplier = 1.f;
#endif
static std::unordered_map<FontStyle, UiFontData> defaultSize{
{FontStyle::Tiny, {8, "Monospace", false, QFont::Normal}},
{FontStyle::UiMedium,
{int(9 * multiplier), DEFAULT_FONT_FAMILY, false, QFont::Normal}},
{FontStyle::UiMediumBold,
{int(9 * multiplier), DEFAULT_FONT_FAMILY, false, QFont::Bold}},
{FontStyle::UiTabs,
{int(9 * multiplier), DEFAULT_FONT_FAMILY, false, QFont::Normal}},
};
UiFontData &data = defaultSize[type];
QFont font(data.name, int(data.size * scale), data.weight, data.italic);
return FontData(font);
}
}
Fonts *getFonts()
{
return Fonts::instance;
}
} // namespace AB_NAMESPACE
-93
View File
@@ -1,93 +0,0 @@
#pragma once
#include "common/ChatterinoSetting.hpp"
#include "common/Singleton.hpp"
#include <QFont>
#include <QFontDatabase>
#include <QFontMetrics>
#include <boost/noncopyable.hpp>
#include <pajlada/signals/signal.hpp>
#include <array>
#include <unordered_map>
namespace AB_NAMESPACE {
class Settings;
class Paths;
enum class FontStyle : uint8_t {
Tiny,
ChatSmall,
ChatMediumSmall,
ChatMedium,
ChatMediumBold,
ChatMediumItalic,
ChatLarge,
ChatVeryLarge,
UiMedium,
UiMediumBold,
UiTabs,
// don't remove this value
EndType,
// make sure to update these values accordingly!
ChatStart = ChatSmall,
ChatEnd = ChatVeryLarge,
};
class Fonts final : public Singleton
{
public:
Fonts();
virtual void initialize(Settings &settings, Paths &paths) override;
// font data gets set in createFontData(...)
QFont getFont(FontStyle type, float scale);
QFontMetrics getFontMetrics(FontStyle type, float scale);
QStringSetting chatFontFamily;
IntSetting chatFontSize;
pajlada::Signals::NoArgSignal fontChanged;
static Fonts *instance;
private:
struct FontData {
FontData(const QFont &_font)
: font(_font)
, metrics(_font)
{
}
const QFont font;
const QFontMetrics metrics;
};
struct ChatFontData {
float scale;
bool italic;
QFont::Weight weight;
};
struct UiFontData {
float size;
const char *name;
bool italic;
QFont::Weight weight;
};
FontData &getOrCreateFontData(FontStyle type, float scale);
FontData createFontData(FontStyle type, float scale);
std::vector<std::unordered_map<float, FontData>> fontsByType_;
};
Fonts *getFonts();
} // namespace AB_NAMESPACE
-13
View File
@@ -1,13 +0,0 @@
#pragma once
namespace AB_NAMESPACE {
// http://en.cppreference.com/w/cpp/algorithm/clamp
template <class T>
constexpr const T &clamp(const T &v, const T &lo, const T &hi)
{
return assert(!(hi < lo)), (v < lo) ? lo : (hi < v) ? hi : v;
}
} // namespace AB_NAMESPACE
-14
View File
@@ -1,14 +0,0 @@
#pragma once
#include <QDir>
#include <QString>
namespace chatterino {
// https://stackoverflow.com/a/13014491
inline QString combinePath(const QString &a, const QString &b)
{
return QDir::cleanPath(a + QDir::separator() + b);
}
} // namespace chatterino
@@ -1,20 +0,0 @@
#pragma once
#include <QPointF>
#include <cmath>
namespace chatterino {
inline float distanceBetweenPoints(const QPointF &p1, const QPointF &p2)
{
QPointF tmp = p1 - p2;
float distance = 0.f;
distance += tmp.x() * tmp.x();
distance += tmp.y() * tmp.y();
return sqrt(distance);
}
} // namespace chatterino
-17
View File
@@ -1,17 +0,0 @@
#include "FunctionEventFilter.hpp"
namespace AB_NAMESPACE {
FunctionEventFilter::FunctionEventFilter(
QObject *parent, std::function<bool(QObject *, QEvent *)> function)
: QObject(parent)
, function_(std::move(function))
{
}
bool FunctionEventFilter::eventFilter(QObject *watched, QEvent *event)
{
return this->function_(watched, event);
}
} // namespace AB_NAMESPACE
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include <QEvent>
#include <QObject>
#include <functional>
namespace AB_NAMESPACE {
class FunctionEventFilter : public QObject
{
Q_OBJECT
public:
FunctionEventFilter(QObject *parent,
std::function<bool(QObject *, QEvent *)> function);
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
std::function<bool(QObject *, QEvent *)> function_;
};
} // namespace AB_NAMESPACE
-33
View File
@@ -1,33 +0,0 @@
#include "FuzzyConvert.hpp"
#include <QRegularExpression>
namespace chatterino {
int fuzzyToInt(const QString &str, int default_)
{
static auto intFinder = QRegularExpression("[0-9]+");
auto match = intFinder.match(str);
if (match.hasMatch())
{
return match.captured().toInt();
}
return default_;
}
float fuzzyToFloat(const QString &str, float default_)
{
static auto floatFinder = QRegularExpression("[0-9]+(\\.[0-9]+)?");
auto match = floatFinder.match(str);
if (match.hasMatch())
{
return match.captured().toFloat();
}
return default_;
}
} // namespace chatterino
-10
View File
@@ -1,10 +0,0 @@
#pragma once
#include <QString>
namespace chatterino {
int fuzzyToInt(const QString &str, int default_);
float fuzzyToFloat(const QString &str, float default_);
} // namespace chatterino
-38
View File
@@ -1,38 +0,0 @@
#include "Helpers.hpp"
#include <QUuid>
namespace AB_NAMESPACE {
QString generateUuid()
{
auto uuid = QUuid::createUuid();
return uuid.toString();
}
QString formatRichLink(const QString &url, bool file)
{
return QString("<a href=\"") + (file ? "file:///" : "") + url + "\">" +
url + "</a>";
}
QString formatRichNamedLink(const QString &url, const QString &name, bool file)
{
return QString("<a href=\"") + (file ? "file:///" : "") + url + "\">" +
name + "</a>";
}
QString shortenString(const QString &str, unsigned maxWidth)
{
auto shortened = QString(str);
if (str.size() > int(maxWidth))
{
shortened.resize(int(maxWidth));
shortened += "...";
}
return shortened;
}
} // namespace AB_NAMESPACE
-33
View File
@@ -1,33 +0,0 @@
#pragma once
#include <fmt/format.h>
#include <QString>
namespace AB_NAMESPACE {
template <typename... Args>
auto fS(Args &&... args)
{
return fmt::format(std::forward<Args>(args)...);
}
QString generateUuid();
QString formatRichLink(const QString &url, bool file = false);
QString formatRichNamedLink(const QString &url, const QString &name,
bool file = false);
QString shortenString(const QString &str, unsigned maxWidth = 50);
} // namespace AB_NAMESPACE
namespace fmt {
// format_arg for QString
inline void format_arg(BasicFormatter<char> &f, const char *&, const QString &v)
{
f.writer().write("{}", v.toStdString());
}
} // namespace fmt
-42
View File
@@ -1,42 +0,0 @@
#pragma once
#include <QLayout>
#include <QWidget>
#include <boost/variant.hpp>
namespace chatterino {
using LayoutItem = boost::variant<QWidget *, QLayout *>;
template <typename T>
T *makeLayout(std::initializer_list<LayoutItem> items)
{
auto t = new T;
for (auto &item : items)
{
switch (item.which())
{
case 0:
t->addItem(new QWidgetItem(boost::get<QWidget *>(item)));
break;
case 1:
t->addItem(boost::get<QLayout *>(item));
break;
}
}
return t;
}
template <typename T, typename With>
T *makeWidget(With with)
{
auto t = new T;
with(t);
return t;
}
} // namespace chatterino
-59
View File
@@ -1,59 +0,0 @@
#pragma once
#include <QCoreApplication>
#include <QRunnable>
#include <QThreadPool>
#include <functional>
#define async_exec(a) \
QThreadPool::globalInstance()->start(new LambdaRunnable(a));
namespace AB_NAMESPACE {
class LambdaRunnable : public QRunnable
{
public:
LambdaRunnable(std::function<void()> action)
{
this->action_ = action;
}
void run()
{
this->action_();
}
private:
std::function<void()> action_;
};
// Taken from
// https://stackoverflow.com/questions/21646467/how-to-execute-a-functor-or-a-lambda-in-a-given-thread-in-qt-gcd-style
// Qt 5/4 - preferred, has least allocations
template <typename F>
static void postToThread(F &&fun, QObject *obj = qApp)
{
struct Event : public QEvent {
using Fun = typename std::decay<F>::type;
Fun fun;
Event(Fun &&fun)
: QEvent(QEvent::None)
, fun(std::move(fun))
{
}
Event(const Fun &fun)
: QEvent(QEvent::None)
, fun(fun)
{
}
~Event() override
{
fun();
}
};
QCoreApplication::postEvent(obj, new Event(std::forward<F>(fun)));
}
} // namespace AB_NAMESPACE
@@ -1,45 +0,0 @@
#pragma once
#include <QString>
#include <pajlada/serialize.hpp>
namespace pajlada {
template <>
struct Serialize<QString> {
static rapidjson::Value get(const QString &value,
rapidjson::Document::AllocatorType &a)
{
return rapidjson::Value(value.toUtf8(), a);
}
};
template <>
struct Deserialize<QString> {
static QString get(const rapidjson::Value &value, bool *error = nullptr)
{
if (!value.IsString())
{
PAJLADA_REPORT_ERROR(error)
return QString{};
}
try
{
return QString::fromUtf8(value.GetString(),
value.GetStringLength());
}
catch (const std::exception &)
{
// int x = 5;
}
catch (...)
{
// int y = 5;
}
return QString{};
}
};
} // namespace pajlada
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include <QShortcut>
#include <QWidget>
namespace AB_NAMESPACE {
template <typename WidgetType, typename Func>
inline void createShortcut(WidgetType *w, const char *key, Func func)
{
auto s = new QShortcut(QKeySequence(key), w);
s->setContext(Qt::WidgetWithChildrenShortcut);
QObject::connect(s, &QShortcut::activated, w, func);
}
template <typename WidgetType, typename Func>
inline void createWindowShortcut(WidgetType *w, const char *key, Func func)
{
auto s = new QShortcut(QKeySequence(key), w);
s->setContext(Qt::WindowShortcut);
QObject::connect(s, &QShortcut::activated, w, func);
}
} // namespace AB_NAMESPACE
-86
View File
@@ -1,86 +0,0 @@
#include "WindowsHelper.hpp"
#include <QSettings>
#ifdef USEWINSDK
namespace AB_NAMESPACE {
typedef enum MONITOR_DPI_TYPE {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
typedef HRESULT(CALLBACK *GetDpiForMonitor_)(HMONITOR, MONITOR_DPI_TYPE, UINT *,
UINT *);
boost::optional<UINT> getWindowDpi(HWND hwnd)
{
static HINSTANCE shcore = LoadLibrary(L"Shcore.dll");
if (shcore != nullptr)
{
if (auto getDpiForMonitor =
GetDpiForMonitor_(GetProcAddress(shcore, "GetDpiForMonitor")))
{
HMONITOR monitor =
MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
UINT xScale, yScale;
getDpiForMonitor(monitor, MDT_DEFAULT, &xScale, &yScale);
return xScale;
}
}
return boost::none;
}
typedef HRESULT(CALLBACK *OleFlushClipboard_)();
void flushClipboard()
{
static HINSTANCE ole32 = LoadLibrary(L"Ole32.dll");
if (ole32 != nullptr)
{
if (auto oleFlushClipboard =
OleFlushClipboard_(GetProcAddress(ole32, "OleFlushClipboard")))
{
oleFlushClipboard();
}
}
}
constexpr const char *runKey =
"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
bool isRegisteredForStartup()
{
QSettings settings(runKey, QSettings::NativeFormat);
return !settings.value("Chatterino").toString().isEmpty();
}
void setRegisteredForStartup(bool isRegistered)
{
QSettings settings(runKey, QSettings::NativeFormat);
if (isRegistered)
{
auto exePath = QFileInfo(QCoreApplication::applicationFilePath())
.absoluteFilePath()
.replace('/', '\\');
settings.setValue("Chatterino", "\"" + exePath + "\" --autorun");
}
else
{
settings.remove("Chatterino");
}
}
} // namespace AB_NAMESPACE
#endif
-18
View File
@@ -1,18 +0,0 @@
#pragma once
#ifdef USEWINSDK
# include <Windows.h>
# include <boost/optional.hpp>
namespace AB_NAMESPACE {
boost::optional<UINT> getWindowDpi(HWND hwnd);
void flushClipboard();
bool isRegisteredForStartup();
void setRegisteredForStartup(bool isRegistered);
} // namespace AB_NAMESPACE
#endif
-164
View File
@@ -1,164 +0,0 @@
#include "widgets/BaseWidget.hpp"
#include "BaseSettings.hpp"
#include "BaseTheme.hpp"
#include "debug/Log.hpp"
#include "widgets/BaseWindow.hpp"
#include <QChildEvent>
#include <QDebug>
#include <QIcon>
#include <QLayout>
#include <QtGlobal>
namespace AB_NAMESPACE {
BaseWidget::BaseWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
// REMOVED
this->theme = getTheme();
this->signalHolder_.managedConnect(this->theme->updated, [this]() {
this->themeChangedEvent();
this->update();
});
}
float BaseWidget::scale() const
{
if (this->overrideScale_)
{
return this->overrideScale_.get();
}
else if (auto baseWidget = dynamic_cast<BaseWidget *>(this->window()))
{
return baseWidget->scale_;
}
else
{
return 1.f;
}
}
void BaseWidget::setScale(float value)
{
// update scale value
this->scale_ = value;
this->scaleChangedEvent(this->scale());
this->scaleChanged.invoke(this->scale());
this->setScaleIndependantSize(this->scaleIndependantSize());
}
void BaseWidget::setOverrideScale(boost::optional<float> value)
{
this->overrideScale_ = value;
this->setScale(this->scale());
}
boost::optional<float> BaseWidget::overrideScale() const
{
return this->overrideScale_;
}
QSize BaseWidget::scaleIndependantSize() const
{
return this->scaleIndependantSize_;
}
int BaseWidget::scaleIndependantWidth() const
{
return this->scaleIndependantSize_.width();
}
int BaseWidget::scaleIndependantHeight() const
{
return this->scaleIndependantSize_.height();
}
void BaseWidget::setScaleIndependantSize(int width, int height)
{
this->setScaleIndependantSize(QSize(width, height));
}
void BaseWidget::setScaleIndependantSize(QSize size)
{
this->scaleIndependantSize_ = size;
if (size.width() > 0)
{
this->setFixedWidth(int(size.width() * this->scale()));
}
if (size.height() > 0)
{
this->setFixedHeight(int(size.height() * this->scale()));
}
}
void BaseWidget::setScaleIndependantWidth(int value)
{
this->setScaleIndependantSize(
QSize(value, this->scaleIndependantSize_.height()));
}
void BaseWidget::setScaleIndependantHeight(int value)
{
this->setScaleIndependantSize(
QSize(this->scaleIndependantSize_.width(), value));
}
float BaseWidget::qtFontScale() const
{
if (auto window = dynamic_cast<BaseWindow *>(this->window()))
{
return this->scale() / window->nativeScale_;
}
else
{
return this->scale();
}
}
void BaseWidget::childEvent(QChildEvent *event)
{
if (event->added())
{
// add element if it's a basewidget
if (auto widget = dynamic_cast<BaseWidget *>(event->child()))
{
this->widgets_.push_back(widget);
}
}
else if (event->removed())
{
// find element to be removed
auto it = std::find_if(this->widgets_.begin(), this->widgets_.end(),
[&](auto &&x) { return x == event->child(); });
// remove if found
if (it != this->widgets_.end())
{
this->widgets_.erase(it);
}
}
}
void BaseWidget::showEvent(QShowEvent *)
{
this->setScale(this->scale());
this->themeChangedEvent();
}
void BaseWidget::scaleChangedEvent(float newDpi)
{
}
void BaseWidget::themeChangedEvent()
{
// Do any color scheme updates here
}
} // namespace AB_NAMESPACE
-59
View File
@@ -1,59 +0,0 @@
#pragma once
#include <QWidget>
#include <boost/optional.hpp>
#include <pajlada/signals/signal.hpp>
#include <pajlada/signals/signalholder.hpp>
namespace AB_NAMESPACE {
class Theme;
class BaseWindow;
class BaseWidget : public QWidget
{
Q_OBJECT
public:
explicit BaseWidget(QWidget *parent, Qt::WindowFlags f = Qt::WindowFlags());
virtual float scale() const;
pajlada::Signals::Signal<float> scaleChanged;
boost::optional<float> overrideScale() const;
void setOverrideScale(boost::optional<float>);
QSize scaleIndependantSize() const;
int scaleIndependantWidth() const;
int scaleIndependantHeight() const;
void setScaleIndependantSize(int width, int height);
void setScaleIndependantSize(QSize);
void setScaleIndependantWidth(int value);
void setScaleIndependantHeight(int value);
float qtFontScale() const;
protected:
virtual void childEvent(QChildEvent *) override;
virtual void showEvent(QShowEvent *) override;
virtual void scaleChangedEvent(float newScale);
virtual void themeChangedEvent();
void setScale(float value);
Theme *theme;
private:
float scale_{1.f};
boost::optional<float> overrideScale_;
QSize scaleIndependantSize_;
std::vector<BaseWidget *> widgets_;
pajlada::Signals::SignalHolder signalHolder_;
friend class BaseWindow;
};
} // namespace AB_NAMESPACE
File diff suppressed because it is too large Load Diff
-138
View File
@@ -1,138 +0,0 @@
#pragma once
#include "widgets/BaseWidget.hpp"
#include <functional>
#include <pajlada/signals/signalholder.hpp>
#include "common/FlagsEnum.hpp"
class QHBoxLayout;
struct tagMSG;
typedef struct tagMSG MSG;
namespace AB_NAMESPACE {
class Button;
class EffectLabel;
class TitleBarButton;
enum class TitleBarButtonStyle;
class BaseWindow : public BaseWidget
{
Q_OBJECT
public:
enum Flags {
None = 0,
EnableCustomFrame = 1,
Frameless = 2,
TopMost = 4,
DisableCustomScaling = 8,
FramelessDraggable = 16,
};
enum ActionOnFocusLoss { Nothing, Delete, Close, Hide };
explicit BaseWindow(FlagsEnum<Flags> flags_ = None,
QWidget *parent = nullptr);
void setInitialBounds(const QRect &bounds);
QRect getBounds();
QWidget *getLayoutContainer();
bool hasCustomWindowFrame();
TitleBarButton *addTitleBarButton(const TitleBarButtonStyle &style,
std::function<void()> onClicked);
EffectLabel *addTitleBarLabel(std::function<void()> onClicked);
void setStayInScreenRect(bool value);
bool getStayInScreenRect() const;
void setActionOnFocusLoss(ActionOnFocusLoss value);
ActionOnFocusLoss getActionOnFocusLoss() const;
void moveTo(QWidget *widget, QPoint point, bool offset = true);
virtual float scale() const override;
float qtFontScale() const;
pajlada::Signals::NoArgSignal closing;
static bool supportsCustomWindowFrame();
protected:
virtual bool nativeEvent(const QByteArray &eventType, void *message,
long *result) override;
virtual void scaleChangedEvent(float) override;
virtual void paintEvent(QPaintEvent *) override;
virtual void changeEvent(QEvent *) override;
virtual void leaveEvent(QEvent *) override;
virtual void resizeEvent(QResizeEvent *) override;
virtual void moveEvent(QMoveEvent *) override;
virtual void closeEvent(QCloseEvent *) override;
virtual void showEvent(QShowEvent *) override;
virtual void themeChangedEvent() override;
virtual bool event(QEvent *event) override;
virtual void wheelEvent(QWheelEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
QPointF movingRelativePos;
bool moving{};
void updateScale();
boost::optional<QColor> overrideBackgroundColor_;
private:
void init();
void moveIntoDesktopRect(QWidget *parent);
void calcButtonsSizes();
void drawCustomWindowFrame(QPainter &painter);
void onFocusLost();
bool handleDPICHANGED(MSG *msg);
bool handleSHOWWINDOW(MSG *msg);
bool handleNCCALCSIZE(MSG *msg, long *result);
bool handleSIZE(MSG *msg);
bool handleMOVE(MSG *msg);
bool handleNCHITTEST(MSG *msg, long *result);
bool enableCustomFrame_;
ActionOnFocusLoss actionOnFocusLoss_ = Nothing;
bool frameless_;
bool stayInScreenRect_ = false;
bool shown_ = false;
FlagsEnum<Flags> flags_;
float nativeScale_ = 1;
struct {
QLayout *windowLayout = nullptr;
QHBoxLayout *titlebarBox = nullptr;
QWidget *titleLabel = nullptr;
TitleBarButton *minButton = nullptr;
TitleBarButton *maxButton = nullptr;
TitleBarButton *exitButton = nullptr;
QWidget *layoutBase = nullptr;
std::vector<Button *> buttons;
} ui_;
#ifdef USEWINSDK
QRect initalBounds_;
QRect currentBounds_;
QRect nextBounds_;
QTimer useNextBounds_;
bool isNotMinimizedOrMaximized_{};
#endif
pajlada::Signals::SignalHolder connections_;
std::vector<pajlada::Signals::ScopedConnection> managedConnections_;
friend class BaseWidget;
};
} // namespace AB_NAMESPACE
-140
View File
@@ -1,140 +0,0 @@
#include "Label.hpp"
#include <QPainter>
namespace AB_NAMESPACE {
Label::Label(QString text, FontStyle style)
: Label(nullptr, text, style)
{
}
Label::Label(BaseWidget *parent, QString text, FontStyle style)
: BaseWidget(parent)
, text_(text)
, fontStyle_(style)
{
this->connections_.managedConnect(getFonts()->fontChanged,
[this] { this->updateSize(); });
}
const QString &Label::getText() const
{
return this->text_;
}
void Label::setText(const QString &text)
{
if (this->text_ != text)
{
this->text_ = text;
this->updateSize();
this->update();
}
}
FontStyle Label::getFontStyle() const
{
return this->fontStyle_;
}
bool Label::getCentered() const
{
return this->centered_;
}
void Label::setCentered(bool centered)
{
this->centered_ = centered;
this->updateSize();
}
bool Label::getHasOffset() const
{
return this->hasOffset_;
}
void Label::setHasOffset(bool hasOffset)
{
this->hasOffset_ = hasOffset;
this->updateSize();
}
void Label::setFontStyle(FontStyle style)
{
this->fontStyle_ = style;
this->updateSize();
}
void Label::scaleChangedEvent(float scale)
{
this->updateSize();
}
QSize Label::sizeHint() const
{
return this->preferedSize_;
}
QSize Label::minimumSizeHint() const
{
return this->preferedSize_;
}
void Label::paintEvent(QPaintEvent *)
{
QPainter painter(this);
qreal deviceDpi =
#ifdef Q_OS_WIN
this->devicePixelRatioF();
#else
1.0;
#endif
QFontMetrics metrics = getFonts()->getFontMetrics(
this->getFontStyle(),
this->scale() * 96.f / this->logicalDpiX() * deviceDpi);
painter.setFont(getFonts()->getFont(
this->getFontStyle(),
this->scale() * 96.f / this->logicalDpiX() * deviceDpi));
int offset = this->getOffset();
// draw text
QRect textRect(offset, 0, this->width() - offset - offset, this->height());
int width = metrics.width(this->text_);
Qt::Alignment alignment = !this->centered_ || width > textRect.width()
? Qt::AlignLeft | Qt::AlignVCenter
: Qt::AlignCenter;
painter.setBrush(this->palette().windowText());
QTextOption option(alignment);
option.setWrapMode(QTextOption::NoWrap);
painter.drawText(textRect, this->text_, option);
#if 0
painter.setPen(QColor(255, 0, 0));
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
#endif
}
void Label::updateSize()
{
QFontMetrics metrics =
getFonts()->getFontMetrics(this->fontStyle_, this->scale());
int width = metrics.width(this->text_) + (2 * this->getOffset());
int height = metrics.height();
this->preferedSize_ = QSize(width, height);
this->updateGeometry();
}
int Label::getOffset()
{
return this->hasOffset_ ? int(8 * this->scale()) : 0;
}
} // namespace AB_NAMESPACE
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#include "singletons/Fonts.hpp"
#include "widgets/BaseWidget.hpp"
#include <pajlada/signals/signalholder.hpp>
namespace AB_NAMESPACE {
class Label : public BaseWidget
{
public:
explicit Label(QString text = QString(),
FontStyle style = FontStyle::UiMedium);
explicit Label(BaseWidget *parent, QString text = QString(),
FontStyle style = FontStyle::UiMedium);
const QString &getText() const;
void setText(const QString &text);
FontStyle getFontStyle() const;
void setFontStyle(FontStyle style);
bool getCentered() const;
void setCentered(bool centered);
bool getHasOffset() const;
void setHasOffset(bool hasOffset);
protected:
virtual void scaleChangedEvent(float scale_) override;
virtual void paintEvent(QPaintEvent *) override;
virtual QSize sizeHint() const override;
virtual QSize minimumSizeHint() const override;
private:
void updateSize();
int getOffset();
QString text_;
FontStyle fontStyle_;
QSize preferedSize_;
bool centered_ = false;
bool hasOffset_ = true;
pajlada::Signals::SignalHolder connections_;
};
} // namespace AB_NAMESPACE
-122
View File
@@ -1,122 +0,0 @@
#include "TooltipWidget.hpp"
#include "BaseTheme.hpp"
#include "singletons/Fonts.hpp"
#include <QDebug>
#include <QDesktopWidget>
#include <QStyle>
#include <QVBoxLayout>
#ifdef USEWINSDK
# include <Windows.h>
#endif
namespace AB_NAMESPACE {
TooltipWidget *TooltipWidget::getInstance()
{
static TooltipWidget *tooltipWidget = new TooltipWidget();
return tooltipWidget;
}
TooltipWidget::TooltipWidget(BaseWidget *parent)
: BaseWindow(BaseWindow::TopMost, parent)
, displayImage_(new QLabel())
, displayText_(new QLabel())
{
this->setStyleSheet("color: #fff; background: rgba(11, 11, 11, 0.8)");
this->setAttribute(Qt::WA_TranslucentBackground);
//this->setWindowOpacity(0.8);
this->updateFont();
this->setStayInScreenRect(true);
this->setAttribute(Qt::WA_ShowWithoutActivating);
this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint |
Qt::X11BypassWindowManagerHint |
Qt::BypassWindowManagerHint);
displayImage_->hide();
displayImage_->setAlignment(Qt::AlignHCenter);
displayImage_->setStyleSheet("background: transparent");
displayText_->setAlignment(Qt::AlignHCenter);
displayText_->setText("tooltip text");
displayText_->setStyleSheet("background: transparent");
auto layout = new QVBoxLayout();
layout->setContentsMargins(10, 5, 10, 5);
layout->addWidget(displayImage_);
layout->addWidget(displayText_);
this->setLayout(layout);
this->fontChangedConnection_ =
getFonts()->fontChanged.connect([this] { this->updateFont(); });
}
TooltipWidget::~TooltipWidget()
{
this->fontChangedConnection_.disconnect();
}
#ifdef USEWINSDK
void TooltipWidget::raise()
{
::SetWindowPos(HWND(this->winId()), HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
#endif
void TooltipWidget::themeChangedEvent()
{
// this->setStyleSheet("color: #fff; background: #000");
}
void TooltipWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(this->rect(), QColor(0, 0, 0, int(0.8 * 255)));
}
void TooltipWidget::scaleChangedEvent(float)
{
this->updateFont();
}
void TooltipWidget::updateFont()
{
this->setFont(
getFonts()->getFont(FontStyle::ChatMediumSmall, this->scale()));
}
void TooltipWidget::setText(QString text)
{
this->displayText_->setText(text);
}
void TooltipWidget::setWordWrap(bool wrap)
{
this->displayText_->setWordWrap(wrap);
}
void TooltipWidget::clearImage()
{
this->displayImage_->hide();
}
void TooltipWidget::setImage(QPixmap image)
{
this->displayImage_->show();
this->displayImage_->setPixmap(image);
}
void TooltipWidget::changeEvent(QEvent *)
{
// clear parents event
}
void TooltipWidget::leaveEvent(QEvent *)
{
// clear parents event
}
} // namespace AB_NAMESPACE
-45
View File
@@ -1,45 +0,0 @@
#pragma once
#include "widgets/BaseWindow.hpp"
#include <QLabel>
#include <QWidget>
#include <pajlada/signals/signal.hpp>
namespace AB_NAMESPACE {
class TooltipWidget : public BaseWindow
{
Q_OBJECT
public:
static TooltipWidget *getInstance();
TooltipWidget(BaseWidget *parent = nullptr);
~TooltipWidget() override;
void setText(QString text);
void setWordWrap(bool wrap);
void clearImage();
void setImage(QPixmap image);
#ifdef USEWINSDK
void raise();
#endif
protected:
void changeEvent(QEvent *) override;
void leaveEvent(QEvent *) override;
void themeChangedEvent() override;
void scaleChangedEvent(float) override;
void paintEvent(QPaintEvent *) override;
private:
void updateFont();
QLabel *displayImage_;
QLabel *displayText_;
pajlada::Signals::Connection fontChangedConnection_;
};
} // namespace AB_NAMESPACE
-343
View File
@@ -1,343 +0,0 @@
#include "Button.hpp"
#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include <QPainter>
#include "BaseTheme.hpp"
#include "util/FunctionEventFilter.hpp"
namespace AB_NAMESPACE {
Button::Button(BaseWidget *parent)
: BaseWidget(parent)
{
connect(&effectTimer_, &QTimer::timeout, this,
&Button::onMouseEffectTimeout);
this->effectTimer_.setInterval(20);
this->effectTimer_.start();
this->setMouseTracking(true);
}
void Button::setMouseEffectColor(boost::optional<QColor> color)
{
this->mouseEffectColor_ = color;
}
void Button::setPixmap(const QPixmap &_pixmap)
{
this->pixmap_ = _pixmap;
this->update();
}
const QPixmap &Button::getPixmap() const
{
return this->pixmap_;
}
void Button::setDim(Dim value)
{
this->dimPixmap_ = value;
this->update();
}
Button::Dim Button::getDim() const
{
return this->dimPixmap_;
}
void Button::setEnable(bool value)
{
this->enabled_ = value;
this->update();
}
bool Button::getEnable() const
{
return this->enabled_;
}
void Button::setEnableMargin(bool value)
{
this->enableMargin_ = value;
this->update();
}
bool Button::getEnableMargin() const
{
return this->enableMargin_;
}
qreal Button::getCurrentDimAmount() const
{
if (this->dimPixmap_ == Dim::None || this->mouseOver_)
return 1;
else if (this->dimPixmap_ == Dim::Some)
return 0.7;
else
return 0.15;
}
void Button::setBorderColor(const QColor &color)
{
this->borderColor_ = color;
this->update();
}
const QColor &Button::getBorderColor() const
{
return this->borderColor_;
}
void Button::setMenu(std::unique_ptr<QMenu> menu)
{
this->menu_ = std::move(menu);
this->menu_->installEventFilter(
new FunctionEventFilter(this, [this](QObject *, QEvent *event) {
if (event->type() == QEvent::Hide)
{
QTimer::singleShot(20, this,
[this] { this->menuVisible_ = false; });
}
return false;
}));
}
void Button::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
if (!this->pixmap_.isNull())
{
painter.setOpacity(this->getCurrentDimAmount());
QRect rect = this->rect();
int margin = this->height() < 22 * this->scale() ? 3 : 6;
int s = this->enableMargin_ ? int(margin * this->scale()) : 0;
rect.moveLeft(s);
rect.setRight(rect.right() - s - s);
rect.moveTop(s);
rect.setBottom(rect.bottom() - s - s);
painter.drawPixmap(rect, this->pixmap_);
painter.setOpacity(1);
}
this->fancyPaint(painter);
if (this->borderColor_.isValid())
{
painter.setRenderHint(QPainter::Antialiasing, false);
painter.setPen(this->borderColor_);
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
}
}
void Button::fancyPaint(QPainter &painter)
{
if (!this->enabled_)
{
return;
}
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setRenderHint(QPainter::Antialiasing);
QColor c;
if (this->mouseEffectColor_)
{
c = this->mouseEffectColor_.get();
}
else
{
c = this->theme->isLightTheme() ? QColor(0, 0, 0)
: QColor(255, 255, 255);
}
if (this->hoverMultiplier_ > 0)
{
QRadialGradient gradient(QPointF(mousePos_), this->width() / 2);
gradient.setColorAt(0, QColor(c.red(), c.green(), c.blue(),
int(50 * this->hoverMultiplier_)));
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(),
int(40 * this->hoverMultiplier_)));
painter.fillRect(this->rect(), gradient);
}
for (auto effect : this->clickEffects_)
{
QRadialGradient gradient(effect.position.x(), effect.position.y(),
effect.progress * qreal(width()) * 2,
effect.position.x(), effect.position.y());
gradient.setColorAt(0, QColor(c.red(), c.green(), c.blue(),
int((1 - effect.progress) * 95)));
gradient.setColorAt(0.9999, QColor(c.red(), c.green(), c.blue(),
int((1 - effect.progress) * 95)));
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(), int(0)));
painter.fillRect(this->rect(), gradient);
}
}
void Button::enterEvent(QEvent *)
{
this->mouseOver_ = true;
}
void Button::leaveEvent(QEvent *)
{
this->mouseOver_ = false;
}
void Button::mousePressEvent(QMouseEvent *event)
{
if (!this->enabled_)
{
return;
}
if (event->button() != Qt::LeftButton)
{
return;
}
this->clickEffects_.push_back(ClickEffect(event->pos()));
this->mouseDown_ = true;
emit this->leftMousePress();
if (this->menu_ && !this->menuVisible_)
{
QTimer::singleShot(80, this, [this] { this->showMenu(); });
this->mouseDown_ = false;
this->mouseOver_ = false;
}
}
void Button::mouseReleaseEvent(QMouseEvent *event)
{
if (!this->enabled_)
return;
if (event->button() == Qt::LeftButton)
{
this->mouseDown_ = false;
if (this->rect().contains(event->pos()))
emit leftClicked();
}
emit clicked(event->button());
}
void Button::mouseMoveEvent(QMouseEvent *event)
{
if (this->enabled_)
{
this->mousePos_ = event->pos();
this->update();
}
}
void Button::onMouseEffectTimeout()
{
bool performUpdate = false;
if (selected_)
{
if (this->hoverMultiplier_ != 0)
{
this->hoverMultiplier_ =
std::max(0.0, this->hoverMultiplier_ - 0.1);
performUpdate = true;
}
}
else if (mouseOver_)
{
if (this->hoverMultiplier_ != 1)
{
this->hoverMultiplier_ =
std::min(1.0, this->hoverMultiplier_ + 0.5);
performUpdate = true;
}
}
else
{
if (this->hoverMultiplier_ != 0)
{
this->hoverMultiplier_ =
std::max(0.0, this->hoverMultiplier_ - 0.3);
performUpdate = true;
}
}
if (this->clickEffects_.size() != 0)
{
performUpdate = true;
for (auto it = this->clickEffects_.begin();
it != this->clickEffects_.end();)
{
it->progress += mouseDown_ ? 0.02 : 0.07;
if (it->progress >= 1.0)
{
it = this->clickEffects_.erase(it);
}
else
{
it++;
}
}
}
if (performUpdate)
{
update();
}
}
void Button::showMenu()
{
if (!this->menu_)
return;
auto point = [this] {
auto bounds = QApplication::desktop()->availableGeometry(this);
auto point = this->mapToGlobal(
QPoint(this->width() - this->menu_->width(), this->height()));
if (point.y() + this->menu_->height() > bounds.bottom())
{
point.setY(point.y() - this->menu_->height() - this->height());
}
return point;
};
this->menu_->popup(point());
this->menu_->move(point());
this->menuVisible_ = true;
}
} // namespace AB_NAMESPACE
-91
View File
@@ -1,91 +0,0 @@
#pragma once
#include <boost/optional.hpp>
#include "widgets/BaseWidget.hpp"
#include <QMenu>
#include <QMouseEvent>
#include <QPainter>
#include <QPoint>
#include <QTimer>
#include <QWidget>
namespace AB_NAMESPACE {
class Button : public BaseWidget
{
Q_OBJECT
struct ClickEffect {
double progress = 0.0;
QPoint position;
ClickEffect(QPoint _position)
: position(_position)
{
}
};
public:
enum class Dim { None, Some, Lots };
Button(BaseWidget *parent = nullptr);
void setMouseEffectColor(boost::optional<QColor> color);
void setPixmap(const QPixmap &pixmap_);
const QPixmap &getPixmap() const;
void setDim(Dim value);
Dim getDim() const;
qreal getCurrentDimAmount() const;
void setEnable(bool value);
bool getEnable() const;
void setEnableMargin(bool value);
bool getEnableMargin() const;
void setBorderColor(const QColor &color);
const QColor &getBorderColor() const;
void setMenu(std::unique_ptr<QMenu> menu);
signals:
void leftClicked();
void clicked(Qt::MouseButton button);
void leftMousePress();
protected:
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);
bool enabled_{true};
bool selected_{false};
bool mouseOver_{false};
bool mouseDown_{false};
bool menuVisible_{false};
private:
void onMouseEffectTimeout();
void showMenu();
QColor borderColor_{};
QPixmap pixmap_{};
Dim dimPixmap_{Dim::Some};
bool enableMargin_{true};
QPoint mousePos_{};
double hoverMultiplier_{0.0};
QTimer effectTimer_{};
std::vector<ClickEffect> clickEffects_{};
boost::optional<QColor> mouseEffectColor_{};
std::unique_ptr<QMenu> menu_{};
};
} // namespace AB_NAMESPACE
@@ -1,43 +0,0 @@
#include "widgets/helper/EffectLabel.hpp"
#include <QBrush>
#include <QPainter>
namespace AB_NAMESPACE {
EffectLabel::EffectLabel(BaseWidget *parent, int spacing)
: Button(parent)
, label_(this)
{
setLayout(&this->hbox_);
this->label_.setAlignment(Qt::AlignCenter);
this->hbox_.setMargin(0);
this->hbox_.addSpacing(spacing);
this->hbox_.addWidget(&this->label_);
this->hbox_.addSpacing(spacing);
}
EffectLabel2::EffectLabel2(BaseWidget *parent, int padding)
: Button(parent)
, label_(this)
{
auto *hbox = new QHBoxLayout(this);
this->setLayout(hbox);
// this->label_.setAlignment(Qt::AlignCenter);
this->label_.setCentered(true);
hbox->setMargin(0);
// hbox.addSpacing(spacing);
hbox->addWidget(&this->label_);
// hbox.addSpacing(spacing);
}
Label &EffectLabel2::getLabel()
{
return this->label_;
}
} // namespace AB_NAMESPACE
@@ -1,41 +0,0 @@
#pragma once
#include "widgets/BaseWidget.hpp"
#include "widgets/Label.hpp"
#include "widgets/helper/Button.hpp"
#include "widgets/helper/SignalLabel.hpp"
#include <QHBoxLayout>
#include <QLabel>
#include <QPaintEvent>
#include <QWidget>
namespace AB_NAMESPACE {
class EffectLabel : public Button
{
public:
explicit EffectLabel(BaseWidget *parent = nullptr, int spacing = 6);
SignalLabel &getLabel()
{
return this->label_;
}
private:
QHBoxLayout hbox_;
SignalLabel label_;
};
class EffectLabel2 : public Button
{
public:
explicit EffectLabel2(BaseWidget *parent = nullptr, int padding = 6);
Label &getLabel();
private:
Label label_;
};
} // namespace AB_NAMESPACE
@@ -1,41 +0,0 @@
#include "widgets/helper/SignalLabel.hpp"
namespace AB_NAMESPACE {
SignalLabel::SignalLabel(QWidget *parent, Qt::WindowFlags f)
: QLabel(parent, f)
{
}
void SignalLabel::mouseDoubleClickEvent(QMouseEvent *ev)
{
emit this->mouseDoubleClick(ev);
}
void SignalLabel::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
emit mouseDown();
}
event->ignore();
}
void SignalLabel::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
emit mouseUp();
}
event->ignore();
}
void SignalLabel::mouseMoveEvent(QMouseEvent *event)
{
emit this->mouseMove(event);
event->ignore();
}
} // namespace AB_NAMESPACE
@@ -1,32 +0,0 @@
#pragma once
#include <QFlags>
#include <QLabel>
#include <QMouseEvent>
#include <QWidget>
namespace AB_NAMESPACE {
class SignalLabel : public QLabel
{
Q_OBJECT
public:
explicit SignalLabel(QWidget *parent = nullptr, Qt::WindowFlags f = 0);
virtual ~SignalLabel() override = default;
signals:
void mouseDoubleClick(QMouseEvent *ev);
void mouseDown();
void mouseUp();
void mouseMove(QMouseEvent *event);
protected:
void mouseDoubleClickEvent(QMouseEvent *ev) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
};
} // namespace AB_NAMESPACE
@@ -1,134 +0,0 @@
#include "TitlebarButton.hpp"
#include "BaseTheme.hpp"
namespace AB_NAMESPACE {
TitleBarButton::TitleBarButton()
: Button(nullptr)
{
}
TitleBarButtonStyle TitleBarButton::getButtonStyle() const
{
return this->style_;
}
void TitleBarButton::setButtonStyle(TitleBarButtonStyle _style)
{
this->style_ = _style;
this->update();
}
void TitleBarButton::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setOpacity(this->getCurrentDimAmount());
QColor color = this->theme->window.text;
QColor background = this->theme->window.background;
int xD = this->height() / 3;
int centerX = this->width() / 2;
painter.setRenderHint(QPainter::Antialiasing, false);
switch (this->style_)
{
case TitleBarButtonStyle::Minimize:
{
painter.fillRect(centerX - xD / 2, xD * 3 / 2, xD, 1, color);
break;
}
case TitleBarButtonStyle::Maximize:
{
painter.setPen(color);
painter.drawRect(centerX - xD / 2, xD, xD - 1, xD - 1);
break;
}
case TitleBarButtonStyle::Unmaximize:
{
int xD2 = xD * 1 / 5;
int xD3 = xD * 4 / 5;
painter.drawRect(centerX - xD / 2 + xD2, xD, xD3, xD3);
painter.fillRect(centerX - xD / 2, xD + xD2, xD3, xD3,
this->theme->window.background);
painter.drawRect(centerX - xD / 2, xD + xD2, xD3, xD3);
break;
}
case TitleBarButtonStyle::Close:
{
QRect rect(centerX - xD / 2, xD, xD - 1, xD - 1);
painter.setPen(QPen(color, 1));
painter.drawLine(rect.topLeft(), rect.bottomRight());
painter.drawLine(rect.topRight(), rect.bottomLeft());
break;
}
case TitleBarButtonStyle::User:
{
color = "#999";
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
auto a = xD / 3;
QPainterPath path;
painter.save();
painter.translate(3, 3);
path.arcMoveTo(a, 4 * a, 6 * a, 6 * a, 0);
path.arcTo(a, 4 * a, 6 * a, 6 * a, 0, 180);
painter.fillPath(path, color);
painter.setBrush(background);
painter.drawEllipse(2 * a, 1 * a, 4 * a, 4 * a);
painter.setBrush(color);
painter.drawEllipse(2.5 * a, 1.5 * a, 3 * a + 1, 3 * a);
painter.restore();
break;
}
case TitleBarButtonStyle::Settings:
{
color = "#999";
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.save();
painter.translate(3, 3);
auto a = xD / 3;
QPainterPath path;
path.arcMoveTo(a, a, 6 * a, 6 * a, 0 - (360 / 32.0));
for (int i = 0; i < 8; i++)
{
path.arcTo(a, a, 6 * a, 6 * a, i * (360 / 8.0) - (360 / 32.0),
(360 / 32.0));
path.arcTo(2 * a, 2 * a, 4 * a, 4 * a,
i * (360 / 8.0) + (360 / 32.0), (360 / 32.0));
}
painter.strokePath(path, color);
painter.fillPath(path, color);
painter.setBrush(background);
painter.drawEllipse(3 * a, 3 * a, 2 * a, 2 * a);
painter.restore();
break;
}
default:;
}
Button::paintEvent(event);
// this->fancyPaint(painter);
}
} // namespace AB_NAMESPACE
@@ -1,32 +0,0 @@
#pragma once
#include "widgets/helper/Button.hpp"
namespace AB_NAMESPACE {
enum class TitleBarButtonStyle {
None = 0,
Minimize = 1,
Maximize = 2,
Unmaximize = 4,
Close = 8,
User = 16,
Settings = 32
};
class TitleBarButton : public Button
{
public:
TitleBarButton();
TitleBarButtonStyle getButtonStyle() const;
void setButtonStyle(TitleBarButtonStyle style_);
protected:
void paintEvent(QPaintEvent *) override;
private:
TitleBarButtonStyle style_;
};
} // namespace AB_NAMESPACE