Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tooltips to pad settings #8581

Merged
merged 1 commit into from Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 59 additions & 15 deletions rpcs3/rpcs3qt/pad_settings_dialog.cpp
Expand Up @@ -217,6 +217,9 @@ pad_settings_dialog::pad_settings_dialog(std::shared_ptr<gui_settings> gui_setti
// Initialize configurable buttons
InitButtons();

// Initialize tooltips
SubscribeTooltips();

// Repaint controller image
ui->l_controller->setPixmap(gui::utils::get_colorized_pixmap(*ui->l_controller->pixmap(), QColor(), gui::utils::get_label_color("l_controller"), false, true));

Expand Down Expand Up @@ -867,6 +870,26 @@ bool pad_settings_dialog::eventFilter(QObject* object, QEvent* event)
{
mouseMoveEvent(static_cast<QMouseEvent*>(event));
}

if (event->type() == QEvent::Enter || event->type() == QEvent::Leave)
{
if (ui->l_description && m_descriptions.contains(object))
{
if (event->type() == QEvent::Enter)
{
// Check for visibility when entering a widget (needed in case of overlapping widgets in a QStackedWidget for example)
if (const auto widget = qobject_cast<QWidget*>(object); widget && widget->isVisible())
{
ui->l_description->setText(m_descriptions[object]);
}
}
else if (event->type() == QEvent::Leave)
{
ui->l_description->setText(m_description);
}
}
}

return QDialog::eventFilter(object, event);
}

Expand Down Expand Up @@ -1145,45 +1168,44 @@ void pad_settings_dialog::ChangeInputType()
Tooltips tooltips;

// Change the description
QString description;
switch (m_handler->m_type)
{
case pad_handler::null:
if (is_ldd_pad)
description = tooltips.gamepad_settings.ldd_pad;
m_description = tooltips.gamepad_settings.ldd_pad;
else
description = tooltips.gamepad_settings.null;
m_description = tooltips.gamepad_settings.null;
break;
case pad_handler::keyboard:
description = tooltips.gamepad_settings.keyboard; break;
m_description = tooltips.gamepad_settings.keyboard; break;
#ifdef _WIN32
case pad_handler::xinput:
description = tooltips.gamepad_settings.xinput; break;
m_description = tooltips.gamepad_settings.xinput; break;
case pad_handler::mm:
description = tooltips.gamepad_settings.mmjoy; break;
m_description = tooltips.gamepad_settings.mmjoy; break;
case pad_handler::ds3:
description = tooltips.gamepad_settings.ds3_windows; break;
m_description = tooltips.gamepad_settings.ds3_windows; break;
case pad_handler::ds4:
description = tooltips.gamepad_settings.ds4_windows; break;
m_description = tooltips.gamepad_settings.ds4_windows; break;
#elif __linux__
case pad_handler::ds3:
description = tooltips.gamepad_settings.ds3_linux; break;
m_description = tooltips.gamepad_settings.ds3_linux; break;
case pad_handler::ds4:
description = tooltips.gamepad_settings.ds4_linux; break;
m_description = tooltips.gamepad_settings.ds4_linux; break;
#else
case pad_handler::ds3:
description = tooltips.gamepad_settings.ds3_other; break;
m_description = tooltips.gamepad_settings.ds3_other; break;
case pad_handler::ds4:
description = tooltips.gamepad_settings.ds4_other; break;
m_description = tooltips.gamepad_settings.ds4_other; break;
#endif
#ifdef HAVE_LIBEVDEV
case pad_handler::evdev:
description = tooltips.gamepad_settings.evdev; break;
m_description = tooltips.gamepad_settings.evdev; break;
#endif
default:
description = "";
m_description = "";
}
ui->l_description->setText(description);
ui->l_description->setText(m_description);

// change our contextual widgets
ui->left_stack->setCurrentIndex((m_handler->m_type == pad_handler::keyboard) ? 1 : 0);
Expand Down Expand Up @@ -1588,3 +1610,25 @@ void pad_settings_dialog::ResizeDialog()
resize(tabwidget_size + buttons_size + margin_size + spacing_size);
setMaximumSize(size());
}

