properties-view.hpp 6.5 KB

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