Skip to content

Commit

Permalink
preferences: add a macro to handle all preferences creation.
Browse files Browse the repository at this point in the history
All the preferences now require a description and are created
using function macros in order to parse and automatically detect all.

Signed-off-by: AlexandraTrifan <Alexandra.Trifan@analog.com>
  • Loading branch information
AlexandraTrifan committed Feb 4, 2025
1 parent b48df83 commit 9dde572
Show file tree
Hide file tree
Showing 12 changed files with 374 additions and 137 deletions.
139 changes: 103 additions & 36 deletions core/src/scopypreferencespage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,10 @@ QWidget *ScopyPreferencesPage::buildSaveSessionPreference()
QHBoxLayout *lay = new QHBoxLayout(w);
lay->setMargin(0);

lay->addWidget(
PreferencesHelper::addPreferenceCheckBox(p, "general_save_session", "Save/Load Scopy session", this));
lay->addWidget(PREFERENCE_CHECK_BOX(p, "general_save_session", "Save/Load Scopy session",
"Allow Scopy to automatically save/load the session "
"using .ini files into a predefined location.",
this));
lay->addSpacerItem(new QSpacerItem(40, 40, QSizePolicy::Expanding, QSizePolicy::Fixed));
lay->addWidget(new QLabel("Settings files location ", this));
QPushButton *navigateBtn = new QPushButton("Open", this);
Expand Down Expand Up @@ -242,41 +244,96 @@ QWidget *ScopyPreferencesPage::buildGeneralPreferencesPage()
lay->addWidget(generalWidget);
lay->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));

generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_save_attached", "Save/Load tool attached state", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_doubleclick_attach", "Doubleclick to attach/detach tool", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_doubleclick_ctrl_opens_menu", "Doubleclick control buttons to open menu", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_use_opengl", "Enable OpenGL plotting", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_use_animations", "Enable menu animations", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_check_online_version", "Enable automatic online check for updates.", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
generalSection->contentLayout()->addWidget(
PREFERENCE_CHECK_BOX(p, "general_save_attached", "Save/Load tool attached state",
"Allow Scopy to save the state of all instruments, whether they were "
"detached/attached when the application was closed, and load this "
"state accordingly when the application restarts.",
generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_CHECK_BOX(p, "general_doubleclick_attach", "Doubleclick to attach/detach tool",
"Indicates whether double-clicking attaches instruments in the application. "
"Enabling this option allows the user to quickly attach instruments by "
"double-clicking on them.",
generalSection));
generalSection->contentLayout()->addWidget(PREFERENCE_CHECK_BOX(
p, "general_doubleclick_ctrl_opens_menu", "Doubleclick control buttons to open menu",
"Enable the double click action for menu opening.", generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_CHECK_BOX(p, "general_use_opengl", "Enable OpenGL plotting",
"Use OpenGL accelerated plotting in order to speed-up the process and "
"avoid blocking the application while large numbers of samples are "
"displayed. This feature may not be supported on all systems.",
generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_CHECK_BOX(p, "general_use_animations", "Enable menu animations",
"Enable a smooth sliding transition effect for menus when they are "
"opened or closed.",
generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_CHECK_BOX(p, "general_check_online_version", "Enable automatic online check for updates.",
"Indicates whether the application should check for online version updates. "
"Enabling this option allows the application to automatically check for and "
"notify the user of available updates at startup.",
generalSection));
generalSection->contentLayout()->addWidget(PREFERENCE_CHECK_BOX(
p, "general_show_status_bar", "Enable the status bar for displaying important messages.",
"Indicates whether the status bar should be displayed in the application. This setting "
"allows the user to enable or disable the status bar, which provides information about "
"the current state of the application. "
"Important messages such as connection done or alerts are displayed here.",
generalSection));
generalSection->contentLayout()->addWidget(
PreferencesHelper::addPreferenceCheckBox(p, "show_grid", "Show Grid", generalSection));
PREFERENCE_CHECK_BOX(p, "show_grid", "Show Grid",
"Indicates whether the plot grid is visible across the application. "
"The user can enable or disable this in order to configure the ",
generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_CHECK_BOX(p, "show_graticule", "Show Graticule",
"This setting allows the user to enable or disable the display of the graticule "
"on all the plots in the application for better signal visualization.",
generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_CHECK_BOX(p, "iiowidgets_use_lazy_loading", "Use Lazy Loading",
"Indicates whether lazy loading should be used for IIO widgets. "
"Enabling this option allows the application to load IIO widgets only "
"when they are needed, improving startup performance.",
generalSection));
generalSection->contentLayout()->addWidget(
PreferencesHelper::addPreferenceCheckBox(p, "show_graticule", "Show Graticule", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "iiowidgets_use_lazy_loading", "Use Lazy Loading", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_use_native_dialogs", "Use native dialogs", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCombo(
p, "font_scale", "Font scale (EXPERIMENTAL)", {"1", "1.15", "1.3", "1.45", "1.6", "1.75", "1.9"},
PREFERENCE_CHECK_BOX(p, "general_use_native_dialogs", "Use native dialogs",
"Indicates whether native dialogs should be used in the application. "
"This setting allows the user to enable or disable the use of native file "
"dialogs and other system dialogs within the application.",
generalSection));

QStringList font_scale_options = {"1", "1.15", "1.3", "1.45", "1.6", "1.75", "1.9"};
generalSection->contentLayout()->addWidget(
PREFERENCE_COMBO(p, "font_scale", "Font scale (EXPERIMENTAL)",
"Scale factor for the font size used across the application, suitable for "
"different display settings.",
font_scale_options, generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_COMBO(p, "general_theme", "Theme",
"Theme setting for the application interface. "
"The user can choose between Harmonic style (light or dark) or Scopy style.",
Style::GetInstance()->getThemeList(), generalSection));
generalSection->contentLayout()->addWidget(
PREFERENCE_COMBO(p, "general_language", "Language",
"Language setting for the application interface. "
"Multiple options available, check out the documentation if a new language is needed.",
t->getLanguages(), generalSection));
generalSection->contentLayout()->addWidget(PREFERENCE_CHECK_BOX(
p, "general_connect_to_multiple_devices", "Connect to multiple devices (EXPERIMENTAL)",
"Allows the application to connect to multiple devices simultaneously, providing a mechanism "
"to handle them separately using different sections in the left side menu. "
"Due to not being tested using enough scenarios it is still marked as an experimental feature.",
generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCombo(
p, "general_theme", "Theme", Style::GetInstance()->getThemeList(), generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCombo(
p, "general_language", "Language", t->getLanguages(), generalSection));
generalSection->contentLayout()->addWidget(
PreferencesHelper::addPreferenceCheckBox(p, "general_connect_to_multiple_devices",
"Connect to multiple devices (EXPERIMENTAL)", generalSection));
generalSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCheckBox(
p, "general_scan_for_devices", "Regularly scan for new devices", generalSection));
PREFERENCE_CHECK_BOX(p, "general_scan_for_devices", "Regularly scan for new devices",
"Select whether Scopy should be able to search for new devices periodically, "
"allowing the application to automatically populate the device list with connected"
"devices. Otherwise, all devices need to be added manually from the Add page.",
generalSection));

// Auto-connect
m_autoConnectWidget = new MenuSectionCollapseWidget("Session ", MenuCollapseSection::MHCW_NONE,
Expand All @@ -287,8 +344,11 @@ QWidget *ScopyPreferencesPage::buildGeneralPreferencesPage()
lay->addWidget(m_autoConnectWidget);
lay->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));

QWidget *autoConnectCb = PreferencesHelper::addPreferenceCheckBox(
p, "autoconnect_previous", "Auto-connect to previous session", generalSection);
QWidget *autoConnectCb = PREFERENCE_CHECK_BOX(p, "autoconnect_previous", "Auto-connect to previous session",
"Automatically use the saved URI to connect to previous devices, "
"if available, when the application starts. This speeds up the "
"connection process and reduces the number of necessary steps.",
generalSection);
m_autoConnectWidget->contentLayout()->addWidget(autoConnectCb);

m_autoConnectWidget->contentLayout()->addWidget(buildSaveSessionPreference());
Expand Down Expand Up @@ -317,9 +377,16 @@ QWidget *ScopyPreferencesPage::buildGeneralPreferencesPage()
lay->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));

debugSection->contentLayout()->addWidget(
PreferencesHelper::addPreferenceCheckBox(p, "general_show_plot_fps", "Show plot FPS", debugSection));
debugSection->contentLayout()->addWidget(PreferencesHelper::addPreferenceCombo(
p, "general_plot_target_fps", "Plot target FPS", {"15", "20", "30", "60"}, debugSection));
PREFERENCE_CHECK_BOX(p, "general_show_plot_fps", "Show plot FPS",
"Indicates whether the frames per second should be displayed in plots "
"across the entire application.",
debugSection));

QStringList fps_options = {"15", "20", "30", "60"};
debugSection->contentLayout()->addWidget(
PREFERENCE_COMBO(p, "general_plot_target_fps", "Plot target FPS",
"Select the Frames per second value for rendering plots in the entire application.",
fps_options, debugSection));
debugSection->contentLayout()->addWidget(buildResetScopyDefaultButton());

return page;
Expand Down
24 changes: 19 additions & 5 deletions gui/include/gui/preferenceshelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@

#include <pluginbase/preferences.h>

#define PREFERENCE_CHECK_BOX(p, id, title, description, parent) \
PreferencesHelper::addPreferenceCheckBox(p, id, title, description, parent)

#define PREFERENCE_EDIT(p, id, title, description, parent) \
PreferencesHelper::addPreferenceEdit(p, id, title, description, parent)

#define PREFERENCE_COMBO(p, id, title, description, options, parent) \
PreferencesHelper::addPreferenceCombo(p, id, title, description, options, parent)

#define PREFERENCE_COMBO_LIST(p, id, title, description, options, parent) \
PreferencesHelper::addPreferenceComboList(p, id, title, description, options, parent)

namespace scopy {

class SmallOnOffSwitch;
Expand All @@ -40,13 +52,15 @@ class SCOPY_GUI_EXPORT PreferencesHelper
{

public:
static QWidget *addPreferenceCheckBox(Preferences *p, QString id, QString description,
static QWidget *addPreferenceCheckBox(Preferences *p, QString id, QString title, QString description,
QObject *parent = nullptr);
static QWidget *addPreferenceEdit(Preferences *p, QString id, QString description, QObject *parent = nullptr);
static QWidget *addPreferenceCombo(Preferences *p, QString id, QString description, QStringList options,
QObject *parent = nullptr);
static QWidget *addPreferenceComboList(Preferences *p, QString id, QString description,
static QWidget *addPreferenceEdit(Preferences *p, QString id, QString title, QString description,
QObject *parent = nullptr);
static QWidget *addPreferenceCombo(Preferences *p, QString id, QString title, QString description,
QStringList options, QObject *parent = nullptr);
static QWidget *addPreferenceComboList(Preferences *p, QString id, QString title, QString description,
QList<QPair<QString, QVariant>> options, QObject *parent);
static QWidget *setupDescriptionButton(QString id, QString description, QObject *parent);
};
} // namespace scopy
#endif // PREFERENCESHELPER_H
68 changes: 59 additions & 9 deletions gui/src/preferenceshelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,40 @@

#include <QHBoxLayout>
#include <QLabel>
#include <QObject>
#include <QApplication>
#include <smallOnOffSwitch.h>
#include <toolbuttons.h>
#include <popupwidget.h>
#include <style.h>

using namespace scopy;
QWidget *PreferencesHelper::addPreferenceCheckBox(Preferences *p, QString id, QString description, QObject *parent)

QWidget *PreferencesHelper::setupDescriptionButton(QString id, QString description, QObject *parent)
{
InfoBtn *infoBtn = new InfoBtn();
Style::setStyle(infoBtn, style::properties::button::squareIconButton, false);
Style::setStyle(infoBtn, style::properties::button::smallSquareIconButton);
Style::setStyle(infoBtn, style::properties::widget::basicBackground);

parent->connect(infoBtn, &InfoBtn::clicked, parent, [parent, id, description](bool b) {
QWidget *parentWidget = QApplication::activeWindow();
PopupWidget *popup = new PopupWidget(parentWidget);
popup->enableCenterOnParent(true);
popup->setTitle("ID: " + id);
popup->setDescription(description);
popup->getExitBtn()->hide();
popup->getContinueBtn()->hide();
popup->enableCloseButton(true);
popup->enableTintedOverlay(true);
popup->show();
popup->raise();
});
return infoBtn;
}

QWidget *PreferencesHelper::addPreferenceCheckBox(Preferences *p, QString id, QString title, QString description,
QObject *parent)
{
QWidget *widget = new QWidget();
QHBoxLayout *layout = new QHBoxLayout();
Expand All @@ -35,21 +65,27 @@ QWidget *PreferencesHelper::addPreferenceCheckBox(Preferences *p, QString id, QS
layout->setMargin(0);
widget->setLayout(layout);

QWidget *infoBtn = setupDescriptionButton(id, description, parent);

SmallOnOffSwitch *pref = new SmallOnOffSwitch();
pref->setChecked(p->get(id).toBool());
parent->connect(pref, &SmallOnOffSwitch::toggled, parent, [p, id](bool b) { p->set(id, b); });

p->initDescription(id, title, description);

QSpacerItem *space = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);

layout->addWidget(new QLabel(description, widget));
layout->addWidget(infoBtn);
layout->addWidget(new QLabel(title, widget));
layout->addSpacerItem(space);
layout->addWidget(pref);
widget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

return widget;
}

QWidget *PreferencesHelper::addPreferenceEdit(Preferences *p, QString id, QString description, QObject *parent)
QWidget *PreferencesHelper::addPreferenceEdit(Preferences *p, QString id, QString title, QString description,
QObject *parent)
{
QWidget *widget = new QWidget();
QHBoxLayout *layout = new QHBoxLayout();
Expand All @@ -58,22 +94,26 @@ QWidget *PreferencesHelper::addPreferenceEdit(Preferences *p, QString id, QStrin
layout->setMargin(0);
widget->setLayout(layout);

QWidget *infoBtn = setupDescriptionButton(id, description, parent);

QString pref1Val = p->get(id).toString();
QLineEdit *pref = new QLineEdit();
pref->setText(pref1Val);
parent->connect(pref, &QLineEdit::textChanged, parent, [p, id](QString b) { p->set(id, b); });

QLabel *label = new QLabel(description);
QLabel *label = new QLabel(title);
p->initDescription(id, title, description);

QSpacerItem *space = new QSpacerItem(20, 20, QSizePolicy::Preferred, QSizePolicy::Preferred);

layout->addWidget(infoBtn);
layout->addWidget(label, 1);
layout->addSpacerItem(space);
layout->addWidget(pref, 1);
return widget;
}

QWidget *PreferencesHelper::addPreferenceComboList(Preferences *p, QString id, QString description,
QWidget *PreferencesHelper::addPreferenceComboList(Preferences *p, QString id, QString title, QString description,
QList<QPair<QString, QVariant>> options, QObject *parent)
{
QWidget *w = new QWidget();
Expand All @@ -82,7 +122,11 @@ QWidget *PreferencesHelper::addPreferenceComboList(Preferences *p, QString id, Q
lay->setSpacing(0);
lay->setMargin(0);
w->setLayout(lay);
QLabel *lab = new QLabel(description);

QWidget *infoBtn = setupDescriptionButton(id, description, parent);

QLabel *lab = new QLabel(title);
p->initDescription(id, title, description);
QSpacerItem *space = new QSpacerItem(20, 20, QSizePolicy::Preferred, QSizePolicy::Preferred);
QString pref1Val;

Expand All @@ -95,6 +139,7 @@ QWidget *PreferencesHelper::addPreferenceComboList(Preferences *p, QString id, Q
}

pref->setCurrentText(pref1Val);
lay->addWidget(infoBtn);
lay->addWidget(lab, 1);
lay->addSpacerItem(space);
lay->addWidget(pref, 1);
Expand All @@ -106,20 +151,25 @@ QWidget *PreferencesHelper::addPreferenceComboList(Preferences *p, QString id, Q
return w;
}

QWidget *PreferencesHelper::addPreferenceCombo(Preferences *p, QString id, QString description, QStringList options,
QObject *parent)
QWidget *PreferencesHelper::addPreferenceCombo(Preferences *p, QString id, QString title, QString description,
QStringList options, QObject *parent)
{
QWidget *w = new QWidget();
QHBoxLayout *lay = new QHBoxLayout();
lay->setSpacing(0);
lay->setMargin(0);

QWidget *infoBtn = setupDescriptionButton(id, description, parent);

w->setLayout(lay);
QLabel *lab = new QLabel(description);
QLabel *lab = new QLabel(title);
p->initDescription(id, title, description);
QSpacerItem *space = new QSpacerItem(20, 20, QSizePolicy::Preferred, QSizePolicy::Preferred);
QString pref1Val = p->get(id).toString();
QComboBox *pref = new QComboBox();
pref->addItems(options);
pref->setCurrentText(pref1Val);
lay->addWidget(infoBtn);
lay->addWidget(lab, 1);
lay->addSpacerItem(space);
lay->addWidget(pref, 1);
Expand Down
13 changes: 13 additions & 0 deletions pluginbase/include/pluginbase/preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ class SCOPY_PLUGINBASE_EXPORT Preferences : public QObject
*/
static void init(QString, QVariant);
void _init(QString, QVariant);

/**
* @brief initDescription
* Initialize a map with title and description for each preference
* to be later used in docs and hover widgets in the Scopy prefs page.
* @param k
* @param title
* @param description
*/
void initDescription(QString k, QString title, QString description);
void _initDescription(QString k, QString title, QString description);

/**
* @brief clear
* clears preferences table
Expand Down Expand Up @@ -109,6 +121,7 @@ public Q_SLOTS:

private:
QMap<QString, QVariant> p;
QMap<QString, QVector<QString>> pDescriptions;
QSettings *s;
static Preferences *pinstance_;
};
Expand Down
Loading

0 comments on commit 9dde572

Please sign in to comment.