diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp index 794ed02997..3af4c2e00e 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp @@ -72,7 +72,7 @@ bool MappingButton::IsInput() const return m_reference->IsInput(); } -MappingButton::MappingButton(MappingWidget* parent, ControlReference* ref, bool indicator) +MappingButton::MappingButton(MappingWidget* parent, ControlReference* ref) : ElidedButton(RefToDisplayString(ref)), m_mapping_window(parent->GetParent()), m_reference(ref) { if (IsInput()) @@ -87,9 +87,6 @@ MappingButton::MappingButton(MappingWidget* parent, ControlReference* ref, bool connect(this, &MappingButton::clicked, this, &MappingButton::Clicked); - if (indicator) - connect(parent, &MappingWidget::Update, this, &MappingButton::UpdateIndicator); - connect(parent, &MappingWidget::ConfigChanged, this, &MappingButton::ConfigChanged); connect(this, &MappingButton::ConfigChanged, [this] { setText(RefToDisplayString(m_reference)); @@ -134,21 +131,6 @@ void MappingButton::Clear() m_mapping_window->UnQueueInputDetection(this); } -void MappingButton::UpdateIndicator() -{ - QFont f = m_mapping_window->font(); - - if (isActiveWindow() && m_reference->IsInput() && m_reference->GetState() && !m_is_mapping) - f.setBold(true); - - // If the expression has failed to parse, show it in italic. - // Some expressions still work even the failed to parse so don't prevent the GetState() above. - if (m_reference->GetParseStatus() == ciface::ExpressionParser::ParseStatus::SyntaxError) - f.setItalic(true); - - setFont(f); -} - void MappingButton::StartMapping() { // Focus just makes it more clear which button is currently being mapped. diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingButton.h b/Source/Core/DolphinQt/Config/Mapping/MappingButton.h index 11da51da6c..76bb412079 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingButton.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingButton.h @@ -15,7 +15,7 @@ class MappingButton : public ElidedButton { Q_OBJECT public: - MappingButton(MappingWidget* widget, ControlReference* ref, bool indicator); + MappingButton(MappingWidget* widget, ControlReference* ref); bool IsInput() const; ControlReference* GetControlReference(); @@ -26,7 +26,6 @@ signals: private: void Clear(); - void UpdateIndicator(); void AdvancedPressed(); void Clicked(); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp index 42f6f28de9..1528e4061a 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp @@ -128,6 +128,37 @@ void MappingIndicator::AdjustGateColor(QColor* color) color->setHsvF(color->hueF(), color->saturationF(), 1 - color->valueF()); } +ButtonIndicator::ButtonIndicator(ControlReference* control_ref) : m_control_ref{control_ref} +{ + setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed); +} + +QSize ButtonIndicator::sizeHint() const +{ + return QSize{INPUT_DOT_RADIUS + 2, + QFontMetrics(font()).boundingRect(QStringLiteral("[")).height()}; +} + +void ButtonIndicator::Draw() +{ + QPainter p(this); + p.setBrush(GetBBoxBrush()); + p.setPen(GetBBoxPen()); + p.drawRect(QRect{{0, 0}, size() - QSize{1, 1}}); + + const auto input_value = std::clamp(m_control_ref->GetState(), 0.0, 1.0); + const bool is_pressed = std::lround(input_value) != 0; + QSizeF value_size = size() - QSizeF{2, 2}; + value_size.setHeight(value_size.height() * input_value); + + p.translate(0, height()); + p.scale(1, -1); + + p.setPen(Qt::NoPen); + p.setBrush(is_pressed ? GetAdjustedInputColor() : GetRawInputColor()); + p.drawRect(QRectF{{1, 1}, value_size}); +} + SquareIndicator::SquareIndicator() { // Additional pixel for border. diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h index f571d5072d..ca6f9b96fd 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h @@ -53,6 +53,17 @@ private: Clock::time_point m_last_update = Clock::now(); }; +class ButtonIndicator final : public MappingIndicator +{ +public: + ButtonIndicator(ControlReference* control_ref); + +private: + ControlReference* const m_control_ref; + QSize sizeHint() const override; + void Draw() override; +}; + class SquareIndicator : public MappingIndicator { protected: diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp index 30f0e41e86..82fe042f9a 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp @@ -173,19 +173,19 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con form_layout->insertRow(2, mouse_button); using ControllerEmu::Cursor; - connect(mouse_button, &QCheckBox::clicked, [this, group = static_cast(group)] { + connect(mouse_button, &QCheckBox::clicked, [this, grp = static_cast(group)] { std::string default_device = g_controller_interface.GetDefaultDeviceString() + ":"; const std::string controller_device = GetController()->GetDefaultDevice().ToString() + ":"; if (default_device == controller_device) { default_device.clear(); } - group->SetControlExpression(0, fmt::format("`{}Cursor Y-`", default_device)); - group->SetControlExpression(1, fmt::format("`{}Cursor Y+`", default_device)); - group->SetControlExpression(2, fmt::format("`{}Cursor X-`", default_device)); - group->SetControlExpression(3, fmt::format("`{}Cursor X+`", default_device)); + grp->SetControlExpression(0, fmt::format("`{}Cursor Y-`", default_device)); + grp->SetControlExpression(1, fmt::format("`{}Cursor Y+`", default_device)); + grp->SetControlExpression(2, fmt::format("`{}Cursor X-`", default_device)); + grp->SetControlExpression(3, fmt::format("`{}Cursor X+`", default_device)); - group->SetRelativeInput(false); + grp->SetRelativeInput(false); emit ConfigChanged(); GetController()->UpdateReferences(g_controller_interface); @@ -313,14 +313,29 @@ QGroupBox* MappingWidget::CreateControlsBox(const QString& name, ControllerEmu:: void MappingWidget::CreateControl(const ControllerEmu::Control* control, QFormLayout* layout, bool indicator) { - auto* button = new MappingButton(this, control->control_ref.get(), indicator); - + auto* const button = new MappingButton(this, control->control_ref.get()); button->setMinimumWidth(100); button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + const bool translate = control->translate == ControllerEmu::Translatability::Translate; const QString translated_name = translate ? tr(control->ui_name.c_str()) : QString::fromStdString(control->ui_name); - layout->addRow(translated_name, button); + + if (indicator && control->control_ref->IsInput()) + { + auto* const button_indicator = new ButtonIndicator{control->control_ref.get()}; + connect(this, &MappingWidget::Update, button_indicator, qOverload<>(&MappingIndicator::update)); + + auto* const hbox = new QHBoxLayout; + hbox->setSpacing(0); + hbox->addWidget(button_indicator); + hbox->addWidget(button); + layout->addRow(translated_name, hbox); + } + else + { + layout->addRow(translated_name, button); + } } ControllerEmu::EmulatedController* MappingWidget::GetController() const