void pad_settings_dialog::SubscribeTooltip(QObject* object, const QString& tooltip)
{
m_descriptions[object] = tooltip;
object->installEventFilter(this);
}

void pad_settings_dialog::SubscribeTooltips()
{
// Localized tooltips
Tooltips tooltips;

SubscribeTooltip(ui->gb_squircle, tooltips.gamepad_settings.squircle_factor);
SubscribeTooltip(ui->gb_stick_multi, tooltips.gamepad_settings.stick_multiplier);
SubscribeTooltip(ui->gb_vibration, tooltips.gamepad_settings.vibration);
SubscribeTooltip(ui->gb_sticks, tooltips.gamepad_settings.stick_deadzones);
SubscribeTooltip(ui->gb_stick_preview, tooltips.gamepad_settings.emulated_preview);
SubscribeTooltip(ui->gb_triggers, tooltips.gamepad_settings.trigger_deadzones);
SubscribeTooltip(ui->gb_stick_lerp, tooltips.gamepad_settings.stick_lerp);
SubscribeTooltip(ui->gb_mouse_accel, tooltips.gamepad_settings.mouse_acceleration);
SubscribeTooltip(ui->gb_mouse_dz, tooltips.gamepad_settings.mouse_deadzones);
}
10 changes: 10 additions & 0 deletions rpcs3/rpcs3qt/pad_settings_dialog.h
Expand Up @@ -108,6 +108,10 @@ private Q_SLOTS:
std::string m_title_id;
std::shared_ptr<gui_settings> m_gui_settings;

// Tooltips
QString m_description;
QHash<QObject*, QString> m_descriptions;

// Capabilities
bool m_enable_buttons{ false };
bool m_enable_rumble{ false };
Expand Down Expand Up @@ -185,6 +189,12 @@ private Q_SLOTS:
/** Resizes the dialog. We need to do this because the main scroll area can't determine the size on its own. */
void ResizeDialog();

/** Register a widget for tooltips */
void SubscribeTooltip(QObject* object, const QString& tooltip);

/** Used to keep all tooltip subscriptions in one place. */
void SubscribeTooltips();

