visibility-item-widget.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include "visibility-item-widget.hpp"
  2. #include "visibility-checkbox.hpp"
  3. #include "qt-wrappers.hpp"
  4. #include "obs-app.hpp"
  5. #include <QListWidget>
  6. #include <QLineEdit>
  7. #include <QHBoxLayout>
  8. #include <QMessageBox>
  9. #include <QLabel>
  10. VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
  11. : source (source_),
  12. enabledSignal (obs_source_get_signal_handler(source), "enable",
  13. OBSSourceEnabled, this),
  14. renamedSignal (obs_source_get_signal_handler(source), "rename",
  15. OBSSourceRenamed, this)
  16. {
  17. const char *name = obs_source_get_name(source);
  18. bool enabled = obs_source_enabled(source);
  19. vis = new VisibilityCheckBox();
  20. vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
  21. /* Fix for non-apple systems where the spacing would be too big */
  22. #ifndef __APPLE__
  23. vis->setMaximumSize(16, 16);
  24. #endif
  25. vis->setChecked(enabled);
  26. label = new QLabel(QT_UTF8(name));
  27. label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
  28. QHBoxLayout *itemLayout = new QHBoxLayout();
  29. itemLayout->addWidget(vis);
  30. itemLayout->addWidget(label);
  31. itemLayout->setContentsMargins(5, 2, 5, 2);
  32. setLayout(itemLayout);
  33. setStyleSheet("background-color: rgba(255, 255, 255, 0);");
  34. connect(vis, SIGNAL(clicked(bool)),
  35. this, SLOT(VisibilityClicked(bool)));
  36. }
  37. VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
  38. : item (item_),
  39. source (obs_sceneitem_get_source(item)),
  40. renamedSignal (obs_source_get_signal_handler(source), "rename",
  41. OBSSourceRenamed, this)
  42. {
  43. const char *name = obs_source_get_name(source);
  44. bool enabled = obs_sceneitem_visible(item);
  45. obs_scene_t *scene = obs_sceneitem_get_scene(item);
  46. obs_source_t *sceneSource = obs_scene_get_source(scene);
  47. vis = new VisibilityCheckBox();
  48. vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
  49. /* Fix for non-apple systems where the spacing would be too big */
  50. #ifndef __APPLE__
  51. vis->setMaximumSize(16, 16);
  52. #endif
  53. vis->setChecked(enabled);
  54. label = new QLabel(QT_UTF8(name));
  55. label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
  56. QHBoxLayout *itemLayout = new QHBoxLayout();
  57. itemLayout->addWidget(vis);
  58. itemLayout->addWidget(label);
  59. itemLayout->setContentsMargins(5, 2, 5, 2);
  60. setLayout(itemLayout);
  61. setStyleSheet("background-color: rgba(255, 255, 255, 0);");
  62. signal_handler_t *signal = obs_source_get_signal_handler(sceneSource);
  63. signal_handler_connect(signal, "remove", OBSSceneRemove, this);
  64. signal_handler_connect(signal, "item_remove", OBSSceneItemRemove,
  65. this);
  66. signal_handler_connect(signal, "item_visible", OBSSceneItemVisible,
  67. this);
  68. connect(vis, SIGNAL(clicked(bool)),
  69. this, SLOT(VisibilityClicked(bool)));
  70. }
  71. VisibilityItemWidget::~VisibilityItemWidget()
  72. {
  73. DisconnectItemSignals();
  74. }
  75. void VisibilityItemWidget::DisconnectItemSignals()
  76. {
  77. if (!item || sceneRemoved)
  78. return;
  79. obs_scene_t *scene = obs_sceneitem_get_scene(item);
  80. obs_source_t *sceneSource = obs_scene_get_source(scene);
  81. signal_handler_t *signal = obs_source_get_signal_handler(sceneSource);
  82. signal_handler_disconnect(signal, "remove", OBSSceneRemove, this);
  83. signal_handler_disconnect(signal, "item_remove", OBSSceneItemRemove,
  84. this);
  85. signal_handler_disconnect(signal, "item_visible", OBSSceneItemVisible,
  86. this);
  87. sceneRemoved = true;
  88. }
  89. void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data)
  90. {
  91. VisibilityItemWidget *window =
  92. reinterpret_cast<VisibilityItemWidget*>(param);
  93. window->DisconnectItemSignals();
  94. UNUSED_PARAMETER(data);
  95. }
  96. void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data)
  97. {
  98. VisibilityItemWidget *window =
  99. reinterpret_cast<VisibilityItemWidget*>(param);
  100. obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(data, "item");
  101. if (item == window->item)
  102. window->DisconnectItemSignals();
  103. }
  104. void VisibilityItemWidget::OBSSceneItemVisible(void *param, calldata_t *data)
  105. {
  106. VisibilityItemWidget *window =
  107. reinterpret_cast<VisibilityItemWidget*>(param);
  108. obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
  109. bool enabled = calldata_bool(data, "visible");
  110. if (window->item == curItem)
  111. QMetaObject::invokeMethod(window, "SourceEnabled",
  112. Q_ARG(bool, enabled));
  113. }
  114. void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data)
  115. {
  116. VisibilityItemWidget *window =
  117. reinterpret_cast<VisibilityItemWidget*>(param);
  118. bool enabled = calldata_bool(data, "enabled");
  119. QMetaObject::invokeMethod(window, "SourceEnabled",
  120. Q_ARG(bool, enabled));
  121. }
  122. void VisibilityItemWidget::OBSSourceRenamed(void *param, calldata_t *data)
  123. {
  124. VisibilityItemWidget *window =
  125. reinterpret_cast<VisibilityItemWidget*>(param);
  126. const char *name = calldata_string(data, "new_name");
  127. QMetaObject::invokeMethod(window, "SourceRenamed",
  128. Q_ARG(QString, QT_UTF8(name)));
  129. }
  130. void VisibilityItemWidget::VisibilityClicked(bool visible)
  131. {
  132. if (item)
  133. obs_sceneitem_set_visible(item, visible);
  134. else
  135. obs_source_set_enabled(source, visible);
  136. }
  137. void VisibilityItemWidget::SourceEnabled(bool enabled)
  138. {
  139. if (vis->isChecked() != enabled)
  140. vis->setChecked(enabled);
  141. }
  142. void VisibilityItemWidget::SourceRenamed(QString name)
  143. {
  144. if (label && name != label->text())
  145. label->setText(name);
  146. }
  147. void VisibilityItemWidget::SetColor(const QColor &color,
  148. bool active_, bool selected_)
  149. {
  150. /* Do not update unless the state has actually changed */
  151. if (active_ == active && selected_ == selected)
  152. return;
  153. QPalette pal = vis->palette();
  154. pal.setColor(QPalette::WindowText, color);
  155. vis->setPalette(pal);
  156. label->setStyleSheet(QString("color: %1;").arg(color.name()));
  157. active = active_;
  158. selected = selected_;
  159. }
  160. VisibilityItemDelegate::VisibilityItemDelegate(QObject *parent)
  161. : QStyledItemDelegate(parent)
  162. {
  163. }
  164. void VisibilityItemDelegate::paint(QPainter *painter,
  165. const QStyleOptionViewItem &option,
  166. const QModelIndex &index) const
  167. {
  168. QStyledItemDelegate::paint(painter, option, index);
  169. QObject *parentObj = parent();
  170. QListWidget *list = qobject_cast<QListWidget*>(parentObj);
  171. if (!list)
  172. return;
  173. QListWidgetItem *item = list->item(index.row());
  174. VisibilityItemWidget *widget =
  175. qobject_cast<VisibilityItemWidget*>(list->itemWidget(item));
  176. if (!widget)
  177. return;
  178. bool selected = option.state.testFlag(QStyle::State_Selected);
  179. bool active = option.state.testFlag(QStyle::State_Active);
  180. QPalette palette = list->palette();
  181. QPalette::ColorGroup group = active ?
  182. QPalette::Active : QPalette::Inactive;
  183. #ifdef _WIN32
  184. QPalette::ColorRole highlightRole = QPalette::WindowText;
  185. #else
  186. QPalette::ColorRole highlightRole = QPalette::HighlightedText;
  187. #endif
  188. QPalette::ColorRole role;
  189. if (selected && active)
  190. role = highlightRole;
  191. else
  192. role = QPalette::WindowText;
  193. widget->SetColor(palette.color(group, role), active, selected);
  194. }
  195. void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
  196. obs_source_t *source)
  197. {
  198. VisibilityItemWidget *baseWidget = new VisibilityItemWidget(source);
  199. item->setSizeHint(baseWidget->sizeHint());
  200. list->setItemWidget(item, baseWidget);
  201. }
  202. void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
  203. obs_sceneitem_t *sceneItem)
  204. {
  205. VisibilityItemWidget *baseWidget = new VisibilityItemWidget(sceneItem);
  206. item->setSizeHint(baseWidget->sizeHint());
  207. list->setItemWidget(item, baseWidget);
  208. }