diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-09-18 00:22:33 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-09-18 00:45:50 +0200 |
commit | cfca7157b98c9dc8e0852fe6484bc3f75008af7d (patch) | |
tree | 32b92340908a9374214ec7b84c1fac7ea338f56d /src/ui | |
parent | Merge pull request #728 from Thulinma/goto (diff) | |
download | nheko-cfca7157b98c9dc8e0852fe6484bc3f75008af7d.tar.xz |
Change indentation to 4 spaces
Diffstat (limited to 'src/ui')
52 files changed, 3314 insertions, 3368 deletions
diff --git a/src/ui/Badge.cpp b/src/ui/Badge.cpp index 66210d06..1b5aba2f 100644 --- a/src/ui/Badge.cpp +++ b/src/ui/Badge.cpp @@ -9,214 +9,214 @@ Badge::Badge(QWidget *parent) : OverlayWidget(parent) { - init(); + init(); } Badge::Badge(const QIcon &icon, QWidget *parent) : OverlayWidget(parent) { - init(); - setIcon(icon); + init(); + setIcon(icon); } Badge::Badge(const QString &text, QWidget *parent) : OverlayWidget(parent) { - init(); - setText(text); + init(); + setText(text); } void Badge::init() { - x_ = 0; - y_ = 0; - // TODO: Make padding configurable. - padding_ = 5; - diameter_ = 24; + x_ = 0; + y_ = 0; + // TODO: Make padding configurable. + padding_ = 5; + diameter_ = 24; - setAttribute(Qt::WA_TransparentForMouseEvents); + setAttribute(Qt::WA_TransparentForMouseEvents); - QFont _font(font()); - _font.setPointSizeF(7.5); - _font.setStyleName("Bold"); + QFont _font(font()); + _font.setPointSizeF(7.5); + _font.setStyleName("Bold"); - setFont(_font); - setText(""); + setFont(_font); + setText(""); } QString Badge::text() const { - return text_; + return text_; } QIcon Badge::icon() const { - return icon_; + return icon_; } QSize Badge::sizeHint() const { - const int d = diameter(); - return QSize(d + 4, d + 4); + const int d = diameter(); + return QSize(d + 4, d + 4); } qreal Badge::relativeYPosition() const { - return y_; + return y_; } qreal Badge::relativeXPosition() const { - return x_; + return x_; } QPointF Badge::relativePosition() const { - return QPointF(x_, y_); + return QPointF(x_, y_); } QColor Badge::backgroundColor() const { - if (!background_color_.isValid()) - return QColor("black"); + if (!background_color_.isValid()) + return QColor("black"); - return background_color_; + return background_color_; } QColor Badge::textColor() const { - if (!text_color_.isValid()) - return QColor("white"); + if (!text_color_.isValid()) + return QColor("white"); - return text_color_; + return text_color_; } void Badge::setTextColor(const QColor &color) { - text_color_ = color; + text_color_ = color; } void Badge::setBackgroundColor(const QColor &color) { - background_color_ = color; + background_color_ = color; } void Badge::setRelativePosition(const QPointF &pos) { - setRelativePosition(pos.x(), pos.y()); + setRelativePosition(pos.x(), pos.y()); } void Badge::setRelativePosition(qreal x, qreal y) { - x_ = x; - y_ = y; - update(); + x_ = x; + y_ = y; + update(); } void Badge::setRelativeXPosition(qreal x) { - x_ = x; - update(); + x_ = x; + update(); } void Badge::setRelativeYPosition(qreal y) { - y_ = y; - update(); + y_ = y; + update(); } void Badge::setIcon(const QIcon &icon) { - icon_ = icon; - update(); + icon_ = icon; + update(); } void Badge::setText(const QString &text) { - text_ = text; + text_ = text; - if (!icon_.isNull()) - icon_ = QIcon(); + if (!icon_.isNull()) + icon_ = QIcon(); - size_ = fontMetrics().size(Qt::TextShowMnemonic, text); + size_ = fontMetrics().size(Qt::TextShowMnemonic, text); - update(); + update(); } void Badge::setDiameter(int diameter) { - if (diameter > 0) { - diameter_ = diameter; - update(); - } + if (diameter > 0) { + diameter_ = diameter; + update(); + } } void Badge::paintEvent(QPaintEvent *) { - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.translate(x_, y_); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.translate(x_, y_); - QBrush brush; - brush.setStyle(Qt::SolidPattern); + QBrush brush; + brush.setStyle(Qt::SolidPattern); - painter.setBrush(brush); - painter.setPen(Qt::NoPen); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); - const int d = diameter(); + const int d = diameter(); - QRectF r(0, 0, d, d); - r.translate(QPointF((width() - d), (height() - d)) / 2); + QRectF r(0, 0, d, d); + r.translate(QPointF((width() - d), (height() - d)) / 2); - if (icon_.isNull()) { - QPen pen; - // TODO: Make badge width configurable. - pen.setWidth(1); - pen.setColor(textColor()); + if (icon_.isNull()) { + QPen pen; + // TODO: Make badge width configurable. + pen.setWidth(1); + pen.setColor(textColor()); - painter.setPen(pen); - painter.drawEllipse(r); + painter.setPen(pen); + painter.drawEllipse(r); - painter.setPen(textColor()); - painter.setBrush(Qt::NoBrush); - painter.drawText(r.translated(0, -0.5), Qt::AlignCenter, text_); - } else { - painter.drawEllipse(r); - QRectF q(0, 0, 16, 16); - q.moveCenter(r.center()); - QPixmap pixmap = icon().pixmap(16, 16); - QPainter icon(&pixmap); - icon.setCompositionMode(QPainter::CompositionMode_SourceIn); - icon.fillRect(pixmap.rect(), textColor()); - painter.drawPixmap(q.toRect(), pixmap); - } + painter.setPen(textColor()); + painter.setBrush(Qt::NoBrush); + painter.drawText(r.translated(0, -0.5), Qt::AlignCenter, text_); + } else { + painter.drawEllipse(r); + QRectF q(0, 0, 16, 16); + q.moveCenter(r.center()); + QPixmap pixmap = icon().pixmap(16, 16); + QPainter icon(&pixmap); + icon.setCompositionMode(QPainter::CompositionMode_SourceIn); + icon.fillRect(pixmap.rect(), textColor()); + painter.drawPixmap(q.toRect(), pixmap); + } } int Badge::diameter() const { - if (icon_.isNull()) { - return qMax(size_.width(), size_.height()) + padding_; - } + if (icon_.isNull()) { + return qMax(size_.width(), size_.height()) + padding_; + } - return diameter_; + return diameter_; } diff --git a/src/ui/Badge.h b/src/ui/Badge.h index 98e16873..15b69b58 100644 --- a/src/ui/Badge.h +++ b/src/ui/Badge.h @@ -13,54 +13,54 @@ class Badge : public OverlayWidget { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) - Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) - Q_PROPERTY(QPointF relativePosition WRITE setRelativePosition READ relativePosition) + Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + Q_PROPERTY(QPointF relativePosition WRITE setRelativePosition READ relativePosition) public: - explicit Badge(QWidget *parent = nullptr); - explicit Badge(const QIcon &icon, QWidget *parent = nullptr); - explicit Badge(const QString &text, QWidget *parent = nullptr); + explicit Badge(QWidget *parent = nullptr); + explicit Badge(const QIcon &icon, QWidget *parent = nullptr); + explicit Badge(const QString &text, QWidget *parent = nullptr); - void setBackgroundColor(const QColor &color); - void setTextColor(const QColor &color); - void setIcon(const QIcon &icon); - void setRelativePosition(const QPointF &pos); - void setRelativePosition(qreal x, qreal y); - void setRelativeXPosition(qreal x); - void setRelativeYPosition(qreal y); - void setText(const QString &text); - void setDiameter(int diameter); + void setBackgroundColor(const QColor &color); + void setTextColor(const QColor &color); + void setIcon(const QIcon &icon); + void setRelativePosition(const QPointF &pos); + void setRelativePosition(qreal x, qreal y); + void setRelativeXPosition(qreal x); + void setRelativeYPosition(qreal y); + void setText(const QString &text); + void setDiameter(int diameter); - QIcon icon() const; - QString text() const; - QColor backgroundColor() const; - QColor textColor() const; - QPointF relativePosition() const; - QSize sizeHint() const override; - qreal relativeXPosition() const; - qreal relativeYPosition() const; + QIcon icon() const; + QString text() const; + QColor backgroundColor() const; + QColor textColor() const; + QPointF relativePosition() const; + QSize sizeHint() const override; + qreal relativeXPosition() const; + qreal relativeYPosition() const; - int diameter() const; + int diameter() const; protected: - void paintEvent(QPaintEvent *event) override; + void paintEvent(QPaintEvent *event) override; private: - void init(); + void init(); - QColor background_color_; - QColor text_color_; + QColor background_color_; + QColor text_color_; - QIcon icon_; - QSize size_; - QString text_; + QIcon icon_; + QSize size_; + QString text_; - int padding_; - int diameter_; + int padding_; + int diameter_; - qreal x_; - qreal y_; + qreal x_; + qreal y_; }; diff --git a/src/ui/DropShadow.cpp b/src/ui/DropShadow.cpp index a413e3f7..31d13b93 100644 --- a/src/ui/DropShadow.cpp +++ b/src/ui/DropShadow.cpp @@ -19,94 +19,89 @@ DropShadow::draw(QPainter &painter, qreal width, qreal height) { - painter.setPen(Qt::NoPen); + painter.setPen(Qt::NoPen); - QLinearGradient gradient; - gradient.setColorAt(startPosition, start); - gradient.setColorAt(endPosition0, end); + QLinearGradient gradient; + gradient.setColorAt(startPosition, start); + gradient.setColorAt(endPosition0, end); - // Right - QPointF right0(width - margin, height / 2); - QPointF right1(width, height / 2); - gradient.setStart(right0); - gradient.setFinalStop(right1); - painter.setBrush(QBrush(gradient)); - // Deprecated in 5.13: painter.drawRoundRect( - // QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - - // margin)), 0.0, 0.0); - painter.drawRoundedRect( - QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), - 0.0, - 0.0); + // Right + QPointF right0(width - margin, height / 2); + QPointF right1(width, height / 2); + gradient.setStart(right0); + gradient.setFinalStop(right1); + painter.setBrush(QBrush(gradient)); + // Deprecated in 5.13: painter.drawRoundRect( + // QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - + // margin)), 0.0, 0.0); + painter.drawRoundedRect( + QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), 0.0, 0.0); - // Left - QPointF left0(margin, height / 2); - QPointF left1(0, height / 2); - gradient.setStart(left0); - gradient.setFinalStop(left1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0); + // Left + QPointF left0(margin, height / 2); + QPointF left1(0, height / 2); + gradient.setStart(left0); + gradient.setFinalStop(left1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0); - // Top - QPointF top0(width / 2, margin); - QPointF top1(width / 2, 0); - gradient.setStart(top0); - gradient.setFinalStop(top1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0); + // Top + QPointF top0(width / 2, margin); + QPointF top1(width / 2, 0); + gradient.setStart(top0); + gradient.setFinalStop(top1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0); - // Bottom - QPointF bottom0(width / 2, height - margin); - QPointF bottom1(width / 2, height); - gradient.setStart(bottom0); - gradient.setFinalStop(bottom1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), 0.0, 0.0); + // Bottom + QPointF bottom0(width / 2, height - margin); + QPointF bottom1(width / 2, height); + gradient.setStart(bottom0); + gradient.setFinalStop(bottom1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), 0.0, 0.0); - // BottomRight - QPointF bottomright0(width - margin, height - margin); - QPointF bottomright1(width, height); - gradient.setStart(bottomright0); - gradient.setFinalStop(bottomright1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); + // BottomRight + QPointF bottomright0(width - margin, height - margin); + QPointF bottomright1(width, height); + gradient.setStart(bottomright0); + gradient.setFinalStop(bottomright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); - // BottomLeft - QPointF bottomleft0(margin, height - margin); - QPointF bottomleft1(0, height); - gradient.setStart(bottomleft0); - gradient.setFinalStop(bottomleft1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); + // BottomLeft + QPointF bottomleft0(margin, height - margin); + QPointF bottomleft1(0, height); + gradient.setStart(bottomleft0); + gradient.setFinalStop(bottomleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); - // TopLeft - QPointF topleft0(margin, margin); - QPointF topleft1(0, 0); - gradient.setStart(topleft0); - gradient.setFinalStop(topleft1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0); + // TopLeft + QPointF topleft0(margin, margin); + QPointF topleft1(0, 0); + gradient.setStart(topleft0); + gradient.setFinalStop(topleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0); - // TopRight - QPointF topright0(width - margin, margin); - QPointF topright1(width, 0); - gradient.setStart(topright0); - gradient.setFinalStop(topright1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0); + // TopRight + QPointF topright0(width - margin, margin); + QPointF topright1(width, 0); + gradient.setStart(topright0); + gradient.setFinalStop(topright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0); - // Widget - painter.setBrush(QBrush("#FFFFFF")); - painter.setRenderHint(QPainter::Antialiasing); - painter.drawRoundedRect( - QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), - radius, - radius); + // Widget + painter.setBrush(QBrush("#FFFFFF")); + painter.setRenderHint(QPainter::Antialiasing); + painter.drawRoundedRect( + QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), radius, radius); } diff --git a/src/ui/DropShadow.h b/src/ui/DropShadow.h index 4ace4731..f089d0b3 100644 --- a/src/ui/DropShadow.h +++ b/src/ui/DropShadow.h @@ -11,14 +11,14 @@ class QPainter; class DropShadow { public: - static void draw(QPainter &painter, - qint16 margin, - qreal radius, - QColor start, - QColor end, - qreal startPosition, - qreal endPosition0, - qreal endPosition1, - qreal width, - qreal height); + static void draw(QPainter &painter, + qint16 margin, + qreal radius, + QColor start, + QColor end, + qreal startPosition, + qreal endPosition0, + qreal endPosition1, + qreal width, + qreal height); }; diff --git a/src/ui/FlatButton.cpp b/src/ui/FlatButton.cpp index c036401b..4d19c8bb 100644 --- a/src/ui/FlatButton.cpp +++ b/src/ui/FlatButton.cpp @@ -30,60 +30,60 @@ static QString removeKDEAccelerators(QString text) { - return text.remove(QChar('&')); + return text.remove(QChar('&')); } void FlatButton::init() { - ripple_overlay_ = new RippleOverlay(this); - state_machine_ = new FlatButtonStateMachine(this); - role_ = ui::Role::Default; - ripple_style_ = ui::RippleStyle::PositionedRipple; - icon_placement_ = ui::ButtonIconPlacement::LeftIcon; - overlay_style_ = ui::OverlayStyle::GrayOverlay; - bg_mode_ = Qt::TransparentMode; - fixed_ripple_radius_ = 64; - corner_radius_ = 3; - base_opacity_ = 0.13; - font_size_ = 10; // 10.5; - use_fixed_ripple_radius_ = false; - - setStyle(&ThemeManager::instance()); - setAttribute(Qt::WA_Hover); - setMouseTracking(true); - setCursor(QCursor(Qt::PointingHandCursor)); + ripple_overlay_ = new RippleOverlay(this); + state_machine_ = new FlatButtonStateMachine(this); + role_ = ui::Role::Default; + ripple_style_ = ui::RippleStyle::PositionedRipple; + icon_placement_ = ui::ButtonIconPlacement::LeftIcon; + overlay_style_ = ui::OverlayStyle::GrayOverlay; + bg_mode_ = Qt::TransparentMode; + fixed_ripple_radius_ = 64; + corner_radius_ = 3; + base_opacity_ = 0.13; + font_size_ = 10; // 10.5; + use_fixed_ripple_radius_ = false; - QPainterPath path; - path.addRoundedRect(rect(), corner_radius_, corner_radius_); + setStyle(&ThemeManager::instance()); + setAttribute(Qt::WA_Hover); + setMouseTracking(true); + setCursor(QCursor(Qt::PointingHandCursor)); + + QPainterPath path; + path.addRoundedRect(rect(), corner_radius_, corner_radius_); - ripple_overlay_->setClipPath(path); - ripple_overlay_->setClipping(true); + ripple_overlay_->setClipPath(path); + ripple_overlay_->setClipping(true); - state_machine_->setupProperties(); - state_machine_->startAnimations(); + state_machine_->setupProperties(); + state_machine_->startAnimations(); } FlatButton::FlatButton(QWidget *parent, ui::ButtonPreset preset) : QPushButton(parent) { - init(); - applyPreset(preset); + init(); + applyPreset(preset); } FlatButton::FlatButton(const QString &text, QWidget *parent, ui::ButtonPreset preset) : QPushButton(text, parent) { - init(); - applyPreset(preset); + init(); + applyPreset(preset); } FlatButton::FlatButton(const QString &text, ui::Role role, QWidget *parent, ui::ButtonPreset preset) : QPushButton(text, parent) { - init(); - applyPreset(preset); - setRole(role); + init(); + applyPreset(preset); + setRole(role); } FlatButton::~FlatButton() {} @@ -91,406 +91,406 @@ FlatButton::~FlatButton() {} void FlatButton::applyPreset(ui::ButtonPreset preset) { - switch (preset) { - case ui::ButtonPreset::FlatPreset: - setOverlayStyle(ui::OverlayStyle::NoOverlay); - break; - case ui::ButtonPreset::CheckablePreset: - setOverlayStyle(ui::OverlayStyle::NoOverlay); - setCheckable(true); - break; - default: - break; - } + switch (preset) { + case ui::ButtonPreset::FlatPreset: + setOverlayStyle(ui::OverlayStyle::NoOverlay); + break; + case ui::ButtonPreset::CheckablePreset: + setOverlayStyle(ui::OverlayStyle::NoOverlay); + setCheckable(true); + break; + default: + break; + } } void FlatButton::setRole(ui::Role role) { - role_ = role; - state_machine_->setupProperties(); + role_ = role; + state_machine_->setupProperties(); } ui::Role FlatButton::role() const { - return role_; + return role_; } void FlatButton::setForegroundColor(const QColor &color) { - foreground_color_ = color; + foreground_color_ = color; } QColor FlatButton::foregroundColor() const { - if (!foreground_color_.isValid()) { - if (bg_mode_ == Qt::OpaqueMode) { - return ThemeManager::instance().themeColor("BrightWhite"); - } - - switch (role_) { - case ui::Role::Primary: - return ThemeManager::instance().themeColor("Blue"); - case ui::Role::Secondary: - return ThemeManager::instance().themeColor("Gray"); - case ui::Role::Default: - default: - return ThemeManager::instance().themeColor("Black"); - } + if (!foreground_color_.isValid()) { + if (bg_mode_ == Qt::OpaqueMode) { + return ThemeManager::instance().themeColor("BrightWhite"); + } + + switch (role_) { + case ui::Role::Primary: + return ThemeManager::instance().themeColor("Blue"); + case ui::Role::Secondary: + return ThemeManager::instance().themeColor("Gray"); + case ui::Role::Default: + default: + return ThemeManager::instance().themeColor("Black"); } + } - return foreground_color_; + return foreground_color_; } void FlatButton::setBackgroundColor(const QColor &color) { - background_color_ = color; + background_color_ = color; } QColor FlatButton::backgroundColor() const { - if (!background_color_.isValid()) { - switch (role_) { - case ui::Role::Primary: - return ThemeManager::instance().themeColor("Blue"); - case ui::Role::Secondary: - return ThemeManager::instance().themeColor("Gray"); - case ui::Role::Default: - default: - return ThemeManager::instance().themeColor("Black"); - } + if (!background_color_.isValid()) { + switch (role_) { + case ui::Role::Primary: + return ThemeManager::instance().themeColor("Blue"); + case ui::Role::Secondary: + return ThemeManager::instance().themeColor("Gray"); + case ui::Role::Default: + default: + return ThemeManager::instance().themeColor("Black"); } + } - return background_color_; + return background_color_; } void FlatButton::setOverlayColor(const QColor &color) { - overlay_color_ = color; - setOverlayStyle(ui::OverlayStyle::TintedOverlay); + overlay_color_ = color; + setOverlayStyle(ui::OverlayStyle::TintedOverlay); } QColor FlatButton::overlayColor() const { - if (!overlay_color_.isValid()) { - return foregroundColor(); - } + if (!overlay_color_.isValid()) { + return foregroundColor(); + } - return overlay_color_; + return overlay_color_; } void FlatButton::setDisabledForegroundColor(const QColor &color) { - disabled_color_ = color; + disabled_color_ = color; } QColor FlatButton::disabledForegroundColor() const { - if (!disabled_color_.isValid()) { - return ThemeManager::instance().themeColor("FadedWhite"); - } + if (!disabled_color_.isValid()) { + return ThemeManager::instance().themeColor("FadedWhite"); + } - return disabled_color_; + return disabled_color_; } void FlatButton::setDisabledBackgroundColor(const QColor &color) { - disabled_background_color_ = color; + disabled_background_color_ = color; } QColor FlatButton::disabledBackgroundColor() const { - if (!disabled_background_color_.isValid()) { - return ThemeManager::instance().themeColor("FadedWhite"); - } + if (!disabled_background_color_.isValid()) { + return ThemeManager::instance().themeColor("FadedWhite"); + } - return disabled_background_color_; + return disabled_background_color_; } void FlatButton::setFontSize(qreal size) { - font_size_ = size; + font_size_ = size; - QFont f(font()); - f.setPointSizeF(size); - setFont(f); + QFont f(font()); + f.setPointSizeF(size); + setFont(f); - update(); + update(); } qreal FlatButton::fontSize() const { - return font_size_; + return font_size_; } void FlatButton::setOverlayStyle(ui::OverlayStyle style) { - overlay_style_ = style; - update(); + overlay_style_ = style; + update(); } ui::OverlayStyle FlatButton::overlayStyle() const { - return overlay_style_; + return overlay_style_; } void FlatButton::setRippleStyle(ui::RippleStyle style) { - ripple_style_ = style; + ripple_style_ = style; } ui::RippleStyle FlatButton::rippleStyle() const { - return ripple_style_; + return ripple_style_; } void FlatButton::setIconPlacement(ui::ButtonIconPlacement placement) { - icon_placement_ = placement; - update(); + icon_placement_ = placement; + update(); } ui::ButtonIconPlacement FlatButton::iconPlacement() const { - return icon_placement_; + return icon_placement_; } void FlatButton::setCornerRadius(qreal radius) { - corner_radius_ = radius; - updateClipPath(); - update(); + corner_radius_ = radius; + updateClipPath(); + update(); } qreal FlatButton::cornerRadius() const { - return corner_radius_; + return corner_radius_; } void FlatButton::setBackgroundMode(Qt::BGMode mode) { - bg_mode_ = mode; - state_machine_->setupProperties(); + bg_mode_ = mode; + state_machine_->setupProperties(); } Qt::BGMode FlatButton::backgroundMode() const { - return bg_mode_; + return bg_mode_; } void FlatButton::setBaseOpacity(qreal opacity) { - base_opacity_ = opacity; - state_machine_->setupProperties(); + base_opacity_ = opacity; + state_machine_->setupProperties(); } qreal FlatButton::baseOpacity() const { - return base_opacity_; + return base_opacity_; } void FlatButton::setCheckable(bool value) { - state_machine_->updateCheckedStatus(); - state_machine_->setCheckedOverlayProgress(0); + state_machine_->updateCheckedStatus(); + state_machine_->setCheckedOverlayProgress(0); - QPushButton::setCheckable(value); + QPushButton::setCheckable(value); } void FlatButton::setHasFixedRippleRadius(bool value) { - use_fixed_ripple_radius_ = value; + use_fixed_ripple_radius_ = value; } bool FlatButton::hasFixedRippleRadius() const { - return use_fixed_ripple_radius_; + return use_fixed_ripple_radius_; } void FlatButton::setFixedRippleRadius(qreal radius) { - fixed_ripple_radius_ = radius; - setHasFixedRippleRadius(true); + fixed_ripple_radius_ = radius; + setHasFixedRippleRadius(true); } QSize FlatButton::sizeHint() const { - ensurePolished(); + ensurePolished(); - QSize label(fontMetrics().size(Qt::TextSingleLine, removeKDEAccelerators(text()))); + QSize label(fontMetrics().size(Qt::TextSingleLine, removeKDEAccelerators(text()))); - int w = 20 + label.width(); - int h = label.height(); + int w = 20 + label.width(); + int h = label.height(); - if (!icon().isNull()) { - w += iconSize().width() + FlatButton::IconPadding; - h = qMax(h, iconSize().height()); - } + if (!icon().isNull()) { + w += iconSize().width() + FlatButton::IconPadding; + h = qMax(h, iconSize().height()); + } - return QSize(w, 20 + h); + return QSize(w, 20 + h); } void FlatButton::checkStateSet() { - state_machine_->updateCheckedStatus(); - QPushButton::checkStateSet(); + state_machine_->updateCheckedStatus(); + QPushButton::checkStateSet(); } void FlatButton::mousePressEvent(QMouseEvent *event) { - if (ui::RippleStyle::NoRipple != ripple_style_) { - QPoint pos; - qreal radiusEndValue; + if (ui::RippleStyle::NoRipple != ripple_style_) { + QPoint pos; + qreal radiusEndValue; - if (ui::RippleStyle::CenteredRipple == ripple_style_) { - pos = rect().center(); - } else { - pos = event->pos(); - } + if (ui::RippleStyle::CenteredRipple == ripple_style_) { + pos = rect().center(); + } else { + pos = event->pos(); + } - if (use_fixed_ripple_radius_) { - radiusEndValue = fixed_ripple_radius_; - } else { - radiusEndValue = static_cast<qreal>(width()) / 2; - } + if (use_fixed_ripple_radius_) { + radiusEndValue = fixed_ripple_radius_; + } else { + radiusEndValue = static_cast<qreal>(width()) / 2; + } - Ripple *ripple = new Ripple(pos); + Ripple *ripple = new Ripple(pos); - ripple->setRadiusEndValue(radiusEndValue); - ripple->setOpacityStartValue(0.35); - ripple->setColor(foregroundColor()); - ripple->radiusAnimation()->setDuration(250); - ripple->opacityAnimation()->setDuration(250); + ripple->setRadiusEndValue(radiusEndValue); + ripple->setOpacityStartValue(0.35); + ripple->setColor(foregroundColor()); + ripple->radiusAnimation()->setDuration(250); + ripple->opacityAnimation()->setDuration(250); - ripple_overlay_->addRipple(ripple); - } + ripple_overlay_->addRipple(ripple); + } - QPushButton::mousePressEvent(event); + QPushButton::mousePressEvent(event); } void FlatButton::mouseReleaseEvent(QMouseEvent *event) { - QPushButton::mouseReleaseEvent(event); - state_machine_->updateCheckedStatus(); + QPushButton::mouseReleaseEvent(event); + state_machine_->updateCheckedStatus(); } void FlatButton::resizeEvent(QResizeEvent *event) { - QPushButton::resizeEvent(event); - updateClipPath(); + QPushButton::resizeEvent(event); + updateClipPath(); } void FlatButton::paintEvent(QPaintEvent *event) { - Q_UNUSED(event) + Q_UNUSED(event) - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); - const qreal cr = corner_radius_; + const qreal cr = corner_radius_; - if (cr > 0) { - QPainterPath path; - path.addRoundedRect(rect(), cr, cr); + if (cr > 0) { + QPainterPath path; + path.addRoundedRect(rect(), cr, cr); - painter.setClipPath(path); - painter.setClipping(true); - } + painter.setClipPath(path); + painter.setClipping(true); + } - paintBackground(&painter); + paintBackground(&painter); - painter.setOpacity(1); - painter.setClipping(false); + painter.setOpacity(1); + painter.setClipping(false); - paintForeground(&painter); + paintForeground(&painter); } void FlatButton::paintBackground(QPainter *painter) { - const qreal overlayOpacity = state_machine_->overlayOpacity(); - const qreal checkedProgress = state_machine_->checkedOverlayProgress(); + const qreal overlayOpacity = state_machine_->overlayOpacity(); + const qreal checkedProgress = state_machine_->checkedOverlayProgress(); - if (Qt::OpaqueMode == bg_mode_) { - QBrush brush; - brush.setStyle(Qt::SolidPattern); - - if (isEnabled()) { - brush.setColor(backgroundColor()); - } else { - brush.setColor(disabledBackgroundColor()); - } + if (Qt::OpaqueMode == bg_mode_) { + QBrush brush; + brush.setStyle(Qt::SolidPattern); - painter->setOpacity(1); - painter->setBrush(brush); - painter->setPen(Qt::NoPen); - painter->drawRect(rect()); + if (isEnabled()) { + brush.setColor(backgroundColor()); + } else { + brush.setColor(disabledBackgroundColor()); } - QBrush brush; - brush.setStyle(Qt::SolidPattern); + painter->setOpacity(1); + painter->setBrush(brush); painter->setPen(Qt::NoPen); + painter->drawRect(rect()); + } - if (!isEnabled()) { - return; - } + QBrush brush; + brush.setStyle(Qt::SolidPattern); + painter->setPen(Qt::NoPen); - if ((ui::OverlayStyle::NoOverlay != overlay_style_) && (overlayOpacity > 0)) { - if (ui::OverlayStyle::TintedOverlay == overlay_style_) { - brush.setColor(overlayColor()); - } else { - brush.setColor(Qt::gray); - } + if (!isEnabled()) { + return; + } - painter->setOpacity(overlayOpacity); - painter->setBrush(brush); - painter->drawRect(rect()); + if ((ui::OverlayStyle::NoOverlay != overlay_style_) && (overlayOpacity > 0)) { + if (ui::OverlayStyle::TintedOverlay == overlay_style_) { + brush.setColor(overlayColor()); + } else { + brush.setColor(Qt::gray); } - 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); - } + 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() @@ -498,64 +498,63 @@ FlatButton::paintBackground(QPainter *painter) void FlatButton::paintForeground(QPainter *painter) { - if (isEnabled()) { - 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 { - painter->setPen(disabledForegroundColor()); + if (isEnabled()) { + 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 { + painter->setPen(disabledForegroundColor()); + } - if (icon().isNull()) { - painter->drawText(rect(), Qt::AlignCenter, removeKDEAccelerators(text())); - return; - } + if (icon().isNull()) { + painter->drawText(rect(), Qt::AlignCenter, removeKDEAccelerators(text())); + return; + } - QSize textSize(fontMetrics().size(Qt::TextSingleLine, removeKDEAccelerators(text()))); - QSize base(size() - textSize); + QSize textSize(fontMetrics().size(Qt::TextSingleLine, removeKDEAccelerators(text()))); + QSize base(size() - textSize); - const int iw = iconSize().width() + IconPadding; - QPoint pos((base.width() - iw) / 2, 0); + const int iw = iconSize().width() + IconPadding; + QPoint pos((base.width() - iw) / 2, 0); - QRect textGeometry(pos + QPoint(0, base.height() / 2), textSize); - QRect iconGeometry(pos + QPoint(0, (height() - iconSize().height()) / 2), iconSize()); + QRect textGeometry(pos + QPoint(0, base.height() / 2), textSize); + QRect iconGeometry(pos + QPoint(0, (height() - iconSize().height()) / 2), iconSize()); - /* if (ui::LeftIcon == icon_placement_) { */ - /* textGeometry.translate(iw, 0); */ - /* } else { */ - /* iconGeometry.translate(textSize.width() + IconPadding, 0); */ - /* } */ + /* if (ui::LeftIcon == icon_placement_) { */ + /* textGeometry.translate(iw, 0); */ + /* } else { */ + /* iconGeometry.translate(textSize.width() + IconPadding, 0); */ + /* } */ - painter->drawText(textGeometry, Qt::AlignCenter, removeKDEAccelerators(text())); + painter->drawText(textGeometry, Qt::AlignCenter, removeKDEAccelerators(text())); - QPixmap pixmap = icon().pixmap(iconSize()); - QPainter icon(&pixmap); - icon.setCompositionMode(QPainter::CompositionMode_SourceIn); - icon.fillRect(pixmap.rect(), painter->pen().color()); - painter->drawPixmap(iconGeometry, pixmap); + QPixmap pixmap = icon().pixmap(iconSize()); + QPainter icon(&pixmap); + icon.setCompositionMode(QPainter::CompositionMode_SourceIn); + icon.fillRect(pixmap.rect(), painter->pen().color()); + painter->drawPixmap(iconGeometry, pixmap); } void FlatButton::updateClipPath() { - const qreal radius = corner_radius_; + const qreal radius = corner_radius_; - QPainterPath path; - path.addRoundedRect(rect(), radius, radius); - ripple_overlay_->setClipPath(path); + QPainterPath path; + path.addRoundedRect(rect(), radius, radius); + ripple_overlay_->setClipPath(path); } FlatButtonStateMachine::FlatButtonStateMachine(FlatButton *parent) @@ -575,45 +574,45 @@ FlatButtonStateMachine::FlatButtonStateMachine(FlatButton *parent) , checked_overlay_progress_(parent->isChecked() ? 1 : 0) , was_checked_(false) { - Q_ASSERT(parent); + Q_ASSERT(parent); - parent->installEventFilter(this); + parent->installEventFilter(this); - config_state_->setInitialState(neutral_state_); - addState(top_level_state_); - setInitialState(top_level_state_); + 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; + 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); + 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); + 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); + 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); + 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_); + 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_); } FlatButtonStateMachine::~FlatButtonStateMachine() {} @@ -621,73 +620,73 @@ FlatButtonStateMachine::~FlatButtonStateMachine() {} void FlatButtonStateMachine::setOverlayOpacity(qreal opacity) { - overlay_opacity_ = opacity; - button_->update(); + overlay_opacity_ = opacity; + button_->update(); } void FlatButtonStateMachine::setCheckedOverlayProgress(qreal opacity) { - checked_overlay_progress_ = opacity; - button_->update(); + checked_overlay_progress_ = opacity; + button_->update(); } void FlatButtonStateMachine::startAnimations() { - start(); + start(); } void FlatButtonStateMachine::setupProperties() { - QColor overlayColor; + QColor overlayColor; - if (Qt::TransparentMode == button_->backgroundMode()) { - overlayColor = button_->backgroundColor(); - } else { - overlayColor = button_->foregroundColor(); - } + if (Qt::TransparentMode == button_->backgroundMode()) { + overlayColor = button_->backgroundColor(); + } else { + overlayColor = button_->foregroundColor(); + } - const qreal baseOpacity = button_->baseOpacity(); + 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); + 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(); + button_->update(); } void FlatButtonStateMachine::updateCheckedStatus() { - const bool checked = button_->isChecked(); - if (was_checked_ != checked) { - was_checked_ = checked; - if (checked) { - emit buttonChecked(); - } else { - emit buttonUnchecked(); - } + 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; - } + 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); + return QStateMachine::eventFilter(watched, event); } void @@ -696,7 +695,7 @@ FlatButtonStateMachine::addTransition(QObject *object, QState *fromState, QState *toState) { - addTransition(new QSignalTransition(object, signal), fromState, toState); + addTransition(new QSignalTransition(object, signal), fromState, toState); } void @@ -705,7 +704,7 @@ FlatButtonStateMachine::addTransition(QObject *object, QState *fromState, QState *toState) { - addTransition(new QEventTransition(object, eventType), fromState, toState); + addTransition(new QEventTransition(object, eventType), fromState, toState); } void @@ -713,13 +712,13 @@ FlatButtonStateMachine::addTransition(QAbstractTransition *transition, QState *fromState, QState *toState) { - transition->setTargetState(toState); + transition->setTargetState(toState); - QPropertyAnimation *animation; + QPropertyAnimation *animation; - animation = new QPropertyAnimation(this, "overlayOpacity", this); - animation->setDuration(150); - transition->addAnimation(animation); + animation = new QPropertyAnimation(this, "overlayOpacity", this); + animation->setDuration(150); + transition->addAnimation(animation); - fromState->addTransition(transition); + fromState->addTransition(transition); } diff --git a/src/ui/FlatButton.h b/src/ui/FlatButton.h index c79945b7..b39c94ac 100644 --- a/src/ui/FlatButton.h +++ b/src/ui/FlatButton.h @@ -14,174 +14,171 @@ class FlatButton; class FlatButtonStateMachine : public QStateMachine { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(qreal overlayOpacity WRITE setOverlayOpacity READ overlayOpacity) - Q_PROPERTY( - qreal checkedOverlayProgress WRITE setCheckedOverlayProgress READ checkedOverlayProgress) + Q_PROPERTY(qreal overlayOpacity WRITE setOverlayOpacity READ overlayOpacity) + Q_PROPERTY( + qreal checkedOverlayProgress WRITE setCheckedOverlayProgress READ checkedOverlayProgress) public: - explicit FlatButtonStateMachine(FlatButton *parent); - ~FlatButtonStateMachine() override; + explicit FlatButtonStateMachine(FlatButton *parent); + ~FlatButtonStateMachine() override; - void setOverlayOpacity(qreal opacity); - void setCheckedOverlayProgress(qreal opacity); + void setOverlayOpacity(qreal opacity); + void setCheckedOverlayProgress(qreal opacity); - inline qreal overlayOpacity() const; - inline qreal checkedOverlayProgress() const; + inline qreal overlayOpacity() const; + inline qreal checkedOverlayProgress() const; - void startAnimations(); - void setupProperties(); - void updateCheckedStatus(); + void startAnimations(); + void setupProperties(); + void updateCheckedStatus(); signals: - void buttonPressed(); - void buttonChecked(); - void buttonUnchecked(); + void buttonPressed(); + void buttonChecked(); + void buttonUnchecked(); protected: - bool eventFilter(QObject *watched, QEvent *event) override; + 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_; + 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_; + return overlay_opacity_; } inline qreal FlatButtonStateMachine::checkedOverlayProgress() const { - return checked_overlay_progress_; + return checked_overlay_progress_; } class FlatButton : public QPushButton { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor foregroundColor WRITE setForegroundColor READ foregroundColor) - Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) - Q_PROPERTY(QColor overlayColor WRITE setOverlayColor READ overlayColor) - Q_PROPERTY(QColor disabledForegroundColor WRITE setDisabledForegroundColor READ - disabledForegroundColor) - Q_PROPERTY(QColor disabledBackgroundColor WRITE setDisabledBackgroundColor READ - disabledBackgroundColor) - Q_PROPERTY(qreal fontSize WRITE setFontSize READ fontSize) + Q_PROPERTY(QColor foregroundColor WRITE setForegroundColor READ foregroundColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + Q_PROPERTY(QColor overlayColor WRITE setOverlayColor READ overlayColor) + Q_PROPERTY( + QColor disabledForegroundColor WRITE setDisabledForegroundColor READ disabledForegroundColor) + Q_PROPERTY( + QColor disabledBackgroundColor WRITE setDisabledBackgroundColor READ disabledBackgroundColor) + Q_PROPERTY(qreal fontSize WRITE setFontSize READ fontSize) public: - explicit FlatButton(QWidget *parent = nullptr, - ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); - explicit FlatButton(const QString &text, - QWidget *parent = nullptr, - ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); - FlatButton(const QString &text, - ui::Role role, - QWidget *parent = nullptr, - ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); - ~FlatButton() override; - - void applyPreset(ui::ButtonPreset preset); - - void setBackgroundColor(const QColor &color); - void setBackgroundMode(Qt::BGMode mode); - void setBaseOpacity(qreal opacity); - void setCheckable(bool value); - void setCornerRadius(qreal radius); - void setDisabledBackgroundColor(const QColor &color); - void setDisabledForegroundColor(const QColor &color); - void setFixedRippleRadius(qreal radius); - void setFontSize(qreal size); - void setForegroundColor(const QColor &color); - void setHasFixedRippleRadius(bool value); - void setIconPlacement(ui::ButtonIconPlacement placement); - void setOverlayColor(const QColor &color); - void setOverlayStyle(ui::OverlayStyle style); - void setRippleStyle(ui::RippleStyle style); - void setRole(ui::Role role); - - QColor foregroundColor() const; - QColor backgroundColor() const; - QColor overlayColor() const; - QColor disabledForegroundColor() const; - QColor disabledBackgroundColor() const; - - qreal fontSize() const; - qreal cornerRadius() const; - qreal baseOpacity() const; - - bool hasFixedRippleRadius() const; - - ui::Role role() const; - ui::OverlayStyle overlayStyle() const; - ui::RippleStyle rippleStyle() const; - ui::ButtonIconPlacement iconPlacement() const; - - Qt::BGMode backgroundMode() const; - - QSize sizeHint() const override; + explicit FlatButton(QWidget *parent = nullptr, + ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); + explicit FlatButton(const QString &text, + QWidget *parent = nullptr, + ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); + FlatButton(const QString &text, + ui::Role role, + QWidget *parent = nullptr, + ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); + ~FlatButton() override; + + void applyPreset(ui::ButtonPreset preset); + + void setBackgroundColor(const QColor &color); + void setBackgroundMode(Qt::BGMode mode); + void setBaseOpacity(qreal opacity); + void setCheckable(bool value); + void setCornerRadius(qreal radius); + void setDisabledBackgroundColor(const QColor &color); + void setDisabledForegroundColor(const QColor &color); + void setFixedRippleRadius(qreal radius); + void setFontSize(qreal size); + void setForegroundColor(const QColor &color); + void setHasFixedRippleRadius(bool value); + void setIconPlacement(ui::ButtonIconPlacement placement); + void setOverlayColor(const QColor &color); + void setOverlayStyle(ui::OverlayStyle style); + void setRippleStyle(ui::RippleStyle style); + void setRole(ui::Role role); + + QColor foregroundColor() const; + QColor backgroundColor() const; + QColor overlayColor() const; + QColor disabledForegroundColor() const; + QColor disabledBackgroundColor() const; + + qreal fontSize() const; + qreal cornerRadius() const; + qreal baseOpacity() const; + + bool hasFixedRippleRadius() const; + + ui::Role role() const; + ui::OverlayStyle overlayStyle() const; + ui::RippleStyle rippleStyle() const; + ui::ButtonIconPlacement iconPlacement() const; + + Qt::BGMode backgroundMode() const; + + QSize sizeHint() const override; protected: - int IconPadding = 0; + int IconPadding = 0; - void checkStateSet() override; - void mousePressEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void paintEvent(QPaintEvent *event) override; + void checkStateSet() override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void paintEvent(QPaintEvent *event) override; - virtual void paintBackground(QPainter *painter); - virtual void paintForeground(QPainter *painter); - virtual void updateClipPath(); + virtual void paintBackground(QPainter *painter); + virtual void paintForeground(QPainter *painter); + virtual void updateClipPath(); - void init(); + void init(); private: - RippleOverlay *ripple_overlay_; - FlatButtonStateMachine *state_machine_; + RippleOverlay *ripple_overlay_; + FlatButtonStateMachine *state_machine_; - ui::Role role_; - ui::RippleStyle ripple_style_; - ui::ButtonIconPlacement icon_placement_; - ui::OverlayStyle overlay_style_; + ui::Role role_; + ui::RippleStyle ripple_style_; + ui::ButtonIconPlacement icon_placement_; + ui::OverlayStyle overlay_style_; - Qt::BGMode bg_mode_; + Qt::BGMode bg_mode_; - QColor background_color_; - QColor foreground_color_; - QColor overlay_color_; - QColor disabled_color_; - QColor disabled_background_color_; + QColor background_color_; + QColor foreground_color_; + QColor overlay_color_; + QColor disabled_color_; + QColor disabled_background_color_; - qreal fixed_ripple_radius_; - qreal corner_radius_; - qreal base_opacity_; - qreal font_size_; + qreal fixed_ripple_radius_; + qreal corner_radius_; + qreal base_opacity_; + qreal font_size_; - bool use_fixed_ripple_radius_; + bool use_fixed_ripple_radius_; }; diff --git a/src/ui/FloatingButton.cpp b/src/ui/FloatingButton.cpp index 95b6ae1d..3f88e313 100644 --- a/src/ui/FloatingButton.cpp +++ b/src/ui/FloatingButton.cpp @@ -10,91 +10,91 @@ FloatingButton::FloatingButton(const QIcon &icon, QWidget *parent) : RaisedButton(parent) { - setFixedSize(DIAMETER, DIAMETER); - setGeometry(buttonGeometry()); + setFixedSize(DIAMETER, DIAMETER); + setGeometry(buttonGeometry()); - if (parentWidget()) - parentWidget()->installEventFilter(this); + if (parentWidget()) + parentWidget()->installEventFilter(this); - setFixedRippleRadius(50); - setIcon(icon); - raise(); + setFixedRippleRadius(50); + setIcon(icon); + raise(); } QRect FloatingButton::buttonGeometry() const { - QWidget *parent = parentWidget(); + QWidget *parent = parentWidget(); - if (!parent) - return QRect(); + if (!parent) + return QRect(); - return QRect(parent->width() - (OFFSET_X + DIAMETER), - parent->height() - (OFFSET_Y + DIAMETER), - DIAMETER, - DIAMETER); + return QRect(parent->width() - (OFFSET_X + DIAMETER), + parent->height() - (OFFSET_Y + DIAMETER), + DIAMETER, + DIAMETER); } bool FloatingButton::event(QEvent *event) { - if (!parent()) - return RaisedButton::event(event); - - switch (event->type()) { - case QEvent::ParentChange: { - parent()->installEventFilter(this); - setGeometry(buttonGeometry()); - break; - } - case QEvent::ParentAboutToChange: { - parent()->installEventFilter(this); - break; - } - default: - break; - } - + if (!parent()) return RaisedButton::event(event); + + switch (event->type()) { + case QEvent::ParentChange: { + parent()->installEventFilter(this); + setGeometry(buttonGeometry()); + break; + } + case QEvent::ParentAboutToChange: { + parent()->installEventFilter(this); + break; + } + default: + break; + } + + return RaisedButton::event(event); } bool FloatingButton::eventFilter(QObject *obj, QEvent *event) { - const QEvent::Type type = event->type(); + const QEvent::Type type = event->type(); - if (QEvent::Move == type || QEvent::Resize == type) - setGeometry(buttonGeometry()); + if (QEvent::Move == type || QEvent::Resize == type) + setGeometry(buttonGeometry()); - return RaisedButton::eventFilter(obj, event); + return RaisedButton::eventFilter(obj, event); } void FloatingButton::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); + Q_UNUSED(event); - QRect square = QRect(0, 0, DIAMETER, DIAMETER); - square.moveCenter(rect().center()); + QRect square = QRect(0, 0, DIAMETER, DIAMETER); + square.moveCenter(rect().center()); - QPainter p(this); - p.setRenderHints(QPainter::Antialiasing); + QPainter p(this); + p.setRenderHints(QPainter::Antialiasing); - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor(backgroundColor()); + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(backgroundColor()); - p.setBrush(brush); - p.setPen(Qt::NoPen); - p.drawEllipse(square); + p.setBrush(brush); + p.setPen(Qt::NoPen); + p.drawEllipse(square); - QRect iconGeometry(0, 0, ICON_SIZE, ICON_SIZE); - iconGeometry.moveCenter(square.center()); + QRect iconGeometry(0, 0, ICON_SIZE, ICON_SIZE); + iconGeometry.moveCenter(square.center()); - QPixmap pixmap = icon().pixmap(QSize(ICON_SIZE, ICON_SIZE)); - QPainter icon(&pixmap); - icon.setCompositionMode(QPainter::CompositionMode_SourceIn); - icon.fillRect(pixmap.rect(), foregroundColor()); + QPixmap pixmap = icon().pixmap(QSize(ICON_SIZE, ICON_SIZE)); + QPainter icon(&pixmap); + icon.setCompositionMode(QPainter::CompositionMode_SourceIn); + icon.fillRect(pixmap.rect(), foregroundColor()); - p.drawPixmap(iconGeometry, pixmap); + p.drawPixmap(iconGeometry, pixmap); } diff --git a/src/ui/FloatingButton.h b/src/ui/FloatingButton.h index b59b3854..df14dd2c 100644 --- a/src/ui/FloatingButton.h +++ b/src/ui/FloatingButton.h @@ -14,17 +14,17 @@ constexpr int OFFSET_Y = 20; class FloatingButton : public RaisedButton { - Q_OBJECT + Q_OBJECT public: - FloatingButton(const QIcon &icon, QWidget *parent = nullptr); + FloatingButton(const QIcon &icon, QWidget *parent = nullptr); - QSize sizeHint() const override { return QSize(DIAMETER, DIAMETER); }; - QRect buttonGeometry() const; + QSize sizeHint() const override { return QSize(DIAMETER, DIAMETER); }; + QRect buttonGeometry() const; protected: - bool event(QEvent *event) override; - bool eventFilter(QObject *obj, QEvent *event) override; + bool event(QEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; - void paintEvent(QPaintEvent *event) override; + void paintEvent(QPaintEvent *event) override; }; diff --git a/src/ui/InfoMessage.cpp b/src/ui/InfoMessage.cpp index ebe0e63f..e238a4d2 100644 --- a/src/ui/InfoMessage.cpp +++ b/src/ui/InfoMessage.cpp @@ -19,60 +19,60 @@ constexpr int HMargin = 20; InfoMessage::InfoMessage(QWidget *parent) : QWidget{parent} { - initFont(); + initFont(); } InfoMessage::InfoMessage(QString msg, QWidget *parent) : QWidget{parent} , msg_{msg} { - initFont(); + initFont(); - QFontMetrics fm{font()}; - width_ = fm.horizontalAdvance(msg_) + HPadding * 2; - height_ = fm.ascent() + 2 * VPadding; + QFontMetrics fm{font()}; + width_ = fm.horizontalAdvance(msg_) + HPadding * 2; + height_ = fm.ascent() + 2 * VPadding; - setFixedHeight(height_ + 2 * HMargin); + setFixedHeight(height_ + 2 * HMargin); } void InfoMessage::paintEvent(QPaintEvent *) { - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - p.setFont(font()); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + p.setFont(font()); - // Center the box horizontally & vertically. - auto textRegion = QRectF(width() / 2 - width_ / 2, HMargin, width_, height_); + // Center the box horizontally & vertically. + auto textRegion = QRectF(width() / 2 - width_ / 2, HMargin, width_, height_); - QPainterPath ppath; - ppath.addRoundedRect(textRegion, height_ / 2, height_ / 2); + QPainterPath ppath; + ppath.addRoundedRect(textRegion, height_ / 2, height_ / 2); - p.setPen(Qt::NoPen); - p.fillPath(ppath, boxColor()); - p.drawPath(ppath); + p.setPen(Qt::NoPen); + p.fillPath(ppath, boxColor()); + p.drawPath(ppath); - p.setPen(QPen(textColor())); - p.drawText(textRegion, Qt::AlignCenter, msg_); + p.setPen(QPen(textColor())); + p.drawText(textRegion, Qt::AlignCenter, msg_); } DateSeparator::DateSeparator(QDateTime datetime, QWidget *parent) : InfoMessage{parent} { - auto now = QDateTime::currentDateTime(); + auto now = QDateTime::currentDateTime(); - QString fmt = QLocale::system().dateFormat(QLocale::LongFormat); + QString fmt = QLocale::system().dateFormat(QLocale::LongFormat); - if (now.date().year() == datetime.date().year()) { - QRegularExpression rx("[^a-zA-Z]*y+[^a-zA-Z]*"); - fmt = fmt.remove(rx); - } + if (now.date().year() == datetime.date().year()) { + QRegularExpression rx("[^a-zA-Z]*y+[^a-zA-Z]*"); + fmt = fmt.remove(rx); + } - msg_ = datetime.date().toString(fmt); + msg_ = datetime.date().toString(fmt); - QFontMetrics fm{font()}; - width_ = fm.horizontalAdvance(msg_) + HPadding * 2; - height_ = fm.ascent() + 2 * VPadding; + QFontMetrics fm{font()}; + width_ = fm.horizontalAdvance(msg_) + HPadding * 2; + height_ = fm.ascent() + 2 * VPadding; - setFixedHeight(height_ + 2 * HMargin); + setFixedHeight(height_ + 2 * HMargin); } diff --git a/src/ui/InfoMessage.h b/src/ui/InfoMessage.h index cc0c57dc..486812a2 100644 --- a/src/ui/InfoMessage.h +++ b/src/ui/InfoMessage.h @@ -10,47 +10,47 @@ class InfoMessage : public QWidget { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) - Q_PROPERTY(QColor boxColor WRITE setBoxColor READ boxColor) + Q_PROPERTY(QColor textColor WRITE setTextColor READ textColor) + Q_PROPERTY(QColor boxColor WRITE setBoxColor READ boxColor) public: - explicit InfoMessage(QWidget *parent = nullptr); - InfoMessage(QString msg, QWidget *parent = nullptr); + explicit InfoMessage(QWidget *parent = nullptr); + InfoMessage(QString msg, QWidget *parent = nullptr); - void setTextColor(QColor color) { textColor_ = color; } - void setBoxColor(QColor color) { boxColor_ = color; } - void saveDatetime(QDateTime datetime) { datetime_ = datetime; } + void setTextColor(QColor color) { textColor_ = color; } + void setBoxColor(QColor color) { boxColor_ = color; } + void saveDatetime(QDateTime datetime) { datetime_ = datetime; } - QColor textColor() const { return textColor_; } - QColor boxColor() const { return boxColor_; } - QDateTime datetime() const { return datetime_; } + QColor textColor() const { return textColor_; } + QColor boxColor() const { return boxColor_; } + QDateTime datetime() const { return datetime_; } protected: - void paintEvent(QPaintEvent *event) override; - void initFont() - { - QFont f; - f.setWeight(QFont::Medium); - setFont(f); - } + void paintEvent(QPaintEvent *event) override; + void initFont() + { + QFont f; + f.setWeight(QFont::Medium); + setFont(f); + } - int width_; - int height_; + int width_; + int height_; - QString msg_; + QString msg_; - QDateTime datetime_; + QDateTime datetime_; - QColor textColor_ = QColor("black"); - QColor boxColor_ = QColor("white"); + QColor textColor_ = QColor("black"); + QColor boxColor_ = QColor("white"); }; class DateSeparator : public InfoMessage { - Q_OBJECT + Q_OBJECT public: - DateSeparator(QDateTime datetime, QWidget *parent = nullptr); + DateSeparator(QDateTime datetime, QWidget *parent = nullptr); }; diff --git a/src/ui/Label.cpp b/src/ui/Label.cpp index 2e8f8e1d..220fe2f0 100644 --- a/src/ui/Label.cpp +++ b/src/ui/Label.cpp @@ -17,16 +17,16 @@ Label::Label(const QString &text, QWidget *parent, Qt::WindowFlags f) void Label::mousePressEvent(QMouseEvent *e) { - pressPosition_ = e->pos(); - emit pressed(e); - QLabel::mousePressEvent(e); + pressPosition_ = e->pos(); + emit pressed(e); + QLabel::mousePressEvent(e); } void Label::mouseReleaseEvent(QMouseEvent *e) { - emit released(e); - if (pressPosition_ == e->pos()) - emit clicked(e); - QLabel::mouseReleaseEvent(e); + emit released(e); + if (pressPosition_ == e->pos()) + emit clicked(e); + QLabel::mouseReleaseEvent(e); } diff --git a/src/ui/Label.h b/src/ui/Label.h index a3eb511b..b6e76b77 100644 --- a/src/ui/Label.h +++ b/src/ui/Label.h @@ -8,22 +8,22 @@ class Label : public QLabel { - Q_OBJECT + Q_OBJECT public: - explicit Label(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); - explicit Label(const QString &text, - QWidget *parent = Q_NULLPTR, - Qt::WindowFlags f = Qt::WindowFlags()); + explicit Label(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); + explicit Label(const QString &text, + QWidget *parent = Q_NULLPTR, + Qt::WindowFlags f = Qt::WindowFlags()); signals: - void clicked(QMouseEvent *e); - void pressed(QMouseEvent *e); - void released(QMouseEvent *e); + void clicked(QMouseEvent *e); + void pressed(QMouseEvent *e); + void released(QMouseEvent *e); protected: - void mousePressEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; - QPoint pressPosition_; + QPoint pressPosition_; }; diff --git a/src/ui/LoadingIndicator.cpp b/src/ui/LoadingIndicator.cpp index fb3c761c..7581ec83 100644 --- a/src/ui/LoadingIndicator.cpp +++ b/src/ui/LoadingIndicator.cpp @@ -14,70 +14,70 @@ LoadingIndicator::LoadingIndicator(QWidget *parent) , angle_(0) , color_(Qt::black) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFocusPolicy(Qt::NoFocus); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setFocusPolicy(Qt::NoFocus); - timer_ = new QTimer(this); - connect(timer_, SIGNAL(timeout()), this, SLOT(onTimeout())); + timer_ = new QTimer(this); + connect(timer_, SIGNAL(timeout()), this, SLOT(onTimeout())); } void LoadingIndicator::paintEvent(QPaintEvent *e) { - Q_UNUSED(e) + Q_UNUSED(e) - if (!timer_->isActive()) - return; + if (!timer_->isActive()) + return; - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); - int width = qMin(this->width(), this->height()); + int width = qMin(this->width(), this->height()); - int outerRadius = (width - 4) * 0.5f; - int innerRadius = outerRadius * 0.78f; + int outerRadius = (width - 4) * 0.5f; + int innerRadius = outerRadius * 0.78f; - int capsuleRadius = (outerRadius - innerRadius) / 2; + int capsuleRadius = (outerRadius - innerRadius) / 2; - for (int i = 0; i < 8; ++i) { - QColor color = color_; + for (int i = 0; i < 8; ++i) { + QColor color = color_; - color.setAlphaF(1.0f - (i / 8.0f)); + color.setAlphaF(1.0f - (i / 8.0f)); - painter.setPen(Qt::NoPen); - painter.setBrush(color); + painter.setPen(Qt::NoPen); + painter.setBrush(color); - qreal radius = capsuleRadius * (1.0f - (i / 16.0f)); + qreal radius = capsuleRadius * (1.0f - (i / 16.0f)); - painter.save(); + painter.save(); - painter.translate(rect().center()); - painter.rotate(angle_ - i * 45.0f); + painter.translate(rect().center()); + painter.rotate(angle_ - i * 45.0f); - QPointF center = QPointF(-capsuleRadius, -innerRadius); - painter.drawEllipse(center, radius * 2, radius * 2); + QPointF center = QPointF(-capsuleRadius, -innerRadius); + painter.drawEllipse(center, radius * 2, radius * 2); - painter.restore(); - } + painter.restore(); + } } void LoadingIndicator::start() { - timer_->start(interval_); - show(); + timer_->start(interval_); + show(); } void LoadingIndicator::stop() { - timer_->stop(); - hide(); + timer_->stop(); + hide(); } void LoadingIndicator::onTimeout() { - angle_ = (angle_ + 45) % 360; - repaint(); + angle_ = (angle_ + 45) % 360; + repaint(); } diff --git a/src/ui/LoadingIndicator.h b/src/ui/LoadingIndicator.h index ba56b449..458ecd40 100644 --- a/src/ui/LoadingIndicator.h +++ b/src/ui/LoadingIndicator.h @@ -12,30 +12,30 @@ class QTimer; class QPaintEvent; class LoadingIndicator : public QWidget { - Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor) public: - LoadingIndicator(QWidget *parent = nullptr); + LoadingIndicator(QWidget *parent = nullptr); - void paintEvent(QPaintEvent *e) override; + void paintEvent(QPaintEvent *e) override; - void start(); - void stop(); + void start(); + void stop(); - QColor color() { return color_; } - void setColor(QColor color) { color_ = color; } + QColor color() { return color_; } + void setColor(QColor color) { color_ = color; } - int interval() { return interval_; } - void setInterval(int interval) { interval_ = interval; } + int interval() { return interval_; } + void setInterval(int interval) { interval_ = interval; } private slots: - void onTimeout(); + void onTimeout(); private: - int interval_; - int angle_; + int interval_; + int angle_; - QColor color_; - QTimer *timer_; + QColor color_; + QTimer *timer_; }; diff --git a/src/ui/Menu.h b/src/ui/Menu.h index fd2946dd..d1ac2b80 100644 --- a/src/ui/Menu.h +++ b/src/ui/Menu.h @@ -10,16 +10,16 @@ class Menu : public QMenu { - Q_OBJECT + Q_OBJECT public: - Menu(QWidget *parent = nullptr) - : QMenu(parent){}; + Menu(QWidget *parent = nullptr) + : QMenu(parent){}; protected: - void leaveEvent(QEvent *e) override - { - hide(); + void leaveEvent(QEvent *e) override + { + hide(); - QMenu::leaveEvent(e); - } + QMenu::leaveEvent(e); + } }; diff --git a/src/ui/MxcAnimatedImage.cpp b/src/ui/MxcAnimatedImage.cpp index c691bab0..72758653 100644 --- a/src/ui/MxcAnimatedImage.cpp +++ b/src/ui/MxcAnimatedImage.cpp @@ -19,160 +19,157 @@ void MxcAnimatedImage::startDownload() { - if (!room_) - return; - if (eventId_.isEmpty()) - return; - - auto event = room_->eventById(eventId_); - if (!event) { - nhlog::ui()->error("Failed to load media for event {}, event not found.", - eventId_.toStdString()); - return; - } + if (!room_) + return; + if (eventId_.isEmpty()) + return; - QByteArray mimeType = QString::fromStdString(mtx::accessors::mimetype(*event)).toUtf8(); + auto event = room_->eventById(eventId_); + if (!event) { + nhlog::ui()->error("Failed to load media for event {}, event not found.", + eventId_.toStdString()); + return; + } - animatable_ = QMovie::supportedFormats().contains(mimeType.split('/').back()); - animatableChanged(); + QByteArray mimeType = QString::fromStdString(mtx::accessors::mimetype(*event)).toUtf8(); - if (!animatable_) - return; + animatable_ = QMovie::supportedFormats().contains(mimeType.split('/').back()); + animatableChanged(); - QString mxcUrl = QString::fromStdString(mtx::accessors::url(*event)); - QString originalFilename = QString::fromStdString(mtx::accessors::filename(*event)); + if (!animatable_) + return; - auto encryptionInfo = mtx::accessors::file(*event); + QString mxcUrl = QString::fromStdString(mtx::accessors::url(*event)); + QString originalFilename = QString::fromStdString(mtx::accessors::filename(*event)); - // If the message is a link to a non mxcUrl, don't download it - if (!mxcUrl.startsWith("mxc://")) { - return; - } + auto encryptionInfo = mtx::accessors::file(*event); - QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix(); - - const auto url = mxcUrl.toStdString(); - const auto name = QString(mxcUrl).remove("mxc://"); - QFileInfo filename(QString("%1/media_cache/media/%2.%3") - .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) - .arg(name) - .arg(suffix)); - if (QDir::cleanPath(name) != name) { - nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url); - return; - } + // If the message is a link to a non mxcUrl, don't download it + if (!mxcUrl.startsWith("mxc://")) { + return; + } + + QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix(); + + const auto url = mxcUrl.toStdString(); + const auto name = QString(mxcUrl).remove("mxc://"); + QFileInfo filename(QString("%1/media_cache/media/%2.%3") + .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) + .arg(name) + .arg(suffix)); + if (QDir::cleanPath(name) != name) { + nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url); + return; + } + + QDir().mkpath(filename.path()); + + QPointer<MxcAnimatedImage> self = this; + + auto processBuffer = [this, mimeType, encryptionInfo, self](QIODevice &device) { + if (!self) + return; - QDir().mkpath(filename.path()); - - QPointer<MxcAnimatedImage> self = this; - - auto processBuffer = [this, mimeType, encryptionInfo, self](QIODevice &device) { - if (!self) - return; - - if (buffer.isOpen()) { - movie.stop(); - movie.setDevice(nullptr); - buffer.close(); - } - - if (encryptionInfo) { - QByteArray ba = device.readAll(); - std::string temp(ba.constData(), ba.size()); - temp = mtx::crypto::to_string( - mtx::crypto::decrypt_file(temp, encryptionInfo.value())); - buffer.setData(temp.data(), temp.size()); - } else { - buffer.setData(device.readAll()); - } - buffer.open(QIODevice::ReadOnly); - buffer.reset(); - - QTimer::singleShot(0, this, [this, mimeType] { - nhlog::ui()->info("Playing movie with size: {}, {}", - buffer.bytesAvailable(), - buffer.isOpen()); - movie.setFormat(mimeType); - movie.setDevice(&buffer); - if (play_) - movie.start(); - else - movie.jumpToFrame(0); - emit loadedChanged(); - update(); - }); - }; - - if (filename.isReadable()) { - QFile f(filename.filePath()); - if (f.open(QIODevice::ReadOnly)) { - processBuffer(f); - return; - } + if (buffer.isOpen()) { + movie.stop(); + movie.setDevice(nullptr); + buffer.close(); } - http::client()->download( - url, - [filename, url, processBuffer](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to retrieve media {}: {} {}", - url, - err->matrix_error.error, - static_cast<int>(err->status_code)); - return; - } - - try { - QFile file(filename.filePath()); - - if (!file.open(QIODevice::WriteOnly)) - return; - - QByteArray ba(data.data(), (int)data.size()); - file.write(ba); - file.close(); - - QBuffer buf(&ba); - buf.open(QBuffer::ReadOnly); - processBuffer(buf); - } catch (const std::exception &e) { - nhlog::ui()->warn("Error while saving file to: {}", e.what()); - } - }); + if (encryptionInfo) { + QByteArray ba = device.readAll(); + std::string temp(ba.constData(), ba.size()); + temp = mtx::crypto::to_string(mtx::crypto::decrypt_file(temp, encryptionInfo.value())); + buffer.setData(temp.data(), temp.size()); + } else { + buffer.setData(device.readAll()); + } + buffer.open(QIODevice::ReadOnly); + buffer.reset(); + + QTimer::singleShot(0, this, [this, mimeType] { + nhlog::ui()->info( + "Playing movie with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen()); + movie.setFormat(mimeType); + movie.setDevice(&buffer); + if (play_) + movie.start(); + else + movie.jumpToFrame(0); + emit loadedChanged(); + update(); + }); + }; + + if (filename.isReadable()) { + QFile f(filename.filePath()); + if (f.open(QIODevice::ReadOnly)) { + processBuffer(f); + return; + } + } + + http::client()->download(url, + [filename, url, processBuffer](const std::string &data, + const std::string &, + const std::string &, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to retrieve media {}: {} {}", + url, + err->matrix_error.error, + static_cast<int>(err->status_code)); + return; + } + + try { + QFile file(filename.filePath()); + + if (!file.open(QIODevice::WriteOnly)) + return; + + QByteArray ba(data.data(), (int)data.size()); + file.write(ba); + file.close(); + + QBuffer buf(&ba); + buf.open(QBuffer::ReadOnly); + processBuffer(buf); + } catch (const std::exception &e) { + nhlog::ui()->warn("Error while saving file to: {}", e.what()); + } + }); } QSGNode * MxcAnimatedImage::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) { - if (!imageDirty) - return oldNode; - - imageDirty = false; - QSGImageNode *n = static_cast<QSGImageNode *>(oldNode); - if (!n) { - n = window()->createImageNode(); - n->setOwnsTexture(true); - // n->setFlags(QSGNode::OwnedByParent | QSGNode::OwnsGeometry | - // GSGNode::OwnsMaterial); - n->setFlags(QSGNode::OwnedByParent); - } - - // n->setTexture(nullptr); - auto img = movie.currentImage(); - if (!img.isNull()) - n->setTexture(window()->createTextureFromImage(img)); - else { - delete n; - return nullptr; - } - - n->setSourceRect(img.rect()); - n->setRect(QRect(0, 0, width(), height())); - n->setFiltering(QSGTexture::Linear); - n->setMipmapFiltering(QSGTexture::Linear); - - return n; + if (!imageDirty) + return oldNode; + + imageDirty = false; + QSGImageNode *n = static_cast<QSGImageNode *>(oldNode); + if (!n) { + n = window()->createImageNode(); + n->setOwnsTexture(true); + // n->setFlags(QSGNode::OwnedByParent | QSGNode::OwnsGeometry | + // GSGNode::OwnsMaterial); + n->setFlags(QSGNode::OwnedByParent); + } + + // n->setTexture(nullptr); + auto img = movie.currentImage(); + if (!img.isNull()) + n->setTexture(window()->createTextureFromImage(img)); + else { + delete n; + return nullptr; + } + + n->setSourceRect(img.rect()); + n->setRect(QRect(0, 0, width(), height())); + n->setFiltering(QSGTexture::Linear); + n->setMipmapFiltering(QSGTexture::Linear); + + return n; } diff --git a/src/ui/MxcAnimatedImage.h b/src/ui/MxcAnimatedImage.h index 2e0489ad..c3ca24d1 100644 --- a/src/ui/MxcAnimatedImage.h +++ b/src/ui/MxcAnimatedImage.h @@ -14,78 +14,78 @@ class TimelineModel; // This is an AnimatedImage, that can draw encrypted images class MxcAnimatedImage : public QQuickItem { - Q_OBJECT - Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) - Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) - Q_PROPERTY(bool animatable READ animatable NOTIFY animatableChanged) - Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) - Q_PROPERTY(bool play READ play WRITE setPlay NOTIFY playChanged) + Q_OBJECT + Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) + Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) + Q_PROPERTY(bool animatable READ animatable NOTIFY animatableChanged) + Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) + Q_PROPERTY(bool play READ play WRITE setPlay NOTIFY playChanged) public: - MxcAnimatedImage(QQuickItem *parent = nullptr) - : QQuickItem(parent) - { - connect(this, &MxcAnimatedImage::eventIdChanged, &MxcAnimatedImage::startDownload); - connect(this, &MxcAnimatedImage::roomChanged, &MxcAnimatedImage::startDownload); - connect(&movie, &QMovie::frameChanged, this, &MxcAnimatedImage::newFrame); - setFlag(QQuickItem::ItemHasContents); - // setAcceptHoverEvents(true); - } + MxcAnimatedImage(QQuickItem *parent = nullptr) + : QQuickItem(parent) + { + connect(this, &MxcAnimatedImage::eventIdChanged, &MxcAnimatedImage::startDownload); + connect(this, &MxcAnimatedImage::roomChanged, &MxcAnimatedImage::startDownload); + connect(&movie, &QMovie::frameChanged, this, &MxcAnimatedImage::newFrame); + setFlag(QQuickItem::ItemHasContents); + // setAcceptHoverEvents(true); + } - bool animatable() const { return animatable_; } - bool loaded() const { return buffer.size() > 0; } - bool play() const { return play_; } - QString eventId() const { return eventId_; } - TimelineModel *room() const { return room_; } - void setEventId(QString newEventId) - { - if (eventId_ != newEventId) { - eventId_ = newEventId; - emit eventIdChanged(); - } + bool animatable() const { return animatable_; } + bool loaded() const { return buffer.size() > 0; } + bool play() const { return play_; } + QString eventId() const { return eventId_; } + TimelineModel *room() const { return room_; } + void setEventId(QString newEventId) + { + if (eventId_ != newEventId) { + eventId_ = newEventId; + emit eventIdChanged(); } - void setRoom(TimelineModel *room) - { - if (room_ != room) { - room_ = room; - emit roomChanged(); - } + } + void setRoom(TimelineModel *room) + { + if (room_ != room) { + room_ = room; + emit roomChanged(); } - void setPlay(bool newPlay) - { - if (play_ != newPlay) { - play_ = newPlay; - movie.setPaused(!play_); - emit playChanged(); - } + } + void setPlay(bool newPlay) + { + if (play_ != newPlay) { + play_ = newPlay; + movie.setPaused(!play_); + emit playChanged(); } + } - QSGNode *updatePaintNode(QSGNode *oldNode, - QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override; + QSGNode *updatePaintNode(QSGNode *oldNode, + QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override; signals: - void roomChanged(); - void eventIdChanged(); - void animatableChanged(); - void loadedChanged(); - void playChanged(); + void roomChanged(); + void eventIdChanged(); + void animatableChanged(); + void loadedChanged(); + void playChanged(); private slots: - void startDownload(); - void newFrame(int frame) - { - currentFrame = frame; - imageDirty = true; - update(); - } + void startDownload(); + void newFrame(int frame) + { + currentFrame = frame; + imageDirty = true; + update(); + } private: - TimelineModel *room_ = nullptr; - QString eventId_; - QString filename_; - bool animatable_ = false; - QBuffer buffer; - QMovie movie; - int currentFrame = 0; - bool imageDirty = true; - bool play_ = true; + TimelineModel *room_ = nullptr; + QString eventId_; + QString filename_; + bool animatable_ = false; + QBuffer buffer; + QMovie movie; + int currentFrame = 0; + bool imageDirty = true; + bool play_ = true; }; diff --git a/src/ui/MxcMediaProxy.cpp b/src/ui/MxcMediaProxy.cpp index dc65de7c..db8c0f1f 100644 --- a/src/ui/MxcMediaProxy.cpp +++ b/src/ui/MxcMediaProxy.cpp @@ -21,122 +21,119 @@ void MxcMediaProxy::setVideoSurface(QAbstractVideoSurface *surface) { - qDebug() << "Changing surface"; - m_surface = surface; - setVideoOutput(m_surface); + qDebug() << "Changing surface"; + m_surface = surface; + setVideoOutput(m_surface); } QAbstractVideoSurface * MxcMediaProxy::getVideoSurface() { - return m_surface; + return m_surface; } void MxcMediaProxy::startDownload() { - if (!room_) - return; - if (eventId_.isEmpty()) - return; - - auto event = room_->eventById(eventId_); - if (!event) { - nhlog::ui()->error("Failed to load media for event {}, event not found.", - eventId_.toStdString()); - return; + if (!room_) + return; + if (eventId_.isEmpty()) + return; + + auto event = room_->eventById(eventId_); + if (!event) { + nhlog::ui()->error("Failed to load media for event {}, event not found.", + eventId_.toStdString()); + return; + } + + QString mxcUrl = QString::fromStdString(mtx::accessors::url(*event)); + QString originalFilename = QString::fromStdString(mtx::accessors::filename(*event)); + QString mimeType = QString::fromStdString(mtx::accessors::mimetype(*event)); + + auto encryptionInfo = mtx::accessors::file(*event); + + // If the message is a link to a non mxcUrl, don't download it + if (!mxcUrl.startsWith("mxc://")) { + return; + } + + QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix(); + + const auto url = mxcUrl.toStdString(); + const auto name = QString(mxcUrl).remove("mxc://"); + QFileInfo filename(QString("%1/media_cache/media/%2.%3") + .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) + .arg(name) + .arg(suffix)); + if (QDir::cleanPath(name) != name) { + nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url); + return; + } + + QDir().mkpath(filename.path()); + + QPointer<MxcMediaProxy> self = this; + + auto processBuffer = [this, encryptionInfo, filename, self](QIODevice &device) { + if (!self) + return; + + if (encryptionInfo) { + QByteArray ba = device.readAll(); + std::string temp(ba.constData(), ba.size()); + temp = mtx::crypto::to_string(mtx::crypto::decrypt_file(temp, encryptionInfo.value())); + buffer.setData(temp.data(), temp.size()); + } else { + buffer.setData(device.readAll()); } - - QString mxcUrl = QString::fromStdString(mtx::accessors::url(*event)); - QString originalFilename = QString::fromStdString(mtx::accessors::filename(*event)); - QString mimeType = QString::fromStdString(mtx::accessors::mimetype(*event)); - - auto encryptionInfo = mtx::accessors::file(*event); - - // If the message is a link to a non mxcUrl, don't download it - if (!mxcUrl.startsWith("mxc://")) { - return; - } - - QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix(); - - const auto url = mxcUrl.toStdString(); - const auto name = QString(mxcUrl).remove("mxc://"); - QFileInfo filename(QString("%1/media_cache/media/%2.%3") - .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) - .arg(name) - .arg(suffix)); - if (QDir::cleanPath(name) != name) { - nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url); - return; - } - - QDir().mkpath(filename.path()); - - QPointer<MxcMediaProxy> self = this; - - auto processBuffer = [this, encryptionInfo, filename, self](QIODevice &device) { - if (!self) - return; - - if (encryptionInfo) { - QByteArray ba = device.readAll(); - std::string temp(ba.constData(), ba.size()); - temp = mtx::crypto::to_string( - mtx::crypto::decrypt_file(temp, encryptionInfo.value())); - buffer.setData(temp.data(), temp.size()); - } else { - buffer.setData(device.readAll()); - } - buffer.open(QIODevice::ReadOnly); - buffer.reset(); - - QTimer::singleShot(0, this, [this, filename] { - nhlog::ui()->info("Playing buffer with size: {}, {}", - buffer.bytesAvailable(), - buffer.isOpen()); - this->setMedia(QMediaContent(filename.fileName()), &buffer); - emit loadedChanged(); - }); - }; - - if (filename.isReadable()) { - QFile f(filename.filePath()); - if (f.open(QIODevice::ReadOnly)) { - processBuffer(f); - return; - } + buffer.open(QIODevice::ReadOnly); + buffer.reset(); + + QTimer::singleShot(0, this, [this, filename] { + nhlog::ui()->info( + "Playing buffer with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen()); + this->setMedia(QMediaContent(filename.fileName()), &buffer); + emit loadedChanged(); + }); + }; + + if (filename.isReadable()) { + QFile f(filename.filePath()); + if (f.open(QIODevice::ReadOnly)) { + processBuffer(f); + return; } - - http::client()->download( - url, - [filename, url, processBuffer](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to retrieve media {}: {} {}", - url, - err->matrix_error.error, - static_cast<int>(err->status_code)); - return; - } - - try { - QFile file(filename.filePath()); - - if (!file.open(QIODevice::WriteOnly)) - return; - - QByteArray ba(data.data(), (int)data.size()); - file.write(ba); - file.close(); - - QBuffer buf(&ba); - buf.open(QBuffer::ReadOnly); - processBuffer(buf); - } catch (const std::exception &e) { - nhlog::ui()->warn("Error while saving file to: {}", e.what()); - } - }); + } + + http::client()->download(url, + [filename, url, processBuffer](const std::string &data, + const std::string &, + const std::string &, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to retrieve media {}: {} {}", + url, + err->matrix_error.error, + static_cast<int>(err->status_code)); + return; + } + + try { + QFile file(filename.filePath()); + + if (!file.open(QIODevice::WriteOnly)) + return; + + QByteArray ba(data.data(), (int)data.size()); + file.write(ba); + file.close(); + + QBuffer buf(&ba); + buf.open(QBuffer::ReadOnly); + processBuffer(buf); + } catch (const std::exception &e) { + nhlog::ui()->warn("Error while saving file to: {}", e.what()); + } + }); } diff --git a/src/ui/MxcMediaProxy.h b/src/ui/MxcMediaProxy.h index 14541815..18152c75 100644 --- a/src/ui/MxcMediaProxy.h +++ b/src/ui/MxcMediaProxy.h @@ -20,61 +20,58 @@ class TimelineModel; // need the videoSurface property, so that part is really easy! class MxcMediaProxy : public QMediaPlayer { - Q_OBJECT - Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) - Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) - Q_PROPERTY(QAbstractVideoSurface *videoSurface READ getVideoSurface WRITE setVideoSurface) - Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) + Q_OBJECT + Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) + Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) + Q_PROPERTY(QAbstractVideoSurface *videoSurface READ getVideoSurface WRITE setVideoSurface) + Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) public: - MxcMediaProxy(QObject *parent = nullptr) - : QMediaPlayer(parent) - { - connect(this, &MxcMediaProxy::eventIdChanged, &MxcMediaProxy::startDownload); - connect(this, &MxcMediaProxy::roomChanged, &MxcMediaProxy::startDownload); - connect(this, - qOverload<QMediaPlayer::Error>(&MxcMediaProxy::error), - [this](QMediaPlayer::Error error) { - nhlog::ui()->info("Media player error {} and errorStr {}", - error, - this->errorString().toStdString()); - }); - connect(this, - &MxcMediaProxy::mediaStatusChanged, - [this](QMediaPlayer::MediaStatus status) { - nhlog::ui()->info( - "Media player status {} and error {}", status, this->error()); - }); - } + MxcMediaProxy(QObject *parent = nullptr) + : QMediaPlayer(parent) + { + connect(this, &MxcMediaProxy::eventIdChanged, &MxcMediaProxy::startDownload); + connect(this, &MxcMediaProxy::roomChanged, &MxcMediaProxy::startDownload); + connect(this, + qOverload<QMediaPlayer::Error>(&MxcMediaProxy::error), + [this](QMediaPlayer::Error error) { + nhlog::ui()->info("Media player error {} and errorStr {}", + error, + this->errorString().toStdString()); + }); + connect(this, &MxcMediaProxy::mediaStatusChanged, [this](QMediaPlayer::MediaStatus status) { + nhlog::ui()->info("Media player status {} and error {}", status, this->error()); + }); + } - bool loaded() const { return buffer.size() > 0; } - QString eventId() const { return eventId_; } - TimelineModel *room() const { return room_; } - void setEventId(QString newEventId) - { - eventId_ = newEventId; - emit eventIdChanged(); - } - void setRoom(TimelineModel *room) - { - room_ = room; - emit roomChanged(); - } - void setVideoSurface(QAbstractVideoSurface *surface); - QAbstractVideoSurface *getVideoSurface(); + bool loaded() const { return buffer.size() > 0; } + QString eventId() const { return eventId_; } + TimelineModel *room() const { return room_; } + void setEventId(QString newEventId) + { + eventId_ = newEventId; + emit eventIdChanged(); + } + void setRoom(TimelineModel *room) + { + room_ = room; + emit roomChanged(); + } + void setVideoSurface(QAbstractVideoSurface *surface); + QAbstractVideoSurface *getVideoSurface(); signals: - void roomChanged(); - void eventIdChanged(); - void loadedChanged(); - void newBuffer(QMediaContent, QIODevice *buf); + void roomChanged(); + void eventIdChanged(); + void loadedChanged(); + void newBuffer(QMediaContent, QIODevice *buf); private slots: - void startDownload(); + void startDownload(); private: - TimelineModel *room_ = nullptr; - QString eventId_; - QString filename_; - QBuffer buffer; - QAbstractVideoSurface *m_surface = nullptr; + TimelineModel *room_ = nullptr; + QString eventId_; + QString filename_; + QBuffer buffer; + QAbstractVideoSurface *m_surface = nullptr; }; diff --git a/src/ui/NhekoCursorShape.cpp b/src/ui/NhekoCursorShape.cpp index b36eedbd..70991757 100644 --- a/src/ui/NhekoCursorShape.cpp +++ b/src/ui/NhekoCursorShape.cpp @@ -14,16 +14,16 @@ NhekoCursorShape::NhekoCursorShape(QQuickItem *parent) Qt::CursorShape NhekoCursorShape::cursorShape() const { - return cursor().shape(); + return cursor().shape(); } void NhekoCursorShape::setCursorShape(Qt::CursorShape cursorShape) { - if (currentShape_ == cursorShape) - return; + if (currentShape_ == cursorShape) + return; - currentShape_ = cursorShape; - setCursor(cursorShape); - emit cursorShapeChanged(); + currentShape_ = cursorShape; + setCursor(cursorShape); + emit cursorShapeChanged(); } diff --git a/src/ui/NhekoCursorShape.h b/src/ui/NhekoCursorShape.h index 6f6a2b82..b3a0a1ba 100644 --- a/src/ui/NhekoCursorShape.h +++ b/src/ui/NhekoCursorShape.h @@ -11,20 +11,20 @@ class NhekoCursorShape : public QQuickItem { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY - cursorShapeChanged) + Q_PROPERTY( + Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY cursorShapeChanged) public: - explicit NhekoCursorShape(QQuickItem *parent = 0); + explicit NhekoCursorShape(QQuickItem *parent = 0); private: - Qt::CursorShape cursorShape() const; - void setCursorShape(Qt::CursorShape cursorShape); + Qt::CursorShape cursorShape() const; + void setCursorShape(Qt::CursorShape cursorShape); - Qt::CursorShape currentShape_; + Qt::CursorShape currentShape_; signals: - void cursorShapeChanged(); + void cursorShapeChanged(); }; diff --git a/src/ui/NhekoDropArea.cpp b/src/ui/NhekoDropArea.cpp index bbcedd7e..b1b53c3d 100644 --- a/src/ui/NhekoDropArea.cpp +++ b/src/ui/NhekoDropArea.cpp @@ -16,28 +16,28 @@ NhekoDropArea::NhekoDropArea(QQuickItem *parent) : QQuickItem(parent) { - setFlags(ItemAcceptsDrops); + setFlags(ItemAcceptsDrops); } void NhekoDropArea::dragEnterEvent(QDragEnterEvent *event) { - event->acceptProposedAction(); + event->acceptProposedAction(); } void NhekoDropArea::dragMoveEvent(QDragMoveEvent *event) { - event->acceptProposedAction(); + event->acceptProposedAction(); } void NhekoDropArea::dropEvent(QDropEvent *event) { - if (event) { - auto model = ChatPage::instance()->timelineManager()->rooms()->getRoomById(roomid_); - if (model) { - model->input()->insertMimeData(event->mimeData()); - } + if (event) { + auto model = ChatPage::instance()->timelineManager()->rooms()->getRoomById(roomid_); + if (model) { + model->input()->insertMimeData(event->mimeData()); } + } } diff --git a/src/ui/NhekoDropArea.h b/src/ui/NhekoDropArea.h index 9fbf1737..7b3de5c9 100644 --- a/src/ui/NhekoDropArea.h +++ b/src/ui/NhekoDropArea.h @@ -6,29 +6,29 @@ class NhekoDropArea : public QQuickItem { - Q_OBJECT - Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged) + Q_OBJECT + Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged) public: - NhekoDropArea(QQuickItem *parent = nullptr); + NhekoDropArea(QQuickItem *parent = nullptr); signals: - void roomidChanged(QString roomid); + void roomidChanged(QString roomid); public slots: - void setRoomid(QString roomid) - { - if (roomid_ != roomid) { - roomid_ = roomid; - emit roomidChanged(roomid); - } + void setRoomid(QString roomid) + { + if (roomid_ != roomid) { + roomid_ = roomid; + emit roomidChanged(roomid); } - QString roomid() const { return roomid_; } + } + QString roomid() const { return roomid_; } protected: - void dragEnterEvent(QDragEnterEvent *event) override; - void dragMoveEvent(QDragMoveEvent *event) override; - void dropEvent(QDropEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; private: - QString roomid_; + QString roomid_; }; diff --git a/src/ui/NhekoGlobalObject.cpp b/src/ui/NhekoGlobalObject.cpp index 355f187b..d6824996 100644 --- a/src/ui/NhekoGlobalObject.cpp +++ b/src/ui/NhekoGlobalObject.cpp @@ -17,93 +17,93 @@ Nheko::Nheko() { - connect( - UserSettings::instance().get(), &UserSettings::themeChanged, this, &Nheko::colorsChanged); - connect(ChatPage::instance(), &ChatPage::contentLoaded, this, &Nheko::updateUserProfile); + connect( + UserSettings::instance().get(), &UserSettings::themeChanged, this, &Nheko::colorsChanged); + connect(ChatPage::instance(), &ChatPage::contentLoaded, this, &Nheko::updateUserProfile); } void Nheko::updateUserProfile() { - if (cache::client() && cache::client()->isInitialized()) - currentUser_.reset( - new UserProfile("", utils::localUser(), ChatPage::instance()->timelineManager())); - else - currentUser_.reset(); - emit profileChanged(); + if (cache::client() && cache::client()->isInitialized()) + currentUser_.reset( + new UserProfile("", utils::localUser(), ChatPage::instance()->timelineManager())); + else + currentUser_.reset(); + emit profileChanged(); } QPalette Nheko::colors() const { - return Theme::paletteFromTheme(UserSettings::instance()->theme().toStdString()); + return Theme::paletteFromTheme(UserSettings::instance()->theme().toStdString()); } QPalette Nheko::inactiveColors() const { - auto p = colors(); - p.setCurrentColorGroup(QPalette::ColorGroup::Inactive); - return p; + auto p = colors(); + p.setCurrentColorGroup(QPalette::ColorGroup::Inactive); + return p; } Theme Nheko::theme() const { - return Theme(UserSettings::instance()->theme().toStdString()); + return Theme(UserSettings::instance()->theme().toStdString()); } void Nheko::openLink(QString link) const { - QUrl url(link); - // Open externally if we couldn't handle it internally - if (!ChatPage::instance()->handleMatrixUri(url)) { - QDesktopServices::openUrl(url); - } + QUrl url(link); + // Open externally if we couldn't handle it internally + if (!ChatPage::instance()->handleMatrixUri(url)) { + QDesktopServices::openUrl(url); + } } void Nheko::setStatusMessage(QString msg) const { - ChatPage::instance()->setStatus(msg); + ChatPage::instance()->setStatus(msg); } UserProfile * Nheko::currentUser() const { - nhlog::ui()->debug("Profile requested"); + nhlog::ui()->debug("Profile requested"); - return currentUser_.get(); + return currentUser_.get(); } void Nheko::showUserSettingsPage() const { - ChatPage::instance()->showUserSettingsPage(); + ChatPage::instance()->showUserSettingsPage(); } void Nheko::openLogoutDialog() const { - MainWindow::instance()->openLogoutDialog(); + MainWindow::instance()->openLogoutDialog(); } void Nheko::openCreateRoomDialog() const { - MainWindow::instance()->openCreateRoomDialog( - [](const mtx::requests::CreateRoom &req) { ChatPage::instance()->createRoom(req); }); + MainWindow::instance()->openCreateRoomDialog( + [](const mtx::requests::CreateRoom &req) { ChatPage::instance()->createRoom(req); }); } void Nheko::openJoinRoomDialog() const { - MainWindow::instance()->openJoinRoomDialog( - [](const QString &room_id) { ChatPage::instance()->joinRoom(room_id); }); + MainWindow::instance()->openJoinRoomDialog( + [](const QString &room_id) { ChatPage::instance()->joinRoom(room_id); }); } void Nheko::reparent(QWindow *win) const { - win->setTransientParent(MainWindow::instance()->windowHandle()); + win->setTransientParent(MainWindow::instance()->windowHandle()); } diff --git a/src/ui/NhekoGlobalObject.h b/src/ui/NhekoGlobalObject.h index d4d119dc..aa8435d1 100644 --- a/src/ui/NhekoGlobalObject.h +++ b/src/ui/NhekoGlobalObject.h @@ -15,51 +15,51 @@ class QWindow; class Nheko : public QObject { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QPalette colors READ colors NOTIFY colorsChanged) - Q_PROPERTY(QPalette inactiveColors READ inactiveColors NOTIFY colorsChanged) - Q_PROPERTY(Theme theme READ theme NOTIFY colorsChanged) - Q_PROPERTY(int avatarSize READ avatarSize CONSTANT) - Q_PROPERTY(int paddingSmall READ paddingSmall CONSTANT) - Q_PROPERTY(int paddingMedium READ paddingMedium CONSTANT) - Q_PROPERTY(int paddingLarge READ paddingLarge CONSTANT) + Q_PROPERTY(QPalette colors READ colors NOTIFY colorsChanged) + Q_PROPERTY(QPalette inactiveColors READ inactiveColors NOTIFY colorsChanged) + Q_PROPERTY(Theme theme READ theme NOTIFY colorsChanged) + Q_PROPERTY(int avatarSize READ avatarSize CONSTANT) + Q_PROPERTY(int paddingSmall READ paddingSmall CONSTANT) + Q_PROPERTY(int paddingMedium READ paddingMedium CONSTANT) + Q_PROPERTY(int paddingLarge READ paddingLarge CONSTANT) - Q_PROPERTY(UserProfile *currentUser READ currentUser NOTIFY profileChanged) + Q_PROPERTY(UserProfile *currentUser READ currentUser NOTIFY profileChanged) public: - Nheko(); + Nheko(); - QPalette colors() const; - QPalette inactiveColors() const; - Theme theme() const; + QPalette colors() const; + QPalette inactiveColors() const; + Theme theme() const; - int avatarSize() const { return 40; } + int avatarSize() const { return 40; } - int paddingSmall() const { return 4; } - int paddingMedium() const { return 8; } - int paddingLarge() const { return 20; } - UserProfile *currentUser() const; + int paddingSmall() const { return 4; } + int paddingMedium() const { return 8; } + int paddingLarge() const { return 20; } + UserProfile *currentUser() const; - Q_INVOKABLE QFont monospaceFont() const - { - return QFontDatabase::systemFont(QFontDatabase::FixedFont); - } - Q_INVOKABLE void openLink(QString link) const; - Q_INVOKABLE void setStatusMessage(QString msg) const; - Q_INVOKABLE void showUserSettingsPage() const; - Q_INVOKABLE void openLogoutDialog() const; - Q_INVOKABLE void openCreateRoomDialog() const; - Q_INVOKABLE void openJoinRoomDialog() const; - Q_INVOKABLE void reparent(QWindow *win) const; + Q_INVOKABLE QFont monospaceFont() const + { + return QFontDatabase::systemFont(QFontDatabase::FixedFont); + } + Q_INVOKABLE void openLink(QString link) const; + Q_INVOKABLE void setStatusMessage(QString msg) const; + Q_INVOKABLE void showUserSettingsPage() const; + Q_INVOKABLE void openLogoutDialog() const; + Q_INVOKABLE void openCreateRoomDialog() const; + Q_INVOKABLE void openJoinRoomDialog() const; + Q_INVOKABLE void reparent(QWindow *win) const; public slots: - void updateUserProfile(); + void updateUserProfile(); signals: - void colorsChanged(); - void profileChanged(); + void colorsChanged(); + void profileChanged(); private: - QScopedPointer<UserProfile> currentUser_; + QScopedPointer<UserProfile> currentUser_; }; diff --git a/src/ui/OverlayModal.cpp b/src/ui/OverlayModal.cpp index f5f28732..6534c4bc 100644 --- a/src/ui/OverlayModal.cpp +++ b/src/ui/OverlayModal.cpp @@ -12,50 +12,50 @@ OverlayModal::OverlayModal(QWidget *parent) : OverlayWidget(parent) , color_{QColor(30, 30, 30, 170)} { - layout_ = new QVBoxLayout(this); - layout_->setSpacing(0); - layout_->setContentsMargins(10, 40, 10, 20); - setContentAlignment(Qt::AlignCenter); + layout_ = new QVBoxLayout(this); + layout_->setSpacing(0); + layout_->setContentsMargins(10, 40, 10, 20); + setContentAlignment(Qt::AlignCenter); } void OverlayModal::setWidget(QWidget *widget) { - // Delete the previous widget - if (layout_->count() > 0) { - QLayoutItem *item; - while ((item = layout_->takeAt(0)) != nullptr) { - delete item->widget(); - delete item; - } + // Delete the previous widget + if (layout_->count() > 0) { + QLayoutItem *item; + while ((item = layout_->takeAt(0)) != nullptr) { + delete item->widget(); + delete item; } + } - layout_->addWidget(widget); - content_ = widget; - content_->setFocus(); + layout_->addWidget(widget); + content_ = widget; + content_->setFocus(); } void OverlayModal::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); + Q_UNUSED(event); - QPainter painter(this); - painter.fillRect(rect(), color_); + QPainter painter(this); + painter.fillRect(rect(), color_); } void OverlayModal::mousePressEvent(QMouseEvent *e) { - if (isDismissible_ && content_ && !content_->geometry().contains(e->pos())) - hide(); + if (isDismissible_ && content_ && !content_->geometry().contains(e->pos())) + hide(); } void OverlayModal::keyPressEvent(QKeyEvent *event) { - if (event->key() == Qt::Key_Escape) { - event->accept(); - hide(); - } + if (event->key() == Qt::Key_Escape) { + event->accept(); + hide(); + } } diff --git a/src/ui/OverlayModal.h b/src/ui/OverlayModal.h index 005614fa..5c15f17f 100644 --- a/src/ui/OverlayModal.h +++ b/src/ui/OverlayModal.h @@ -15,25 +15,25 @@ class OverlayModal : public OverlayWidget { public: - OverlayModal(QWidget *parent); + OverlayModal(QWidget *parent); - void setColor(QColor color) { color_ = color; } - void setDismissible(bool state) { isDismissible_ = state; } + void setColor(QColor color) { color_ = color; } + void setDismissible(bool state) { isDismissible_ = state; } - void setContentAlignment(QFlags<Qt::AlignmentFlag> flag) { layout_->setAlignment(flag); } - void setWidget(QWidget *widget); + void setContentAlignment(QFlags<Qt::AlignmentFlag> flag) { layout_->setAlignment(flag); } + void setWidget(QWidget *widget); protected: - void paintEvent(QPaintEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; + void paintEvent(QPaintEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; private: - QWidget *content_; - QVBoxLayout *layout_; + QWidget *content_; + QVBoxLayout *layout_; - QColor color_; + QColor color_; - //! Decides whether or not the modal can be removed by clicking into it. - bool isDismissible_ = true; + //! Decides whether or not the modal can be removed by clicking into it. + bool isDismissible_ = true; }; diff --git a/src/ui/OverlayWidget.cpp b/src/ui/OverlayWidget.cpp index c8c95581..4e338753 100644 --- a/src/ui/OverlayWidget.cpp +++ b/src/ui/OverlayWidget.cpp @@ -10,69 +10,69 @@ OverlayWidget::OverlayWidget(QWidget *parent) : QWidget(parent) { - if (parent) { - parent->installEventFilter(this); - setGeometry(overlayGeometry()); - raise(); - } + if (parent) { + parent->installEventFilter(this); + setGeometry(overlayGeometry()); + raise(); + } } bool OverlayWidget::event(QEvent *event) { - if (!parent()) - return QWidget::event(event); + if (!parent()) + return QWidget::event(event); - switch (event->type()) { - case QEvent::ParentChange: { - parent()->installEventFilter(this); - setGeometry(overlayGeometry()); - break; - } - case QEvent::ParentAboutToChange: { - parent()->removeEventFilter(this); - break; - } - default: - break; - } + switch (event->type()) { + case QEvent::ParentChange: { + parent()->installEventFilter(this); + setGeometry(overlayGeometry()); + break; + } + case QEvent::ParentAboutToChange: { + parent()->removeEventFilter(this); + break; + } + default: + break; + } - return QWidget::event(event); + return QWidget::event(event); } bool OverlayWidget::eventFilter(QObject *obj, QEvent *event) { - switch (event->type()) { - case QEvent::Move: - case QEvent::Resize: - setGeometry(overlayGeometry()); - break; - default: - break; - } + switch (event->type()) { + case QEvent::Move: + case QEvent::Resize: + setGeometry(overlayGeometry()); + break; + default: + break; + } - return QWidget::eventFilter(obj, event); + return QWidget::eventFilter(obj, event); } QRect OverlayWidget::overlayGeometry() const { - QWidget *widget = parentWidget(); + QWidget *widget = parentWidget(); - if (!widget) - return QRect(); + if (!widget) + return QRect(); - return widget->rect(); + return widget->rect(); } void OverlayWidget::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); + Q_UNUSED(event); - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/src/ui/OverlayWidget.h b/src/ui/OverlayWidget.h index 05bb8696..5f023e35 100644 --- a/src/ui/OverlayWidget.h +++ b/src/ui/OverlayWidget.h @@ -11,15 +11,15 @@ class QPainter; class OverlayWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit OverlayWidget(QWidget *parent = nullptr); + explicit OverlayWidget(QWidget *parent = nullptr); protected: - bool event(QEvent *event) override; - bool eventFilter(QObject *obj, QEvent *event) override; + bool event(QEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; - QRect overlayGeometry() const; - void paintEvent(QPaintEvent *event) override; + QRect overlayGeometry() const; + void paintEvent(QPaintEvent *event) override; }; diff --git a/src/ui/Painter.h b/src/ui/Painter.h index 9f974116..f78b55e5 100644 --- a/src/ui/Painter.h +++ b/src/ui/Painter.h @@ -13,147 +13,141 @@ class Painter : public QPainter { public: - explicit Painter(QPaintDevice *device) - : QPainter(device) - {} - - void drawTextLeft(int x, int y, const QString &text) - { - QFontMetrics m(fontMetrics()); - drawText(x, y + m.ascent(), text); - } - - void drawTextRight(int x, int y, int outerw, const QString &text, int textWidth = -1) - { - QFontMetrics m(fontMetrics()); - if (textWidth < 0) { - textWidth = m.horizontalAdvance(text); - } - drawText((outerw - x - textWidth), y + m.ascent(), text); - } - - void drawPixmapLeft(int x, int y, const QPixmap &pix, const QRect &from) - { - drawPixmap(QPoint(x, y), pix, from); - } - - void drawPixmapLeft(const QPoint &p, const QPixmap &pix, const QRect &from) - { - return drawPixmapLeft(p.x(), p.y(), pix, from); - } - - void drawPixmapLeft(int x, int y, int w, int h, const QPixmap &pix, const QRect &from) - { - drawPixmap(QRect(x, y, w, h), pix, from); - } - - void drawPixmapLeft(const QRect &r, const QPixmap &pix, const QRect &from) - { - return drawPixmapLeft(r.x(), r.y(), r.width(), r.height(), pix, from); - } - - void drawPixmapLeft(int x, int y, int outerw, const QPixmap &pix) - { - Q_UNUSED(outerw); - drawPixmap(QPoint(x, y), pix); - } - - void drawPixmapLeft(const QPoint &p, int outerw, const QPixmap &pix) - { - return drawPixmapLeft(p.x(), p.y(), outerw, pix); - } - - void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix, const QRect &from) - { - drawPixmap( - QPoint((outerw - x - (from.width() / pix.devicePixelRatio())), y), pix, from); - } - - void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix, const QRect &from) - { - return drawPixmapRight(p.x(), p.y(), outerw, pix, from); - } - void drawPixmapRight(int x, - int y, - int w, - int h, - int outerw, - const QPixmap &pix, - const QRect &from) - { - drawPixmap(QRect((outerw - x - w), y, w, h), pix, from); - } - - void drawPixmapRight(const QRect &r, int outerw, const QPixmap &pix, const QRect &from) - { - return drawPixmapRight(r.x(), r.y(), r.width(), r.height(), outerw, pix, from); - } - - void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix) - { - drawPixmap(QPoint((outerw - x - (pix.width() / pix.devicePixelRatio())), y), pix); - } - - void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix) - { - return drawPixmapRight(p.x(), p.y(), outerw, pix); - } - - void drawAvatar(const QPixmap &pix, int w, int h, int d) - { - QPainterPath pp; - pp.addEllipse((w - d) / 2, (h - d) / 2, d, d); - - QRect region((w - d) / 2, (h - d) / 2, d, d); - - setClipPath(pp); - drawPixmap(region, pix); - } - - void drawLetterAvatar(const QString &c, - const QColor &penColor, - const QColor &brushColor, - int w, - int h, - int d) - { - QRect region((w - d) / 2, (h - d) / 2, d, d); - - setPen(Qt::NoPen); - setBrush(brushColor); - - drawEllipse(region.center(), d / 2, d / 2); - - setBrush(Qt::NoBrush); - drawEllipse(region.center(), d / 2, d / 2); - - setPen(penColor); - drawText(region.translated(0, -1), Qt::AlignCenter, c); - } + explicit Painter(QPaintDevice *device) + : QPainter(device) + {} + + void drawTextLeft(int x, int y, const QString &text) + { + QFontMetrics m(fontMetrics()); + drawText(x, y + m.ascent(), text); + } + + void drawTextRight(int x, int y, int outerw, const QString &text, int textWidth = -1) + { + QFontMetrics m(fontMetrics()); + if (textWidth < 0) { + textWidth = m.horizontalAdvance(text); + } + drawText((outerw - x - textWidth), y + m.ascent(), text); + } + + void drawPixmapLeft(int x, int y, const QPixmap &pix, const QRect &from) + { + drawPixmap(QPoint(x, y), pix, from); + } + + void drawPixmapLeft(const QPoint &p, const QPixmap &pix, const QRect &from) + { + return drawPixmapLeft(p.x(), p.y(), pix, from); + } + + void drawPixmapLeft(int x, int y, int w, int h, const QPixmap &pix, const QRect &from) + { + drawPixmap(QRect(x, y, w, h), pix, from); + } + + void drawPixmapLeft(const QRect &r, const QPixmap &pix, const QRect &from) + { + return drawPixmapLeft(r.x(), r.y(), r.width(), r.height(), pix, from); + } + + void drawPixmapLeft(int x, int y, int outerw, const QPixmap &pix) + { + Q_UNUSED(outerw); + drawPixmap(QPoint(x, y), pix); + } + + void drawPixmapLeft(const QPoint &p, int outerw, const QPixmap &pix) + { + return drawPixmapLeft(p.x(), p.y(), outerw, pix); + } + + void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix, const QRect &from) + { + drawPixmap(QPoint((outerw - x - (from.width() / pix.devicePixelRatio())), y), pix, from); + } + + void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix, const QRect &from) + { + return drawPixmapRight(p.x(), p.y(), outerw, pix, from); + } + void + drawPixmapRight(int x, int y, int w, int h, int outerw, const QPixmap &pix, const QRect &from) + { + drawPixmap(QRect((outerw - x - w), y, w, h), pix, from); + } + + void drawPixmapRight(const QRect &r, int outerw, const QPixmap &pix, const QRect &from) + { + return drawPixmapRight(r.x(), r.y(), r.width(), r.height(), outerw, pix, from); + } + + void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix) + { + drawPixmap(QPoint((outerw - x - (pix.width() / pix.devicePixelRatio())), y), pix); + } + + void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix) + { + return drawPixmapRight(p.x(), p.y(), outerw, pix); + } + + void drawAvatar(const QPixmap &pix, int w, int h, int d) + { + QPainterPath pp; + pp.addEllipse((w - d) / 2, (h - d) / 2, d, d); + + QRect region((w - d) / 2, (h - d) / 2, d, d); + + setClipPath(pp); + drawPixmap(region, pix); + } + + void drawLetterAvatar(const QString &c, + const QColor &penColor, + const QColor &brushColor, + int w, + int h, + int d) + { + QRect region((w - d) / 2, (h - d) / 2, d, d); + + setPen(Qt::NoPen); + setBrush(brushColor); + + drawEllipse(region.center(), d / 2, d / 2); + + setBrush(Qt::NoBrush); + drawEllipse(region.center(), d / 2, d / 2); + + setPen(penColor); + drawText(region.translated(0, -1), Qt::AlignCenter, c); + } }; class PainterHighQualityEnabler { public: - PainterHighQualityEnabler(Painter &p) - : _painter(p) - { - hints_ = QPainter::Antialiasing | QPainter::SmoothPixmapTransform | - QPainter::TextAntialiasing; + PainterHighQualityEnabler(Painter &p) + : _painter(p) + { + hints_ = + QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing; - _painter.setRenderHints(hints_); - } + _painter.setRenderHints(hints_); + } - ~PainterHighQualityEnabler() - { - if (hints_) - _painter.setRenderHints(hints_, false); - } + ~PainterHighQualityEnabler() + { + if (hints_) + _painter.setRenderHints(hints_, false); + } - PainterHighQualityEnabler(const PainterHighQualityEnabler &other) = delete; - PainterHighQualityEnabler &operator=(const PainterHighQualityEnabler &other) = delete; + PainterHighQualityEnabler(const PainterHighQualityEnabler &other) = delete; + PainterHighQualityEnabler &operator=(const PainterHighQualityEnabler &other) = delete; private: - Painter &_painter; - QPainter::RenderHints hints_ = {}; + Painter &_painter; + QPainter::RenderHints hints_ = {}; }; diff --git a/src/ui/RaisedButton.cpp b/src/ui/RaisedButton.cpp index 563cb8e5..fd0cbd76 100644 --- a/src/ui/RaisedButton.cpp +++ b/src/ui/RaisedButton.cpp @@ -10,68 +10,68 @@ void RaisedButton::init() { - shadow_state_machine_ = new QStateMachine(this); - normal_state_ = new QState; - pressed_state_ = new QState; - effect_ = new QGraphicsDropShadowEffect; + 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)); + effect_->setBlurRadius(7); + effect_->setOffset(QPointF(0, 2)); + effect_->setColor(QColor(0, 0, 0, 75)); - setBackgroundMode(Qt::OpaqueMode); - setMinimumHeight(42); - setGraphicsEffect(effect_); - setBaseOpacity(0.3); + setBackgroundMode(Qt::OpaqueMode); + setMinimumHeight(42); + setGraphicsEffect(effect_); + setBaseOpacity(0.3); - shadow_state_machine_->addState(normal_state_); - shadow_state_machine_->addState(pressed_state_); + 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); + 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); + pressed_state_->assignProperty(effect_, "offset", QPointF(0, 5)); + pressed_state_->assignProperty(effect_, "blurRadius", 29); - QAbstractTransition *transition; + QAbstractTransition *transition; - transition = new QEventTransition(this, QEvent::MouseButtonPress); - transition->setTargetState(pressed_state_); - normal_state_->addTransition(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::MouseButtonDblClick); + transition->setTargetState(pressed_state_); + normal_state_->addTransition(transition); - transition = new QEventTransition(this, QEvent::MouseButtonRelease); - transition->setTargetState(normal_state_); - pressed_state_->addTransition(transition); + transition = new QEventTransition(this, QEvent::MouseButtonRelease); + transition->setTargetState(normal_state_); + pressed_state_->addTransition(transition); - QPropertyAnimation *animation; + QPropertyAnimation *animation; - animation = new QPropertyAnimation(effect_, "offset", this); - animation->setDuration(100); - shadow_state_machine_->addDefaultAnimation(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); + animation = new QPropertyAnimation(effect_, "blurRadius", this); + animation->setDuration(100); + shadow_state_machine_->addDefaultAnimation(animation); - shadow_state_machine_->setInitialState(normal_state_); - shadow_state_machine_->start(); + shadow_state_machine_->setInitialState(normal_state_); + shadow_state_machine_->start(); } RaisedButton::RaisedButton(QWidget *parent) : FlatButton(parent) { - init(); + init(); } RaisedButton::RaisedButton(const QString &text, QWidget *parent) : FlatButton(parent) { - init(); - setText(text); + init(); + setText(text); } RaisedButton::~RaisedButton() {} @@ -79,15 +79,15 @@ RaisedButton::~RaisedButton() {} bool 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); - } + 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); } diff --git a/src/ui/RaisedButton.h b/src/ui/RaisedButton.h index dcb579bb..277fa7ff 100644 --- a/src/ui/RaisedButton.h +++ b/src/ui/RaisedButton.h @@ -12,21 +12,21 @@ class RaisedButton : public FlatButton { - Q_OBJECT + Q_OBJECT public: - explicit RaisedButton(QWidget *parent = nullptr); - explicit RaisedButton(const QString &text, QWidget *parent = nullptr); - ~RaisedButton() override; + explicit RaisedButton(QWidget *parent = nullptr); + explicit RaisedButton(const QString &text, QWidget *parent = nullptr); + ~RaisedButton() override; protected: - bool event(QEvent *event) override; + bool event(QEvent *event) override; private: - void init(); + void init(); - QStateMachine *shadow_state_machine_; - QState *normal_state_; - QState *pressed_state_; - QGraphicsDropShadowEffect *effect_; + QStateMachine *shadow_state_machine_; + QState *normal_state_; + QState *pressed_state_; + QGraphicsDropShadowEffect *effect_; }; diff --git a/src/ui/Ripple.cpp b/src/ui/Ripple.cpp index f0455f0b..72cf2da2 100644 --- a/src/ui/Ripple.cpp +++ b/src/ui/Ripple.cpp @@ -14,7 +14,7 @@ Ripple::Ripple(const QPoint ¢er, QObject *parent) , opacity_(0) , center_(center) { - init(); + init(); } Ripple::Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent) @@ -26,86 +26,86 @@ Ripple::Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent) , opacity_(0) , center_(center) { - init(); + init(); } void Ripple::setRadius(qreal radius) { - Q_ASSERT(overlay_); + Q_ASSERT(overlay_); - if (radius_ == radius) - return; + if (radius_ == radius) + return; - radius_ = radius; - overlay_->update(); + radius_ = radius; + overlay_->update(); } void Ripple::setOpacity(qreal opacity) { - Q_ASSERT(overlay_); + Q_ASSERT(overlay_); - if (opacity_ == opacity) - return; + if (opacity_ == opacity) + return; - opacity_ = opacity; - overlay_->update(); + opacity_ = opacity; + overlay_->update(); } void Ripple::setColor(const QColor &color) { - if (brush_.color() == color) - return; + if (brush_.color() == color) + return; - brush_.setColor(color); + brush_.setColor(color); - if (overlay_) - overlay_->update(); + if (overlay_) + overlay_->update(); } void Ripple::setBrush(const QBrush &brush) { - brush_ = brush; + brush_ = brush; - if (overlay_) - overlay_->update(); + if (overlay_) + overlay_->update(); } void Ripple::destroy() { - Q_ASSERT(overlay_); + Q_ASSERT(overlay_); - overlay_->removeRipple(this); + overlay_->removeRipple(this); } QPropertyAnimation * Ripple::animate(const QByteArray &property, const QEasingCurve &easing, int duration) { - QPropertyAnimation *animation = new QPropertyAnimation; - animation->setTargetObject(this); - animation->setPropertyName(property); - animation->setEasingCurve(easing); - animation->setDuration(duration); + QPropertyAnimation *animation = new QPropertyAnimation; + animation->setTargetObject(this); + animation->setPropertyName(property); + animation->setEasingCurve(easing); + animation->setDuration(duration); - addAnimation(animation); + addAnimation(animation); - return animation; + return animation; } void Ripple::init() { - setOpacityStartValue(0.5); - setOpacityEndValue(0); - setRadiusStartValue(0); - setRadiusEndValue(300); + setOpacityStartValue(0.5); + setOpacityEndValue(0); + setRadiusStartValue(0); + setRadiusEndValue(300); - brush_.setColor(Qt::black); - brush_.setStyle(Qt::SolidPattern); + brush_.setColor(Qt::black); + brush_.setStyle(Qt::SolidPattern); - connect(this, SIGNAL(finished()), this, SLOT(destroy())); + connect(this, SIGNAL(finished()), this, SLOT(destroy())); } diff --git a/src/ui/Ripple.h b/src/ui/Ripple.h index 2ad42b9e..df09caba 100644 --- a/src/ui/Ripple.h +++ b/src/ui/Ripple.h @@ -14,136 +14,136 @@ class RippleOverlay; class Ripple : public QParallelAnimationGroup { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(qreal radius WRITE setRadius READ radius) - Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity) + Q_PROPERTY(qreal radius WRITE setRadius READ radius) + Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity) public: - explicit Ripple(const QPoint ¢er, QObject *parent = nullptr); - Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent = nullptr); + explicit Ripple(const QPoint ¢er, QObject *parent = nullptr); + Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent = nullptr); - inline void setOverlay(RippleOverlay *overlay); + inline void setOverlay(RippleOverlay *overlay); - void setRadius(qreal radius); - void setOpacity(qreal opacity); - void setColor(const QColor &color); - void setBrush(const QBrush &brush); + void setRadius(qreal radius); + void setOpacity(qreal opacity); + void setColor(const QColor &color); + void setBrush(const QBrush &brush); - inline qreal radius() const; - inline qreal opacity() const; - inline QColor color() const; - inline QBrush brush() const; - inline QPoint center() const; + inline qreal radius() const; + inline qreal opacity() const; + inline QColor color() const; + inline QBrush brush() const; + inline QPoint center() const; - inline QPropertyAnimation *radiusAnimation() const; - inline QPropertyAnimation *opacityAnimation() const; + inline QPropertyAnimation *radiusAnimation() const; + inline QPropertyAnimation *opacityAnimation() const; - inline void setOpacityStartValue(qreal value); - inline void setOpacityEndValue(qreal value); - inline void setRadiusStartValue(qreal value); - inline void setRadiusEndValue(qreal value); - inline void setDuration(int msecs); + inline void setOpacityStartValue(qreal value); + inline void setOpacityEndValue(qreal value); + inline void setRadiusStartValue(qreal value); + inline void setRadiusEndValue(qreal value); + inline void setDuration(int msecs); protected slots: - void destroy(); + void destroy(); private: - Q_DISABLE_COPY(Ripple) + Q_DISABLE_COPY(Ripple) - QPropertyAnimation *animate(const QByteArray &property, - const QEasingCurve &easing = QEasingCurve::OutQuad, - int duration = 800); + QPropertyAnimation *animate(const QByteArray &property, + const QEasingCurve &easing = QEasingCurve::OutQuad, + int duration = 800); - void init(); + void init(); - RippleOverlay *overlay_; + RippleOverlay *overlay_; - QPropertyAnimation *const radius_anim_; - QPropertyAnimation *const opacity_anim_; + QPropertyAnimation *const radius_anim_; + QPropertyAnimation *const opacity_anim_; - qreal radius_; - qreal opacity_; + qreal radius_; + qreal opacity_; - QPoint center_; - QBrush brush_; + QPoint center_; + QBrush brush_; }; inline void Ripple::setOverlay(RippleOverlay *overlay) { - overlay_ = overlay; + overlay_ = overlay; } inline qreal Ripple::radius() const { - return radius_; + return radius_; } inline qreal Ripple::opacity() const { - return opacity_; + return opacity_; } inline QColor Ripple::color() const { - return brush_.color(); + return brush_.color(); } inline QBrush Ripple::brush() const { - return brush_; + return brush_; } inline QPoint Ripple::center() const { - return center_; + return center_; } inline QPropertyAnimation * Ripple::radiusAnimation() const { - return radius_anim_; + return radius_anim_; } inline QPropertyAnimation * Ripple::opacityAnimation() const { - return opacity_anim_; + return opacity_anim_; } inline void Ripple::setOpacityStartValue(qreal value) { - opacity_anim_->setStartValue(value); + opacity_anim_->setStartValue(value); } inline void Ripple::setOpacityEndValue(qreal value) { - opacity_anim_->setEndValue(value); + opacity_anim_->setEndValue(value); } inline void Ripple::setRadiusStartValue(qreal value) { - radius_anim_->setStartValue(value); + radius_anim_->setStartValue(value); } inline void Ripple::setRadiusEndValue(qreal value) { - radius_anim_->setEndValue(value); + radius_anim_->setEndValue(value); } inline void Ripple::setDuration(int msecs) { - radius_anim_->setDuration(msecs); - opacity_anim_->setDuration(msecs); + radius_anim_->setDuration(msecs); + opacity_anim_->setDuration(msecs); } diff --git a/src/ui/RippleOverlay.cpp b/src/ui/RippleOverlay.cpp index 00915deb..6745cc37 100644 --- a/src/ui/RippleOverlay.cpp +++ b/src/ui/RippleOverlay.cpp @@ -11,56 +11,56 @@ RippleOverlay::RippleOverlay(QWidget *parent) : OverlayWidget(parent) , use_clip_(false) { - setAttribute(Qt::WA_TransparentForMouseEvents); - setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_TransparentForMouseEvents); + setAttribute(Qt::WA_NoSystemBackground); } void RippleOverlay::addRipple(Ripple *ripple) { - ripple->setOverlay(this); - ripples_.push_back(ripple); - ripple->start(); + ripple->setOverlay(this); + ripples_.push_back(ripple); + ripple->start(); } void RippleOverlay::addRipple(const QPoint &position, qreal radius) { - Ripple *ripple = new Ripple(position); - ripple->setRadiusEndValue(radius); - addRipple(ripple); + Ripple *ripple = new Ripple(position); + ripple->setRadiusEndValue(radius); + addRipple(ripple); } void RippleOverlay::removeRipple(Ripple *ripple) { - if (ripples_.removeOne(ripple)) - delete ripple; + if (ripples_.removeOne(ripple)) + delete ripple; } void RippleOverlay::paintEvent(QPaintEvent *event) { - Q_UNUSED(event) + Q_UNUSED(event) - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.setPen(Qt::NoPen); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(Qt::NoPen); - if (use_clip_) - painter.setClipPath(clip_path_); + if (use_clip_) + painter.setClipPath(clip_path_); - for (auto it = ripples_.constBegin(); it != ripples_.constEnd(); ++it) - paintRipple(&painter, *it); + for (auto it = ripples_.constBegin(); it != ripples_.constEnd(); ++it) + paintRipple(&painter, *it); } void RippleOverlay::paintRipple(QPainter *painter, Ripple *ripple) { - const qreal radius = ripple->radius(); - const QPointF center = ripple->center(); + const qreal radius = ripple->radius(); + const QPointF center = ripple->center(); - painter->setOpacity(ripple->opacity()); - painter->setBrush(ripple->brush()); - painter->drawEllipse(center, radius, radius); + painter->setOpacity(ripple->opacity()); + painter->setBrush(ripple->brush()); + painter->drawEllipse(center, radius, radius); } diff --git a/src/ui/RippleOverlay.h b/src/ui/RippleOverlay.h index 7ae3e4f1..3256c28d 100644 --- a/src/ui/RippleOverlay.h +++ b/src/ui/RippleOverlay.h @@ -12,50 +12,50 @@ class Ripple; class RippleOverlay : public OverlayWidget { - Q_OBJECT + Q_OBJECT public: - explicit RippleOverlay(QWidget *parent = nullptr); + explicit RippleOverlay(QWidget *parent = nullptr); - void addRipple(Ripple *ripple); - void addRipple(const QPoint &position, qreal radius = 300); + void addRipple(Ripple *ripple); + void addRipple(const QPoint &position, qreal radius = 300); - void removeRipple(Ripple *ripple); + void removeRipple(Ripple *ripple); - inline void setClipping(bool enable); - inline bool hasClipping() const; + inline void setClipping(bool enable); + inline bool hasClipping() const; - inline void setClipPath(const QPainterPath &path); + inline void setClipPath(const QPainterPath &path); protected: - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; private: - Q_DISABLE_COPY(RippleOverlay) + Q_DISABLE_COPY(RippleOverlay) - void paintRipple(QPainter *painter, Ripple *ripple); + void paintRipple(QPainter *painter, Ripple *ripple); - QList<Ripple *> ripples_; - QPainterPath clip_path_; - bool use_clip_; + QList<Ripple *> ripples_; + QPainterPath clip_path_; + bool use_clip_; }; inline void RippleOverlay::setClipping(bool enable) { - use_clip_ = enable; - update(); + use_clip_ = enable; + update(); } inline bool RippleOverlay::hasClipping() const { - return use_clip_; + return use_clip_; } inline void RippleOverlay::setClipPath(const QPainterPath &path) { - clip_path_ = path; - update(); + clip_path_ = path; + update(); } diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp index 2fb93325..ed8a7cd8 100644 --- a/src/ui/RoomSettings.cpp +++ b/src/ui/RoomSettings.cpp @@ -27,479 +27,473 @@ EditModal::EditModal(const QString &roomId, QWidget *parent) : QWidget(parent) , roomId_{roomId} { - setAutoFillBackground(true); - setAttribute(Qt::WA_DeleteOnClose, true); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setWindowModality(Qt::WindowModal); - - QFont largeFont; - largeFont.setPointSizeF(largeFont.pointSizeF() * 1.4); - setMinimumWidth(conf::window::minModalWidth); - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - - auto layout = new QVBoxLayout(this); - - applyBtn_ = new QPushButton(tr("Apply"), this); - cancelBtn_ = new QPushButton(tr("Cancel"), this); - cancelBtn_->setDefault(true); - - auto btnLayout = new QHBoxLayout; - btnLayout->addStretch(1); - btnLayout->setSpacing(15); - btnLayout->addWidget(cancelBtn_); - btnLayout->addWidget(applyBtn_); - - nameInput_ = new TextField(this); - nameInput_->setLabel(tr("Name").toUpper()); - topicInput_ = new TextField(this); - topicInput_->setLabel(tr("Topic").toUpper()); - - errorField_ = new QLabel(this); - errorField_->setWordWrap(true); - errorField_->hide(); - - layout->addWidget(nameInput_); - layout->addWidget(topicInput_); - layout->addLayout(btnLayout, 1); - - auto labelLayout = new QHBoxLayout; - labelLayout->setAlignment(Qt::AlignHCenter); - labelLayout->addWidget(errorField_); - layout->addLayout(labelLayout); - - connect(applyBtn_, &QPushButton::clicked, this, &EditModal::applyClicked); - connect(cancelBtn_, &QPushButton::clicked, this, &EditModal::close); - - auto window = QApplication::activeWindow(); - - if (window != nullptr) { - auto center = window->frameGeometry().center(); - move(center.x() - (width() * 0.5), center.y() - (height() * 0.5)); - } + setAutoFillBackground(true); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); + setWindowModality(Qt::WindowModal); + + QFont largeFont; + largeFont.setPointSizeF(largeFont.pointSizeF() * 1.4); + setMinimumWidth(conf::window::minModalWidth); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + auto layout = new QVBoxLayout(this); + + applyBtn_ = new QPushButton(tr("Apply"), this); + cancelBtn_ = new QPushButton(tr("Cancel"), this); + cancelBtn_->setDefault(true); + + auto btnLayout = new QHBoxLayout; + btnLayout->addStretch(1); + btnLayout->setSpacing(15); + btnLayout->addWidget(cancelBtn_); + btnLayout->addWidget(applyBtn_); + + nameInput_ = new TextField(this); + nameInput_->setLabel(tr("Name").toUpper()); + topicInput_ = new TextField(this); + topicInput_->setLabel(tr("Topic").toUpper()); + + errorField_ = new QLabel(this); + errorField_->setWordWrap(true); + errorField_->hide(); + + layout->addWidget(nameInput_); + layout->addWidget(topicInput_); + layout->addLayout(btnLayout, 1); + + auto labelLayout = new QHBoxLayout; + labelLayout->setAlignment(Qt::AlignHCenter); + labelLayout->addWidget(errorField_); + layout->addLayout(labelLayout); + + connect(applyBtn_, &QPushButton::clicked, this, &EditModal::applyClicked); + connect(cancelBtn_, &QPushButton::clicked, this, &EditModal::close); + + auto window = QApplication::activeWindow(); + + if (window != nullptr) { + auto center = window->frameGeometry().center(); + move(center.x() - (width() * 0.5), center.y() - (height() * 0.5)); + } } void EditModal::topicEventSent(const QString &topic) { - errorField_->hide(); - emit topicChanged(topic); - close(); + errorField_->hide(); + emit topicChanged(topic); + close(); } void EditModal::nameEventSent(const QString &name) { - errorField_->hide(); - emit nameChanged(name); - close(); + errorField_->hide(); + emit nameChanged(name); + close(); } void EditModal::error(const QString &msg) { - errorField_->setText(msg); - errorField_->show(); + errorField_->setText(msg); + errorField_->show(); } void EditModal::applyClicked() { - // Check if the values are changed from the originals. - auto newName = nameInput_->text().trimmed(); - auto newTopic = topicInput_->text().trimmed(); + // Check if the values are changed from the originals. + auto newName = nameInput_->text().trimmed(); + auto newTopic = topicInput_->text().trimmed(); - errorField_->hide(); + errorField_->hide(); - if (newName == initialName_ && newTopic == initialTopic_) { - close(); - return; - } + if (newName == initialName_ && newTopic == initialTopic_) { + close(); + return; + } - using namespace mtx::events; - auto proxy = std::make_shared<ThreadProxy>(); - connect(proxy.get(), &ThreadProxy::topicEventSent, this, &EditModal::topicEventSent); - connect(proxy.get(), &ThreadProxy::nameEventSent, this, &EditModal::nameEventSent); - connect(proxy.get(), &ThreadProxy::error, this, &EditModal::error); - - if (newName != initialName_ && !newName.isEmpty()) { - state::Name body; - body.name = newName.toStdString(); - - http::client()->send_state_event( - roomId_.toStdString(), - body, - [proxy, newName](const mtx::responses::EventId &, mtx::http::RequestErr err) { - if (err) { - emit proxy->error( - QString::fromStdString(err->matrix_error.error)); - return; - } - - emit proxy->nameEventSent(newName); - }); - } + using namespace mtx::events; + auto proxy = std::make_shared<ThreadProxy>(); + connect(proxy.get(), &ThreadProxy::topicEventSent, this, &EditModal::topicEventSent); + connect(proxy.get(), &ThreadProxy::nameEventSent, this, &EditModal::nameEventSent); + connect(proxy.get(), &ThreadProxy::error, this, &EditModal::error); - if (newTopic != initialTopic_ && !newTopic.isEmpty()) { - state::Topic body; - body.topic = newTopic.toStdString(); - - http::client()->send_state_event( - roomId_.toStdString(), - body, - [proxy, newTopic](const mtx::responses::EventId &, mtx::http::RequestErr err) { - if (err) { - emit proxy->error( - QString::fromStdString(err->matrix_error.error)); - return; - } - - emit proxy->topicEventSent(newTopic); - }); - } + if (newName != initialName_ && !newName.isEmpty()) { + state::Name body; + body.name = newName.toStdString(); + + http::client()->send_state_event( + roomId_.toStdString(), + body, + [proxy, newName](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) { + emit proxy->error(QString::fromStdString(err->matrix_error.error)); + return; + } + + emit proxy->nameEventSent(newName); + }); + } + + if (newTopic != initialTopic_ && !newTopic.isEmpty()) { + state::Topic body; + body.topic = newTopic.toStdString(); + + http::client()->send_state_event( + roomId_.toStdString(), + body, + [proxy, newTopic](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) { + emit proxy->error(QString::fromStdString(err->matrix_error.error)); + return; + } + + emit proxy->topicEventSent(newTopic); + }); + } } void EditModal::setFields(const QString &roomName, const QString &roomTopic) { - initialName_ = roomName; - initialTopic_ = roomTopic; + initialName_ = roomName; + initialTopic_ = roomTopic; - nameInput_->setText(roomName); - topicInput_->setText(roomTopic); + nameInput_->setText(roomName); + topicInput_->setText(roomTopic); } RoomSettings::RoomSettings(QString roomid, QObject *parent) : QObject(parent) , roomid_{std::move(roomid)} { - retrieveRoomInfo(); - - // get room setting notifications - http::client()->get_pushrules( - "global", - "override", - roomid_.toStdString(), - [this](const mtx::pushrules::PushRule &rule, mtx::http::RequestErr &err) { - if (err) { - if (err->status_code == 404) - http::client()->get_pushrules( - "global", - "room", - roomid_.toStdString(), - [this](const mtx::pushrules::PushRule &rule, - mtx::http::RequestErr &err) { - if (err) { - notifications_ = 2; // all messages - emit notificationsChanged(); - return; - } - - if (rule.enabled) { - notifications_ = 1; // mentions only - emit notificationsChanged(); - } - }); - return; - } - - if (rule.enabled) { - notifications_ = 0; // muted - emit notificationsChanged(); - } else { - notifications_ = 2; // all messages - emit notificationsChanged(); - } - }); - - // access rules - if (info_.join_rule == state::JoinRule::Public) { - if (info_.guest_access) { - accessRules_ = 0; - } else { - accessRules_ = 1; - } - } else if (info_.join_rule == state::JoinRule::Invite) { - accessRules_ = 2; - } else if (info_.join_rule == state::JoinRule::Knock) { - accessRules_ = 3; - } else if (info_.join_rule == state::JoinRule::Restricted) { - accessRules_ = 4; + retrieveRoomInfo(); + + // get room setting notifications + http::client()->get_pushrules( + "global", + "override", + roomid_.toStdString(), + [this](const mtx::pushrules::PushRule &rule, mtx::http::RequestErr &err) { + if (err) { + if (err->status_code == 404) + http::client()->get_pushrules( + "global", + "room", + roomid_.toStdString(), + [this](const mtx::pushrules::PushRule &rule, mtx::http::RequestErr &err) { + if (err) { + notifications_ = 2; // all messages + emit notificationsChanged(); + return; + } + + if (rule.enabled) { + notifications_ = 1; // mentions only + emit notificationsChanged(); + } + }); + return; + } + + if (rule.enabled) { + notifications_ = 0; // muted + emit notificationsChanged(); + } else { + notifications_ = 2; // all messages + emit notificationsChanged(); + } + }); + + // access rules + if (info_.join_rule == state::JoinRule::Public) { + if (info_.guest_access) { + accessRules_ = 0; + } else { + accessRules_ = 1; } - emit accessJoinRulesChanged(); + } else if (info_.join_rule == state::JoinRule::Invite) { + accessRules_ = 2; + } else if (info_.join_rule == state::JoinRule::Knock) { + accessRules_ = 3; + } else if (info_.join_rule == state::JoinRule::Restricted) { + accessRules_ = 4; + } + emit accessJoinRulesChanged(); } QString RoomSettings::roomName() const { - return utils::replaceEmoji(QString::fromStdString(info_.name).toHtmlEscaped()); + return utils::replaceEmoji(QString::fromStdString(info_.name).toHtmlEscaped()); } QString RoomSettings::roomTopic() const { - return utils::replaceEmoji(utils::linkifyMessage( - QString::fromStdString(info_.topic).toHtmlEscaped().replace("\n", "<br>"))); + return utils::replaceEmoji(utils::linkifyMessage( + QString::fromStdString(info_.topic).toHtmlEscaped().replace("\n", "<br>"))); } QString RoomSettings::roomId() const { - return roomid_; + return roomid_; } QString RoomSettings::roomVersion() const { - return QString::fromStdString(info_.version); + return QString::fromStdString(info_.version); } bool RoomSettings::isLoading() const { - return isLoading_; + return isLoading_; } QString RoomSettings::roomAvatarUrl() { - return QString::fromStdString(info_.avatar_url); + return QString::fromStdString(info_.avatar_url); } int RoomSettings::memberCount() const { - return info_.member_count; + return info_.member_count; } void RoomSettings::retrieveRoomInfo() { - try { - usesEncryption_ = cache::isRoomEncrypted(roomid_.toStdString()); - info_ = cache::singleRoomInfo(roomid_.toStdString()); - } catch (const lmdb::error &) { - nhlog::db()->warn("failed to retrieve room info from cache: {}", - roomid_.toStdString()); - } + try { + usesEncryption_ = cache::isRoomEncrypted(roomid_.toStdString()); + info_ = cache::singleRoomInfo(roomid_.toStdString()); + } catch (const lmdb::error &) { + nhlog::db()->warn("failed to retrieve room info from cache: {}", roomid_.toStdString()); + } } int RoomSettings::notifications() { - return notifications_; + return notifications_; } int RoomSettings::accessJoinRules() { - return accessRules_; + return accessRules_; } void RoomSettings::enableEncryption() { - if (usesEncryption_) - return; - - const auto room_id = roomid_.toStdString(); - http::client()->enable_encryption( - room_id, [room_id, this](const mtx::responses::EventId &, mtx::http::RequestErr err) { - if (err) { - int status_code = static_cast<int>(err->status_code); - nhlog::net()->warn("failed to enable encryption in room ({}): {} {}", - room_id, - err->matrix_error.error, - status_code); - emit displayError( - tr("Failed to enable encryption: %1") - .arg(QString::fromStdString(err->matrix_error.error))); - usesEncryption_ = false; - emit encryptionChanged(); - return; - } - - nhlog::net()->info("enabled encryption on room ({})", room_id); - }); - - usesEncryption_ = true; - emit encryptionChanged(); + if (usesEncryption_) + return; + + const auto room_id = roomid_.toStdString(); + http::client()->enable_encryption( + room_id, [room_id, this](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) { + int status_code = static_cast<int>(err->status_code); + nhlog::net()->warn("failed to enable encryption in room ({}): {} {}", + room_id, + err->matrix_error.error, + status_code); + emit displayError(tr("Failed to enable encryption: %1") + .arg(QString::fromStdString(err->matrix_error.error))); + usesEncryption_ = false; + emit encryptionChanged(); + return; + } + + nhlog::net()->info("enabled encryption on room ({})", room_id); + }); + + usesEncryption_ = true; + emit encryptionChanged(); } bool RoomSettings::canChangeJoinRules() const { - try { - return cache::hasEnoughPowerLevel({EventType::RoomJoinRules}, - roomid_.toStdString(), - utils::localUser().toStdString()); - } catch (const lmdb::error &e) { - nhlog::db()->warn("lmdb error: {}", e.what()); - } - - return false; + try { + return cache::hasEnoughPowerLevel( + {EventType::RoomJoinRules}, roomid_.toStdString(), utils::localUser().toStdString()); + } catch (const lmdb::error &e) { + nhlog::db()->warn("lmdb error: {}", e.what()); + } + + return false; } bool RoomSettings::canChangeNameAndTopic() const { - try { - return cache::hasEnoughPowerLevel({EventType::RoomName, EventType::RoomTopic}, - roomid_.toStdString(), - utils::localUser().toStdString()); - } catch (const lmdb::error &e) { - nhlog::db()->warn("lmdb error: {}", e.what()); - } - - return false; + try { + return cache::hasEnoughPowerLevel({EventType::RoomName, EventType::RoomTopic}, + roomid_.toStdString(), + utils::localUser().toStdString()); + } catch (const lmdb::error &e) { + nhlog::db()->warn("lmdb error: {}", e.what()); + } + + return false; } bool RoomSettings::canChangeAvatar() const { - try { - return cache::hasEnoughPowerLevel( - {EventType::RoomAvatar}, roomid_.toStdString(), utils::localUser().toStdString()); - } catch (const lmdb::error &e) { - nhlog::db()->warn("lmdb error: {}", e.what()); - } - - return false; + try { + return cache::hasEnoughPowerLevel( + {EventType::RoomAvatar}, roomid_.toStdString(), utils::localUser().toStdString()); + } catch (const lmdb::error &e) { + nhlog::db()->warn("lmdb error: {}", e.what()); + } + + return false; } bool RoomSettings::isEncryptionEnabled() const { - return usesEncryption_; + return usesEncryption_; } bool RoomSettings::supportsKnocking() const { - return info_.version != "" && info_.version != "1" && info_.version != "2" && - info_.version != "3" && info_.version != "4" && info_.version != "5" && - info_.version != "6"; + return info_.version != "" && info_.version != "1" && info_.version != "2" && + info_.version != "3" && info_.version != "4" && info_.version != "5" && + info_.version != "6"; } bool RoomSettings::supportsRestricted() const { - return info_.version != "" && info_.version != "1" && info_.version != "2" && - info_.version != "3" && info_.version != "4" && info_.version != "5" && - info_.version != "6" && info_.version != "7"; + return info_.version != "" && info_.version != "1" && info_.version != "2" && + info_.version != "3" && info_.version != "4" && info_.version != "5" && + info_.version != "6" && info_.version != "7"; } void RoomSettings::openEditModal() { - retrieveRoomInfo(); - - auto modal = new EditModal(roomid_); - modal->setFields(QString::fromStdString(info_.name), QString::fromStdString(info_.topic)); - modal->raise(); - modal->show(); - connect(modal, &EditModal::nameChanged, this, [this](const QString &newName) { - info_.name = newName.toStdString(); - emit roomNameChanged(); - }); - - connect(modal, &EditModal::topicChanged, this, [this](const QString &newTopic) { - info_.topic = newTopic.toStdString(); - emit roomTopicChanged(); - }); + retrieveRoomInfo(); + + auto modal = new EditModal(roomid_); + modal->setFields(QString::fromStdString(info_.name), QString::fromStdString(info_.topic)); + modal->raise(); + modal->show(); + connect(modal, &EditModal::nameChanged, this, [this](const QString &newName) { + info_.name = newName.toStdString(); + emit roomNameChanged(); + }); + + connect(modal, &EditModal::topicChanged, this, [this](const QString &newTopic) { + info_.topic = newTopic.toStdString(); + emit roomTopicChanged(); + }); } void RoomSettings::changeNotifications(int currentIndex) { - notifications_ = currentIndex; - - std::string room_id = roomid_.toStdString(); - if (notifications_ == 0) { - // mute room - // delete old rule first, then add new rule - mtx::pushrules::PushRule rule; - rule.actions = {mtx::pushrules::actions::dont_notify{}}; - mtx::pushrules::PushCondition condition; - condition.kind = "event_match"; - condition.key = "room_id"; - condition.pattern = room_id; - rule.conditions = {condition}; - - http::client()->put_pushrules( - "global", "override", room_id, rule, [room_id](mtx::http::RequestErr &err) { - if (err) - nhlog::net()->error("failed to set pushrule for room {}: {} {}", - room_id, - static_cast<int>(err->status_code), - err->matrix_error.error); - http::client()->delete_pushrules( - "global", "room", room_id, [room_id](mtx::http::RequestErr &) {}); - }); - } else if (notifications_ == 1) { - // mentions only - // delete old rule first, then add new rule - mtx::pushrules::PushRule rule; - rule.actions = {mtx::pushrules::actions::dont_notify{}}; - http::client()->put_pushrules( - "global", "room", room_id, rule, [room_id](mtx::http::RequestErr &err) { - if (err) - nhlog::net()->error("failed to set pushrule for room {}: {} {}", - room_id, - static_cast<int>(err->status_code), - err->matrix_error.error); - http::client()->delete_pushrules( - "global", "override", room_id, [room_id](mtx::http::RequestErr &) {}); - }); - } else { - // all messages - http::client()->delete_pushrules( - "global", "override", room_id, [room_id](mtx::http::RequestErr &) { - http::client()->delete_pushrules( - "global", "room", room_id, [room_id](mtx::http::RequestErr &) {}); - }); - } + notifications_ = currentIndex; + + std::string room_id = roomid_.toStdString(); + if (notifications_ == 0) { + // mute room + // delete old rule first, then add new rule + mtx::pushrules::PushRule rule; + rule.actions = {mtx::pushrules::actions::dont_notify{}}; + mtx::pushrules::PushCondition condition; + condition.kind = "event_match"; + condition.key = "room_id"; + condition.pattern = room_id; + rule.conditions = {condition}; + + http::client()->put_pushrules( + "global", "override", room_id, rule, [room_id](mtx::http::RequestErr &err) { + if (err) + nhlog::net()->error("failed to set pushrule for room {}: {} {}", + room_id, + static_cast<int>(err->status_code), + err->matrix_error.error); + http::client()->delete_pushrules( + "global", "room", room_id, [room_id](mtx::http::RequestErr &) {}); + }); + } else if (notifications_ == 1) { + // mentions only + // delete old rule first, then add new rule + mtx::pushrules::PushRule rule; + rule.actions = {mtx::pushrules::actions::dont_notify{}}; + http::client()->put_pushrules( + "global", "room", room_id, rule, [room_id](mtx::http::RequestErr &err) { + if (err) + nhlog::net()->error("failed to set pushrule for room {}: {} {}", + room_id, + static_cast<int>(err->status_code), + err->matrix_error.error); + http::client()->delete_pushrules( + "global", "override", room_id, [room_id](mtx::http::RequestErr &) {}); + }); + } else { + // all messages + http::client()->delete_pushrules( + "global", "override", room_id, [room_id](mtx::http::RequestErr &) { + http::client()->delete_pushrules( + "global", "room", room_id, [room_id](mtx::http::RequestErr &) {}); + }); + } } void RoomSettings::changeAccessRules(int index) { - using namespace mtx::events::state; - - auto guest_access = [](int index) -> state::GuestAccess { - state::GuestAccess event; - - if (index == 0) - event.guest_access = state::AccessState::CanJoin; - else - event.guest_access = state::AccessState::Forbidden; - - return event; - }(index); - - auto join_rule = [](int index) -> state::JoinRules { - state::JoinRules event; - - switch (index) { - case 0: - case 1: - event.join_rule = state::JoinRule::Public; - break; - case 2: - event.join_rule = state::JoinRule::Invite; - break; - case 3: - event.join_rule = state::JoinRule::Knock; - break; - case 4: - event.join_rule = state::JoinRule::Restricted; - break; - default: - event.join_rule = state::JoinRule::Invite; - } + using namespace mtx::events::state; + + auto guest_access = [](int index) -> state::GuestAccess { + state::GuestAccess event; + + if (index == 0) + event.guest_access = state::AccessState::CanJoin; + else + event.guest_access = state::AccessState::Forbidden; + + return event; + }(index); + + auto join_rule = [](int index) -> state::JoinRules { + state::JoinRules event; + + switch (index) { + case 0: + case 1: + event.join_rule = state::JoinRule::Public; + break; + case 2: + event.join_rule = state::JoinRule::Invite; + break; + case 3: + event.join_rule = state::JoinRule::Knock; + break; + case 4: + event.join_rule = state::JoinRule::Restricted; + break; + default: + event.join_rule = state::JoinRule::Invite; + } - return event; - }(index); + return event; + }(index); - updateAccessRules(roomid_.toStdString(), join_rule, guest_access); + updateAccessRules(roomid_.toStdString(), join_rule, guest_access); } void @@ -507,139 +501,134 @@ RoomSettings::updateAccessRules(const std::string &room_id, const mtx::events::state::JoinRules &join_rule, const mtx::events::state::GuestAccess &guest_access) { - isLoading_ = true; - emit loadingChanged(); + isLoading_ = true; + emit loadingChanged(); + + http::client()->send_state_event( + room_id, + join_rule, + [this, room_id, guest_access](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to send m.room.join_rule: {} {}", + static_cast<int>(err->status_code), + err->matrix_error.error); + emit displayError(QString::fromStdString(err->matrix_error.error)); + isLoading_ = false; + emit loadingChanged(); + return; + } + + http::client()->send_state_event( + room_id, + guest_access, + [this](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to send m.room.guest_access: {} {}", + static_cast<int>(err->status_code), + err->matrix_error.error); + emit displayError(QString::fromStdString(err->matrix_error.error)); + } - http::client()->send_state_event( - room_id, - join_rule, - [this, room_id, guest_access](const mtx::responses::EventId &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to send m.room.join_rule: {} {}", - static_cast<int>(err->status_code), - err->matrix_error.error); - emit displayError(QString::fromStdString(err->matrix_error.error)); - isLoading_ = false; - emit loadingChanged(); - return; - } - - http::client()->send_state_event( - room_id, - guest_access, - [this](const mtx::responses::EventId &, mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to send m.room.guest_access: {} {}", - static_cast<int>(err->status_code), - err->matrix_error.error); - emit displayError( - QString::fromStdString(err->matrix_error.error)); - } - - isLoading_ = false; - emit loadingChanged(); - }); - }); + isLoading_ = false; + emit loadingChanged(); + }); + }); } void RoomSettings::stopLoading() { - isLoading_ = false; - emit loadingChanged(); + isLoading_ = false; + emit loadingChanged(); } void RoomSettings::avatarChanged() { - retrieveRoomInfo(); - emit avatarUrlChanged(); + retrieveRoomInfo(); + emit avatarUrlChanged(); } void RoomSettings::updateAvatar() { - const QString picturesFolder = - QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); - const QString fileName = QFileDialog::getOpenFileName( - nullptr, tr("Select an avatar"), picturesFolder, tr("All Files (*)")); - - if (fileName.isEmpty()) - return; - - QMimeDatabase db; - QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent); - - const auto format = mime.name().split("/")[0]; - - QFile file{fileName, this}; - if (format != "image") { - emit displayError(tr("The selected file is not an image")); - return; - } - - if (!file.open(QIODevice::ReadOnly)) { - emit displayError(tr("Error while reading file: %1").arg(file.errorString())); - return; - } - - isLoading_ = true; - emit loadingChanged(); - - // Events emitted from the http callbacks (different threads) will - // be queued back into the UI thread through this proxy object. - auto proxy = std::make_shared<ThreadProxy>(); - connect(proxy.get(), &ThreadProxy::error, this, &RoomSettings::displayError); - connect(proxy.get(), &ThreadProxy::stopLoading, this, &RoomSettings::stopLoading); - - const auto bin = file.peek(file.size()); - const auto payload = std::string(bin.data(), bin.size()); - const auto dimensions = QImageReader(&file).size(); - - // First we need to create a new mxc URI - // (i.e upload media to the Matrix content repository) for the new avatar. - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fileName).fileName().toStdString(), - [proxy = std::move(proxy), - dimensions, - payload, - mimetype = mime.name().toStdString(), - size = payload.size(), - room_id = roomid_.toStdString(), - content = std::move(bin)](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { - if (err) { - emit proxy->stopLoading(); - emit proxy->error( - tr("Failed to upload image: %s") - .arg(QString::fromStdString(err->matrix_error.error))); - return; - } - - using namespace mtx::events; - state::Avatar avatar_event; - avatar_event.image_info.w = dimensions.width(); - avatar_event.image_info.h = dimensions.height(); - avatar_event.image_info.mimetype = mimetype; - avatar_event.image_info.size = size; - avatar_event.url = res.content_uri; - - http::client()->send_state_event( - room_id, - avatar_event, - [content = std::move(content), proxy = std::move(proxy)]( - const mtx::responses::EventId &, mtx::http::RequestErr err) { - if (err) { - emit proxy->error( - tr("Failed to upload image: %s") + const QString picturesFolder = + QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); + const QString fileName = QFileDialog::getOpenFileName( + nullptr, tr("Select an avatar"), picturesFolder, tr("All Files (*)")); + + if (fileName.isEmpty()) + return; + + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent); + + const auto format = mime.name().split("/")[0]; + + QFile file{fileName, this}; + if (format != "image") { + emit displayError(tr("The selected file is not an image")); + return; + } + + if (!file.open(QIODevice::ReadOnly)) { + emit displayError(tr("Error while reading file: %1").arg(file.errorString())); + return; + } + + isLoading_ = true; + emit loadingChanged(); + + // Events emitted from the http callbacks (different threads) will + // be queued back into the UI thread through this proxy object. + auto proxy = std::make_shared<ThreadProxy>(); + connect(proxy.get(), &ThreadProxy::error, this, &RoomSettings::displayError); + connect(proxy.get(), &ThreadProxy::stopLoading, this, &RoomSettings::stopLoading); + + const auto bin = file.peek(file.size()); + const auto payload = std::string(bin.data(), bin.size()); + const auto dimensions = QImageReader(&file).size(); + + // First we need to create a new mxc URI + // (i.e upload media to the Matrix content repository) for the new avatar. + http::client()->upload( + payload, + mime.name().toStdString(), + QFileInfo(fileName).fileName().toStdString(), + [proxy = std::move(proxy), + dimensions, + payload, + mimetype = mime.name().toStdString(), + size = payload.size(), + room_id = roomid_.toStdString(), + content = std::move(bin)](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) { + if (err) { + emit proxy->stopLoading(); + emit proxy->error(tr("Failed to upload image: %s") + .arg(QString::fromStdString(err->matrix_error.error))); + return; + } + + using namespace mtx::events; + state::Avatar avatar_event; + avatar_event.image_info.w = dimensions.width(); + avatar_event.image_info.h = dimensions.height(); + avatar_event.image_info.mimetype = mimetype; + avatar_event.image_info.size = size; + avatar_event.url = res.content_uri; + + http::client()->send_state_event( + room_id, + avatar_event, + [content = std::move(content), + proxy = std::move(proxy)](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) { + emit proxy->error(tr("Failed to upload image: %s") .arg(QString::fromStdString(err->matrix_error.error))); - return; - } + return; + } - emit proxy->stopLoading(); - }); - }); + emit proxy->stopLoading(); + }); + }); } diff --git a/src/ui/RoomSettings.h b/src/ui/RoomSettings.h index ab768ffe..6ec645e0 100644 --- a/src/ui/RoomSettings.h +++ b/src/ui/RoomSettings.h @@ -19,121 +19,121 @@ class TextField; /// outside of main with the UI code. class ThreadProxy : public QObject { - Q_OBJECT + Q_OBJECT signals: - void error(const QString &msg); - void nameEventSent(const QString &); - void topicEventSent(const QString &); - void stopLoading(); + void error(const QString &msg); + void nameEventSent(const QString &); + void topicEventSent(const QString &); + void stopLoading(); }; class EditModal : public QWidget { - Q_OBJECT + Q_OBJECT public: - EditModal(const QString &roomId, QWidget *parent = nullptr); + EditModal(const QString &roomId, QWidget *parent = nullptr); - void setFields(const QString &roomName, const QString &roomTopic); + void setFields(const QString &roomName, const QString &roomTopic); signals: - void nameChanged(const QString &roomName); - void topicChanged(const QString &topic); + void nameChanged(const QString &roomName); + void topicChanged(const QString &topic); private slots: - void topicEventSent(const QString &topic); - void nameEventSent(const QString &name); - void error(const QString &msg); + void topicEventSent(const QString &topic); + void nameEventSent(const QString &name); + void error(const QString &msg); - void applyClicked(); + void applyClicked(); private: - QString roomId_; - QString initialName_; - QString initialTopic_; + QString roomId_; + QString initialName_; + QString initialTopic_; - QLabel *errorField_; + QLabel *errorField_; - TextField *nameInput_; - TextField *topicInput_; + TextField *nameInput_; + TextField *topicInput_; - QPushButton *applyBtn_; - QPushButton *cancelBtn_; + QPushButton *applyBtn_; + QPushButton *cancelBtn_; }; class RoomSettings : public QObject { - Q_OBJECT - Q_PROPERTY(QString roomId READ roomId CONSTANT) - Q_PROPERTY(QString roomVersion READ roomVersion CONSTANT) - Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) - Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) - Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY avatarUrlChanged) - Q_PROPERTY(int memberCount READ memberCount CONSTANT) - Q_PROPERTY(int notifications READ notifications NOTIFY notificationsChanged) - Q_PROPERTY(int accessJoinRules READ accessJoinRules NOTIFY accessJoinRulesChanged) - Q_PROPERTY(bool isLoading READ isLoading NOTIFY loadingChanged) - Q_PROPERTY(bool canChangeAvatar READ canChangeAvatar CONSTANT) - Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules CONSTANT) - Q_PROPERTY(bool canChangeNameAndTopic READ canChangeNameAndTopic CONSTANT) - Q_PROPERTY(bool isEncryptionEnabled READ isEncryptionEnabled NOTIFY encryptionChanged) - Q_PROPERTY(bool supportsKnocking READ supportsKnocking CONSTANT) - Q_PROPERTY(bool supportsRestricted READ supportsRestricted CONSTANT) + Q_OBJECT + Q_PROPERTY(QString roomId READ roomId CONSTANT) + Q_PROPERTY(QString roomVersion READ roomVersion CONSTANT) + Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) + Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) + Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY avatarUrlChanged) + Q_PROPERTY(int memberCount READ memberCount CONSTANT) + Q_PROPERTY(int notifications READ notifications NOTIFY notificationsChanged) + Q_PROPERTY(int accessJoinRules READ accessJoinRules NOTIFY accessJoinRulesChanged) + Q_PROPERTY(bool isLoading READ isLoading NOTIFY loadingChanged) + Q_PROPERTY(bool canChangeAvatar READ canChangeAvatar CONSTANT) + Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules CONSTANT) + Q_PROPERTY(bool canChangeNameAndTopic READ canChangeNameAndTopic CONSTANT) + Q_PROPERTY(bool isEncryptionEnabled READ isEncryptionEnabled NOTIFY encryptionChanged) + Q_PROPERTY(bool supportsKnocking READ supportsKnocking CONSTANT) + Q_PROPERTY(bool supportsRestricted READ supportsRestricted CONSTANT) public: - RoomSettings(QString roomid, QObject *parent = nullptr); - - QString roomId() const; - QString roomName() const; - QString roomTopic() const; - QString roomVersion() const; - QString roomAvatarUrl(); - int memberCount() const; - int notifications(); - int accessJoinRules(); - bool isLoading() const; - //! Whether the user has enough power level to send m.room.join_rules events. - bool canChangeJoinRules() const; - //! Whether the user has enough power level to send m.room.name & m.room.topic events. - bool canChangeNameAndTopic() const; - //! Whether the user has enough power level to send m.room.avatar event. - bool canChangeAvatar() const; - bool isEncryptionEnabled() const; - bool supportsKnocking() const; - bool supportsRestricted() const; - - Q_INVOKABLE void enableEncryption(); - Q_INVOKABLE void updateAvatar(); - Q_INVOKABLE void openEditModal(); - Q_INVOKABLE void changeAccessRules(int index); - Q_INVOKABLE void changeNotifications(int currentIndex); + RoomSettings(QString roomid, QObject *parent = nullptr); + + QString roomId() const; + QString roomName() const; + QString roomTopic() const; + QString roomVersion() const; + QString roomAvatarUrl(); + int memberCount() const; + int notifications(); + int accessJoinRules(); + bool isLoading() const; + //! Whether the user has enough power level to send m.room.join_rules events. + bool canChangeJoinRules() const; + //! Whether the user has enough power level to send m.room.name & m.room.topic events. + bool canChangeNameAndTopic() const; + //! Whether the user has enough power level to send m.room.avatar event. + bool canChangeAvatar() const; + bool isEncryptionEnabled() const; + bool supportsKnocking() const; + bool supportsRestricted() const; + + Q_INVOKABLE void enableEncryption(); + Q_INVOKABLE void updateAvatar(); + Q_INVOKABLE void openEditModal(); + Q_INVOKABLE void changeAccessRules(int index); + Q_INVOKABLE void changeNotifications(int currentIndex); signals: - void loadingChanged(); - void roomNameChanged(); - void roomTopicChanged(); - void avatarUrlChanged(); - void encryptionChanged(); - void notificationsChanged(); - void accessJoinRulesChanged(); - void displayError(const QString &errorMessage); + void loadingChanged(); + void roomNameChanged(); + void roomTopicChanged(); + void avatarUrlChanged(); + void encryptionChanged(); + void notificationsChanged(); + void accessJoinRulesChanged(); + void displayError(const QString &errorMessage); public slots: - void stopLoading(); - void avatarChanged(); + void stopLoading(); + void avatarChanged(); private: - void retrieveRoomInfo(); - void updateAccessRules(const std::string &room_id, - const mtx::events::state::JoinRules &, - const mtx::events::state::GuestAccess &); + void retrieveRoomInfo(); + void updateAccessRules(const std::string &room_id, + const mtx::events::state::JoinRules &, + const mtx::events::state::GuestAccess &); private: - QString roomid_; - bool usesEncryption_ = false; - bool isLoading_ = false; - RoomInfo info_; - int notifications_ = 0; - int accessRules_ = 0; + QString roomid_; + bool usesEncryption_ = false; + bool isLoading_ = false; + RoomInfo info_; + int notifications_ = 0; + int accessRules_ = 0; }; diff --git a/src/ui/SnackBar.cpp b/src/ui/SnackBar.cpp index 18990c47..90187154 100644 --- a/src/ui/SnackBar.cpp +++ b/src/ui/SnackBar.cpp @@ -15,121 +15,121 @@ SnackBar::SnackBar(QWidget *parent) : OverlayWidget(parent) , offset_anim(this, "offset", this) { - QFont font; - font.setPointSizeF(font.pointSizeF() * 1.2); - font.setWeight(50); - setFont(font); + QFont font; + font.setPointSizeF(font.pointSizeF() * 1.2); + font.setWeight(50); + setFont(font); - boxHeight_ = QFontMetrics(font).height() * 2; - offset_ = STARTING_OFFSET; - position_ = SnackBarPosition::Top; + boxHeight_ = QFontMetrics(font).height() * 2; + offset_ = STARTING_OFFSET; + position_ = SnackBarPosition::Top; - hideTimer_.setSingleShot(true); + hideTimer_.setSingleShot(true); - offset_anim.setStartValue(1.0); - offset_anim.setEndValue(0.0); - offset_anim.setDuration(100); - offset_anim.setEasingCurve(QEasingCurve::OutCubic); + offset_anim.setStartValue(1.0); + offset_anim.setEndValue(0.0); + offset_anim.setDuration(100); + offset_anim.setEasingCurve(QEasingCurve::OutCubic); - connect(this, &SnackBar::offsetChanged, this, [this]() mutable { repaint(); }); - connect( - &offset_anim, &QPropertyAnimation::finished, this, [this]() { hideTimer_.start(10000); }); + connect(this, &SnackBar::offsetChanged, this, [this]() mutable { repaint(); }); + connect( + &offset_anim, &QPropertyAnimation::finished, this, [this]() { hideTimer_.start(10000); }); - connect(&hideTimer_, SIGNAL(timeout()), this, SLOT(hideMessage())); + connect(&hideTimer_, SIGNAL(timeout()), this, SLOT(hideMessage())); - hide(); + hide(); } void SnackBar::start() { - if (messages_.empty()) - return; + if (messages_.empty()) + return; - show(); - raise(); + show(); + raise(); - offset_anim.start(); + offset_anim.start(); } void SnackBar::hideMessage() { - stopTimers(); - hide(); + stopTimers(); + hide(); - if (!messages_.empty()) - // Moving on to the next message. - messages_.pop_front(); + if (!messages_.empty()) + // Moving on to the next message. + messages_.pop_front(); - // Resetting the starting position of the widget. - offset_ = STARTING_OFFSET; + // Resetting the starting position of the widget. + offset_ = STARTING_OFFSET; - if (!messages_.empty()) - start(); + if (!messages_.empty()) + start(); } void SnackBar::stopTimers() { - hideTimer_.stop(); + hideTimer_.stop(); } void SnackBar::showMessage(const QString &msg) { - messages_.push_back(msg); + messages_.push_back(msg); - // There is already an active message. - if (isVisible()) - return; + // There is already an active message. + if (isVisible()) + return; - start(); + start(); } void SnackBar::mousePressEvent(QMouseEvent *) { - hideMessage(); + hideMessage(); } void SnackBar::paintEvent(QPaintEvent *event) { - Q_UNUSED(event) + Q_UNUSED(event) - if (messages_.empty()) - return; + if (messages_.empty()) + return; - auto message_ = messages_.front(); + auto message_ = messages_.front(); - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor(bgColor_); - p.setBrush(brush); + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(bgColor_); + p.setBrush(brush); - QRect r(0, 0, std::max(MIN_WIDTH, width() * MIN_WIDTH_PERCENTAGE), boxHeight_); + QRect r(0, 0, std::max(MIN_WIDTH, width() * MIN_WIDTH_PERCENTAGE), boxHeight_); - p.setPen(Qt::white); - QRect br = p.boundingRect(r, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_); + p.setPen(Qt::white); + QRect br = p.boundingRect(r, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_); - p.setPen(Qt::NoPen); - r = br.united(r).adjusted(-BOX_PADDING, -BOX_PADDING, BOX_PADDING, BOX_PADDING); + p.setPen(Qt::NoPen); + r = br.united(r).adjusted(-BOX_PADDING, -BOX_PADDING, BOX_PADDING, BOX_PADDING); - const qreal s = 1 - offset_; + const qreal s = 1 - offset_; - if (position_ == SnackBarPosition::Bottom) - p.translate((width() - (r.width() - 2 * BOX_PADDING)) / 2, - height() - BOX_PADDING - s * (r.height())); - else - p.translate((width() - (r.width() - 2 * BOX_PADDING)) / 2, - s * (r.height()) - 2 * BOX_PADDING); + if (position_ == SnackBarPosition::Bottom) + p.translate((width() - (r.width() - 2 * BOX_PADDING)) / 2, + height() - BOX_PADDING - s * (r.height())); + else + p.translate((width() - (r.width() - 2 * BOX_PADDING)) / 2, + s * (r.height()) - 2 * BOX_PADDING); - br.moveCenter(r.center()); - p.drawRoundedRect(r.adjusted(0, 0, 0, 4), 4, 4); - p.setPen(textColor_); - p.drawText(br, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_); + br.moveCenter(r.center()); + p.drawRoundedRect(r.adjusted(0, 0, 0, 4), 4, 4); + p.setPen(textColor_); + p.drawText(br, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_); } diff --git a/src/ui/SnackBar.h b/src/ui/SnackBar.h index 8d127933..0459950f 100644 --- a/src/ui/SnackBar.h +++ b/src/ui/SnackBar.h @@ -14,79 +14,79 @@ enum class SnackBarPosition { - Bottom, - Top, + Bottom, + Top, }; class SnackBar : public OverlayWidget { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor bgColor READ backgroundColor WRITE setBackgroundColor) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(double offset READ offset WRITE setOffset NOTIFY offsetChanged) + Q_PROPERTY(QColor bgColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(double offset READ offset WRITE setOffset NOTIFY offsetChanged) public: - explicit SnackBar(QWidget *parent); - - QColor backgroundColor() const { return bgColor_; } - void setBackgroundColor(const QColor &color) - { - bgColor_ = color; - update(); - } - - QColor textColor() const { return textColor_; } - void setTextColor(const QColor &color) - { - textColor_ = color; - update(); - } - void setPosition(SnackBarPosition pos) - { - position_ = pos; - update(); - } - - double offset() { return offset_; } - void setOffset(double offset) - { - if (offset != offset_) { - offset_ = offset; - emit offsetChanged(); - } + explicit SnackBar(QWidget *parent); + + QColor backgroundColor() const { return bgColor_; } + void setBackgroundColor(const QColor &color) + { + bgColor_ = color; + update(); + } + + QColor textColor() const { return textColor_; } + void setTextColor(const QColor &color) + { + textColor_ = color; + update(); + } + void setPosition(SnackBarPosition pos) + { + position_ = pos; + update(); + } + + double offset() { return offset_; } + void setOffset(double offset) + { + if (offset != offset_) { + offset_ = offset; + emit offsetChanged(); } + } public slots: - void showMessage(const QString &msg); + void showMessage(const QString &msg); signals: - void offsetChanged(); + void offsetChanged(); protected: - void paintEvent(QPaintEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; private slots: - void hideMessage(); + void hideMessage(); private: - void stopTimers(); - void start(); + void stopTimers(); + void start(); - QColor bgColor_; - QColor textColor_; + QColor bgColor_; + QColor textColor_; - qreal bgOpacity_; - qreal offset_; + qreal bgOpacity_; + qreal offset_; - std::deque<QString> messages_; + std::deque<QString> messages_; - QTimer hideTimer_; + QTimer hideTimer_; - double boxHeight_; + double boxHeight_; - QPropertyAnimation offset_anim; + QPropertyAnimation offset_anim; - SnackBarPosition position_; + SnackBarPosition position_; }; diff --git a/src/ui/TextField.cpp b/src/ui/TextField.cpp index 7d015e89..8f1a6aa5 100644 --- a/src/ui/TextField.cpp +++ b/src/ui/TextField.cpp @@ -15,363 +15,363 @@ TextField::TextField(QWidget *parent) : QLineEdit(parent) { - // Get rid of the focus border on macOS. - setAttribute(Qt::WA_MacShowFocusRect, 0); + // Get rid of the focus border on macOS. + setAttribute(Qt::WA_MacShowFocusRect, 0); - QPalette pal; + QPalette pal; - state_machine_ = new TextFieldStateMachine(this); - label_ = nullptr; - label_font_size_ = 15; - show_label_ = false; - background_color_ = pal.color(QPalette::Window); - is_valid_ = true; + state_machine_ = new TextFieldStateMachine(this); + label_ = nullptr; + label_font_size_ = 15; + show_label_ = false; + background_color_ = pal.color(QPalette::Window); + is_valid_ = true; - setFrame(false); - setAttribute(Qt::WA_Hover); - setMouseTracking(true); - setTextMargins(0, 4, 0, 6); + setFrame(false); + setAttribute(Qt::WA_Hover); + setMouseTracking(true); + setTextMargins(0, 4, 0, 6); - state_machine_->start(); - QCoreApplication::processEvents(); + state_machine_->start(); + QCoreApplication::processEvents(); } void TextField::setBackgroundColor(const QColor &color) { - background_color_ = color; + background_color_ = color; } QColor TextField::backgroundColor() const { - return background_color_; + return background_color_; } void TextField::setShowLabel(bool value) { - if (show_label_ == value) { - return; - } - - show_label_ = value; - - if (!label_ && value) { - label_ = new TextFieldLabel(this); - state_machine_->setLabel(label_); - } - - if (value) { - setContentsMargins(0, 23, 0, 0); - } else { - setContentsMargins(0, 0, 0, 0); - } + if (show_label_ == value) { + return; + } + + show_label_ = value; + + if (!label_ && value) { + label_ = new TextFieldLabel(this); + state_machine_->setLabel(label_); + } + + if (value) { + setContentsMargins(0, 23, 0, 0); + } else { + setContentsMargins(0, 0, 0, 0); + } } bool TextField::hasLabel() const { - return show_label_; + return show_label_; } void TextField::setValid(bool valid) { - is_valid_ = valid; + is_valid_ = valid; } bool TextField::isValid() const { - QString s = text(); - int pos = 0; - if (regexp_.pattern().isEmpty()) { - return is_valid_; - } - QRegularExpressionValidator v(QRegularExpression(regexp_), 0); - return v.validate(s, pos) == QValidator::Acceptable; + QString s = text(); + int pos = 0; + if (regexp_.pattern().isEmpty()) { + return is_valid_; + } + QRegularExpressionValidator v(QRegularExpression(regexp_), 0); + return v.validate(s, pos) == QValidator::Acceptable; } void TextField::setLabelFontSize(qreal size) { - label_font_size_ = size; + label_font_size_ = size; - if (label_) { - QFont font(label_->font()); - font.setPointSizeF(size); - label_->setFont(font); - label_->update(); - } + if (label_) { + QFont font(label_->font()); + font.setPointSizeF(size); + label_->setFont(font); + label_->update(); + } } qreal TextField::labelFontSize() const { - return label_font_size_; + return label_font_size_; } void TextField::setLabel(const QString &label) { - label_text_ = label; - setShowLabel(true); - label_->update(); + label_text_ = label; + setShowLabel(true); + label_->update(); } QString TextField::label() const { - return label_text_; + return label_text_; } void TextField::setLabelColor(const QColor &color) { - label_color_ = color; - update(); + label_color_ = color; + update(); } QColor TextField::labelColor() const { - if (!label_color_.isValid()) { - return QPalette().color(QPalette::Text); - } + if (!label_color_.isValid()) { + return QPalette().color(QPalette::Text); + } - return label_color_; + return label_color_; } void TextField::setInkColor(const QColor &color) { - ink_color_ = color; - update(); + ink_color_ = color; + update(); } QColor TextField::inkColor() const { - if (!ink_color_.isValid()) { - return QPalette().color(QPalette::Text); - } + if (!ink_color_.isValid()) { + return QPalette().color(QPalette::Text); + } - return ink_color_; + return ink_color_; } void TextField::setUnderlineColor(const QColor &color) { - underline_color_ = color; - update(); + underline_color_ = color; + update(); } void TextField::setRegexp(const QRegularExpression ®exp) { - regexp_ = regexp; + regexp_ = regexp; } QColor TextField::underlineColor() const { - if (!underline_color_.isValid()) { - if ((hasAcceptableInput() && isValid()) || !isModified()) - return QPalette().color(QPalette::Highlight); - else - return Qt::red; - } - - return underline_color_; + if (!underline_color_.isValid()) { + if ((hasAcceptableInput() && isValid()) || !isModified()) + return QPalette().color(QPalette::Highlight); + else + return Qt::red; + } + + return underline_color_; } bool TextField::event(QEvent *event) { - switch (event->type()) { - case QEvent::Resize: - case QEvent::Move: { - if (label_) - label_->setGeometry(rect()); - break; - } - default: - break; - } - - return QLineEdit::event(event); + switch (event->type()) { + case QEvent::Resize: + case QEvent::Move: { + if (label_) + label_->setGeometry(rect()); + break; + } + default: + break; + } + + return QLineEdit::event(event); } void TextField::paintEvent(QPaintEvent *event) { - QLineEdit::paintEvent(event); + QLineEdit::paintEvent(event); - QPainter painter(this); + QPainter painter(this); - if (text().isEmpty()) { - painter.setOpacity(1 - state_machine_->progress()); - painter.fillRect(rect(), backgroundColor()); - } + if (text().isEmpty()) { + painter.setOpacity(1 - state_machine_->progress()); + painter.fillRect(rect(), backgroundColor()); + } - const int y = height() - 1; - const int wd = width() - 5; + const int y = height() - 1; + const int wd = width() - 5; - QPen pen; - pen.setWidth(1); - pen.setColor(underlineColor()); - painter.setPen(pen); - painter.setOpacity(1); - painter.drawLine(2, y, wd, y); + QPen pen; + pen.setWidth(1); + pen.setColor(underlineColor()); + painter.setPen(pen); + painter.setOpacity(1); + painter.drawLine(2, y, wd, y); - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor(inkColor()); + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(inkColor()); - const qreal progress = state_machine_->progress(); + 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); - } + 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; + normal_state_ = new QState; + focused_state_ = new QState; - label_ = nullptr; - offset_anim_ = nullptr; - color_anim_ = nullptr; - progress_ = 0.0; + label_ = nullptr; + offset_anim_ = nullptr; + color_anim_ = nullptr; + progress_ = 0.0; - addState(normal_state_); - addState(focused_state_); + addState(normal_state_); + addState(focused_state_); - setInitialState(normal_state_); + setInitialState(normal_state_); - QEventTransition *transition; - QPropertyAnimation *animation; + QEventTransition *transition; + QPropertyAnimation *animation; - transition = new QEventTransition(parent, QEvent::FocusIn); - transition->setTargetState(focused_state_); - normal_state_->addTransition(transition); + 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); + 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); + 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); + 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); + normal_state_->assignProperty(this, "progress", 0); + focused_state_->assignProperty(this, "progress", 1); - setupProperties(); + setupProperties(); - connect(text_field_, SIGNAL(textChanged(QString)), this, SLOT(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(); + 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)); - } + 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(); + 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); + 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; + if (!text_field_->hasLabel()) + return; - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.scale(scale_, scale_); - painter.setPen(color_); - painter.setOpacity(1); + 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()); + QPointF pos(2 + x_, height() - 36 + y_); + painter.drawText(pos.x(), pos.y(), text_field_->label()); } diff --git a/src/ui/TextField.h b/src/ui/TextField.h index ac4c396e..47257019 100644 --- a/src/ui/TextField.h +++ b/src/ui/TextField.h @@ -18,163 +18,163 @@ class TextFieldStateMachine; class TextField : public QLineEdit { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor inkColor WRITE setInkColor READ inkColor) - Q_PROPERTY(QColor labelColor WRITE setLabelColor READ labelColor) - Q_PROPERTY(QColor underlineColor WRITE setUnderlineColor READ underlineColor) - Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) + Q_PROPERTY(QColor inkColor WRITE setInkColor READ inkColor) + Q_PROPERTY(QColor labelColor WRITE setLabelColor READ labelColor) + Q_PROPERTY(QColor underlineColor WRITE setUnderlineColor READ underlineColor) + Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) public: - explicit TextField(QWidget *parent = nullptr); - - void setInkColor(const QColor &color); - void setBackgroundColor(const QColor &color); - void setLabel(const QString &label); - void setLabelColor(const QColor &color); - void setLabelFontSize(qreal size); - void setShowLabel(bool value); - void setUnderlineColor(const QColor &color); - void setRegexp(const QRegularExpression ®exp); - void setValid(bool valid); - - QColor inkColor() const; - QColor labelColor() const; - QColor underlineColor() const; - QColor backgroundColor() const; - QString label() const; - bool hasLabel() const; - bool isValid() const; - qreal labelFontSize() const; + explicit TextField(QWidget *parent = nullptr); + + void setInkColor(const QColor &color); + void setBackgroundColor(const QColor &color); + void setLabel(const QString &label); + void setLabelColor(const QColor &color); + void setLabelFontSize(qreal size); + void setShowLabel(bool value); + void setUnderlineColor(const QColor &color); + void setRegexp(const QRegularExpression ®exp); + void setValid(bool valid); + + QColor inkColor() const; + QColor labelColor() const; + QColor underlineColor() const; + QColor backgroundColor() const; + QString label() const; + bool hasLabel() const; + bool isValid() const; + qreal labelFontSize() const; protected: - bool event(QEvent *event) override; - void paintEvent(QPaintEvent *event) override; + bool event(QEvent *event) override; + void paintEvent(QPaintEvent *event) override; private: - void init(); - - QColor ink_color_; - QColor background_color_; - QColor label_color_; - QColor underline_color_; - QString label_text_; - TextFieldLabel *label_; - TextFieldStateMachine *state_machine_; - bool show_label_; - QRegularExpression regexp_; - bool is_valid_; - qreal label_font_size_; + void init(); + + QColor ink_color_; + QColor background_color_; + QColor label_color_; + QColor underline_color_; + QString label_text_; + TextFieldLabel *label_; + TextFieldStateMachine *state_machine_; + bool show_label_; + QRegularExpression regexp_; + bool is_valid_; + qreal label_font_size_; }; class TextFieldLabel : public QWidget { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(qreal scale WRITE setScale READ scale) - Q_PROPERTY(QPointF offset WRITE setOffset READ offset) - Q_PROPERTY(QColor color WRITE setColor READ color) + Q_PROPERTY(qreal scale WRITE setScale READ scale) + Q_PROPERTY(QPointF offset WRITE setOffset READ offset) + Q_PROPERTY(QColor color WRITE setColor READ color) public: - TextFieldLabel(TextField *parent); + TextFieldLabel(TextField *parent); - inline void setColor(const QColor &color); - inline void setOffset(const QPointF &pos); - inline void setScale(qreal scale); + inline void setColor(const QColor &color); + inline void setOffset(const QPointF &pos); + inline void setScale(qreal scale); - inline QColor color() const; - inline QPointF offset() const; - inline qreal scale() const; + inline QColor color() const; + inline QPointF offset() const; + inline qreal scale() const; protected: - void paintEvent(QPaintEvent *event) override; + void paintEvent(QPaintEvent *event) override; private: - TextField *const text_field_; + TextField *const text_field_; - QColor color_; - qreal scale_; - qreal x_; - qreal y_; + QColor color_; + qreal scale_; + qreal x_; + qreal y_; }; inline void TextFieldLabel::setColor(const QColor &color) { - color_ = color; - update(); + color_ = color; + update(); } inline void TextFieldLabel::setOffset(const QPointF &pos) { - x_ = pos.x(); - y_ = pos.y(); - update(); + x_ = pos.x(); + y_ = pos.y(); + update(); } inline void TextFieldLabel::setScale(qreal scale) { - scale_ = scale; - update(); + scale_ = scale; + update(); } inline QPointF TextFieldLabel::offset() const { - return QPointF(x_, y_); + return QPointF(x_, y_); } inline qreal TextFieldLabel::scale() const { - return scale_; + return scale_; } inline QColor TextFieldLabel::color() const { - return color_; + return color_; } class TextFieldStateMachine : public QStateMachine { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(qreal progress WRITE setProgress READ progress) + Q_PROPERTY(qreal progress WRITE setProgress READ progress) public: - TextFieldStateMachine(TextField *parent); + TextFieldStateMachine(TextField *parent); - inline void setProgress(qreal progress); - void setLabel(TextFieldLabel *label); + inline void setProgress(qreal progress); + void setLabel(TextFieldLabel *label); - inline qreal progress() const; + inline qreal progress() const; public slots: - void setupProperties(); + void setupProperties(); private: - QPropertyAnimation *color_anim_; - QPropertyAnimation *offset_anim_; + QPropertyAnimation *color_anim_; + QPropertyAnimation *offset_anim_; - QState *focused_state_; - QState *normal_state_; + QState *focused_state_; + QState *normal_state_; - TextField *text_field_; - TextFieldLabel *label_; + TextField *text_field_; + TextFieldLabel *label_; - qreal progress_; + qreal progress_; }; inline void TextFieldStateMachine::setProgress(qreal progress) { - progress_ = progress; - text_field_->update(); + progress_ = progress; + text_field_->update(); } inline qreal TextFieldStateMachine::progress() const { - return progress_; + return progress_; } diff --git a/src/ui/TextLabel.cpp b/src/ui/TextLabel.cpp index 3568e15c..340d3b8f 100644 --- a/src/ui/TextLabel.cpp +++ b/src/ui/TextLabel.cpp @@ -14,12 +14,12 @@ bool ContextMenuFilter::eventFilter(QObject *obj, QEvent *event) { - if (event->type() == QEvent::MouseButtonPress) { - emit contextMenuIsOpening(); - return true; - } + if (event->type() == QEvent::MouseButtonPress) { + emit contextMenuIsOpening(); + return true; + } - return QObject::eventFilter(obj, event); + return QObject::eventFilter(obj, event); } TextLabel::TextLabel(QWidget *parent) @@ -29,94 +29,94 @@ TextLabel::TextLabel(QWidget *parent) TextLabel::TextLabel(const QString &text, QWidget *parent) : QTextBrowser(parent) { - document()->setDefaultStyleSheet(QString("a {color: %1; }").arg(utils::linkColor())); - - setText(text); - setOpenExternalLinks(true); - - // Make it look and feel like an ordinary label. - setReadOnly(true); - setFrameStyle(QFrame::NoFrame); - QPalette pal = palette(); - pal.setColor(QPalette::Base, Qt::transparent); - setPalette(pal); - - // Wrap anywhere but prefer words, adjust minimum height on the fly. - setLineWrapMode(QTextEdit::WidgetWidth); - setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - connect(document()->documentLayout(), - &QAbstractTextDocumentLayout::documentSizeChanged, - this, - &TextLabel::adjustHeight); - document()->setDocumentMargin(0); - - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - setFixedHeight(0); - - connect(this, &TextLabel::linkActivated, this, &TextLabel::handleLinkActivation); - - auto filter = new ContextMenuFilter(this); - installEventFilter(filter); - connect(filter, &ContextMenuFilter::contextMenuIsOpening, this, [this]() { - contextMenuRequested_ = true; - }); + document()->setDefaultStyleSheet(QString("a {color: %1; }").arg(utils::linkColor())); + + setText(text); + setOpenExternalLinks(true); + + // Make it look and feel like an ordinary label. + setReadOnly(true); + setFrameStyle(QFrame::NoFrame); + QPalette pal = palette(); + pal.setColor(QPalette::Base, Qt::transparent); + setPalette(pal); + + // Wrap anywhere but prefer words, adjust minimum height on the fly. + setLineWrapMode(QTextEdit::WidgetWidth); + setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + connect(document()->documentLayout(), + &QAbstractTextDocumentLayout::documentSizeChanged, + this, + &TextLabel::adjustHeight); + document()->setDocumentMargin(0); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + setFixedHeight(0); + + connect(this, &TextLabel::linkActivated, this, &TextLabel::handleLinkActivation); + + auto filter = new ContextMenuFilter(this); + installEventFilter(filter); + connect(filter, &ContextMenuFilter::contextMenuIsOpening, this, [this]() { + contextMenuRequested_ = true; + }); } void TextLabel::focusOutEvent(QFocusEvent *e) { - QTextBrowser::focusOutEvent(e); + QTextBrowser::focusOutEvent(e); - // We keep the selection available for the context menu. - if (contextMenuRequested_) { - contextMenuRequested_ = false; - return; - } + // We keep the selection available for the context menu. + if (contextMenuRequested_) { + contextMenuRequested_ = false; + return; + } - QTextCursor cursor = textCursor(); - cursor.clearSelection(); - setTextCursor(cursor); + QTextCursor cursor = textCursor(); + cursor.clearSelection(); + setTextCursor(cursor); } void TextLabel::mousePressEvent(QMouseEvent *e) { - link_ = (e->button() & Qt::LeftButton) ? anchorAt(e->pos()) : QString(); - QTextBrowser::mousePressEvent(e); + link_ = (e->button() & Qt::LeftButton) ? anchorAt(e->pos()) : QString(); + QTextBrowser::mousePressEvent(e); } void TextLabel::mouseReleaseEvent(QMouseEvent *e) { - if (e->button() & Qt::LeftButton && !link_.isEmpty() && anchorAt(e->pos()) == link_) { - emit linkActivated(link_); - return; - } + if (e->button() & Qt::LeftButton && !link_.isEmpty() && anchorAt(e->pos()) == link_) { + emit linkActivated(link_); + return; + } - QTextBrowser::mouseReleaseEvent(e); + QTextBrowser::mouseReleaseEvent(e); } void TextLabel::wheelEvent(QWheelEvent *event) { - event->ignore(); + event->ignore(); } void TextLabel::handleLinkActivation(const QUrl &url) { - auto parts = url.toString().split('/'); - auto defaultHandler = [](const QUrl &url) { QDesktopServices::openUrl(url); }; + auto parts = url.toString().split('/'); + auto defaultHandler = [](const QUrl &url) { QDesktopServices::openUrl(url); }; - if (url.host() != "matrix.to" || parts.isEmpty()) - return defaultHandler(url); + if (url.host() != "matrix.to" || parts.isEmpty()) + return defaultHandler(url); - try { - using namespace mtx::identifiers; - parse<User>(parts.last().toStdString()); - } catch (const std::exception &) { - return defaultHandler(url); - } + try { + using namespace mtx::identifiers; + parse<User>(parts.last().toStdString()); + } catch (const std::exception &) { + return defaultHandler(url); + } - emit userProfileTriggered(parts.last()); + emit userProfileTriggered(parts.last()); } diff --git a/src/ui/TextLabel.h b/src/ui/TextLabel.h index bc095823..313ad97c 100644 --- a/src/ui/TextLabel.h +++ b/src/ui/TextLabel.h @@ -15,45 +15,45 @@ class QWheelEvent; class ContextMenuFilter : public QObject { - Q_OBJECT + Q_OBJECT public: - explicit ContextMenuFilter(QWidget *parent) - : QObject(parent) - {} + explicit ContextMenuFilter(QWidget *parent) + : QObject(parent) + {} signals: - void contextMenuIsOpening(); + void contextMenuIsOpening(); protected: - bool eventFilter(QObject *obj, QEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; }; class TextLabel : public QTextBrowser { - Q_OBJECT + Q_OBJECT public: - TextLabel(const QString &text, QWidget *parent = nullptr); - TextLabel(QWidget *parent = nullptr); + TextLabel(const QString &text, QWidget *parent = nullptr); + TextLabel(QWidget *parent = nullptr); - void wheelEvent(QWheelEvent *event) override; - void clearLinks() { link_.clear(); } + void wheelEvent(QWheelEvent *event) override; + void clearLinks() { link_.clear(); } protected: - void mousePressEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void focusOutEvent(QFocusEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void focusOutEvent(QFocusEvent *e) override; private slots: - void adjustHeight(const QSizeF &size) { setFixedHeight(size.height()); } - void handleLinkActivation(const QUrl &link); + void adjustHeight(const QSizeF &size) { setFixedHeight(size.height()); } + void handleLinkActivation(const QUrl &link); signals: - void userProfileTriggered(const QString &user_id); - void linkActivated(const QUrl &link); + void userProfileTriggered(const QString &user_id); + void linkActivated(const QUrl &link); private: - QString link_; - bool contextMenuRequested_ = false; + QString link_; + bool contextMenuRequested_ = false; }; diff --git a/src/ui/Theme.cpp b/src/ui/Theme.cpp index 732a0443..d6f0b72f 100644 --- a/src/ui/Theme.cpp +++ b/src/ui/Theme.cpp @@ -9,66 +9,66 @@ Q_DECLARE_METATYPE(Theme) QPalette Theme::paletteFromTheme(std::string_view theme) { - [[maybe_unused]] static auto meta = qRegisterMetaType<Theme>("Theme"); - static QPalette original; - if (theme == "light") { - QPalette lightActive( - /*windowText*/ QColor("#333"), - /*button*/ QColor("white"), - /*light*/ QColor(0xef, 0xef, 0xef), - /*dark*/ QColor(70, 77, 93), - /*mid*/ QColor(220, 220, 220), - /*text*/ QColor("#333"), - /*bright_text*/ QColor("#f2f5f8"), - /*base*/ QColor("#fff"), - /*window*/ QColor("white")); - lightActive.setColor(QPalette::AlternateBase, QColor("#eee")); - lightActive.setColor(QPalette::Highlight, QColor("#38a3d8")); - lightActive.setColor(QPalette::HighlightedText, QColor("#f4f4f5")); - lightActive.setColor(QPalette::ToolTipBase, lightActive.base().color()); - lightActive.setColor(QPalette::ToolTipText, lightActive.text().color()); - lightActive.setColor(QPalette::Link, QColor("#0077b5")); - lightActive.setColor(QPalette::ButtonText, QColor("#555459")); - return lightActive; - } else if (theme == "dark") { - QPalette darkActive( - /*windowText*/ QColor("#caccd1"), - /*button*/ QColor(0xff, 0xff, 0xff), - /*light*/ QColor("#caccd1"), - /*dark*/ QColor(60, 70, 77), - /*mid*/ QColor("#202228"), - /*text*/ QColor("#caccd1"), - /*bright_text*/ QColor("#f4f5f8"), - /*base*/ QColor("#202228"), - /*window*/ QColor("#2d3139")); - darkActive.setColor(QPalette::AlternateBase, QColor("#2d3139")); - darkActive.setColor(QPalette::Highlight, QColor("#38a3d8")); - darkActive.setColor(QPalette::HighlightedText, QColor("#f4f5f8")); - darkActive.setColor(QPalette::ToolTipBase, darkActive.base().color()); - darkActive.setColor(QPalette::ToolTipText, darkActive.text().color()); - darkActive.setColor(QPalette::Link, QColor("#38a3d8")); - darkActive.setColor(QPalette::ButtonText, "#828284"); - return darkActive; - } else { - return original; - } + [[maybe_unused]] static auto meta = qRegisterMetaType<Theme>("Theme"); + static QPalette original; + if (theme == "light") { + QPalette lightActive( + /*windowText*/ QColor("#333"), + /*button*/ QColor("white"), + /*light*/ QColor(0xef, 0xef, 0xef), + /*dark*/ QColor(70, 77, 93), + /*mid*/ QColor(220, 220, 220), + /*text*/ QColor("#333"), + /*bright_text*/ QColor("#f2f5f8"), + /*base*/ QColor("#fff"), + /*window*/ QColor("white")); + lightActive.setColor(QPalette::AlternateBase, QColor("#eee")); + lightActive.setColor(QPalette::Highlight, QColor("#38a3d8")); + lightActive.setColor(QPalette::HighlightedText, QColor("#f4f4f5")); + lightActive.setColor(QPalette::ToolTipBase, lightActive.base().color()); + lightActive.setColor(QPalette::ToolTipText, lightActive.text().color()); + lightActive.setColor(QPalette::Link, QColor("#0077b5")); + lightActive.setColor(QPalette::ButtonText, QColor("#555459")); + return lightActive; + } else if (theme == "dark") { + QPalette darkActive( + /*windowText*/ QColor("#caccd1"), + /*button*/ QColor(0xff, 0xff, 0xff), + /*light*/ QColor("#caccd1"), + /*dark*/ QColor(60, 70, 77), + /*mid*/ QColor("#202228"), + /*text*/ QColor("#caccd1"), + /*bright_text*/ QColor("#f4f5f8"), + /*base*/ QColor("#202228"), + /*window*/ QColor("#2d3139")); + darkActive.setColor(QPalette::AlternateBase, QColor("#2d3139")); + darkActive.setColor(QPalette::Highlight, QColor("#38a3d8")); + darkActive.setColor(QPalette::HighlightedText, QColor("#f4f5f8")); + darkActive.setColor(QPalette::ToolTipBase, darkActive.base().color()); + darkActive.setColor(QPalette::ToolTipText, darkActive.text().color()); + darkActive.setColor(QPalette::Link, QColor("#38a3d8")); + darkActive.setColor(QPalette::ButtonText, "#828284"); + return darkActive; + } else { + return original; + } } Theme::Theme(std::string_view theme) { - auto p = paletteFromTheme(theme); - separator_ = p.mid().color(); - if (theme == "light") { - sidebarBackground_ = QColor("#233649"); - alternateButton_ = QColor("#ccc"); - red_ = QColor("#a82353"); - } else if (theme == "dark") { - sidebarBackground_ = QColor("#2d3139"); - alternateButton_ = QColor("#414A59"); - red_ = QColor("#a82353"); - } else { - sidebarBackground_ = p.window().color(); - alternateButton_ = p.dark().color(); - red_ = QColor("red"); - } + auto p = paletteFromTheme(theme); + separator_ = p.mid().color(); + if (theme == "light") { + sidebarBackground_ = QColor("#233649"); + alternateButton_ = QColor("#ccc"); + red_ = QColor("#a82353"); + } else if (theme == "dark") { + sidebarBackground_ = QColor("#2d3139"); + alternateButton_ = QColor("#414A59"); + red_ = QColor("#a82353"); + } else { + sidebarBackground_ = p.window().color(); + alternateButton_ = p.dark().color(); + red_ = QColor("red"); + } } diff --git a/src/ui/Theme.h b/src/ui/Theme.h index cc39714b..f3e7c287 100644 --- a/src/ui/Theme.h +++ b/src/ui/Theme.h @@ -16,62 +16,62 @@ const int AvatarSize = 40; enum class ButtonPreset { - FlatPreset, - CheckablePreset + FlatPreset, + CheckablePreset }; enum class RippleStyle { - CenteredRipple, - PositionedRipple, - NoRipple + CenteredRipple, + PositionedRipple, + NoRipple }; enum class OverlayStyle { - NoOverlay, - TintedOverlay, - GrayOverlay + NoOverlay, + TintedOverlay, + GrayOverlay }; enum class Role { - Default, - Primary, - Secondary + Default, + Primary, + Secondary }; enum class ButtonIconPlacement { - LeftIcon, - RightIcon + LeftIcon, + RightIcon }; enum class ProgressType { - DeterminateProgress, - IndeterminateProgress + DeterminateProgress, + IndeterminateProgress }; } // namespace ui class Theme : public QPalette { - Q_GADGET - Q_PROPERTY(QColor sidebarBackground READ sidebarBackground CONSTANT) - Q_PROPERTY(QColor alternateButton READ alternateButton CONSTANT) - Q_PROPERTY(QColor separator READ separator CONSTANT) - Q_PROPERTY(QColor red READ red CONSTANT) + Q_GADGET + Q_PROPERTY(QColor sidebarBackground READ sidebarBackground CONSTANT) + Q_PROPERTY(QColor alternateButton READ alternateButton CONSTANT) + Q_PROPERTY(QColor separator READ separator CONSTANT) + Q_PROPERTY(QColor red READ red CONSTANT) public: - Theme() {} - explicit Theme(std::string_view theme); - static QPalette paletteFromTheme(std::string_view theme); + Theme() {} + explicit Theme(std::string_view theme); + static QPalette paletteFromTheme(std::string_view theme); - QColor sidebarBackground() const { return sidebarBackground_; } - QColor alternateButton() const { return alternateButton_; } - QColor separator() const { return separator_; } - QColor red() const { return red_; } + QColor sidebarBackground() const { return sidebarBackground_; } + QColor alternateButton() const { return alternateButton_; } + QColor separator() const { return separator_; } + QColor red() const { return red_; } private: - QColor sidebarBackground_, separator_, red_, alternateButton_; + QColor sidebarBackground_, separator_, red_, alternateButton_; }; diff --git a/src/ui/ThemeManager.cpp b/src/ui/ThemeManager.cpp index b7b3df40..0c84777a 100644 --- a/src/ui/ThemeManager.cpp +++ b/src/ui/ThemeManager.cpp @@ -11,32 +11,32 @@ ThemeManager::ThemeManager() {} QColor ThemeManager::themeColor(const QString &key) const { - if (key == "Black") - return QColor("#171919"); - - else if (key == "BrightWhite") - return QColor("#EBEBEB"); - else if (key == "FadedWhite") - return QColor("#C9C9C9"); - else if (key == "MediumWhite") - return QColor("#929292"); - - else if (key == "BrightGreen") - return QColor("#1C3133"); - else if (key == "DarkGreen") - return QColor("#577275"); - else if (key == "LightGreen") - return QColor("#46A451"); - - else if (key == "Gray") - return QColor("#5D6565"); - else if (key == "Red") - return QColor("#E22826"); - else if (key == "Blue") - return QColor("#81B3A9"); - - else if (key == "Transparent") - return QColor(0, 0, 0, 0); - - return (QColor(0, 0, 0, 0)); + if (key == "Black") + return QColor("#171919"); + + else if (key == "BrightWhite") + return QColor("#EBEBEB"); + else if (key == "FadedWhite") + return QColor("#C9C9C9"); + else if (key == "MediumWhite") + return QColor("#929292"); + + else if (key == "BrightGreen") + return QColor("#1C3133"); + else if (key == "DarkGreen") + return QColor("#577275"); + else if (key == "LightGreen") + return QColor("#46A451"); + + else if (key == "Gray") + return QColor("#5D6565"); + else if (key == "Red") + return QColor("#E22826"); + else if (key == "Blue") + return QColor("#81B3A9"); + + else if (key == "Transparent") + return QColor(0, 0, 0, 0); + + return (QColor(0, 0, 0, 0)); } diff --git a/src/ui/ThemeManager.h b/src/ui/ThemeManager.h index cbb355fd..5e86c68f 100644 --- a/src/ui/ThemeManager.h +++ b/src/ui/ThemeManager.h @@ -8,23 +8,23 @@ class ThemeManager : public QCommonStyle { - Q_OBJECT + Q_OBJECT public: - inline static ThemeManager &instance(); + inline static ThemeManager &instance(); - QColor themeColor(const QString &key) const; + QColor themeColor(const QString &key) const; private: - ThemeManager(); + ThemeManager(); - ThemeManager(ThemeManager const &); - void operator=(ThemeManager const &); + ThemeManager(ThemeManager const &); + void operator=(ThemeManager const &); }; inline ThemeManager & ThemeManager::instance() { - static ThemeManager instance; - return instance; + static ThemeManager instance; + return instance; } diff --git a/src/ui/ToggleButton.cpp b/src/ui/ToggleButton.cpp index 33bf8f92..04f752d7 100644 --- a/src/ui/ToggleButton.cpp +++ b/src/ui/ToggleButton.cpp @@ -12,84 +12,84 @@ void Toggle::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); + Q_UNUSED(event); } Toggle::Toggle(QWidget *parent) : QAbstractButton{parent} { - init(); + init(); - connect(this, &QAbstractButton::toggled, this, &Toggle::setState); + connect(this, &QAbstractButton::toggled, this, &Toggle::setState); } void Toggle::setState(bool isEnabled) { - setChecked(isEnabled); - thumb_->setShift(isEnabled ? Position::Left : Position::Right); - setupProperties(); + setChecked(isEnabled); + thumb_->setShift(isEnabled ? Position::Left : Position::Right); + setupProperties(); } void Toggle::init() { - track_ = new ToggleTrack(this); - thumb_ = new ToggleThumb(this); + track_ = new ToggleTrack(this); + thumb_ = new ToggleThumb(this); - setCursor(QCursor(Qt::PointingHandCursor)); - setCheckable(true); - setChecked(false); + setCursor(QCursor(Qt::PointingHandCursor)); + setCheckable(true); + setChecked(false); - setState(false); - setupProperties(); + setState(false); + setupProperties(); - QCoreApplication::processEvents(); + QCoreApplication::processEvents(); } void Toggle::setupProperties() { - if (isEnabled()) { - Position position = thumb_->shift(); + if (isEnabled()) { + Position position = thumb_->shift(); - thumb_->setThumbColor(trackColor()); + thumb_->setThumbColor(trackColor()); - if (position == Position::Left) - track_->setTrackColor(activeColor()); - else if (position == Position::Right) - track_->setTrackColor(inactiveColor()); - } + if (position == Position::Left) + track_->setTrackColor(activeColor()); + else if (position == Position::Right) + track_->setTrackColor(inactiveColor()); + } - update(); + update(); } void Toggle::setDisabledColor(const QColor &color) { - disabledColor_ = color; - setupProperties(); + disabledColor_ = color; + setupProperties(); } void Toggle::setActiveColor(const QColor &color) { - activeColor_ = color; - setupProperties(); + activeColor_ = color; + setupProperties(); } void Toggle::setInactiveColor(const QColor &color) { - inactiveColor_ = color; - setupProperties(); + inactiveColor_ = color; + setupProperties(); } void Toggle::setTrackColor(const QColor &color) { - trackColor_ = color; - setupProperties(); + trackColor_ = color; + setupProperties(); } ToggleThumb::ToggleThumb(Toggle *parent) @@ -98,119 +98,119 @@ ToggleThumb::ToggleThumb(Toggle *parent) , position_{Position::Right} , offset_{0} { - parent->installEventFilter(this); + parent->installEventFilter(this); } void ToggleThumb::setShift(Position position) { - if (position_ != position) { - position_ = position; - updateOffset(); - } + if (position_ != position) { + position_ = position; + updateOffset(); + } } bool ToggleThumb::eventFilter(QObject *obj, QEvent *event) { - const QEvent::Type type = event->type(); + const QEvent::Type type = event->type(); - if (QEvent::Resize == type || QEvent::Move == type) { - setGeometry(toggle_->rect().adjusted(8, 8, -8, -8)); - updateOffset(); - } + if (QEvent::Resize == type || QEvent::Move == type) { + setGeometry(toggle_->rect().adjusted(8, 8, -8, -8)); + updateOffset(); + } - return QWidget::eventFilter(obj, event); + return QWidget::eventFilter(obj, event); } void ToggleThumb::paintEvent(QPaintEvent *event) { - Q_UNUSED(event) + Q_UNUSED(event) - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor(toggle_->isEnabled() ? thumbColor_ : Qt::white); + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(toggle_->isEnabled() ? thumbColor_ : Qt::white); - painter.setBrush(brush); - painter.setPen(Qt::NoPen); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); - int s; - QRectF r; + int s; + QRectF r; - s = height() - 10; - r = QRectF(5 + offset_, 5, s, s); + s = height() - 10; + r = QRectF(5 + offset_, 5, s, s); - painter.drawEllipse(r); + painter.drawEllipse(r); - if (!toggle_->isEnabled()) { - brush.setColor(toggle_->disabledColor()); - painter.setBrush(brush); - painter.drawEllipse(r); - } + if (!toggle_->isEnabled()) { + brush.setColor(toggle_->disabledColor()); + painter.setBrush(brush); + painter.drawEllipse(r); + } } void ToggleThumb::updateOffset() { - const QSize s(size()); - offset_ = position_ == Position::Left ? static_cast<qreal>(s.width() - s.height()) : 0; - update(); + const QSize s(size()); + offset_ = position_ == Position::Left ? static_cast<qreal>(s.width() - s.height()) : 0; + update(); } ToggleTrack::ToggleTrack(Toggle *parent) : QWidget{parent} , toggle_{parent} { - Q_ASSERT(parent); + Q_ASSERT(parent); - parent->installEventFilter(this); + parent->installEventFilter(this); } void ToggleTrack::setTrackColor(const QColor &color) { - trackColor_ = color; - update(); + trackColor_ = color; + update(); } bool ToggleTrack::eventFilter(QObject *obj, QEvent *event) { - const QEvent::Type type = event->type(); + const QEvent::Type type = event->type(); - if (QEvent::Resize == type || QEvent::Move == type) { - setGeometry(toggle_->rect()); - } + if (QEvent::Resize == type || QEvent::Move == type) { + setGeometry(toggle_->rect()); + } - return QWidget::eventFilter(obj, event); + return QWidget::eventFilter(obj, event); } void ToggleTrack::paintEvent(QPaintEvent *event) { - Q_UNUSED(event) + Q_UNUSED(event) - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); - QBrush brush; - if (toggle_->isEnabled()) { - brush.setColor(trackColor_); - painter.setOpacity(0.8); - } else { - brush.setColor(toggle_->disabledColor()); - painter.setOpacity(0.6); - } + QBrush brush; + if (toggle_->isEnabled()) { + brush.setColor(trackColor_); + painter.setOpacity(0.8); + } else { + brush.setColor(toggle_->disabledColor()); + painter.setOpacity(0.6); + } - brush.setStyle(Qt::SolidPattern); - painter.setBrush(brush); - painter.setPen(Qt::NoPen); + brush.setStyle(Qt::SolidPattern); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); - const int h = height() / 2; - const QRect r(0, h / 2, width(), h); - painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h / 2 - 4, h / 2 - 4); + const int h = height() / 2; + const QRect r(0, h / 2, width(), h); + painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h / 2 - 4, h / 2 - 4); } diff --git a/src/ui/ToggleButton.h b/src/ui/ToggleButton.h index 2413b086..15d5e192 100644 --- a/src/ui/ToggleButton.h +++ b/src/ui/ToggleButton.h @@ -12,103 +12,103 @@ class ToggleThumb; enum class Position { - Left, - Right + Left, + Right }; class Toggle : public QAbstractButton { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor activeColor WRITE setActiveColor READ activeColor) - Q_PROPERTY(QColor disabledColor WRITE setDisabledColor READ disabledColor) - Q_PROPERTY(QColor inactiveColor WRITE setInactiveColor READ inactiveColor) - Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) + Q_PROPERTY(QColor activeColor WRITE setActiveColor READ activeColor) + Q_PROPERTY(QColor disabledColor WRITE setDisabledColor READ disabledColor) + Q_PROPERTY(QColor inactiveColor WRITE setInactiveColor READ inactiveColor) + Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) public: - Toggle(QWidget *parent = nullptr); + Toggle(QWidget *parent = nullptr); - void setState(bool isEnabled); + void setState(bool isEnabled); - void setActiveColor(const QColor &color); - void setDisabledColor(const QColor &color); - void setInactiveColor(const QColor &color); - void setTrackColor(const QColor &color); + void setActiveColor(const QColor &color); + void setDisabledColor(const QColor &color); + void setInactiveColor(const QColor &color); + void setTrackColor(const QColor &color); - QColor activeColor() const { return activeColor_; }; - QColor disabledColor() const { return disabledColor_; }; - QColor inactiveColor() const { return inactiveColor_; }; - QColor trackColor() const { return trackColor_.isValid() ? trackColor_ : QColor("#eee"); }; + QColor activeColor() const { return activeColor_; }; + QColor disabledColor() const { return disabledColor_; }; + QColor inactiveColor() const { return inactiveColor_; }; + QColor trackColor() const { return trackColor_.isValid() ? trackColor_ : QColor("#eee"); }; - QSize sizeHint() const override { return QSize(64, 48); }; + QSize sizeHint() const override { return QSize(64, 48); }; protected: - void paintEvent(QPaintEvent *event) override; + void paintEvent(QPaintEvent *event) override; private: - void init(); - void setupProperties(); + void init(); + void setupProperties(); - ToggleTrack *track_; - ToggleThumb *thumb_; + ToggleTrack *track_; + ToggleThumb *thumb_; - QColor disabledColor_; - QColor activeColor_; - QColor inactiveColor_; - QColor trackColor_; + QColor disabledColor_; + QColor activeColor_; + QColor inactiveColor_; + QColor trackColor_; }; class ToggleThumb : public QWidget { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor) + Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor) public: - ToggleThumb(Toggle *parent); + ToggleThumb(Toggle *parent); - Position shift() const { return position_; }; - qreal offset() const { return offset_; }; - QColor thumbColor() const { return thumbColor_; }; + Position shift() const { return position_; }; + qreal offset() const { return offset_; }; + QColor thumbColor() const { return thumbColor_; }; - void setShift(Position position); - void setThumbColor(const QColor &color) - { - thumbColor_ = color; - update(); - }; + void setShift(Position position); + void setThumbColor(const QColor &color) + { + thumbColor_ = color; + update(); + }; protected: - bool eventFilter(QObject *obj, QEvent *event) override; - void paintEvent(QPaintEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + void paintEvent(QPaintEvent *event) override; private: - void updateOffset(); + void updateOffset(); - Toggle *const toggle_; - QColor thumbColor_; + Toggle *const toggle_; + QColor thumbColor_; - Position position_; - qreal offset_; + Position position_; + qreal offset_; }; class ToggleTrack : public QWidget { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) + Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor) public: - ToggleTrack(Toggle *parent); + ToggleTrack(Toggle *parent); - void setTrackColor(const QColor &color); - QColor trackColor() const { return trackColor_; }; + void setTrackColor(const QColor &color); + QColor trackColor() const { return trackColor_; }; protected: - bool eventFilter(QObject *obj, QEvent *event) override; - void paintEvent(QPaintEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + void paintEvent(QPaintEvent *event) override; private: - Toggle *const toggle_; - QColor trackColor_; + Toggle *const toggle_; + QColor trackColor_; }; diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp index fbd0f4f7..58150ed7 100644 --- a/src/ui/UserProfile.cpp +++ b/src/ui/UserProfile.cpp @@ -27,210 +27,200 @@ UserProfile::UserProfile(QString roomid, , manager(manager_) , model(parent) { - globalAvatarUrl = ""; - - connect(this, - &UserProfile::globalUsernameRetrieved, - this, - &UserProfile::setGlobalUsername, - Qt::QueuedConnection); - - if (isGlobalUserProfile()) { - getGlobalProfileData(); - } - - if (!cache::client() || !cache::client()->isDatabaseReady() || - !ChatPage::instance()->timelineManager()) - return; - - connect(cache::client(), - &Cache::verificationStatusChanged, - this, - [this](const std::string &user_id) { - if (user_id != this->userid_.toStdString()) - return; - - auto status = cache::verificationStatus(user_id); - if (!status) - return; - this->isUserVerified = status->user_verified; - emit userStatusChanged(); - - for (auto &deviceInfo : deviceList_.deviceList_) { - deviceInfo.verification_status = - std::find(status->verified_devices.begin(), - status->verified_devices.end(), - deviceInfo.device_id.toStdString()) == - status->verified_devices.end() - ? verification::UNVERIFIED - : verification::VERIFIED; - } - deviceList_.reset(deviceList_.deviceList_); - emit devicesChanged(); - }); - fetchDeviceList(this->userid_); + globalAvatarUrl = ""; + + connect(this, + &UserProfile::globalUsernameRetrieved, + this, + &UserProfile::setGlobalUsername, + Qt::QueuedConnection); + + if (isGlobalUserProfile()) { + getGlobalProfileData(); + } + + if (!cache::client() || !cache::client()->isDatabaseReady() || + !ChatPage::instance()->timelineManager()) + return; + + connect( + cache::client(), &Cache::verificationStatusChanged, this, [this](const std::string &user_id) { + if (user_id != this->userid_.toStdString()) + return; + + auto status = cache::verificationStatus(user_id); + if (!status) + return; + this->isUserVerified = status->user_verified; + emit userStatusChanged(); + + for (auto &deviceInfo : deviceList_.deviceList_) { + deviceInfo.verification_status = + std::find(status->verified_devices.begin(), + status->verified_devices.end(), + deviceInfo.device_id.toStdString()) == status->verified_devices.end() + ? verification::UNVERIFIED + : verification::VERIFIED; + } + deviceList_.reset(deviceList_.deviceList_); + emit devicesChanged(); + }); + fetchDeviceList(this->userid_); } QHash<int, QByteArray> DeviceInfoModel::roleNames() const { - return { - {DeviceId, "deviceId"}, - {DeviceName, "deviceName"}, - {VerificationStatus, "verificationStatus"}, - }; + return { + {DeviceId, "deviceId"}, + {DeviceName, "deviceName"}, + {VerificationStatus, "verificationStatus"}, + }; } QVariant DeviceInfoModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= (int)deviceList_.size() || index.row() < 0) - return {}; - - switch (role) { - case DeviceId: - return deviceList_[index.row()].device_id; - case DeviceName: - return deviceList_[index.row()].display_name; - case VerificationStatus: - return QVariant::fromValue(deviceList_[index.row()].verification_status); - default: - return {}; - } + if (!index.isValid() || index.row() >= (int)deviceList_.size() || index.row() < 0) + return {}; + + switch (role) { + case DeviceId: + return deviceList_[index.row()].device_id; + case DeviceName: + return deviceList_[index.row()].display_name; + case VerificationStatus: + return QVariant::fromValue(deviceList_[index.row()].verification_status); + default: + return {}; + } } void DeviceInfoModel::reset(const std::vector<DeviceInfo> &deviceList) { - beginResetModel(); - this->deviceList_ = std::move(deviceList); - endResetModel(); + beginResetModel(); + this->deviceList_ = std::move(deviceList); + endResetModel(); } DeviceInfoModel * UserProfile::deviceList() { - return &this->deviceList_; + return &this->deviceList_; } QString UserProfile::userid() { - return this->userid_; + return this->userid_; } QString UserProfile::displayName() { - return isGlobalUserProfile() ? globalUsername : cache::displayName(roomid_, userid_); + return isGlobalUserProfile() ? globalUsername : cache::displayName(roomid_, userid_); } QString UserProfile::avatarUrl() { - return isGlobalUserProfile() ? globalAvatarUrl : cache::avatarUrl(roomid_, userid_); + return isGlobalUserProfile() ? globalAvatarUrl : cache::avatarUrl(roomid_, userid_); } bool UserProfile::isGlobalUserProfile() const { - return roomid_ == ""; + return roomid_ == ""; } crypto::Trust UserProfile::getUserStatus() { - return isUserVerified; + return isUserVerified; } bool UserProfile::userVerificationEnabled() const { - return hasMasterKey; + return hasMasterKey; } bool UserProfile::isSelf() const { - return this->userid_ == utils::localUser(); + return this->userid_ == utils::localUser(); } void UserProfile::fetchDeviceList(const QString &userID) { - auto localUser = utils::localUser(); - - if (!cache::client() || !cache::client()->isDatabaseReady()) - return; - - cache::client()->query_keys( - userID.toStdString(), - [other_user_id = userID.toStdString(), this](const UserKeyCache &other_user_keys, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to query device keys: {},{}", - mtx::errors::to_string(err->matrix_error.errcode), - static_cast<int>(err->status_code)); - return; - } - - // Ensure local key cache is up to date - cache::client()->query_keys( - utils::localUser().toStdString(), - [other_user_id, other_user_keys, this](const UserKeyCache &, - mtx::http::RequestErr err) { - using namespace mtx; - std::string local_user_id = utils::localUser().toStdString(); - - if (err) { - nhlog::net()->warn( - "failed to query device keys: {},{}", - mtx::errors::to_string(err->matrix_error.errcode), - static_cast<int>(err->status_code)); - return; - } - - this->hasMasterKey = !other_user_keys.master_keys.keys.empty(); - - std::vector<DeviceInfo> deviceInfo; - auto devices = other_user_keys.device_keys; - auto verificationStatus = - cache::client()->verificationStatus(other_user_id); - - isUserVerified = verificationStatus.user_verified; - emit userStatusChanged(); - - for (const auto &d : devices) { - auto device = d.second; - verification::Status verified = - verification::Status::UNVERIFIED; - - if (std::find(verificationStatus.verified_devices.begin(), - verificationStatus.verified_devices.end(), - device.device_id) != - verificationStatus.verified_devices.end() && - mtx::crypto::verify_identity_signature( - device, - DeviceId(device.device_id), - UserId(other_user_id))) - verified = verification::Status::VERIFIED; - - deviceInfo.push_back( - {QString::fromStdString(d.first), - QString::fromStdString( - device.unsigned_info.device_display_name), - verified}); - } - - this->deviceList_.queueReset(std::move(deviceInfo)); - emit devicesChanged(); - }); - }); + auto localUser = utils::localUser(); + + if (!cache::client() || !cache::client()->isDatabaseReady()) + return; + + cache::client()->query_keys( + userID.toStdString(), + [other_user_id = userID.toStdString(), this](const UserKeyCache &other_user_keys, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to query device keys: {},{}", + mtx::errors::to_string(err->matrix_error.errcode), + static_cast<int>(err->status_code)); + return; + } + + // Ensure local key cache is up to date + cache::client()->query_keys( + utils::localUser().toStdString(), + [other_user_id, other_user_keys, this](const UserKeyCache &, + mtx::http::RequestErr err) { + using namespace mtx; + std::string local_user_id = utils::localUser().toStdString(); + + if (err) { + nhlog::net()->warn("failed to query device keys: {},{}", + mtx::errors::to_string(err->matrix_error.errcode), + static_cast<int>(err->status_code)); + return; + } + + this->hasMasterKey = !other_user_keys.master_keys.keys.empty(); + + std::vector<DeviceInfo> deviceInfo; + auto devices = other_user_keys.device_keys; + auto verificationStatus = cache::client()->verificationStatus(other_user_id); + + isUserVerified = verificationStatus.user_verified; + emit userStatusChanged(); + + for (const auto &d : devices) { + auto device = d.second; + verification::Status verified = verification::Status::UNVERIFIED; + + if (std::find(verificationStatus.verified_devices.begin(), + verificationStatus.verified_devices.end(), + device.device_id) != verificationStatus.verified_devices.end() && + mtx::crypto::verify_identity_signature( + device, DeviceId(device.device_id), UserId(other_user_id))) + verified = verification::Status::VERIFIED; + + deviceInfo.push_back( + {QString::fromStdString(d.first), + QString::fromStdString(device.unsigned_info.device_display_name), + verified}); + } + + this->deviceList_.queueReset(std::move(deviceInfo)); + emit devicesChanged(); + }); + }); } void UserProfile::banUser() { - ChatPage::instance()->banUser(this->userid_, ""); + ChatPage::instance()->banUser(this->userid_, ""); } // void ignoreUser(){ @@ -240,188 +230,180 @@ UserProfile::banUser() void UserProfile::kickUser() { - ChatPage::instance()->kickUser(this->userid_, ""); + ChatPage::instance()->kickUser(this->userid_, ""); } void UserProfile::startChat() { - ChatPage::instance()->startChat(this->userid_); + ChatPage::instance()->startChat(this->userid_); } void UserProfile::changeUsername(QString username) { - if (isGlobalUserProfile()) { - // change global - http::client()->set_displayname( - username.toStdString(), [](mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("could not change username"); - return; - } - }); - } else { - // change room username - mtx::events::state::Member member; - member.display_name = username.toStdString(); - member.avatar_url = - cache::avatarUrl(roomid_, - QString::fromStdString(http::client()->user_id().to_string())) - .toStdString(); - member.membership = mtx::events::state::Membership::Join; - - updateRoomMemberState(std::move(member)); - } + if (isGlobalUserProfile()) { + // change global + http::client()->set_displayname(username.toStdString(), [](mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("could not change username"); + return; + } + }); + } else { + // change room username + mtx::events::state::Member member; + member.display_name = username.toStdString(); + member.avatar_url = + cache::avatarUrl(roomid_, QString::fromStdString(http::client()->user_id().to_string())) + .toStdString(); + member.membership = mtx::events::state::Membership::Join; + + updateRoomMemberState(std::move(member)); + } } void UserProfile::verify(QString device) { - if (!device.isEmpty()) - manager->verifyDevice(userid_, device); - else { - manager->verifyUser(userid_); - } + if (!device.isEmpty()) + manager->verifyDevice(userid_, device); + else { + manager->verifyUser(userid_); + } } void UserProfile::unverify(QString device) { - cache::markDeviceUnverified(userid_.toStdString(), device.toStdString()); + cache::markDeviceUnverified(userid_.toStdString(), device.toStdString()); } void UserProfile::setGlobalUsername(const QString &globalUser) { - globalUsername = globalUser; - emit displayNameChanged(); + globalUsername = globalUser; + emit displayNameChanged(); } void UserProfile::changeAvatar() { - const QString picturesFolder = - QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); - const QString fileName = QFileDialog::getOpenFileName( - nullptr, tr("Select an avatar"), picturesFolder, tr("All Files (*)")); - - if (fileName.isEmpty()) - return; - - QMimeDatabase db; - QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent); - - const auto format = mime.name().split("/")[0]; - - QFile file{fileName, this}; - if (format != "image") { - emit displayError(tr("The selected file is not an image")); - return; - } - - if (!file.open(QIODevice::ReadOnly)) { - emit displayError(tr("Error while reading file: %1").arg(file.errorString())); - return; - } - - const auto bin = file.peek(file.size()); - const auto payload = std::string(bin.data(), bin.size()); - - isLoading_ = true; - emit loadingChanged(); - - // First we need to create a new mxc URI - // (i.e upload media to the Matrix content repository) for the new avatar. - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fileName).fileName().toStdString(), - [this, - payload, - mimetype = mime.name().toStdString(), - size = payload.size(), - room_id = roomid_.toStdString(), - content = std::move(bin)](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { + const QString picturesFolder = + QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); + const QString fileName = QFileDialog::getOpenFileName( + nullptr, tr("Select an avatar"), picturesFolder, tr("All Files (*)")); + + if (fileName.isEmpty()) + return; + + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent); + + const auto format = mime.name().split("/")[0]; + + QFile file{fileName, this}; + if (format != "image") { + emit displayError(tr("The selected file is not an image")); + return; + } + + if (!file.open(QIODevice::ReadOnly)) { + emit displayError(tr("Error while reading file: %1").arg(file.errorString())); + return; + } + + const auto bin = file.peek(file.size()); + const auto payload = std::string(bin.data(), bin.size()); + + isLoading_ = true; + emit loadingChanged(); + + // First we need to create a new mxc URI + // (i.e upload media to the Matrix content repository) for the new avatar. + http::client()->upload( + payload, + mime.name().toStdString(), + QFileInfo(fileName).fileName().toStdString(), + [this, + payload, + mimetype = mime.name().toStdString(), + size = payload.size(), + room_id = roomid_.toStdString(), + content = std::move(bin)](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) { + if (err) { + nhlog::ui()->error("Failed to upload image", err->matrix_error.error); + return; + } + + if (isGlobalUserProfile()) { + http::client()->set_avatar_url(res.content_uri, [this](mtx::http::RequestErr err) { if (err) { - nhlog::ui()->error("Failed to upload image", err->matrix_error.error); - return; + nhlog::ui()->error("Failed to set user avatar url", err->matrix_error.error); } - if (isGlobalUserProfile()) { - http::client()->set_avatar_url( - res.content_uri, [this](mtx::http::RequestErr err) { - if (err) { - nhlog::ui()->error("Failed to set user avatar url", - err->matrix_error.error); - } - - isLoading_ = false; - emit loadingChanged(); - getGlobalProfileData(); - }); - } else { - // change room username - mtx::events::state::Member member; - member.display_name = cache::displayName(roomid_, userid_).toStdString(); - member.avatar_url = res.content_uri; - member.membership = mtx::events::state::Membership::Join; - - updateRoomMemberState(std::move(member)); - } - }); + isLoading_ = false; + emit loadingChanged(); + getGlobalProfileData(); + }); + } else { + // change room username + mtx::events::state::Member member; + member.display_name = cache::displayName(roomid_, userid_).toStdString(); + member.avatar_url = res.content_uri; + member.membership = mtx::events::state::Membership::Join; + + updateRoomMemberState(std::move(member)); + } + }); } void UserProfile::updateRoomMemberState(mtx::events::state::Member member) { - http::client()->send_state_event(roomid_.toStdString(), - http::client()->user_id().to_string(), - member, - [](mtx::responses::EventId, mtx::http::RequestErr err) { - if (err) - nhlog::net()->error( - "Failed to update room member state : ", - err->matrix_error.error); - }); + http::client()->send_state_event( + roomid_.toStdString(), + http::client()->user_id().to_string(), + member, + [](mtx::responses::EventId, mtx::http::RequestErr err) { + if (err) + nhlog::net()->error("Failed to update room member state : ", err->matrix_error.error); + }); } void UserProfile::updateAvatarUrl() { - isLoading_ = false; - emit loadingChanged(); + isLoading_ = false; + emit loadingChanged(); - emit avatarUrlChanged(); + emit avatarUrlChanged(); } bool UserProfile::isLoading() const { - return isLoading_; + return isLoading_; } void UserProfile::getGlobalProfileData() { - http::client()->get_profile( - userid_.toStdString(), - [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to retrieve profile info for {}", - userid_.toStdString()); - return; - } - - emit globalUsernameRetrieved(QString::fromStdString(res.display_name)); - globalAvatarUrl = QString::fromStdString(res.avatar_url); - emit avatarUrlChanged(); - }); + http::client()->get_profile( + userid_.toStdString(), [this](const mtx::responses::Profile &res, mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to retrieve profile info for {}", userid_.toStdString()); + return; + } + + emit globalUsernameRetrieved(QString::fromStdString(res.display_name)); + globalAvatarUrl = QString::fromStdString(res.avatar_url); + emit avatarUrlChanged(); + }); } void UserProfile::openGlobalProfile() { - emit manager->openGlobalUserProfile(userid_); + emit manager->openGlobalUserProfile(userid_); } diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h index fd8772d5..a148c431 100644 --- a/src/ui/UserProfile.h +++ b/src/ui/UserProfile.h @@ -18,9 +18,9 @@ Q_NAMESPACE enum Status { - VERIFIED, - UNVERIFIED, - BLOCKED + VERIFIED, + UNVERIFIED, + BLOCKED }; Q_ENUM_NS(Status) } @@ -32,128 +32,127 @@ class TimelineViewManager; class DeviceInfo { public: - DeviceInfo(const QString deviceID, - const QString displayName, - verification::Status verification_status_) - : device_id(deviceID) - , display_name(displayName) - , verification_status(verification_status_) - {} - DeviceInfo() - : verification_status(verification::UNVERIFIED) - {} - - QString device_id; - QString display_name; - - verification::Status verification_status; + DeviceInfo(const QString deviceID, + const QString displayName, + verification::Status verification_status_) + : device_id(deviceID) + , display_name(displayName) + , verification_status(verification_status_) + {} + DeviceInfo() + : verification_status(verification::UNVERIFIED) + {} + + QString device_id; + QString display_name; + + verification::Status verification_status; }; class DeviceInfoModel : public QAbstractListModel { - Q_OBJECT + Q_OBJECT public: - enum Roles - { - DeviceId, - DeviceName, - VerificationStatus, - }; - - explicit DeviceInfoModel(QObject *parent = nullptr) - { - (void)parent; - connect(this, &DeviceInfoModel::queueReset, this, &DeviceInfoModel::reset); - }; - QHash<int, QByteArray> roleNames() const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override - { - (void)parent; - return (int)deviceList_.size(); - } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + enum Roles + { + DeviceId, + DeviceName, + VerificationStatus, + }; + + explicit DeviceInfoModel(QObject *parent = nullptr) + { + (void)parent; + connect(this, &DeviceInfoModel::queueReset, this, &DeviceInfoModel::reset); + }; + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + (void)parent; + return (int)deviceList_.size(); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; signals: - void queueReset(const std::vector<DeviceInfo> &deviceList); + void queueReset(const std::vector<DeviceInfo> &deviceList); public slots: - void reset(const std::vector<DeviceInfo> &deviceList); + void reset(const std::vector<DeviceInfo> &deviceList); private: - std::vector<DeviceInfo> deviceList_; + std::vector<DeviceInfo> deviceList_; - friend class UserProfile; + friend class UserProfile; }; class UserProfile : public QObject { - Q_OBJECT - Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged) - Q_PROPERTY(QString userid READ userid CONSTANT) - Q_PROPERTY(QString avatarUrl READ avatarUrl NOTIFY avatarUrlChanged) - Q_PROPERTY(DeviceInfoModel *deviceList READ deviceList NOTIFY devicesChanged) - Q_PROPERTY(bool isGlobalUserProfile READ isGlobalUserProfile CONSTANT) - Q_PROPERTY(int userVerified READ getUserStatus NOTIFY userStatusChanged) - Q_PROPERTY(bool isLoading READ isLoading NOTIFY loadingChanged) - Q_PROPERTY( - bool userVerificationEnabled READ userVerificationEnabled NOTIFY userStatusChanged) - Q_PROPERTY(bool isSelf READ isSelf CONSTANT) - Q_PROPERTY(TimelineModel *room READ room CONSTANT) + Q_OBJECT + Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged) + Q_PROPERTY(QString userid READ userid CONSTANT) + Q_PROPERTY(QString avatarUrl READ avatarUrl NOTIFY avatarUrlChanged) + Q_PROPERTY(DeviceInfoModel *deviceList READ deviceList NOTIFY devicesChanged) + Q_PROPERTY(bool isGlobalUserProfile READ isGlobalUserProfile CONSTANT) + Q_PROPERTY(int userVerified READ getUserStatus NOTIFY userStatusChanged) + Q_PROPERTY(bool isLoading READ isLoading NOTIFY loadingChanged) + Q_PROPERTY(bool userVerificationEnabled READ userVerificationEnabled NOTIFY userStatusChanged) + Q_PROPERTY(bool isSelf READ isSelf CONSTANT) + Q_PROPERTY(TimelineModel *room READ room CONSTANT) public: - UserProfile(QString roomid, - QString userid, - TimelineViewManager *manager_, - TimelineModel *parent = nullptr); - - DeviceInfoModel *deviceList(); - - QString userid(); - QString displayName(); - QString avatarUrl(); - bool isGlobalUserProfile() const; - crypto::Trust getUserStatus(); - bool userVerificationEnabled() const; - bool isSelf() const; - bool isLoading() const; - TimelineModel *room() const { return model; } - - Q_INVOKABLE void verify(QString device = ""); - Q_INVOKABLE void unverify(QString device = ""); - Q_INVOKABLE void fetchDeviceList(const QString &userID); - Q_INVOKABLE void banUser(); - // Q_INVOKABLE void ignoreUser(); - Q_INVOKABLE void kickUser(); - Q_INVOKABLE void startChat(); - Q_INVOKABLE void changeUsername(QString username); - Q_INVOKABLE void changeAvatar(); - Q_INVOKABLE void openGlobalProfile(); + UserProfile(QString roomid, + QString userid, + TimelineViewManager *manager_, + TimelineModel *parent = nullptr); + + DeviceInfoModel *deviceList(); + + QString userid(); + QString displayName(); + QString avatarUrl(); + bool isGlobalUserProfile() const; + crypto::Trust getUserStatus(); + bool userVerificationEnabled() const; + bool isSelf() const; + bool isLoading() const; + TimelineModel *room() const { return model; } + + Q_INVOKABLE void verify(QString device = ""); + Q_INVOKABLE void unverify(QString device = ""); + Q_INVOKABLE void fetchDeviceList(const QString &userID); + Q_INVOKABLE void banUser(); + // Q_INVOKABLE void ignoreUser(); + Q_INVOKABLE void kickUser(); + Q_INVOKABLE void startChat(); + Q_INVOKABLE void changeUsername(QString username); + Q_INVOKABLE void changeAvatar(); + Q_INVOKABLE void openGlobalProfile(); signals: - void userStatusChanged(); - void loadingChanged(); - void displayNameChanged(); - void avatarUrlChanged(); - void displayError(const QString &errorMessage); - void globalUsernameRetrieved(const QString &globalUser); - void devicesChanged(); + void userStatusChanged(); + void loadingChanged(); + void displayNameChanged(); + void avatarUrlChanged(); + void displayError(const QString &errorMessage); + void globalUsernameRetrieved(const QString &globalUser); + void devicesChanged(); public slots: - void updateAvatarUrl(); + void updateAvatarUrl(); protected slots: - void setGlobalUsername(const QString &globalUser); + void setGlobalUsername(const QString &globalUser); private: - void updateRoomMemberState(mtx::events::state::Member member); - void getGlobalProfileData(); + void updateRoomMemberState(mtx::events::state::Member member); + void getGlobalProfileData(); private: - QString roomid_, userid_; - QString globalUsername; - QString globalAvatarUrl; - DeviceInfoModel deviceList_; - crypto::Trust isUserVerified = crypto::Trust::Unverified; - bool hasMasterKey = false; - bool isLoading_ = false; - TimelineViewManager *manager; - TimelineModel *model; + QString roomid_, userid_; + QString globalUsername; + QString globalAvatarUrl; + DeviceInfoModel deviceList_; + crypto::Trust isUserVerified = crypto::Trust::Unverified; + bool hasMasterKey = false; + bool isLoading_ = false; + TimelineViewManager *manager; + TimelineModel *model; }; |