qt(wallet): outline the HD status letters in TRI brand red

Adds OutlinedLabel, a small QLabel subclass that paints each character
with a colored outline and a hollow interior. Used for the HD badge
in the status bar so each letter H and D is bordered in the same

- outline + fill done in custom paintEvent (no QSS hacks)
- updateHDStatus() now drives setOutlineColor/setOutlineWidth
  directly instead of stylesheets
- registered OutlinedLabel as a custom widget in mainwindow.ui
- labelHdIcon pointer type updated to OutlinedLabel*
This commit is contained in:
Krystie
2026-07-02 20:14:34 -07:00
committed by root
parent 0712e5b08c
commit c7314b2357
6 changed files with 163 additions and 5 deletions
+1
View File
@@ -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
+18 -1
View File
@@ -1664,7 +1664,7 @@ QProgressBar::chunk {
</widget>
</item>
<item>
<widget class="QLabel" name="label_hd">
<widget class="OutlinedLabel" name="label_hd">
<property name="font">
<font>
<pointsize>9</pointsize>
@@ -1672,6 +1672,16 @@ QProgressBar::chunk {
<bold>true</bold>
</font>
</property>
<property name="outlineColor">
<color>
<red>242</red>
<green>101</green>
<blue>34</blue>
</color>
</property>
<property name="outlineWidth">
<number>3</number>
</property>
<property name="toolTip">
<string>HD (BIP39) wallet seed status</string>
</property>
@@ -1759,6 +1769,13 @@ QProgressBar::chunk {
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>OutlinedLabel</class>
<extends>QLabel</extends>
<header>qt/outlinedlabel.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../triangles.qrc"/>
</resources>
+93
View File
@@ -0,0 +1,93 @@
#include "outlinedlabel.h"
#include <QPainter>
#include <QPainterPath>
#include <QPaintEvent>
#include <QStyleOption>
#include <QTextDocument>
#include <QString>
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);
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef TRIANGLES_QT_OUTLINEDLABEL_H
#define TRIANGLES_QT_OUTLINEDLABEL_H
#include <QLabel>
/**
* 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
+8 -3
View File
@@ -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();
+3 -1
View File
@@ -6,6 +6,8 @@
#include <QMap>
#include <QBitmap>
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;