1 #ifndef SETTINGSWIDGETS_H
2 #define SETTINGSWIDGETS_H
3 
4 #include <QCheckBox>
5 #include <QComboBox>
6 #include <QLineEdit>
7 #include <QSpinBox>
8 #include <QSlider>
9 #include <QGroupBox>
10 #include <QToolButton>
11 #include <QPushButton>
12 #include <QRadioButton>
13 #include <QHBoxLayout>
14 #include <QFormLayout>
15 #include <QPainter>
16 #include <QColorDialog>
17 
18 #ifndef CXX_BUILD
19 extern "C" {
20 #endif
21 
22 #include "../../../configuration.h"
23 #include "../../../setting_list.h"
24 #include "../../../menu/menu_setting.h"
25 #include "../../../menu/menu_cbs.h"
26 
27 #ifndef CXX_BUILD
28 }
29 #endif
30 
31 class FormLayout : public QFormLayout
32 {
33 public:
34    FormLayout(QWidget *parent = 0);
35    void addSizeSpinBox(rarch_setting_t *setting, unsigned scale = 1024 * 1024);
36    void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b);
37    void addUIntSpinBox(rarch_setting_t *setting);
38    void addFloatSpinBox(rarch_setting_t *setting);
39    void addCheckBox(rarch_setting_t *setting);
40    void addUIntComboBox(rarch_setting_t *setting);
41    bool addBindButton(rarch_setting_t *setting);
42    void addFileSelector(rarch_setting_t *setting);
43    void addDirectorySelector(rarch_setting_t *setting);
44    void addFloatSliderAndSpinBox(rarch_setting_t *setting);
45    void addUIntRadioButtons(rarch_setting_t *setting);
46    void addStringComboBox(rarch_setting_t *setting);
47    void addStringLineEdit(rarch_setting_t *setting);
48    void addPasswordLineEdit(rarch_setting_t *setting);
49 
add(rarch_setting_t * setting)50    bool add(rarch_setting_t *setting)
51    {
52       enum ui_setting_type ui_type = ST_UI_TYPE_NONE;
53 
54       if (!setting)
55          return false;
56 
57       ui_type = setting->ui_type;
58 
59       switch (ui_type)
60       {
61          case ST_UI_TYPE_CHECKBOX:
62             this->addCheckBox(setting);
63             break;
64          case ST_UI_TYPE_UINT_COLOR_BUTTON:
65             /* TODO/FIXME */
66             break;
67          case ST_UI_TYPE_UINT_SPINBOX:
68             this->addUIntSpinBox(setting);
69             break;
70          case ST_UI_TYPE_UINT_COMBOBOX:
71             this->addUIntComboBox(setting);
72             break;
73          case ST_UI_TYPE_UINT_RADIO_BUTTONS:
74             this->addUIntRadioButtons(setting);
75             break;
76          case ST_UI_TYPE_FLOAT_COLOR_BUTTON:
77             /* TODO/FIXME */
78             break;
79          case ST_UI_TYPE_FLOAT_SPINBOX:
80             this->addFloatSpinBox(setting);
81             break;
82          case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX:
83             this->addFloatSliderAndSpinBox(setting);
84             break;
85          case ST_UI_TYPE_SIZE_SPINBOX:
86             this->addSizeSpinBox(setting);
87             break;
88          case ST_UI_TYPE_BIND_BUTTON:
89             return this->addBindButton(setting);
90          case ST_UI_TYPE_DIRECTORY_SELECTOR:
91             this->addDirectorySelector(setting);
92             break;
93          case ST_UI_TYPE_FILE_SELECTOR:
94             this->addFileSelector(setting);
95             break;
96          case ST_UI_TYPE_STRING_COMBOBOX:
97             this->addStringComboBox(setting);
98             break;
99          case ST_UI_TYPE_STRING_LINE_EDIT:
100             this->addStringLineEdit(setting);
101             break;
102          case ST_UI_TYPE_PASSWORD_LINE_EDIT:
103             this->addPasswordLineEdit(setting);
104             break;
105          case ST_UI_TYPE_NONE:
106          default:
107             break;
108       }
109 
110       return true;
111    }
112 
add(msg_hash_enums enum_idx)113    bool add(msg_hash_enums enum_idx)
114    {
115       rarch_setting_t *setting     = menu_setting_find_enum(enum_idx);
116       return add(setting);
117    }
118 };
119 
120 class SettingsGroup : public QGroupBox
121 {
122    Q_OBJECT
123 public:
124    SettingsGroup(const QString &title, QWidget *parent = 0);
125    SettingsGroup(QWidget *parent = 0);
126    void addWidget(QWidget *widget);
127    void addRow(QString label, QWidget *widget);
128    void addRow(QWidget *widget);
129    void addRow(QLayout *layout);
130    void addRow(QString label, QLayout *layout);
131    void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b);
132 
add(rarch_setting_t * setting)133    bool add(rarch_setting_t *setting)
134    {
135       enum ui_setting_type ui_type = ST_UI_TYPE_NONE;
136 
137       if (!setting)
138          return false;
139 
140       ui_type = setting->ui_type;
141 
142       switch (ui_type)
143       {
144          case ST_UI_TYPE_CHECKBOX:
145             this->addCheckBox(setting);
146             break;
147          case ST_UI_TYPE_UINT_COLOR_BUTTON:
148             /* TODO/FIXME */
149             break;
150          case ST_UI_TYPE_UINT_SPINBOX:
151             this->addUIntSpinBox(setting);
152             break;
153          case ST_UI_TYPE_UINT_COMBOBOX:
154             this->addUIntComboBox(setting);
155             break;
156          case ST_UI_TYPE_UINT_RADIO_BUTTONS:
157             this->addUIntRadioButtons(setting);
158             break;
159          case ST_UI_TYPE_FLOAT_COLOR_BUTTON:
160             /* TODO/FIXME */
161             break;
162          case ST_UI_TYPE_FLOAT_SPINBOX:
163             this->addFloatSpinBox(setting);
164             break;
165          case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX:
166             this->addFloatSliderAndSpinBox(setting);
167             break;
168          case ST_UI_TYPE_SIZE_SPINBOX:
169             /* TODO/FIXME */
170             break;
171          case ST_UI_TYPE_BIND_BUTTON:
172             /* TODO/FIXME - Why is the returntype void here and bool
173              * for Layout? */
174             this->addBindButton(setting);
175             break;
176          case ST_UI_TYPE_DIRECTORY_SELECTOR:
177             this->addDirectorySelector(setting);
178             break;
179          case ST_UI_TYPE_FILE_SELECTOR:
180             this->addFileSelector(setting);
181             break;
182          case ST_UI_TYPE_STRING_COMBOBOX:
183             this->addStringComboBox(setting);
184             break;
185          case ST_UI_TYPE_STRING_LINE_EDIT:
186             this->addStringLineEdit(setting);
187             break;
188          case ST_UI_TYPE_PASSWORD_LINE_EDIT:
189             this->addPasswordLineEdit(setting);
190             break;
191          case ST_UI_TYPE_NONE:
192          default:
193             break;
194       }
195 
196       return true;
197    }
198 
add(msg_hash_enums enum_idx)199    bool add(msg_hash_enums enum_idx)
200    {
201       rarch_setting_t *setting     = menu_setting_find_enum(enum_idx);
202       return add(setting);
203    }
204 private:
205    void addBindButton(rarch_setting_t *setting);
206    void addCheckBox(rarch_setting_t *setting);
207    void addUIntSpinBox(rarch_setting_t *setting);
208    void addUIntComboBox(rarch_setting_t *setting);
209    void addFloatSpinBox(rarch_setting_t *setting);
210    void addFileSelector(rarch_setting_t *setting);
211    void addDirectorySelector(rarch_setting_t *setting);
212    void addFloatSliderAndSpinBox(rarch_setting_t *setting);
213    void addUIntRadioButtons(rarch_setting_t *setting);
214    void addStringComboBox(rarch_setting_t *setting);
215    void addStringLineEdit(rarch_setting_t *setting);
216    void addPasswordLineEdit(rarch_setting_t *setting);
217    FormLayout *m_layout;
218 };
219 
220 class CheckableSettingsGroup : public SettingsGroup
221 {
222    Q_OBJECT
223 public:
224    CheckableSettingsGroup(rarch_setting_t *setting, QWidget *parent = 0);
225    CheckableSettingsGroup(const char *setting, QWidget *parent = 0);
226    CheckableSettingsGroup(msg_hash_enums enum_idx, QWidget *parent = 0);
227 private slots:
228    void onClicked(bool clicked);
229    void paintEvent(QPaintEvent *event);
230 private:
231    rarch_setting_t *m_setting;
232    bool *m_value;
233 };
234 
235 class CheckBox : public QCheckBox
236 {
237    Q_OBJECT
238 public:
239    CheckBox(rarch_setting_t *setting, QWidget *parent = 0);
240    CheckBox(const char *setting, QWidget *parent = 0);
241    CheckBox(msg_hash_enums enum_idx, QWidget *parent = 0);
242 private slots:
243    void onClicked(bool checked);
244    void paintEvent(QPaintEvent *event);
245 private:
246    rarch_setting_t *m_setting;
247    bool *m_value;
248 };
249 
250 class CheckableIcon : public QToolButton
251 {
252    Q_OBJECT
253 public:
254    CheckableIcon(rarch_setting_t *setting, const QIcon &icon, QWidget *parent = 0);
255    CheckableIcon(const char *setting, const QIcon &icon, QWidget *parent = 0);
256    CheckableIcon(msg_hash_enums enum_idx, const QIcon &icon, QWidget *parent = 0);
257 private slots:
258    void onToggled(bool checked);
259    void paintEvent(QPaintEvent *event);
260 private:
261    rarch_setting_t *m_setting;
262    bool *m_value;
263 };
264 
265 class StringLineEdit : public QLineEdit
266 {
267    Q_OBJECT
268 public:
269    StringLineEdit(rarch_setting_t *setting, QWidget *parent = 0);
270    StringLineEdit(const char *setting, QWidget *parent = 0);
271 private slots:
272    void onEditingFinished();
273    void paintEvent(QPaintEvent *event);
274 private:
275    rarch_setting_t *m_setting;
276    char *m_value;
277 };
278 
279 class PasswordLineEdit : public StringLineEdit
280 {
281    Q_OBJECT
282 public:
283    PasswordLineEdit(rarch_setting_t *setting, QWidget *parent = 0);
284 };
285 
286 class StringComboBox : public QComboBox
287 {
288    Q_OBJECT
289 public:
290    StringComboBox(rarch_setting_t *setting, QWidget *parent = 0);
291    StringComboBox(const char *setting, QWidget *parent = 0);
292 private slots:
293    void onCurrentTextChanged(const QString &text);
294    void paintEvent(QPaintEvent *event);
295 private:
296    rarch_setting_t *m_setting;
297    char *m_value;
298 };
299 
300 class UIntComboBox : public QComboBox
301 {
302    Q_OBJECT
303 public:
304    UIntComboBox(rarch_setting_t *setting, QWidget *parent = 0);
305    UIntComboBox(rarch_setting_t *setting, double min, double max, QWidget *parent = 0);
306    UIntComboBox(msg_hash_enums enum_idx, QWidget *parent = 0);
307    UIntComboBox(msg_hash_enums enum_idx, double min, double max, QWidget *parent = 0);
308    UIntComboBox(const char *setting, QWidget *parent = 0);
309 private slots:
310    void onCurrentIndexChanged(int index);
311    void paintEvent(QPaintEvent *event);
312 private:
313    void populate(double min, double max);
314    rarch_setting_t *m_setting;
315    unsigned *m_value;
316    QHash<unsigned, QString> m_hash;
317 };
318 
319 class UIntRadioButton : public QRadioButton
320 {
321    Q_OBJECT
322 public:
323    UIntRadioButton(const QString &text, rarch_setting_t *setting, unsigned value, QWidget *parent = 0);
324    UIntRadioButton(msg_hash_enums enum_idx, unsigned value, QWidget *parent = 0);
325 private slots:
326    void onClicked(bool);
327    void paintEvent(QPaintEvent *event);
328 private:
329    rarch_setting_t *m_setting;
330    unsigned *m_target;
331    unsigned m_value;
332 };
333 
334 class UIntRadioButtons : public QGroupBox
335 {
336    Q_OBJECT
337 public:
338    UIntRadioButtons(rarch_setting_t *setting, QWidget *parent = 0);
339    UIntRadioButtons(const char *setting, QWidget *parent = 0);
340    UIntRadioButtons(msg_hash_enums enum_idx, QWidget *parent = 0);
341 signals:
342    void currentUIntChanged(unsigned value);
343 private slots:
344    void onButtonClicked(int id);
345 private:
346    rarch_setting_t *m_setting;
347    unsigned *m_value;
348    QButtonGroup *m_buttonGroup;
349 };
350 
351 class UIntSpinBox : public QSpinBox
352 {
353    Q_OBJECT
354 public:
355    UIntSpinBox(rarch_setting_t *setting, QWidget *parent = 0);
356    UIntSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0);
357 private slots:
358    void onValueChanged(int value);
359    void paintEvent(QPaintEvent *event);
360 private:
361    rarch_setting_t *m_setting;
362    unsigned *m_value;
363 };
364 
365 class SizeSpinBox : public QSpinBox
366 {
367    Q_OBJECT
368 public:
369    SizeSpinBox(rarch_setting_t *setting, unsigned scale = 1024*1024, QWidget *parent = 0);
370    SizeSpinBox(msg_hash_enums enum_idx, unsigned scale = 1024 * 1024, QWidget *parent = 0);
371 private slots:
372    void onValueChanged(int value);
373    void paintEvent(QPaintEvent *event);
374 private:
375    rarch_setting_t *m_setting;
376    size_t *m_value;
377    unsigned m_scale;
378 };
379 
380 class IntSpinBox : public QSpinBox
381 {
382    Q_OBJECT
383 public:
384    IntSpinBox(rarch_setting_t *setting, QWidget *parent = 0);
385 private slots:
386    void onValueChanged(int value);
387    void paintEvent(QPaintEvent *event);
388 private:
389    rarch_setting_t *m_setting;
390    int *m_value;
391 };
392 
393 class FloatSpinBox : public QDoubleSpinBox
394 {
395    Q_OBJECT
396 public:
397    FloatSpinBox(rarch_setting_t *setting, QWidget *parent = 0);
398    FloatSpinBox(const char *setting, QWidget *parent = 0);
399    FloatSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0);
400 private slots:
401    void onValueChanged(double value);
402    void paintEvent(QPaintEvent *event);
403 private:
404    rarch_setting_t *m_setting;
405    float *m_value;
406    static const QRegularExpression DECIMALS_REGEX;
407 };
408 
409 class PathButton : public QPushButton
410 {
411    Q_OBJECT
412 public:
413    PathButton(rarch_setting_t *setting, QWidget *parent = 0);
414    PathButton(const char *setting, QWidget *parent = 0);
415 signals:
416    void changed();
417 protected slots:
418    virtual void onClicked(bool checked = false) { Q_UNUSED( checked); }
419 protected:
420    QString m_filter;
421    rarch_setting_t *m_setting;
422    char *m_value;
423    const char *m_dir;
424    QString currentPath();
425 };
426 
427 class DirectoryButton : public PathButton
428 {
429    Q_OBJECT
430 public:
431    DirectoryButton(rarch_setting_t *setting, QWidget *parent = 0) :
PathButton(setting,parent)432       PathButton(setting, parent) {}
433 private:
434    void onClicked(bool checked = false);
435 };
436 
437 class FileButton : public PathButton
438 {
439    Q_OBJECT
440 public:
441    FileButton(rarch_setting_t *setting, QWidget *parent = 0) :
PathButton(setting,parent)442       PathButton(setting, parent) {}
443 private:
444    void onClicked(bool checked = false);
445 };
446 
447 class DirectorySelector : public QHBoxLayout
448 {
449    Q_OBJECT
450 public:
451    DirectorySelector(rarch_setting_t *setting, QWidget *parent = 0);
452 private:
453    StringLineEdit *m_lineEdit;
454    DirectoryButton *m_button;
455 };
456 
457 class FileSelector : public QHBoxLayout
458 {
459    Q_OBJECT
460 public:
461    FileSelector(rarch_setting_t *setting, QWidget *parent = 0);
462    FileSelector(const char *setting, QWidget *parent = 0);
463 private:
464    StringLineEdit *m_lineEdit;
465    FileButton *m_button;
466 };
467 
468 class FloatSlider : public QSlider
469 {
470    Q_OBJECT
471 public:
472    FloatSlider(rarch_setting_t *setting, QWidget *parent = 0);
473    FloatSlider(const char *setting, QWidget *parent = 0);
474 private slots:
475    void onValueChanged(int value);
476    void paintEvent(QPaintEvent *event);
477 private:
478    rarch_setting_t *m_setting;
479    float *m_value;
480    QRegularExpression m_decimalsRegEx;
481    unsigned int m_precision;
482 };
483 
484 class FloatSliderAndSpinBox : public QHBoxLayout
485 {
486    Q_OBJECT
487 public:
488    FloatSliderAndSpinBox(rarch_setting_t *setting, QWidget *parent = 0);
489    FloatSliderAndSpinBox(const char *setting, QWidget *parent = 0);
490    FloatSliderAndSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0);
491 private slots:
492    void onSliderValueChanged(int value);
493    void onSpinBoxValueChanged(double value);
494 private:
495    FloatSlider *m_slider;
496    FloatSpinBox *m_spinBox;
497 };
498 
499 class BindButton : public QPushButton
500 {
501    Q_OBJECT
502 public:
503    BindButton(rarch_setting_t *setting, QWidget *parent = 0);
504    BindButton(msg_hash_enums enum_idx, QWidget *parent = 0);
505 private slots:
506    void onClicked(bool checked);
507 private:
508    rarch_setting_t *m_setting;
509 };
510 
511 class ColorButton : public QToolButton
512 {
513    Q_OBJECT
514 public:
515    ColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent = 0);
516    ColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0);
517 protected slots:
onColorChanged(const QColor & color)518    virtual void onColorChanged(const QColor& color) { Q_UNUSED(color); }
519 protected:
color()520    virtual QColor color() { return QColor(); }
521    void paintEvent(QPaintEvent *event);
522 
523    rarch_setting_t *m_red, *m_green, *m_blue;
524    QColorDialog *m_dialog;
525 };
526 
527 class UIntColorButton : public ColorButton
528 {
529    Q_OBJECT
530 public:
531    UIntColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0);
532    UIntColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent = 0);
533 protected slots:
534    void onColorChanged(const QColor& color);
535 protected:
536    QColor color();
537 };
538 
539 class FloatColorButton : public ColorButton
540 {
541    Q_OBJECT
542 public:
543    explicit FloatColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0);
544 protected slots:
545    void onColorChanged(const QColor& color);
546 protected:
547    QColor color();
548 };
549 
550 #endif
551