mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-06 21:00:21 +01:00
DolphinQt/Mapping: Clear and skip "Modifier" iterative input mappings when using
analog inputs.
This commit is contained in:
parent
3189de6c7a
commit
66624abb12
4 changed files with 72 additions and 23 deletions
|
@ -65,8 +65,9 @@ static QString RefToDisplayString(ControlReference* ref)
|
|||
return expression;
|
||||
}
|
||||
|
||||
MappingButton::MappingButton(MappingWidget* parent, ControlReference* ref)
|
||||
: ElidedButton(RefToDisplayString(ref)), m_mapping_window(parent->GetParent()), m_reference(ref)
|
||||
MappingButton::MappingButton(MappingWidget* parent, ControlReference* ref, ControlType control_type)
|
||||
: ElidedButton{RefToDisplayString(ref)}, m_mapping_window{parent->GetParent()},
|
||||
m_reference{ref}, m_control_type{control_type}
|
||||
{
|
||||
if (m_reference->IsInput())
|
||||
{
|
||||
|
@ -141,3 +142,8 @@ ControlReference* MappingButton::GetControlReference()
|
|||
{
|
||||
return m_reference;
|
||||
}
|
||||
|
||||
auto MappingButton::GetControlType() const -> ControlType
|
||||
{
|
||||
return m_control_type;
|
||||
}
|
||||
|
|
|
@ -15,9 +15,17 @@ class MappingButton : public ElidedButton
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MappingButton(MappingWidget* widget, ControlReference* ref);
|
||||
enum class ControlType
|
||||
{
|
||||
NormalInput,
|
||||
ModifierInput,
|
||||
Output,
|
||||
};
|
||||
|
||||
MappingButton(MappingWidget* widget, ControlReference* ref, ControlType type);
|
||||
|
||||
ControlReference* GetControlReference();
|
||||
ControlType GetControlType() const;
|
||||
|
||||
signals:
|
||||
void ConfigChanged();
|
||||
|
@ -32,4 +40,5 @@ private:
|
|||
|
||||
MappingWindow* const m_mapping_window;
|
||||
ControlReference* const m_reference;
|
||||
const ControlType m_control_type;
|
||||
};
|
||||
|
|
|
@ -25,6 +25,11 @@ constexpr auto INPUT_DETECT_MAXIMUM_TIME = std::chrono::seconds(5);
|
|||
// Ignore the mouse-click when queuing more buttons with "alternate mappings" enabled.
|
||||
constexpr auto INPUT_DETECT_ENDING_IGNORE_TIME = std::chrono::milliseconds(50);
|
||||
|
||||
bool ContainsAnalogInput(const ciface::Core::InputDetector::Results& results)
|
||||
{
|
||||
return std::ranges::any_of(results, [](auto& detection) { return detection.smoothness > 1; });
|
||||
}
|
||||
|
||||
class MappingProcessor : public QWidget
|
||||
{
|
||||
public:
|
||||
|
@ -75,24 +80,40 @@ public:
|
|||
m_input_detector->Update(INPUT_DETECT_INITIAL_TIME, confirmation_time,
|
||||
INPUT_DETECT_MAXIMUM_TIME);
|
||||
|
||||
if (m_input_detector->IsComplete())
|
||||
{
|
||||
auto* const button = m_clicked_mapping_buttons.back();
|
||||
if (!m_input_detector->IsComplete())
|
||||
return;
|
||||
|
||||
if (!FinalizeMapping(m_input_detector->TakeResults()))
|
||||
auto* const button = m_clicked_mapping_buttons.front();
|
||||
|
||||
auto results = m_input_detector->TakeResults();
|
||||
if (!FinalizeMapping(&results))
|
||||
{
|
||||
// No inputs detected. Cancel this and any other queued mappings.
|
||||
CancelMapping();
|
||||
}
|
||||
else if (m_parent->IsIterativeMappingEnabled() && m_clicked_mapping_buttons.empty())
|
||||
{
|
||||
button->QueueNextButtonMapping();
|
||||
|
||||
if (m_clicked_mapping_buttons.empty())
|
||||
return;
|
||||
|
||||
// Skip "Modifier" mappings when using analog inputs.
|
||||
auto* next_button = m_clicked_mapping_buttons.front();
|
||||
if (next_button->GetControlType() == MappingButton::ControlType::ModifierInput &&
|
||||
ContainsAnalogInput(results))
|
||||
{
|
||||
// No inputs detected. Cancel this and any other queued mappings.
|
||||
CancelMapping();
|
||||
}
|
||||
else if (m_parent->IsIterativeMappingEnabled() && m_clicked_mapping_buttons.empty())
|
||||
{
|
||||
button->QueueNextButtonMapping();
|
||||
// Clear "Modifier" mapping and queue the next button.
|
||||
SetButtonExpression(next_button, "");
|
||||
UnQueueInputDetection(next_button);
|
||||
next_button->QueueNextButtonMapping();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FinalizeMapping(ciface::Core::InputDetector::Results detections)
|
||||
bool FinalizeMapping(ciface::Core::InputDetector::Results* detections_ptr)
|
||||
{
|
||||
auto& detections = *detections_ptr;
|
||||
if (!ciface::MappingCommon::ContainsCompleteDetection(detections))
|
||||
return false;
|
||||
|
||||
|
@ -100,18 +121,22 @@ public:
|
|||
|
||||
const auto& default_device = m_parent->GetController()->GetDefaultDevice();
|
||||
auto& button = m_clicked_mapping_buttons.front();
|
||||
auto* const control_reference = button->GetControlReference();
|
||||
SetButtonExpression(
|
||||
button, BuildExpression(detections, default_device, ciface::MappingCommon::Quote::On));
|
||||
|
||||
control_reference->SetExpression(
|
||||
BuildExpression(detections, default_device, ciface::MappingCommon::Quote::On));
|
||||
m_parent->Save();
|
||||
|
||||
m_parent->GetController()->UpdateSingleControlReference(g_controller_interface,
|
||||
control_reference);
|
||||
UnQueueInputDetection(button);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetButtonExpression(MappingButton* button, const std::string& expression)
|
||||
{
|
||||
auto* const control_reference = button->GetControlReference();
|
||||
control_reference->SetExpression(expression);
|
||||
m_parent->Save();
|
||||
m_parent->GetController()->UpdateSingleControlReference(g_controller_interface,
|
||||
control_reference);
|
||||
}
|
||||
|
||||
void UpdateInputDetectionStartTimer()
|
||||
{
|
||||
m_input_detector.reset();
|
||||
|
@ -146,7 +171,7 @@ public:
|
|||
auto results = m_input_detector->TakeResults();
|
||||
ciface::MappingCommon::RemoveDetectionsAfterTimePoint(
|
||||
&results, ciface::Core::DeviceContainer::Clock::now() - INPUT_DETECT_ENDING_IGNORE_TIME);
|
||||
FinalizeMapping(std::move(results));
|
||||
FinalizeMapping(&results);
|
||||
}
|
||||
UpdateInputDetectionStartTimer();
|
||||
}
|
||||
|
|
|
@ -313,7 +313,16 @@ QGroupBox* MappingWidget::CreateControlsBox(const QString& name, ControllerEmu::
|
|||
void MappingWidget::CreateControl(const ControllerEmu::Control* control, QFormLayout* layout,
|
||||
bool indicator)
|
||||
{
|
||||
auto* const button = new MappingButton(this, control->control_ref.get());
|
||||
// I know this check is terrible, but it's just UI code.
|
||||
const bool is_modifier = control->name == "Modifier";
|
||||
|
||||
using ControlType = MappingButton::ControlType;
|
||||
const auto control_type =
|
||||
control->control_ref->IsInput() ?
|
||||
(is_modifier ? ControlType::ModifierInput : ControlType::NormalInput) :
|
||||
ControlType::Output;
|
||||
|
||||
auto* const button = new MappingButton(this, control->control_ref.get(), control_type);
|
||||
|
||||
if (control->control_ref->IsInput())
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue