WIP Qt6 bits

This commit is contained in:
Nicolas Werner 2021-12-28 06:30:51 +01:00
parent 7c61c4a9c9
commit 4011260d37
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
40 changed files with 72 additions and 637 deletions

View file

@ -9,7 +9,7 @@ project(
compiler = meson.get_compiler('cpp') compiler = meson.get_compiler('cpp')
qt5 = import('qt5') qt5 = import('qt6')
qt5_modules = ['Core', 'Gui', 'Qml', 'Quick', 'QuickWidgets', 'Widgets', 'Multimedia', 'Svg'] qt5_modules = ['Core', 'Gui', 'Qml', 'Quick', 'QuickWidgets', 'Widgets', 'Multimedia', 'Svg']
if target_machine.system() == 'windows' if target_machine.system() == 'windows'
#qt5_modules += 'WinMain' #qt5_modules += 'WinMain'
@ -19,7 +19,7 @@ else
qt5_modules += 'DBus' qt5_modules += 'DBus'
endif endif
qt5_dep = dependency('qt5', modules: qt5_modules, include_type: 'system') qt5_dep = dependency('qt6', modules: qt5_modules, include_type: 'system')
inc = include_directories('src', 'includes', 'third_party/cpp-httplib-0.5.12') inc = include_directories('src', 'includes', 'third_party/cpp-httplib-0.5.12')
@ -61,28 +61,9 @@ if not lmdbxx_dep.found()
endif endif
deps += lmdbxx_dep deps += lmdbxx_dep
qtkeychain_dep = dependency('Qt5Keychain', required: get_option('wrap_mode') == 'nofallback') qtkeychain_dep = dependency('Qt6Keychain', required: get_option('wrap_mode') == 'nofallback')
if (not qtkeychain_dep.found() if (not qtkeychain_dep.found())
or get_option('wrap_mode') == 'forcefallback' qtkeychain_dep = dependency('qtkeychain')
or 'QtKeychain' in get_option('force_fallback_for'))
cmake = import('cmake')
qtkeychain_options = cmake.subproject_options()
qtkeychain_options.add_cmake_defines({
'BUILD_SHARED_LIBS': false,
})
if target_machine.system() != 'windows'
qtkeychain_options.add_cmake_defines({
'CMAKE_C_FLAGS': '-fPIC',
})
endif
qtkeychain_options.set_override_option('werror', 'false')
qtkeychain_options.set_override_option('warning_level', '0')
qtkeychain_proj = cmake.subproject('QtKeychain', options: qtkeychain_options)
qtkeychain_dep = qtkeychain_proj.dependency('qt5keychain')
if target_machine.system() == 'linux' or target_machine.system() == 'freebsd' or target_machine.system() == 'netbsd' or target_machine.system() == 'openbsd' or target_machine.system() == 'dragonfly'
deps += dependency('libsecret-1', default_options: ['manpage=false', 'vapi=false', 'gtk_doc=false', 'introspection=false',], include_type: 'system') # 'bash_completion=disabled'])
endif
endif endif
deps += qtkeychain_dep deps += qtkeychain_dep

View file

@ -63,9 +63,7 @@ public:
QImage m_image; QImage m_image;
}; };
class BlurhashProvider class BlurhashProvider : public QQuickAsyncImageProvider
: public QObject
, public QQuickAsyncImageProvider
{ {
Q_OBJECT Q_OBJECT
public slots: public slots:

View file

@ -3833,7 +3833,7 @@ Cache::displayName(const QString &room_id, const QString &user_id)
static bool static bool
isDisplaynameSafe(const std::string &s) isDisplaynameSafe(const std::string &s)
{ {
for (QChar c : QString::fromStdString(s).toUcs4()) { for (QChar c : QString::fromStdString(s)) {
if (c.isPrint() && !c.isSpace()) if (c.isPrint() && !c.isSpace())
return false; return false;
} }

View file

@ -62,7 +62,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
topLayout_ = new QHBoxLayout(this); topLayout_ = new QHBoxLayout(this);
topLayout_->setSpacing(0); topLayout_->setSpacing(0);
topLayout_->setMargin(0);
view_manager_ = new TimelineViewManager(callManager_, this); view_manager_ = new TimelineViewManager(callManager_, this);
@ -1231,18 +1230,18 @@ ChatPage::startChat(QString userid)
} }
static QString static QString
mxidFromSegments(QStringRef sigil, QStringRef mxid) mxidFromSegments(QStringView sigil, QStringView mxid)
{ {
if (mxid.isEmpty()) if (mxid.isEmpty())
return ""; return "";
auto mxid_ = QUrl::fromPercentEncoding(mxid.toUtf8()); auto mxid_ = QUrl::fromPercentEncoding(mxid.toUtf8());
if (sigil == "u") { if (sigil == QAnyStringView("u")) {
return "@" + mxid_; return "@" + mxid_;
} else if (sigil == "roomid") { } else if (sigil == QAnyStringView("roomid")) {
return "!" + mxid_; return "!" + mxid_;
} else if (sigil == "r") { } else if (sigil == QAnyStringView("r")) {
return "#" + mxid_; return "#" + mxid_;
//} else if (sigil == "group") { //} else if (sigil == "group") {
// return "+" + mxid_; // return "+" + mxid_;
@ -1303,7 +1302,7 @@ ChatPage::handleMatrixUri(QString uri)
auto tempPath = uri_.path(QUrl::ComponentFormattingOption::FullyEncoded); auto tempPath = uri_.path(QUrl::ComponentFormattingOption::FullyEncoded);
if (tempPath.startsWith('/')) if (tempPath.startsWith('/'))
tempPath.remove(0, 1); tempPath.remove(0, 1);
auto segments = tempPath.splitRef('/'); auto segments = QStringView(tempPath).split('/');
if (segments.size() != 2 && segments.size() != 4) if (segments.size() != 2 && segments.size() != 4)
return false; return false;
@ -1314,7 +1313,7 @@ ChatPage::handleMatrixUri(QString uri)
return false; return false;
QString mxid2; QString mxid2;
if (segments.size() == 4 && segments[2] == "e") { if (segments.size() == 4 && segments[2] == QAnyStringView("e")) {
if (segments[3].isEmpty()) if (segments[3].isEmpty())
return false; return false;
else else
@ -1335,7 +1334,7 @@ ChatPage::handleMatrixUri(QString uri)
} }
} }
if (sigil1 == "u") { if (sigil1 == QAnyStringView("u")) {
if (action.isEmpty()) { if (action.isEmpty()) {
auto t = view_manager_->rooms()->currentRoom(); auto t = view_manager_->rooms()->currentRoom();
if (t && cache::isRoomMember(mxid1.toStdString(), t->roomId().toStdString())) { if (t && cache::isRoomMember(mxid1.toStdString(), t->roomId().toStdString())) {
@ -1347,7 +1346,7 @@ ChatPage::handleMatrixUri(QString uri)
this->startChat(mxid1); this->startChat(mxid1);
} }
return true; return true;
} else if (sigil1 == "roomid") { } else if (sigil1 == QAnyStringView("roomid")) {
auto joined_rooms = cache::joinedRooms(); auto joined_rooms = cache::joinedRooms();
auto targetRoomId = mxid1.toStdString(); auto targetRoomId = mxid1.toStdString();
@ -1365,7 +1364,7 @@ ChatPage::handleMatrixUri(QString uri)
return true; return true;
} }
return false; return false;
} else if (sigil1 == "r") { } else if (sigil1 == QAnyStringView("r")) {
auto joined_rooms = cache::joinedRooms(); auto joined_rooms = cache::joinedRooms();
auto targetRoomAlias = mxid1.toStdString(); auto targetRoomAlias = mxid1.toStdString();

View file

@ -48,7 +48,7 @@ CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model,
.toString() .toString()
.toLower(); .toLower();
for (const auto &e : string1.splitRef(splitPoints)) { for (const auto &e : QStringView(string1).split(splitPoints)) {
if (!e.isEmpty()) // NOTE(Nico): Use Qt::SkipEmptyParts in Qt 5.14 if (!e.isEmpty()) // NOTE(Nico): Use Qt::SkipEmptyParts in Qt 5.14
trie_.insert(e.toUcs4(), i); trie_.insert(e.toUcs4(), i);
} }
@ -59,7 +59,7 @@ CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model,
.toLower(); .toLower();
if (!string2.isEmpty()) { if (!string2.isEmpty()) {
for (const auto &e : string2.splitRef(splitPoints)) { for (const auto &e : QStringView(string2).split(splitPoints)) {
if (!e.isEmpty()) // NOTE(Nico): Use Qt::SkipEmptyParts in Qt 5.14 if (!e.isEmpty()) // NOTE(Nico): Use Qt::SkipEmptyParts in Qt 5.14
trie_.insert(e.toUcs4(), i); trie_.insert(e.toUcs4(), i);
} }

View file

@ -52,9 +52,7 @@ public:
QImage m_pixmap; QImage m_pixmap;
}; };
class JdenticonProvider class JdenticonProvider : public QQuickAsyncImageProvider
: public QObject
, public QQuickAsyncImageProvider
{ {
Q_OBJECT Q_OBJECT
@ -72,7 +70,7 @@ public slots:
auto queryStart = id.lastIndexOf('?'); auto queryStart = id.lastIndexOf('?');
if (queryStart != -1) { if (queryStart != -1) {
id_ = id.left(queryStart); id_ = id.left(queryStart);
auto query = id.midRef(queryStart + 1); auto query = id.mid(queryStart + 1);
auto queryBits = query.split('&'); auto queryBits = query.split('&');
for (auto b : queryBits) { for (auto b : queryBits) {

View file

@ -40,7 +40,6 @@ LoginPage::LoginPage(QWidget *parent)
top_bar_layout_ = new QHBoxLayout(); top_bar_layout_ = new QHBoxLayout();
top_bar_layout_->setSpacing(0); top_bar_layout_->setSpacing(0);
top_bar_layout_->setMargin(0);
back_button_ = new FlatButton(this); back_button_ = new FlatButton(this);
back_button_->setMinimumSize(QSize(30, 30)); back_button_->setMinimumSize(QSize(30, 30));
@ -497,7 +496,7 @@ void
LoginPage::paintEvent(QPaintEvent *) LoginPage::paintEvent(QPaintEvent *)
{ {
QStyleOption opt; QStyleOption opt;
opt.init(this); opt.initFrom(this);
QPainter p(this); QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
} }

View file

@ -22,7 +22,7 @@ Q_DECLARE_METATYPE(mtx::responses::Sync)
Q_DECLARE_METATYPE(mtx::responses::JoinedGroups) Q_DECLARE_METATYPE(mtx::responses::JoinedGroups)
Q_DECLARE_METATYPE(mtx::responses::GroupProfile) Q_DECLARE_METATYPE(mtx::responses::GroupProfile)
Q_DECLARE_METATYPE(nlohmann::json) // Q_DECLARE_METATYPE(nlohmann::json)
Q_DECLARE_METATYPE(std::string) Q_DECLARE_METATYPE(std::string)
Q_DECLARE_METATYPE(std::vector<std::string>) Q_DECLARE_METATYPE(std::vector<std::string>)
Q_DECLARE_METATYPE(std::vector<QString>) Q_DECLARE_METATYPE(std::vector<QString>)
@ -54,7 +54,7 @@ init()
qRegisterMetaType<mtx::responses::JoinedGroups>(); qRegisterMetaType<mtx::responses::JoinedGroups>();
qRegisterMetaType<mtx::responses::GroupProfile>(); qRegisterMetaType<mtx::responses::GroupProfile>();
qRegisterMetaType<std::string>(); qRegisterMetaType<std::string>();
qRegisterMetaType<nlohmann::json>(); // qRegisterMetaType<nlohmann::json>();
qRegisterMetaType<std::vector<std::string>>(); qRegisterMetaType<std::vector<std::string>>();
qRegisterMetaType<std::vector<QString>>(); qRegisterMetaType<std::vector<QString>>();
qRegisterMetaType<std::map<QString, bool>>("std::map<QString, bool>"); qRegisterMetaType<std::map<QString, bool>>("std::map<QString, bool>");

View file

@ -31,13 +31,13 @@ MxcImageProvider::requestImageResponse(const QString &id, const QSize &requested
auto queryStart = id.lastIndexOf('?'); auto queryStart = id.lastIndexOf('?');
if (queryStart != -1) { if (queryStart != -1) {
id_ = id.left(queryStart); id_ = id.left(queryStart);
auto query = id.midRef(queryStart + 1); auto query = QStringView(id).mid(queryStart + 1);
auto queryBits = query.split('&'); auto queryBits = query.split('&');
for (auto b : queryBits) { for (auto b : queryBits) {
if (b == "scale") { if (b == QAnyStringView("scale")) {
crop = false; crop = false;
} else if (b.startsWith("radius=")) { } else if (b.startsWith(QLatin1String("radius="))) {
radius = b.mid(7).toDouble(); radius = b.mid(7).toDouble();
} }
} }

View file

@ -70,9 +70,7 @@ public:
QImage m_image; QImage m_image;
}; };
class MxcImageProvider class MxcImageProvider : public QQuickAsyncImageProvider
: public QObject
, public QQuickAsyncImageProvider
{ {
Q_OBJECT Q_OBJECT
public slots: public slots:

View file

@ -61,7 +61,6 @@ RegisterPage::RegisterPage(QWidget *parent)
logo_->setPixmap(logo.pixmap(128)); logo_->setPixmap(logo.pixmap(128));
logo_layout_ = new QHBoxLayout(); logo_layout_ = new QHBoxLayout();
logo_layout_->setMargin(0);
logo_layout_->addWidget(logo_, 0, Qt::AlignHCenter); logo_layout_->addWidget(logo_, 0, Qt::AlignHCenter);
form_wrapper_ = new QHBoxLayout(); form_wrapper_ = new QHBoxLayout();
@ -128,7 +127,6 @@ RegisterPage::RegisterPage(QWidget *parent)
button_layout_ = new QHBoxLayout(); button_layout_ = new QHBoxLayout();
button_layout_->setSpacing(0); button_layout_->setSpacing(0);
button_layout_->setMargin(0);
error_label_ = new QLabel(this); error_label_ = new QLabel(this);
error_label_->setWordWrap(true); error_label_->setWordWrap(true);
@ -406,7 +404,7 @@ void
RegisterPage::paintEvent(QPaintEvent *) RegisterPage::paintEvent(QPaintEvent *)
{ {
QStyleOption opt; QStyleOption opt;
opt.init(this); opt.initFrom(this);
QPainter p(this); QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
} }

View file

@ -69,7 +69,7 @@ MsgCountComposedIcon::clone() const
} }
QList<QSize> QList<QSize>
MsgCountComposedIcon::availableSizes(QIcon::Mode mode, QIcon::State state) const MsgCountComposedIcon::availableSizes(QIcon::Mode mode, QIcon::State state)
{ {
Q_UNUSED(mode); Q_UNUSED(mode);
Q_UNUSED(state); Q_UNUSED(state);

View file

@ -20,7 +20,7 @@ public:
void paint(QPainter *p, const QRect &rect, QIcon::Mode mode, QIcon::State state) override; void paint(QPainter *p, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
QIconEngine *clone() const override; QIconEngine *clone() const override;
QList<QSize> availableSizes(QIcon::Mode mode, QIcon::State state) const override; QList<QSize> availableSizes(QIcon::Mode mode, QIcon::State state) override;
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override; QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override;
int msgCount = 0; int msgCount = 0;

View file

@ -771,7 +771,6 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
topBarLayout_ = new QHBoxLayout; topBarLayout_ = new QHBoxLayout;
topBarLayout_->setSpacing(0); topBarLayout_->setSpacing(0);
topBarLayout_->setMargin(0);
topBarLayout_->addWidget(backBtn_, 1, Qt::AlignLeft | Qt::AlignVCenter); topBarLayout_->addWidget(backBtn_, 1, Qt::AlignLeft | Qt::AlignVCenter);
topBarLayout_->addStretch(1); topBarLayout_->addStretch(1);
@ -1443,7 +1442,7 @@ void
UserSettingsPage::paintEvent(QPaintEvent *) UserSettingsPage::paintEvent(QPaintEvent *)
{ {
QStyleOption opt; QStyleOption opt;
opt.init(this); opt.initFrom(this);
QPainter p(this); QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
} }

View file

@ -8,7 +8,6 @@
#include <QBuffer> #include <QBuffer>
#include <QComboBox> #include <QComboBox>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QDesktopWidget>
#include <QGuiApplication> #include <QGuiApplication>
#include <QImageReader> #include <QImageReader>
#include <QProcessEnvironment> #include <QProcessEnvironment>
@ -389,7 +388,7 @@ utils::humanReadableFingerprint(const QString &ed25519)
{ {
QString fingerprint; QString fingerprint;
for (int i = 0; i < ed25519.length(); i = i + 4) { for (int i = 0; i < ed25519.length(); i = i + 4) {
fingerprint.append(ed25519.midRef(i, 4)); fingerprint.append(QStringView(ed25519).mid(i, 4));
if (i > 0 && i % 16 == 12) if (i > 0 && i % 16 == 12)
fingerprint.append('\n'); fingerprint.append('\n');
else if (i < ed25519.length()) else if (i < ed25519.length())
@ -513,7 +512,8 @@ utils::markdownToHtml(const QString &text, bool rainbowify)
while ((boundaryEnd = tbf.toNextBoundary()) != -1) { while ((boundaryEnd = tbf.toNextBoundary()) != -1) {
charIdx++; charIdx++;
// Split text to get current char // Split text to get current char
auto curChar = nodeText.midRef(boundaryStart, boundaryEnd - boundaryStart); auto curChar =
QStringView(nodeText).mid(boundaryStart, boundaryEnd - boundaryStart);
boundaryStart = boundaryEnd; boundaryStart = boundaryEnd;
// Don't rainbowify whitespaces // Don't rainbowify whitespaces
if (curChar.trimmed().isEmpty() || codepointIsEmoji(curChar.toUcs4().first())) { if (curChar.trimmed().isEmpty() || codepointIsEmoji(curChar.toUcs4().first())) {

View file

@ -81,7 +81,7 @@ void
WelcomePage::paintEvent(QPaintEvent *) WelcomePage::paintEvent(QPaintEvent *)
{ {
QStyleOption opt; QStyleOption opt;
opt.init(this); opt.initFrom(this);
QPainter p(this); QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
} }

View file

@ -32,7 +32,10 @@ CreateRoom::CreateRoom(QWidget *parent)
auto layout = new QVBoxLayout(this); auto layout = new QVBoxLayout(this);
layout->setSpacing(conf::modals::WIDGET_SPACING); layout->setSpacing(conf::modals::WIDGET_SPACING);
layout->setMargin(conf::modals::WIDGET_MARGIN); layout->setContentsMargins(conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN);
auto buttonLayout = new QHBoxLayout(); auto buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(15); buttonLayout->setSpacing(15);

View file

@ -25,11 +25,13 @@ FallbackAuth::FallbackAuth(const QString &authType, const QString &session, QWid
auto layout = new QVBoxLayout(this); auto layout = new QVBoxLayout(this);
layout->setSpacing(conf::modals::WIDGET_SPACING); layout->setSpacing(conf::modals::WIDGET_SPACING);
layout->setMargin(conf::modals::WIDGET_MARGIN); layout->setContentsMargins(conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN);
auto buttonLayout = new QHBoxLayout(); auto buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(8); buttonLayout->setSpacing(8);
buttonLayout->setMargin(0);
openBtn_ = new QPushButton(tr("Open Fallback in Browser"), this); openBtn_ = new QPushButton(tr("Open Fallback in Browser"), this);
cancelBtn_ = new QPushButton(tr("Cancel"), this); cancelBtn_ = new QPushButton(tr("Cancel"), this);

View file

@ -4,7 +4,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <QApplication> #include <QApplication>
#include <QDesktopWidget>
#include <QGuiApplication> #include <QGuiApplication>
#include <QPainter> #include <QPainter>
#include <QScreen> #include <QScreen>

View file

@ -25,11 +25,13 @@ Logout::Logout(QWidget *parent)
auto layout = new QVBoxLayout(this); auto layout = new QVBoxLayout(this);
layout->setSpacing(conf::modals::WIDGET_SPACING); layout->setSpacing(conf::modals::WIDGET_SPACING);
layout->setMargin(conf::modals::WIDGET_MARGIN); layout->setContentsMargins(conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN);
auto buttonLayout = new QHBoxLayout(); auto buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0); buttonLayout->setSpacing(0);
buttonLayout->setMargin(0);
confirmBtn_ = new QPushButton("Logout", this); confirmBtn_ = new QPushButton("Logout", this);
cancelBtn_ = new QPushButton(tr("Cancel"), this); cancelBtn_ = new QPushButton(tr("Cancel"), this);

View file

@ -33,7 +33,6 @@ PreviewUploadOverlay::PreviewUploadOverlay(QWidget *parent)
hlayout->addStretch(1); hlayout->addStretch(1);
hlayout->addWidget(&cancel_); hlayout->addWidget(&cancel_);
hlayout->addWidget(&upload_); hlayout->addWidget(&upload_);
hlayout->setMargin(0);
auto vlayout = new QVBoxLayout{this}; auto vlayout = new QVBoxLayout{this};
vlayout->addWidget(&titleLabel_); vlayout->addWidget(&titleLabel_);
@ -41,7 +40,10 @@ PreviewUploadOverlay::PreviewUploadOverlay(QWidget *parent)
vlayout->addWidget(&fileName_); vlayout->addWidget(&fileName_);
vlayout->addLayout(hlayout); vlayout->addLayout(hlayout);
vlayout->setSpacing(conf::modals::WIDGET_SPACING); vlayout->setSpacing(conf::modals::WIDGET_SPACING);
vlayout->setMargin(conf::modals::WIDGET_MARGIN); vlayout->setContentsMargins(conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN);
upload_.setDefault(true); upload_.setDefault(true);
connect(&upload_, &QPushButton::clicked, [this]() { connect(&upload_, &QPushButton::clicked, [this]() {
@ -217,4 +219,4 @@ PreviewUploadOverlay::keyPressEvent(QKeyEvent *event)
} else { } else {
QWidget::keyPressEvent(event); QWidget::keyPressEvent(event);
} }
} }

View file

@ -25,11 +25,13 @@ ReCaptcha::ReCaptcha(const QString &session, QWidget *parent)
auto layout = new QVBoxLayout(this); auto layout = new QVBoxLayout(this);
layout->setSpacing(conf::modals::WIDGET_SPACING); layout->setSpacing(conf::modals::WIDGET_SPACING);
layout->setMargin(conf::modals::WIDGET_MARGIN); layout->setContentsMargins(conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN);
auto buttonLayout = new QHBoxLayout(); auto buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(8); buttonLayout->setSpacing(8);
buttonLayout->setMargin(0);
openCaptchaBtn_ = new QPushButton("Open reCAPTCHA", this); openCaptchaBtn_ = new QPushButton("Open reCAPTCHA", this);
cancelBtn_ = new QPushButton(tr("Cancel"), this); cancelBtn_ = new QPushButton(tr("Cancel"), this);

View file

@ -8,7 +8,6 @@
#include <QApplication> #include <QApplication>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QDesktopServices> #include <QDesktopServices>
#include <QDesktopWidget>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QFontDatabase> #include <QFontDatabase>

View file

@ -76,13 +76,13 @@ DelegateChooser::appendChoice(QQmlListProperty<DelegateChoice> *p, DelegateChoic
dc->choices_.append(c); dc->choices_.append(c);
} }
int qsizetype
DelegateChooser::choiceCount(QQmlListProperty<DelegateChoice> *p) DelegateChooser::choiceCount(QQmlListProperty<DelegateChoice> *p)
{ {
return static_cast<DelegateChooser *>(p->object)->choices_.count(); return static_cast<DelegateChooser *>(p->object)->choices_.count();
} }
DelegateChoice * DelegateChoice *
DelegateChooser::choice(QQmlListProperty<DelegateChoice> *p, int index) DelegateChooser::choice(QQmlListProperty<DelegateChoice> *p, qsizetype index)
{ {
return static_cast<DelegateChooser *>(p->object)->choices_.at(index); return static_cast<DelegateChooser *>(p->object)->choices_.at(index);
} }

View file

@ -84,7 +84,7 @@ private:
DelegateIncubator incubator{*this}; DelegateIncubator incubator{*this};
static void appendChoice(QQmlListProperty<DelegateChoice> *, DelegateChoice *); static void appendChoice(QQmlListProperty<DelegateChoice> *, DelegateChoice *);
static int choiceCount(QQmlListProperty<DelegateChoice> *); static qsizetype choiceCount(QQmlListProperty<DelegateChoice> *);
static DelegateChoice *choice(QQmlListProperty<DelegateChoice> *, int index); static DelegateChoice *choice(QQmlListProperty<DelegateChoice> *, qsizetype index);
static void clearChoices(QQmlListProperty<DelegateChoice> *); static void clearChoices(QQmlListProperty<DelegateChoice> *);
}; };

View file

@ -140,7 +140,7 @@ InputBar::updateAtRoom(const QString &t)
auto start = finder.position(); auto start = finder.position();
finder.toNextBoundary(); finder.toNextBoundary();
auto end = finder.position(); auto end = finder.position();
if (start > 0 && end - start >= 4 && t.midRef(start, end - start) == "room" && if (start > 0 && end - start >= 4 && t.mid(start, end - start) == "room" &&
t.at(start - 1) == QChar('@')) { t.at(start - 1) == QChar('@')) {
roomMention = true; roomMention = true;
break; break;

View file

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <QObject> #include <QObject>
#include <QStringList>
#include <QTimer> #include <QTimer>
#include <deque> #include <deque>
@ -15,7 +16,6 @@ class TimelineModel;
class CombinedImagePackModel; class CombinedImagePackModel;
class QMimeData; class QMimeData;
class QDropEvent; class QDropEvent;
class QStringList;
enum class MarkdownOverride enum class MarkdownOverride
{ {

View file

@ -616,7 +616,7 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
// only show read receipts for messages not from us // only show read receipts for messages not from us
if (acc::sender(event) != http::client()->user_id().to_string()) if (acc::sender(event) != http::client()->user_id().to_string())
return qml_mtx_events::Empty; return qml_mtx_events::Empty;
else if (!id.isEmpty() && id[0] == "m") else if (!id.isEmpty() && id[0] == 'm')
return qml_mtx_events::Sent; return qml_mtx_events::Sent;
else if (read.contains(id) || containsOthers(cache::readReceipts(id, room_id_))) else if (read.contains(id) || containsOthers(cache::readReceipts(id, room_id_)))
return qml_mtx_events::Read; return qml_mtx_events::Read;
@ -1002,7 +1002,7 @@ TimelineModel::setCurrentIndex(int index)
if (!ChatPage::instance()->isActiveWindow()) if (!ChatPage::instance()->isActiveWindow())
return; return;
if (!currentId.startsWith("m")) { if (!currentId.startsWith('m')) {
auto oldReadIndex = auto oldReadIndex =
cache::getEventIndex(roomId().toStdString(), currentReadId.toStdString()); cache::getEventIndex(roomId().toStdString(), currentReadId.toStdString());
auto nextEventIndexAndId = auto nextEventIndexAndId =
@ -1730,8 +1730,7 @@ TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg)
if (startIndex - index != 0) if (startIndex - index != 0)
coloredUsername += coloredUsername +=
prefix + prefix + uncoloredUsername.mid(index, startIndex > 0 ? startIndex - index : -1) +
uncoloredUsername.midRef(index, startIndex > 0 ? startIndex - index : -1) +
"</font>"; "</font>";
auto endIndex = uncoloredUsername.indexOf("</font>", startIndex); auto endIndex = uncoloredUsername.indexOf("</font>", startIndex);
@ -1739,7 +1738,7 @@ TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg)
endIndex += sizeof("</font>") - 1; endIndex += sizeof("</font>") - 1;
if (endIndex - startIndex != 0) if (endIndex - startIndex != 0)
coloredUsername += uncoloredUsername.midRef(startIndex, endIndex - startIndex); coloredUsername += uncoloredUsername.mid(startIndex, endIndex - startIndex);
index = endIndex; index = endIndex;
} while (index > 0 && index < uncoloredUsername.size()); } while (index > 0 && index < uncoloredUsername.size());

View file

@ -2,7 +2,6 @@
// //
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <QEventTransition>
#include <QFontDatabase> #include <QFontDatabase>
#include <QIcon> #include <QIcon>
#include <QMouseEvent> #include <QMouseEvent>
@ -10,7 +9,6 @@
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>
#include <QResizeEvent> #include <QResizeEvent>
#include <QSignalTransition>
#include "FlatButton.h" #include "FlatButton.h"
#include "Ripple.h" #include "Ripple.h"
@ -37,7 +35,6 @@ void
FlatButton::init() FlatButton::init()
{ {
ripple_overlay_ = new RippleOverlay(this); ripple_overlay_ = new RippleOverlay(this);
state_machine_ = new FlatButtonStateMachine(this);
role_ = ui::Role::Default; role_ = ui::Role::Default;
ripple_style_ = ui::RippleStyle::PositionedRipple; ripple_style_ = ui::RippleStyle::PositionedRipple;
icon_placement_ = ui::ButtonIconPlacement::LeftIcon; icon_placement_ = ui::ButtonIconPlacement::LeftIcon;
@ -59,9 +56,6 @@ FlatButton::init()
ripple_overlay_->setClipPath(path); ripple_overlay_->setClipPath(path);
ripple_overlay_->setClipping(true); ripple_overlay_->setClipping(true);
state_machine_->setupProperties();
state_machine_->startAnimations();
} }
FlatButton::FlatButton(QWidget *parent, ui::ButtonPreset preset) FlatButton::FlatButton(QWidget *parent, ui::ButtonPreset preset)
@ -106,7 +100,6 @@ void
FlatButton::setRole(ui::Role role) FlatButton::setRole(ui::Role role)
{ {
role_ = role; role_ = role;
state_machine_->setupProperties();
} }
ui::Role ui::Role
@ -290,7 +283,6 @@ void
FlatButton::setBackgroundMode(Qt::BGMode mode) FlatButton::setBackgroundMode(Qt::BGMode mode)
{ {
bg_mode_ = mode; bg_mode_ = mode;
state_machine_->setupProperties();
} }
Qt::BGMode Qt::BGMode
@ -303,7 +295,6 @@ void
FlatButton::setBaseOpacity(qreal opacity) FlatButton::setBaseOpacity(qreal opacity)
{ {
base_opacity_ = opacity; base_opacity_ = opacity;
state_machine_->setupProperties();
} }
qreal qreal
@ -315,9 +306,6 @@ FlatButton::baseOpacity() const
void void
FlatButton::setCheckable(bool value) FlatButton::setCheckable(bool value)
{ {
state_machine_->updateCheckedStatus();
state_machine_->setCheckedOverlayProgress(0);
QPushButton::setCheckable(value); QPushButton::setCheckable(value);
} }
@ -361,7 +349,6 @@ FlatButton::sizeHint() const
void void
FlatButton::checkStateSet() FlatButton::checkStateSet()
{ {
state_machine_->updateCheckedStatus();
QPushButton::checkStateSet(); QPushButton::checkStateSet();
} }
@ -402,7 +389,6 @@ void
FlatButton::mouseReleaseEvent(QMouseEvent *event) FlatButton::mouseReleaseEvent(QMouseEvent *event)
{ {
QPushButton::mouseReleaseEvent(event); QPushButton::mouseReleaseEvent(event);
state_machine_->updateCheckedStatus();
} }
void void
@ -441,9 +427,6 @@ FlatButton::paintEvent(QPaintEvent *event)
void void
FlatButton::paintBackground(QPainter *painter) FlatButton::paintBackground(QPainter *painter)
{ {
const qreal overlayOpacity = state_machine_->overlayOpacity();
const qreal checkedProgress = state_machine_->checkedOverlayProgress();
if (Qt::OpaqueMode == bg_mode_) { if (Qt::OpaqueMode == bg_mode_) {
QBrush brush; QBrush brush;
brush.setStyle(Qt::SolidPattern); brush.setStyle(Qt::SolidPattern);
@ -468,27 +451,6 @@ FlatButton::paintBackground(QPainter *painter)
return; return;
} }
if ((ui::OverlayStyle::NoOverlay != overlay_style_) && (overlayOpacity > 0)) {
if (ui::OverlayStyle::TintedOverlay == overlay_style_) {
brush.setColor(overlayColor());
} else {
brush.setColor(Qt::gray);
}
painter->setOpacity(overlayOpacity);
painter->setBrush(brush);
painter->drawRect(rect());
}
if (isCheckable() && checkedProgress > 0) {
const qreal q = Qt::TransparentMode == bg_mode_ ? 0.45 : 0.7;
brush.setColor(foregroundColor());
painter->setOpacity(q * checkedProgress);
painter->setBrush(brush);
QRect r(rect());
r.setHeight(static_cast<qreal>(r.height()) * checkedProgress);
painter->drawRect(r);
}
} }
#define COLOR_INTERPOLATE(CH) (1 - progress) * source.CH() + progress *dest.CH() #define COLOR_INTERPOLATE(CH) (1 - progress) * source.CH() + progress *dest.CH()
@ -498,20 +460,6 @@ FlatButton::paintForeground(QPainter *painter)
{ {
if (isEnabled()) { if (isEnabled()) {
painter->setPen(foregroundColor()); painter->setPen(foregroundColor());
const qreal progress = state_machine_->checkedOverlayProgress();
if (isCheckable() && progress > 0) {
QColor source = foregroundColor();
QColor dest = Qt::TransparentMode == bg_mode_ ? Qt::white : backgroundColor();
if (qFuzzyCompare(1, progress)) {
painter->setPen(dest);
} else {
painter->setPen(QColor(COLOR_INTERPOLATE(red),
COLOR_INTERPOLATE(green),
COLOR_INTERPOLATE(blue),
COLOR_INTERPOLATE(alpha)));
}
}
} else { } else {
painter->setPen(disabledForegroundColor()); painter->setPen(disabledForegroundColor());
} }
@ -555,166 +503,3 @@ FlatButton::updateClipPath()
ripple_overlay_->setClipPath(path); ripple_overlay_->setClipPath(path);
} }
FlatButtonStateMachine::FlatButtonStateMachine(FlatButton *parent)
: QStateMachine(parent)
, button_(parent)
, top_level_state_(new QState(QState::ParallelStates))
, config_state_(new QState(top_level_state_))
, checkable_state_(new QState(top_level_state_))
, checked_state_(new QState(checkable_state_))
, unchecked_state_(new QState(checkable_state_))
, neutral_state_(new QState(config_state_))
, neutral_focused_state_(new QState(config_state_))
, hovered_state_(new QState(config_state_))
, hovered_focused_state_(new QState(config_state_))
, pressed_state_(new QState(config_state_))
, overlay_opacity_(0)
, checked_overlay_progress_(parent->isChecked() ? 1 : 0)
, was_checked_(false)
{
Q_ASSERT(parent);
parent->installEventFilter(this);
config_state_->setInitialState(neutral_state_);
addState(top_level_state_);
setInitialState(top_level_state_);
checkable_state_->setInitialState(parent->isChecked() ? checked_state_ : unchecked_state_);
QSignalTransition *transition;
QPropertyAnimation *animation;
transition = new QSignalTransition(this, SIGNAL(buttonChecked()));
transition->setTargetState(checked_state_);
unchecked_state_->addTransition(transition);
animation = new QPropertyAnimation(this, "checkedOverlayProgress", this);
animation->setDuration(200);
transition->addAnimation(animation);
transition = new QSignalTransition(this, SIGNAL(buttonUnchecked()));
transition->setTargetState(unchecked_state_);
checked_state_->addTransition(transition);
animation = new QPropertyAnimation(this, "checkedOverlayProgress", this);
animation->setDuration(200);
transition->addAnimation(animation);
addTransition(button_, QEvent::FocusIn, neutral_state_, neutral_focused_state_);
addTransition(button_, QEvent::FocusOut, neutral_focused_state_, neutral_state_);
addTransition(button_, QEvent::Enter, neutral_state_, hovered_state_);
addTransition(button_, QEvent::Leave, hovered_state_, neutral_state_);
addTransition(button_, QEvent::Enter, neutral_focused_state_, hovered_focused_state_);
addTransition(button_, QEvent::Leave, hovered_focused_state_, neutral_focused_state_);
addTransition(button_, QEvent::FocusIn, hovered_state_, hovered_focused_state_);
addTransition(button_, QEvent::FocusOut, hovered_focused_state_, hovered_state_);
addTransition(this, SIGNAL(buttonPressed()), hovered_state_, pressed_state_);
addTransition(button_, QEvent::Leave, pressed_state_, neutral_focused_state_);
addTransition(button_, QEvent::FocusOut, pressed_state_, hovered_state_);
}
void
FlatButtonStateMachine::setOverlayOpacity(qreal opacity)
{
overlay_opacity_ = opacity;
button_->update();
}
void
FlatButtonStateMachine::setCheckedOverlayProgress(qreal opacity)
{
checked_overlay_progress_ = opacity;
button_->update();
}
void
FlatButtonStateMachine::startAnimations()
{
start();
}
void
FlatButtonStateMachine::setupProperties()
{
QColor overlayColor;
if (Qt::TransparentMode == button_->backgroundMode()) {
overlayColor = button_->backgroundColor();
} else {
overlayColor = button_->foregroundColor();
}
const qreal baseOpacity = button_->baseOpacity();
neutral_state_->assignProperty(this, "overlayOpacity", 0);
neutral_focused_state_->assignProperty(this, "overlayOpacity", 0);
hovered_state_->assignProperty(this, "overlayOpacity", baseOpacity);
hovered_focused_state_->assignProperty(this, "overlayOpacity", baseOpacity);
pressed_state_->assignProperty(this, "overlayOpacity", baseOpacity);
checked_state_->assignProperty(this, "checkedOverlayProgress", 1);
unchecked_state_->assignProperty(this, "checkedOverlayProgress", 0);
button_->update();
}
void
FlatButtonStateMachine::updateCheckedStatus()
{
const bool checked = button_->isChecked();
if (was_checked_ != checked) {
was_checked_ = checked;
if (checked) {
emit buttonChecked();
} else {
emit buttonUnchecked();
}
}
}
bool
FlatButtonStateMachine::eventFilter(QObject *watched, QEvent *event)
{
if (QEvent::FocusIn == event->type()) {
QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
if (focusEvent && Qt::MouseFocusReason == focusEvent->reason()) {
emit buttonPressed();
return true;
}
}
return QStateMachine::eventFilter(watched, event);
}
void
FlatButtonStateMachine::addTransition(QObject *object,
const char *signal,
QState *fromState,
QState *toState)
{
addTransition(new QSignalTransition(object, signal), fromState, toState);
}
void
FlatButtonStateMachine::addTransition(QObject *object,
QEvent::Type eventType,
QState *fromState,
QState *toState)
{
addTransition(new QEventTransition(object, eventType), fromState, toState);
}
void
FlatButtonStateMachine::addTransition(QAbstractTransition *transition,
QState *fromState,
QState *toState)
{
transition->setTargetState(toState);
QPropertyAnimation *animation;
animation = new QPropertyAnimation(this, "overlayOpacity", this);
animation->setDuration(150);
transition->addAnimation(animation);
fromState->addTransition(transition);
}

View file

@ -5,77 +5,11 @@
#pragma once #pragma once
#include <QPushButton> #include <QPushButton>
#include <QStateMachine>
#include "Theme.h" #include "Theme.h"
class RippleOverlay; class RippleOverlay;
class FlatButton;
class FlatButtonStateMachine : public QStateMachine
{
Q_OBJECT
Q_PROPERTY(qreal overlayOpacity WRITE setOverlayOpacity READ overlayOpacity)
Q_PROPERTY(
qreal checkedOverlayProgress WRITE setCheckedOverlayProgress READ checkedOverlayProgress)
public:
explicit FlatButtonStateMachine(FlatButton *parent);
void setOverlayOpacity(qreal opacity);
void setCheckedOverlayProgress(qreal opacity);
inline qreal overlayOpacity() const;
inline qreal checkedOverlayProgress() const;
void startAnimations();
void setupProperties();
void updateCheckedStatus();
signals:
void buttonPressed();
void buttonChecked();
void buttonUnchecked();
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
void addTransition(QObject *object, const char *signal, QState *fromState, QState *toState);
void addTransition(QObject *object, QEvent::Type eventType, QState *fromState, QState *toState);
void addTransition(QAbstractTransition *transition, QState *fromState, QState *toState);
FlatButton *const button_;
QState *const top_level_state_;
QState *const config_state_;
QState *const checkable_state_;
QState *const checked_state_;
QState *const unchecked_state_;
QState *const neutral_state_;
QState *const neutral_focused_state_;
QState *const hovered_state_;
QState *const hovered_focused_state_;
QState *const pressed_state_;
qreal overlay_opacity_;
qreal checked_overlay_progress_;
bool was_checked_;
};
inline qreal
FlatButtonStateMachine::overlayOpacity() const
{
return overlay_opacity_;
}
inline qreal
FlatButtonStateMachine::checkedOverlayProgress() const
{
return checked_overlay_progress_;
}
class FlatButton : public QPushButton class FlatButton : public QPushButton
{ {
@ -158,7 +92,6 @@ protected:
private: private:
RippleOverlay *ripple_overlay_; RippleOverlay *ripple_overlay_;
FlatButtonStateMachine *state_machine_;
ui::Role role_; ui::Role role_;
ui::RippleStyle ripple_style_; ui::RippleStyle ripple_style_;

View file

@ -2,6 +2,7 @@
// //
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <QEvent>
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>

View file

@ -9,7 +9,7 @@
#include <QObject> #include <QObject>
#include <QQuickItem> #include <QQuickItem>
class TimelineModel; #include "timeline/TimelineModel.h"
// This is an AnimatedImage, that can draw encrypted images // This is an AnimatedImage, that can draw encrypted images
class MxcAnimatedImage : public QQuickItem class MxcAnimatedImage : public QQuickItem

View file

@ -72,7 +72,7 @@ OverlayWidget::paintEvent(QPaintEvent *event)
Q_UNUSED(event); Q_UNUSED(event);
QStyleOption opt; QStyleOption opt;
opt.init(this); opt.initFrom(this);
QPainter p(this); QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
} }

View file

@ -2,63 +2,14 @@
// //
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <QEventTransition>
#include <QPropertyAnimation>
#include "RaisedButton.h" #include "RaisedButton.h"
void void
RaisedButton::init() RaisedButton::init()
{ {
shadow_state_machine_ = new QStateMachine(this);
normal_state_ = new QState;
pressed_state_ = new QState;
effect_ = new QGraphicsDropShadowEffect;
effect_->setBlurRadius(7);
effect_->setOffset(QPointF(0, 2));
effect_->setColor(QColor(0, 0, 0, 75));
setBackgroundMode(Qt::OpaqueMode); setBackgroundMode(Qt::OpaqueMode);
setMinimumHeight(42); setMinimumHeight(42);
setGraphicsEffect(effect_);
setBaseOpacity(0.3); setBaseOpacity(0.3);
shadow_state_machine_->addState(normal_state_);
shadow_state_machine_->addState(pressed_state_);
normal_state_->assignProperty(effect_, "offset", QPointF(0, 2));
normal_state_->assignProperty(effect_, "blurRadius", 7);
pressed_state_->assignProperty(effect_, "offset", QPointF(0, 5));
pressed_state_->assignProperty(effect_, "blurRadius", 29);
QAbstractTransition *transition;
transition = new QEventTransition(this, QEvent::MouseButtonPress);
transition->setTargetState(pressed_state_);
normal_state_->addTransition(transition);
transition = new QEventTransition(this, QEvent::MouseButtonDblClick);
transition->setTargetState(pressed_state_);
normal_state_->addTransition(transition);
transition = new QEventTransition(this, QEvent::MouseButtonRelease);
transition->setTargetState(normal_state_);
pressed_state_->addTransition(transition);
QPropertyAnimation *animation;
animation = new QPropertyAnimation(effect_, "offset", this);
animation->setDuration(100);
shadow_state_machine_->addDefaultAnimation(animation);
animation = new QPropertyAnimation(effect_, "blurRadius", this);
animation->setDuration(100);
shadow_state_machine_->addDefaultAnimation(animation);
shadow_state_machine_->setInitialState(normal_state_);
shadow_state_machine_->start();
} }
RaisedButton::RaisedButton(QWidget *parent) RaisedButton::RaisedButton(QWidget *parent)
@ -77,15 +28,5 @@ RaisedButton::RaisedButton(const QString &text, QWidget *parent)
bool bool
RaisedButton::event(QEvent *event) RaisedButton::event(QEvent *event)
{ {
if (QEvent::EnabledChange == event->type()) {
if (isEnabled()) {
shadow_state_machine_->start();
effect_->setEnabled(true);
} else {
shadow_state_machine_->stop();
effect_->setEnabled(false);
}
}
return FlatButton::event(event); return FlatButton::event(event);
} }

View file

@ -5,8 +5,6 @@
#pragma once #pragma once
#include <QGraphicsDropShadowEffect> #include <QGraphicsDropShadowEffect>
#include <QState>
#include <QStateMachine>
#include "FlatButton.h" #include "FlatButton.h"
@ -23,9 +21,4 @@ protected:
private: private:
void init(); void init();
QStateMachine *shadow_state_machine_;
QState *normal_state_;
QState *pressed_state_;
QGraphicsDropShadowEffect *effect_;
}; };

View file

@ -17,7 +17,7 @@ SnackBar::SnackBar(QWidget *parent)
{ {
QFont font; QFont font;
font.setPointSizeF(font.pointSizeF() * 1.2); font.setPointSizeF(font.pointSizeF() * 1.2);
font.setWeight(50); font.setWeight(QFont::Weight::Thin);
setFont(font); setFont(font);
boxHeight_ = QFontMetrics(font).height() * 2; boxHeight_ = QFontMetrics(font).height() * 2;

View file

@ -5,7 +5,6 @@
#include "TextField.h" #include "TextField.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QEventTransition>
#include <QFontDatabase> #include <QFontDatabase>
#include <QPaintEvent> #include <QPaintEvent>
#include <QPainter> #include <QPainter>
@ -20,7 +19,6 @@ TextField::TextField(QWidget *parent)
QPalette pal; QPalette pal;
state_machine_ = new TextFieldStateMachine(this);
label_ = nullptr; label_ = nullptr;
label_font_size_ = 15; label_font_size_ = 15;
show_label_ = false; show_label_ = false;
@ -32,7 +30,6 @@ TextField::TextField(QWidget *parent)
setMouseTracking(true); setMouseTracking(true);
setTextMargins(0, 4, 0, 6); setTextMargins(0, 4, 0, 6);
state_machine_->start();
QCoreApplication::processEvents(); QCoreApplication::processEvents();
} }
@ -59,7 +56,6 @@ TextField::setShowLabel(bool value)
if (!label_ && value) { if (!label_ && value) {
label_ = new TextFieldLabel(this); label_ = new TextFieldLabel(this);
state_machine_->setLabel(label_);
} }
if (value) { if (value) {
@ -211,7 +207,6 @@ TextField::paintEvent(QPaintEvent *event)
QPainter painter(this); QPainter painter(this);
if (text().isEmpty()) { if (text().isEmpty()) {
painter.setOpacity(1 - state_machine_->progress());
painter.fillRect(rect(), backgroundColor()); painter.fillRect(rect(), backgroundColor());
} }
@ -228,150 +223,4 @@ TextField::paintEvent(QPaintEvent *event)
QBrush brush; QBrush brush;
brush.setStyle(Qt::SolidPattern); brush.setStyle(Qt::SolidPattern);
brush.setColor(inkColor()); brush.setColor(inkColor());
const qreal progress = state_machine_->progress();
if (progress > 0) {
painter.setPen(Qt::NoPen);
painter.setBrush(brush);
const int w = (1 - progress) * static_cast<qreal>(wd / 2);
painter.drawRect(w + 2.5, height() - 2, wd - 2 * w, 2);
}
}
TextFieldStateMachine::TextFieldStateMachine(TextField *parent)
: QStateMachine(parent)
, text_field_(parent)
{
normal_state_ = new QState;
focused_state_ = new QState;
label_ = nullptr;
offset_anim_ = nullptr;
color_anim_ = nullptr;
progress_ = 0.0;
addState(normal_state_);
addState(focused_state_);
setInitialState(normal_state_);
QEventTransition *transition;
QPropertyAnimation *animation;
transition = new QEventTransition(parent, QEvent::FocusIn);
transition->setTargetState(focused_state_);
normal_state_->addTransition(transition);
animation = new QPropertyAnimation(this, "progress", this);
animation->setEasingCurve(QEasingCurve::InCubic);
animation->setDuration(310);
transition->addAnimation(animation);
transition = new QEventTransition(parent, QEvent::FocusOut);
transition->setTargetState(normal_state_);
focused_state_->addTransition(transition);
animation = new QPropertyAnimation(this, "progress", this);
animation->setEasingCurve(QEasingCurve::OutCubic);
animation->setDuration(310);
transition->addAnimation(animation);
normal_state_->assignProperty(this, "progress", 0);
focused_state_->assignProperty(this, "progress", 1);
setupProperties();
connect(text_field_, SIGNAL(textChanged(QString)), this, SLOT(setupProperties()));
}
void
TextFieldStateMachine::setLabel(TextFieldLabel *label)
{
if (label_) {
delete label_;
}
if (offset_anim_) {
removeDefaultAnimation(offset_anim_);
delete offset_anim_;
}
if (color_anim_) {
removeDefaultAnimation(color_anim_);
delete color_anim_;
}
label_ = label;
if (label_) {
offset_anim_ = new QPropertyAnimation(label_, "offset", this);
offset_anim_->setDuration(210);
offset_anim_->setEasingCurve(QEasingCurve::OutCubic);
addDefaultAnimation(offset_anim_);
color_anim_ = new QPropertyAnimation(label_, "color", this);
color_anim_->setDuration(210);
addDefaultAnimation(color_anim_);
}
setupProperties();
}
void
TextFieldStateMachine::setupProperties()
{
if (label_) {
const int m = text_field_->textMargins().top();
if (text_field_->text().isEmpty()) {
normal_state_->assignProperty(label_, "offset", QPointF(0, 26));
} else {
normal_state_->assignProperty(label_, "offset", QPointF(0, 0 - m));
}
focused_state_->assignProperty(label_, "offset", QPointF(0, 0 - m));
focused_state_->assignProperty(label_, "color", text_field_->inkColor());
normal_state_->assignProperty(label_, "color", text_field_->labelColor());
if (0 != label_->offset().y() && !text_field_->text().isEmpty()) {
label_->setOffset(QPointF(0, 0 - m));
} else if (!text_field_->hasFocus() && label_->offset().y() <= 0 &&
text_field_->text().isEmpty()) {
label_->setOffset(QPointF(0, 26));
}
}
text_field_->update();
}
TextFieldLabel::TextFieldLabel(TextField *parent)
: QWidget(parent)
, text_field_(parent)
{
x_ = 0;
y_ = 26;
scale_ = 1;
color_ = parent->labelColor();
QFont font;
font.setWeight(60);
font.setLetterSpacing(QFont::PercentageSpacing, 102);
setFont(font);
}
void
TextFieldLabel::paintEvent(QPaintEvent *)
{
if (!text_field_->hasLabel())
return;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.scale(scale_, scale_);
painter.setPen(color_);
painter.setOpacity(1);
QPointF pos(2 + x_, height() - 36 + y_);
painter.drawText(pos.x(), pos.y(), text_field_->label());
} }

View file

@ -9,12 +9,10 @@
#include <QPaintEvent> #include <QPaintEvent>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QRegularExpression> #include <QRegularExpression>
#include <QStateMachine>
#include <QtGlobal> #include <QtGlobal>
class TextField; class TextField;
class TextFieldLabel; class TextFieldLabel;
class TextFieldStateMachine;
class TextField : public QLineEdit class TextField : public QLineEdit
{ {
@ -60,7 +58,6 @@ private:
QColor underline_color_; QColor underline_color_;
QString label_text_; QString label_text_;
TextFieldLabel *label_; TextFieldLabel *label_;
TextFieldStateMachine *state_machine_;
bool show_label_; bool show_label_;
QRegularExpression regexp_; QRegularExpression regexp_;
bool is_valid_; bool is_valid_;
@ -136,45 +133,3 @@ TextFieldLabel::color() const
return color_; return color_;
} }
class TextFieldStateMachine : public QStateMachine
{
Q_OBJECT
Q_PROPERTY(qreal progress WRITE setProgress READ progress)
public:
TextFieldStateMachine(TextField *parent);
inline void setProgress(qreal progress);
void setLabel(TextFieldLabel *label);
inline qreal progress() const;
public slots:
void setupProperties();
private:
QPropertyAnimation *color_anim_;
QPropertyAnimation *offset_anim_;
QState *focused_state_;
QState *normal_state_;
TextField *text_field_;
TextFieldLabel *label_;
qreal progress_;
};
inline void
TextFieldStateMachine::setProgress(qreal progress)
{
progress_ = progress;
text_field_->update();
}
inline qreal
TextFieldStateMachine::progress() const
{
return progress_;
}

View file

@ -12,6 +12,7 @@
#include <mtx/responses/common.hpp> #include <mtx/responses/common.hpp>
#include "CacheCryptoStructs.h" #include "CacheCryptoStructs.h"
#include "timeline/TimelineModel.h"
namespace verification { namespace verification {
Q_NAMESPACE Q_NAMESPACE
@ -28,7 +29,6 @@ Q_ENUM_NS(Status)
} }
class DeviceVerificationFlow; class DeviceVerificationFlow;
class TimelineModel;
class TimelineViewManager; class TimelineViewManager;
class DeviceInfo class DeviceInfo

View file

@ -10,6 +10,7 @@
#include <QMediaPlayer> #include <QMediaPlayer>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QStringList>
#include <QTimer> #include <QTimer>
#include "CallDevices.h" #include "CallDevices.h"
@ -21,7 +22,6 @@ namespace mtx::responses {
struct TurnServer; struct TurnServer;
} }
class QStringList;
class QUrl; class QUrl;
class CallManager : public QObject class CallManager : public QObject