protected:
/** Handle keyboard handler input */
void keyPressEvent(QKeyEvent *keyEvent) override;
Expand Down
17 changes: 14 additions & 3 deletions rpcs3/rpcs3qt/tooltips.h
Expand Up @@ -199,15 +199,26 @@ class Tooltips : public QObject
{
const QString null = tr("This controller is disabled and will appear as disconnected to software. Choose another handler to enable it.");
const QString ldd_pad = tr("This port is currently assigned to a custom controller by the application and can't be changed.");
const QString keyboard = tr("While it is possible to use a keyboard as a pad in RPCS3, the use of an actual controller is strongly recommended.\nTo bind mouse movement to a button or joystick, click on the desired button to activate it, then click and hold while dragging the mouse to a direction.");
const QString ds3_windows = tr("In order to use the DualShock 3 handler, you need to install the official DualShock 3 driver first.\nSee the <a href=\"https://wiki.rpcs3.net/index.php?title=Help:Controller_Configuration\">RPCS3 Wiki</a> for instructions.");
const QString keyboard = tr("While it is possible to use a keyboard as a pad in RPCS3, the use of an actual controller is strongly recommended.<br>To bind mouse movement to a button or joystick, click on the desired button to activate it, then click and hold while dragging the mouse to a direction.");
const QString ds3_windows = tr("In order to use the DualShock 3 handler, you need to install the official DualShock 3 driver first.<br>See the <a href=\"https://wiki.rpcs3.net/index.php?title=Help:Controller_Configuration\">RPCS3 Wiki</a> for instructions.");
const QString ds3_linux = tr("In order to use the DualShock 3 handler, you might need to add udev rules to let RPCS3 access the controller.\nSee the <a href=\"https://wiki.rpcs3.net/index.php?title=Help:Controller_Configuration\">RPCS3 Wiki</a> for instructions.");
const QString ds3_other = tr("The DualShock 3 handler is recommended for official DualShock 3 controllers.");
const QString ds4_windows = tr("If you have any issues with the DualShock 4 handler, it might be caused by third-party tools such as DS4Windows. It's recommended that you disable them while using this handler.");
const QString ds4_linux = tr("In order to use the DualShock 4 handler, you might need to add udev rules to let RPCS3 access the controller.\nSee the <a href=\"https://wiki.rpcs3.net/index.php?title=Help:Controller_Configuration\">RPCS3 Wiki</a> for instructions.");
const QString ds4_other = tr("The DualShock 4 handler is recommended for official DualShock 4 controllers.");
const QString xinput = tr("The XInput handler will work with Xbox controllers and many third-party PC-compatible controllers. Pressure sensitive buttons from SCP are supported when SCP's XInput1_3.dll is placed in the main RPCS3 directory. For more details, see the <a href=\"https://wiki.rpcs3.net/index.php?title=Help:Controller_Configuration\">RPCS3 Wiki</a>.");
const QString evdev = tr("The evdev handler should work with any controller that has linux support.\nIf your joystick is not being centered properly, read the <a href=\"https://wiki.rpcs3.net/index.php?title=Help:Controller_Configuration\">RPCS3 Wiki</a> for instructions.");
const QString evdev = tr("The evdev handler should work with any controller that has linux support.<br>If your joystick is not being centered properly, read the <a href=\"https://wiki.rpcs3.net/index.php?title=Help:Controller_Configuration\">RPCS3 Wiki</a> for instructions.");
const QString mmjoy = tr("The MMJoystick handler should work with almost any controller recognized by Windows. However, it is recommended that you use the more specific handlers if you have a controller that supports them.");

const QString squircle_factor = tr("The actual DualShock 3's stick range is not circular but formed like a rounded square (or squircle) which represents the maximum range of the emulated sticks. You can use the squircle values to modify the stick input if your sticks can't reach the corners of that range. A value of 0 does not apply any so called squircling. A value of 8000 is usually recommended.");
const QString stick_multiplier = tr("The stick multipliers can be used to change the sensitivity of your stick movements.<br>The default setting is 1 and represents normal input.");
const QString stick_deadzones = tr("A stick's deadzone determines how far the stick has to be moved until it is fully recognized by the game. The resulting range will be projected onto the full input range in order to give you a smooth experience. Movement inside the deadzone is actually simulated as a real DualShock 3's deadzone of ~13%, so don't worry if there is still movement shown in the emulated stick preview.");
const QString vibration = tr("The PS3 activates two motors (large and small) to handle controller vibrations.<br>You can enable, disable or even switch these signals for the currently selected pad here.");
const QString emulated_preview = tr("The emulated stick values (red dots) in the stick preview represent the actual stick positions as they will be visible to the game. The actual DualShock 3's stick range is not circular but formed like a rounded square (or squircle) which represents the maximum range of the emulated sticks. The blue regular dots represent the raw stick values (including stick multipliers) before they are converted for ingame usage.");
const QString trigger_deadzones = tr("A trigger's deadzone determines how far the trigger has to be moved until it is recognized by the game. The resulting range will be projected onto the full input range in order to give you a smooth experience.");
const QString stick_lerp = tr("With keyboards you are inevitably restricted to 8 stick directions (4 straight + 4 diagonal). Furthermore when a key is pressed the stick will jump to the maximum value of the chosen direction immediately. The stick interpolation can be used to work-around both of these issues by smoothening out these directional changes. The lower the value, the longer you have to press or release a key until the maximum amplitude is reached.");
const QString mouse_deadzones = tr("The mouse deadzones represent the games' own deadzones on the x and y axes. Games usually enforce their own deadzones to filter out small unwanted stick movements. In consequence mouse input feels unintuitive since it relies on immediate responsiveness. You can change these values temporarily during gameplay in order to find out the optimal values for your game (Alt+T and Alt+Y for x, Alt+U and Alt+I for y).");
const QString mouse_acceleration = tr("The mouse acceleration can be used to amplify your mouse movements on the x and y axes. Increase these values if your mouse movements feel too slow while playing a game. You can change these values temporarily during gameplay in order to find out the optimal values (Alt+G and Alt+H for x, Alt+J and Alt+K for y). Keep in mind that modern mice usually provide different modes and settings that can be used to change mouse movement speeds as well.");

} gamepad_settings;
};