From 4629cdfffc16d81f938923b40634679a111b9747 Mon Sep 17 00:00:00 2001
From: Connor McLaughlin <stenzek@gmail.com>
Date: Sun, 22 Mar 2020 13:16:56 +1000
Subject: [PATCH] Qt: Add help text section to settings dialog

---
 src/duckstation-qt/settingsdialog.cpp | 45 +++++++++++++++++++++++++++
 src/duckstation-qt/settingsdialog.h   |  9 +++++-
 src/duckstation-qt/settingsdialog.ui  | 13 ++++++++
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/src/duckstation-qt/settingsdialog.cpp b/src/duckstation-qt/settingsdialog.cpp
index 4fc1f22f9..6a7205357 100644
--- a/src/duckstation-qt/settingsdialog.cpp
+++ b/src/duckstation-qt/settingsdialog.cpp
@@ -9,6 +9,8 @@
 #include "qthostinterface.h"
 #include <QtWidgets/QTextEdit>
 
+static constexpr char DEFAULT_SETTING_HELP_TEXT[] = "Mouse over an option for additional information.";
+
 SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent /* = nullptr */)
   : QDialog(parent), m_host_interface(host_interface)
 {
@@ -33,6 +35,8 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent
   m_ui.settingsCategory->setCurrentRow(0);
   m_ui.settingsContainer->setCurrentIndex(0);
   connect(m_ui.settingsCategory, &QListWidget::currentRowChanged, this, &SettingsDialog::onCategoryCurrentRowChanged);
+
+  m_ui.helpText->setText(tr(DEFAULT_SETTING_HELP_TEXT));
 }
 
 SettingsDialog::~SettingsDialog() = default;
@@ -49,3 +53,44 @@ void SettingsDialog::onCategoryCurrentRowChanged(int row)
 {
   m_ui.settingsContainer->setCurrentIndex(row);
 }
+
+void SettingsDialog::registerWidgetHelp(QObject* object, const char* title, const char* recommended_value,
+                                        const char* text)
+{
+  // construct rich text with formatted description
+  QString full_text;
+  full_text += "<table width='100%' cellpadding='0' cellspacing='0'><tr><td><strong>";
+  full_text += tr(title);
+  full_text += "</strong></td><td align='right'><strong>";
+  full_text += tr("Recommended Value");
+  full_text += ": </strong>";
+  full_text += recommended_value;
+  full_text += "</td></table><hr>";
+  full_text += text;
+
+  m_widget_help_text_map[object] = std::move(full_text);
+  object->installEventFilter(this);
+}
+
+bool SettingsDialog::eventFilter(QObject* object, QEvent* event)
+{
+  if (event->type() == QEvent::Enter)
+  {
+    auto iter = m_widget_help_text_map.constFind(object);
+    if (iter != m_widget_help_text_map.end())
+    {
+      m_current_help_widget = object;
+      m_ui.helpText->setText(iter.value());
+    }
+  }
+  else if (event->type() == QEvent::Leave)
+  {
+    if (m_current_help_widget)
+    {
+      m_current_help_widget = nullptr;
+      m_ui.helpText->setText(tr(DEFAULT_SETTING_HELP_TEXT));
+    }
+  }
+
+  return QDialog::eventFilter(object, event);
+}
\ No newline at end of file
diff --git a/src/duckstation-qt/settingsdialog.h b/src/duckstation-qt/settingsdialog.h
index 900ca154d..17c231b9f 100644
--- a/src/duckstation-qt/settingsdialog.h
+++ b/src/duckstation-qt/settingsdialog.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "ui_settingsdialog.h"
+#include <QtCore/QMap>
 #include <QtWidgets/QDialog>
 
 class QtHostInterface;
@@ -13,7 +14,7 @@ class PortSettingsWidget;
 class GPUSettingsWidget;
 class AudioSettingsWidget;
 
-class SettingsDialog : public QDialog
+class SettingsDialog final : public QDialog
 {
   Q_OBJECT
 
@@ -41,6 +42,9 @@ public:
   GPUSettingsWidget* getGPUSettingsWidget() const { return m_gpu_settings; }
   AudioSettingsWidget* getAudioSettingsWidget() const { return m_audio_settings; }
 
+  void registerWidgetHelp(QObject* object, const char* title, const char* recommended_value, const char* text);
+  bool eventFilter(QObject* object, QEvent* event) override;
+
 public Q_SLOTS:
   void setCategory(Category category);
 
@@ -59,4 +63,7 @@ private:
   PortSettingsWidget* m_port_settings = nullptr;
   GPUSettingsWidget* m_gpu_settings = nullptr;
   AudioSettingsWidget* m_audio_settings = nullptr;
+
+  QObject* m_current_help_widget = nullptr;
+  QMap<QObject*, QString> m_widget_help_text_map;
 };
diff --git a/src/duckstation-qt/settingsdialog.ui b/src/duckstation-qt/settingsdialog.ui
index 6ac1126f8..911e9b882 100644
--- a/src/duckstation-qt/settingsdialog.ui
+++ b/src/duckstation-qt/settingsdialog.ui
@@ -115,6 +115,19 @@
       </widget>
      </item>
      <item row="1" column="0" colspan="2">
+      <widget class="QTextEdit" name="helpText">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>16777215</width>
+         <height>80</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0" colspan="2">
       <widget class="QDialogButtonBox" name="buttonBox">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>