diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9ee81df..0433b7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -450,6 +450,7 @@ if(BUILD_QT) qt/qvaluecombobox.cpp qt/askpassphrasedialog.cpp qt/hdseeddialog.cpp + qt/outlinedlabel.cpp qt/notificator.cpp qt/qtipcserver.cpp qt/rpcconsole.cpp diff --git a/src/qt/forms/mainwindow.ui b/src/qt/forms/mainwindow.ui index bb85023..acdcb02 100644 --- a/src/qt/forms/mainwindow.ui +++ b/src/qt/forms/mainwindow.ui @@ -1664,7 +1664,7 @@ QProgressBar::chunk { - + 9 @@ -1672,6 +1672,16 @@ QProgressBar::chunk { true + + + 242 + 101 + 34 + + + + 3 + HD (BIP39) wallet seed status @@ -1759,6 +1769,13 @@ QProgressBar::chunk { + + + OutlinedLabel + QLabel +
qt/outlinedlabel.h
+
+
diff --git a/src/qt/outlinedlabel.cpp b/src/qt/outlinedlabel.cpp new file mode 100644 index 0000000..0964f79 --- /dev/null +++ b/src/qt/outlinedlabel.cpp @@ -0,0 +1,93 @@ +#include "outlinedlabel.h" + +#include +#include +#include +#include +#include +#include + +OutlinedLabel::OutlinedLabel(QWidget* parent) + : QLabel(parent) + , m_outlineColor(QColor("#f26522")) + , m_outlineWidth(3) +{ + // OutlinedLabel is always styled; do not let QSS override our paint. + setAttribute(Qt::WA_OpaquePaintEvent, false); +} + +void OutlinedLabel::setOutlineColor(const QColor& c) +{ + if (m_outlineColor == c) return; + m_outlineColor = c; + update(); +} + +void OutlinedLabel::setOutlineWidth(int w) +{ + if (m_outlineWidth == w) return; + m_outlineWidth = w; + update(); +} + +void OutlinedLabel::paintEvent(QPaintEvent* e) +{ + Q_UNUSED(e); + + // Honor any background styling the parent may have given us, but + // do our own text rendering below. We deliberately skip QLabel's + // built-in drawContents/drawText path because it cannot paint a + // per-character outline. + QStyleOption opt; + opt.initFrom(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, nullptr, this); + + if (text().isEmpty()) return; + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::TextAntialiasing, true); + + const QFontMetricsF fm(font()); + const QString t = text(); + // Bounding rect for the text, honoring alignment. Add half the + // outline width on each side so strokes don't clip against the + // widget edge. + const qreal pad = m_outlineWidth / 2.0; + QRectF r = rect().adjusted(pad, pad, -pad, -pad); + + // Center vertically based on font metrics + const qreal yOffset = (r.height() - fm.height()) / 2.0; + QPointF baseline(r.left(), r.top() + yOffset + fm.ascent()); + + // Align: use only the horizontal part of the alignment flag. + const int align = int(alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify)); + const qreal textWidth = fm.horizontalAdvance(t); + qreal x = r.left(); + if (align & Qt::AlignHCenter) { + x = r.left() + (r.width() - textWidth) / 2.0; + } else if (align & Qt::AlignRight) { + x = r.right() - textWidth; + } + baseline.setX(x); + + QPainterPath path; + path.addText(baseline, font(), t); + + // Stroke (outline) — drawn first, in the brand red so each letter + // has a clear 3px red border matching the triangle icons. + QPen outlinePen(m_outlineColor); + outlinePen.setWidth(m_outlineWidth); + outlinePen.setJoinStyle(Qt::RoundJoin); + outlinePen.setCapStyle(Qt::RoundCap); + painter.setPen(outlinePen); + painter.setBrush(Qt::NoBrush); + painter.drawPath(path); + + // Fill the interior with the widget background color so the + // letters read as hollow red outlines against the dark wallet + // background, like the triangle icons beside them. + painter.setPen(Qt::NoPen); + painter.setBrush(QBrush(palette().color(backgroundRole()))); + painter.drawPath(path); +} diff --git a/src/qt/outlinedlabel.h b/src/qt/outlinedlabel.h new file mode 100644 index 0000000..58ab51d --- /dev/null +++ b/src/qt/outlinedlabel.h @@ -0,0 +1,40 @@ +#ifndef TRIANGLES_QT_OUTLINEDLABEL_H +#define TRIANGLES_QT_OUTLINEDLABEL_H + +#include + +/** + * QLabel that renders its text with an outline (stroke) in the + * outline color, and a fill in the fill color. Used for the + * "HD" badge in the status bar of the Triangles Qt wallet so + * that each letter is outlined in the same red (#f26522) as + * the triangle icons. + * + * Outline is drawn first (wide red pen), then the fill is drawn + * on top (narrower pen, slightly inset). Both pens use the + * same font/alignment as the parent label. + */ +class OutlinedLabel : public QLabel +{ + Q_OBJECT + Q_PROPERTY(QColor outlineColor READ outlineColor WRITE setOutlineColor) + Q_PROPERTY(int outlineWidth READ outlineWidth WRITE setOutlineWidth) + +public: + explicit OutlinedLabel(QWidget* parent = nullptr); + + QColor outlineColor() const { return m_outlineColor; } + void setOutlineColor(const QColor& c); + + int outlineWidth() const { return m_outlineWidth; } + void setOutlineWidth(int w); + +protected: + void paintEvent(QPaintEvent* e) override; + +private: + QColor m_outlineColor; + int m_outlineWidth; +}; + +#endif // TRIANGLES_QT_OUTLINEDLABEL_H diff --git a/src/qt/trianglesgui.cpp b/src/qt/trianglesgui.cpp index b9d8e1c..653da75 100644 --- a/src/qt/trianglesgui.cpp +++ b/src/qt/trianglesgui.cpp @@ -32,6 +32,7 @@ #include "guiconstants.h" #include "askpassphrasedialog.h" #include "hdseeddialog.h" +#include "outlinedlabel.h" #include "notificator.h" #include "guiutil.h" #include "rpcconsole.h" @@ -1896,17 +1897,21 @@ void TrianglesGUI::updateHDStatus() } if (fHD) { - labelHdIcon->setStyleSheet("color: #f26522; font-weight: bold;"); + // Both letters outlined in the brand red, 3px stroke (matches the + // triangles beside it). + labelHdIcon->setOutlineColor(QColor("#f26522")); + labelHdIcon->setOutlineWidth(3); labelHdIcon->setToolTip(tr("HD wallet: BIP39 seed active. Backup your seed phrase — individual keys alone will not restore this wallet.")); } else { - labelHdIcon->setStyleSheet("color: #555555; font-weight: bold;"); + // Greyed-out (dim) badge until the user runs hdnew. + labelHdIcon->setOutlineColor(QColor("#555555")); + labelHdIcon->setOutlineWidth(3); labelHdIcon->setToolTip(tr("Non-HD wallet: backup each address key separately. Use hdnew to upgrade to an HD seed.")); } labelHdIcon->setText(QStringLiteral("HD")); labelHdIcon->setVisible(true); } - void TrianglesGUI::on_bHelp_clicked() { ensureRPCConsole(); diff --git a/src/qt/trianglesgui.h b/src/qt/trianglesgui.h index 566da5f..c168172 100644 --- a/src/qt/trianglesgui.h +++ b/src/qt/trianglesgui.h @@ -6,6 +6,8 @@ #include #include +class OutlinedLabel; + class TransactionTableModel; class ClientModel; class WalletModel; @@ -114,7 +116,7 @@ private: QLabel *labelV3Icon; QLabel *labelI2PIcon; QLabel *labelTorIcon; - QLabel *labelHdIcon; + OutlinedLabel *labelHdIcon; QLabel *progressBarLabel; QProgressBar *progressBar;