forked from qt-creator/qt-creator
Core: Add Core::Switch
New Component, implemented according to the design spec in Figma. Change-Id: I12e4882141a1f800b17175ca6dfc2f55517b7115 Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -445,6 +445,95 @@ void ComboBox::paintEvent(QPaintEvent *)
|
||||
p.drawPixmap(iconPos, icon);
|
||||
}
|
||||
|
||||
constexpr TextFormat SwitchLabelTf
|
||||
{Theme::Token_Text_Default, StyleHelper::UiElementLabelMedium};
|
||||
constexpr QSize switchTrackS(32, 16);
|
||||
|
||||
Switch::Switch(const QString &text, QWidget *parent)
|
||||
: QAbstractButton(parent)
|
||||
{
|
||||
setText(text);
|
||||
setCheckable(true);
|
||||
setAttribute(Qt::WA_Hover);
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
|
||||
setLayoutDirection(Qt::RightToLeft); // Switch right, label left
|
||||
}
|
||||
|
||||
QSize Switch::sizeHint() const
|
||||
{
|
||||
const QFontMetrics fm(SwitchLabelTf.font());
|
||||
const int textWidth = fm.horizontalAdvance(text());
|
||||
const int width = switchTrackS.width() + HGapS + textWidth;
|
||||
return {width, ExPaddingGapM + SwitchLabelTf.lineHeight() + ExPaddingGapM};
|
||||
}
|
||||
|
||||
QSize Switch::minimumSizeHint() const
|
||||
{
|
||||
return switchTrackS;
|
||||
}
|
||||
|
||||
void Switch::paintEvent([[maybe_unused]] QPaintEvent *event)
|
||||
{
|
||||
const bool ltr = layoutDirection() == Qt::LeftToRight;
|
||||
const int trackX = ltr ? 0 : width() - switchTrackS.width();
|
||||
const int trackY = (height() - switchTrackS.height()) / 2;
|
||||
const QRect trackR(QPoint(trackX, trackY), switchTrackS);
|
||||
const int trackRounding = trackR.height() / 2;
|
||||
const bool checkedEnabled = isChecked() && isEnabled();
|
||||
QPainter p(this);
|
||||
|
||||
{ // track
|
||||
const bool hovered = underMouse();
|
||||
const QBrush fill = creatorColor(checkedEnabled ? (hovered ? Theme::Token_Accent_Subtle
|
||||
: Theme::Token_Accent_Default)
|
||||
: Theme::Token_Foreground_Subtle);
|
||||
const QPen outline = checkedEnabled ? QPen(Qt::NoPen)
|
||||
: creatorColor(hovered ? Theme::Token_Stroke_Muted
|
||||
: Theme::Token_Stroke_Subtle);
|
||||
drawCardBackground(&p, trackR, fill, outline, trackRounding);
|
||||
}
|
||||
{ // track label
|
||||
const QColor color = creatorColor(isEnabled() ? (isChecked() ? Theme::Token_Basic_White
|
||||
: Theme::Token_Text_Muted)
|
||||
: Theme::Token_Text_Subtle);
|
||||
const int labelS = 6;
|
||||
const int labelY = (height() - labelS) / 2;
|
||||
if (isChecked()) {
|
||||
const QRect onLabelR(trackX + 8, labelY, 1, labelS);
|
||||
p.fillRect(onLabelR, color);
|
||||
} else {
|
||||
const QRect offLabelR(trackX + switchTrackS.width() - trackRounding - labelS / 2 - 1,
|
||||
labelY, labelS, labelS);
|
||||
drawCardBackground(&p, offLabelR, Qt::NoBrush, color, labelS / 2);
|
||||
}
|
||||
}
|
||||
{ // knob
|
||||
const int thumbPadding = checkedEnabled ? 3 : 2;
|
||||
const int thumbH = switchTrackS.height() - thumbPadding - thumbPadding;
|
||||
const int thumbW = isDown() ? (checkedEnabled ? 17 : 19)
|
||||
: thumbH;
|
||||
const int thumbRounding = thumbH / 2;
|
||||
const int thumbX = trackX + (isChecked() ? switchTrackS.width() - thumbW - thumbPadding
|
||||
: thumbPadding);
|
||||
const QRect thumbR(thumbX, trackY + thumbPadding, thumbW, thumbH);
|
||||
const QBrush fill = creatorColor(isEnabled() ? Theme::Token_Basic_White
|
||||
: Theme::Token_Foreground_Default);
|
||||
const QPen outline = checkedEnabled ? QPen(Qt::NoPen)
|
||||
: creatorColor(Theme::Token_Stroke_Subtle);
|
||||
drawCardBackground(&p, thumbR, fill, outline, thumbRounding);
|
||||
}
|
||||
{ // switch text label
|
||||
const int switchAndGapWidth = switchTrackS.width() + HGapS;
|
||||
const QRect textR(ltr ? switchAndGapWidth : 0, 0, width() - switchAndGapWidth,
|
||||
trackY + switchTrackS.height());
|
||||
p.setFont(SwitchLabelTf.font());
|
||||
p.setPen(isEnabled() ? SwitchLabelTf.color() : creatorColor(Theme::Token_Text_Subtle));
|
||||
const QString elidedLabel =
|
||||
p.fontMetrics().elidedText(text(), Qt::ElideRight, textR.width());
|
||||
p.drawText(textR, SwitchLabelTf.drawTextFlags, elidedLabel);
|
||||
}
|
||||
}
|
||||
|
||||
GridView::GridView(QWidget *parent)
|
||||
: QListView(parent)
|
||||
{
|
||||
|
@@ -141,6 +141,18 @@ protected:
|
||||
void leaveEvent(QEvent *event) override;
|
||||
};
|
||||
|
||||
class CORE_EXPORT Switch : public QAbstractButton
|
||||
{
|
||||
public:
|
||||
explicit Switch(const QString &text, QWidget *parent = nullptr);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
};
|
||||
|
||||
class CORE_EXPORT GridView : public QListView
|
||||
{
|
||||
public:
|
||||
|
@@ -17,6 +17,11 @@ QWidget *widgets()
|
||||
const QStringList content = QColor::colorNames();
|
||||
comboBox->addItems(content.first(8));
|
||||
|
||||
auto switchOn = new Core::Switch("Qt::RightToLeft");
|
||||
switchOn->setChecked(true);
|
||||
auto switchOff = new Core::Switch("Qt::LeftToRight");
|
||||
switchOff->setLayoutDirection(Qt::LeftToRight);
|
||||
|
||||
using namespace Layouting;
|
||||
Column {
|
||||
Group {
|
||||
@@ -50,6 +55,13 @@ QWidget *widgets()
|
||||
comboBox,
|
||||
},
|
||||
},
|
||||
Group {
|
||||
title("Core::Switch"),
|
||||
Column {
|
||||
switchOn,
|
||||
switchOff,
|
||||
},
|
||||
},
|
||||
}.attachTo(widget);
|
||||
|
||||
return widget;
|
||||
|
Reference in New Issue
Block a user