properties-view.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #pragma once
  2. #include "vertical-scroll-area.hpp"
  3. #include <obs-data.h>
  4. #include <obs.hpp>
  5. #include <qtimer.h>
  6. #include <QPointer>
  7. #include <vector>
  8. #include <memory>
  9. class QFormLayout;
  10. class OBSPropertiesView;
  11. class QLabel;
  12. typedef obs_properties_t *(*PropertiesReloadCallback)(void *obj);
  13. typedef void (*PropertiesUpdateCallback)(void *obj, obs_data_t *old_settings,
  14. obs_data_t *new_settings);
  15. typedef void (*PropertiesVisualUpdateCb)(void *obj, obs_data_t *settings);
  16. /* ------------------------------------------------------------------------- */
  17. class WidgetInfo : public QObject {
  18. Q_OBJECT
  19. friend class OBSPropertiesView;
  20. private:
  21. OBSPropertiesView *view;
  22. obs_property_t *property;
  23. QWidget *widget;
  24. QPointer<QTimer> update_timer;
  25. bool recently_updated = false;
  26. OBSData old_settings_cache;
  27. void BoolChanged(const char *setting);
  28. void IntChanged(const char *setting);
  29. void FloatChanged(const char *setting);
  30. void TextChanged(const char *setting);
  31. bool PathChanged(const char *setting);
  32. void ListChanged(const char *setting);
  33. bool ColorChangedInternal(const char *setting, bool supportAlpha);
  34. bool ColorChanged(const char *setting);
  35. bool ColorAlphaChanged(const char *setting);
  36. bool FontChanged(const char *setting);
  37. void GroupChanged(const char *setting);
  38. void EditableListChanged();
  39. void ButtonClicked();
  40. void TogglePasswordText(bool checked);
  41. public:
  42. inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
  43. QWidget *widget_)
  44. : view(view_),
  45. property(prop),
  46. widget(widget_)
  47. {
  48. }
  49. ~WidgetInfo()
  50. {
  51. if (update_timer) {
  52. update_timer->stop();
  53. QMetaObject::invokeMethod(update_timer, "timeout");
  54. update_timer->deleteLater();
  55. }
  56. }
  57. public slots:
  58. void ControlChanged();
  59. /* editable list */
  60. void EditListAdd();
  61. void EditListAddText();
  62. void EditListAddFiles();
  63. void EditListAddDir();
  64. void EditListRemove();
  65. void EditListEdit();
  66. void EditListUp();
  67. void EditListDown();
  68. };
  69. /* ------------------------------------------------------------------------- */
  70. class OBSPropertiesView : public VScrollArea {
  71. Q_OBJECT
  72. friend class WidgetInfo;
  73. using properties_delete_t = decltype(&obs_properties_destroy);
  74. using properties_t =
  75. std::unique_ptr<obs_properties_t, properties_delete_t>;
  76. private:
  77. QWidget *widget = nullptr;
  78. properties_t properties;
  79. OBSData settings;
  80. OBSWeakObjectAutoRelease weakObj;
  81. void *rawObj = nullptr;
  82. std::string type;
  83. PropertiesReloadCallback reloadCallback;
  84. PropertiesUpdateCallback callback = nullptr;
  85. PropertiesVisualUpdateCb visUpdateCb = nullptr;
  86. int minSize;
  87. std::vector<std::unique_ptr<WidgetInfo>> children;
  88. std::string lastFocused;
  89. QWidget *lastWidget = nullptr;
  90. bool deferUpdate;
  91. template<typename Sender, typename SenderParent, typename... Args>
  92. QWidget *NewWidget(obs_property_t *prop, Sender *widget,
  93. void (SenderParent::*signal)(Args...));
  94. QWidget *AddCheckbox(obs_property_t *prop);
  95. QWidget *AddText(obs_property_t *prop, QFormLayout *layout,
  96. QLabel *&label);
  97. void AddPath(obs_property_t *prop, QFormLayout *layout, QLabel **label);
  98. void AddInt(obs_property_t *prop, QFormLayout *layout, QLabel **label);
  99. void AddFloat(obs_property_t *prop, QFormLayout *layout,
  100. QLabel **label);
  101. QWidget *AddList(obs_property_t *prop, bool &warning);
  102. void AddEditableList(obs_property_t *prop, QFormLayout *layout,
  103. QLabel *&label);
  104. QWidget *AddButton(obs_property_t *prop);
  105. void AddColorInternal(obs_property_t *prop, QFormLayout *layout,
  106. QLabel *&label, bool supportAlpha);
  107. void AddColor(obs_property_t *prop, QFormLayout *layout,
  108. QLabel *&label);
  109. void AddColorAlpha(obs_property_t *prop, QFormLayout *layout,
  110. QLabel *&label);
  111. void AddFont(obs_property_t *prop, QFormLayout *layout, QLabel *&label);
  112. void AddFrameRate(obs_property_t *prop, bool &warning,
  113. QFormLayout *layout, QLabel *&label);
  114. void AddGroup(obs_property_t *prop, QFormLayout *layout);
  115. void AddProperty(obs_property_t *property, QFormLayout *layout);
  116. void resizeEvent(QResizeEvent *event) override;
  117. void GetScrollPos(int &h, int &v, int &hend, int &vend);
  118. void SetScrollPos(int h, int v, int old_hend, int old_vend);
  119. private slots:
  120. void RefreshProperties();
  121. public slots:
  122. void ReloadProperties();
  123. void SignalChanged();
  124. signals:
  125. void PropertiesResized();
  126. void Changed();
  127. void PropertiesRefreshed();
  128. public:
  129. OBSPropertiesView(OBSData settings, obs_object_t *obj,
  130. PropertiesReloadCallback reloadCallback,
  131. PropertiesUpdateCallback callback,
  132. PropertiesVisualUpdateCb cb = nullptr,
  133. int minSize = 0);
  134. OBSPropertiesView(OBSData settings, void *obj,
  135. PropertiesReloadCallback reloadCallback,
  136. PropertiesUpdateCallback callback,
  137. PropertiesVisualUpdateCb cb = nullptr,
  138. int minSize = 0);
  139. OBSPropertiesView(OBSData settings, const char *type,
  140. PropertiesReloadCallback reloadCallback,
  141. int minSize = 0);
  142. #define obj_constructor(type) \
  143. inline OBSPropertiesView(OBSData settings, obs_##type##_t *type, \
  144. PropertiesReloadCallback reloadCallback, \
  145. PropertiesUpdateCallback callback, \
  146. PropertiesVisualUpdateCb cb = nullptr, \
  147. int minSize = 0) \
  148. : OBSPropertiesView(settings, (obs_object_t *)type, \
  149. reloadCallback, callback, cb, minSize) \
  150. { \
  151. }
  152. obj_constructor(source);
  153. obj_constructor(output);
  154. obj_constructor(encoder);
  155. obj_constructor(service);
  156. #undef obj_constructor
  157. inline obs_data_t *GetSettings() const { return settings; }
  158. inline void UpdateSettings()
  159. {
  160. if (callback)
  161. callback(OBSGetStrongRef(weakObj), nullptr, settings);
  162. else if (visUpdateCb)
  163. visUpdateCb(OBSGetStrongRef(weakObj), settings);
  164. }
  165. inline bool DeferUpdate() const { return deferUpdate; }
  166. inline OBSObject GetObject() const { return OBSGetStrongRef(weakObj); }
  167. #define Def_IsObject(type) \
  168. inline bool IsObject(obs_##type##_t *type) const \
  169. { \
  170. OBSObject obj = OBSGetStrongRef(weakObj); \
  171. return obj.Get() == (obs_object_t *)type; \
  172. }
  173. /* clang-format off */
  174. Def_IsObject(source)
  175. Def_IsObject(output)
  176. Def_IsObject(encoder)
  177. Def_IsObject(service)
  178. /* clang-format on */
  179. #undef Def_IsObject
  180. };