// Copyright (C) 2023 Tasuku Suzuki // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qtcwidgets.h" #include "hostosinfo.h" #include "icon.h" #include "networkaccessmanager.h" #include #include #include #include #include #include #include #include #include #include namespace Utils { using namespace StyleHelper::SpacingTokens; const qreal disabledIconOpacity = 0.3; QColor TextFormat::color() const { return Utils::creatorColor(themeColor); } QFont TextFormat::font(bool underlined) const { QFont result = Utils::StyleHelper::uiFont(uiElement); result.setUnderline(underlined); return result; } int TextFormat::lineHeight() const { return Utils::StyleHelper::uiFontLineHeight(uiElement); } void applyTf(QLabel *label, const TextFormat &tf, bool singleLine) { if (singleLine) label->setFixedHeight(tf.lineHeight()); label->setFont(tf.font()); label->setAlignment(Qt::Alignment(tf.drawTextFlags)); label->setTextInteractionFlags(Qt::TextSelectableByMouse); QPalette pal = label->palette(); pal.setColor(QPalette::WindowText, tf.color()); label->setPalette(pal); } enum WidgetState { WidgetStateDefault, WidgetStateChecked, WidgetStateHovered, }; static const TextFormat &buttonTF(QtcButton::Role role, WidgetState state) { static const TextFormat largePrimaryTF {Theme::Token_Basic_White, StyleHelper::UiElement::UiElementButtonMedium, Qt::AlignCenter | Qt::TextDontClip | Qt::TextShowMnemonic}; static const TextFormat largeSecondaryTF {Theme::Token_Text_Default, largePrimaryTF.uiElement, largePrimaryTF.drawTextFlags}; static const TextFormat smallPrimaryTF {largePrimaryTF.themeColor, StyleHelper::UiElement::UiElementButtonSmall, largePrimaryTF.drawTextFlags}; static const TextFormat smallSecondaryTF {largeSecondaryTF.themeColor, smallPrimaryTF.uiElement, smallPrimaryTF.drawTextFlags}; static const TextFormat smallListDefaultTF {Theme::Token_Text_Default, StyleHelper::UiElement::UiElementIconStandard, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip | Qt::TextShowMnemonic}; static const TextFormat smallListCheckedTF = smallListDefaultTF; static const TextFormat smallLinkDefaultTF {Theme::Token_Text_Default, StyleHelper::UiElement::UiElementIconStandard, smallListDefaultTF.drawTextFlags}; static const TextFormat smallLinkHoveredTF {Theme::Token_Text_Accent, smallLinkDefaultTF.uiElement, smallLinkDefaultTF.drawTextFlags}; static const TextFormat tagDefaultTF {Theme::Token_Text_Muted, StyleHelper::UiElement::UiElementLabelMedium}; static const TextFormat tagHoverTF {Theme::Token_Text_Default, tagDefaultTF.uiElement}; switch (role) { case QtcButton::LargePrimary: return largePrimaryTF; case QtcButton::LargeSecondary: case QtcButton::LargeTertiary: return largeSecondaryTF; case QtcButton::SmallPrimary: return smallPrimaryTF; case QtcButton::SmallSecondary: case QtcButton::SmallTertiary: return smallSecondaryTF; case QtcButton::SmallList: return (state == WidgetStateDefault) ? smallListDefaultTF : smallListCheckedTF; case QtcButton::SmallLink: return (state == WidgetStateDefault) ? smallLinkDefaultTF : smallLinkHoveredTF; case QtcButton::Tag: return (state == WidgetStateDefault) ? tagDefaultTF : tagHoverTF; } return largePrimaryTF; } QtcButton::QtcButton(const QString &text, Role role, QWidget *parent) : QAbstractButton(parent) , m_role(role) { setText(text); setAttribute(Qt::WA_Hover); updateMargins(); if (m_role == SmallList) setCheckable(true); else if (m_role == SmallLink) setCursor(Qt::PointingHandCursor); } QSize QtcButton::minimumSizeHint() const { int maxTextWidth = 0; for (WidgetState state : {WidgetStateDefault, WidgetStateChecked, WidgetStateHovered} ) { const TextFormat &tf = buttonTF(m_role, state); const QFontMetrics fm(tf.font()); const QSize textS = fm.size(Qt::TextShowMnemonic, text()); maxTextWidth = qMax(maxTextWidth, textS.width()); } const TextFormat &tf = buttonTF(m_role, WidgetStateDefault); const QMargins margins = contentsMargins(); return {margins.left() + maxTextWidth + margins.right(), margins.top() + tf.lineHeight() + margins.bottom()}; } void QtcButton::paintEvent(QPaintEvent *event) { // Without pixmap // +----------------+----------------+----------------+ // | |(VPadding[S|XS])| | // | +----------------+----------------+ // |(HPadding[S|XS])|