window-basic-preview.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #pragma once
  2. #include <obs.hpp>
  3. #include <graphics/vec2.h>
  4. #include <graphics/matrix4.h>
  5. #include <util/threading.h>
  6. #include <mutex>
  7. #include <vector>
  8. #include "qt-display.hpp"
  9. #include "obs-app.hpp"
  10. #include "preview-controls.hpp"
  11. class OBSBasic;
  12. class QMouseEvent;
  13. #define ITEM_LEFT (1 << 0)
  14. #define ITEM_RIGHT (1 << 1)
  15. #define ITEM_TOP (1 << 2)
  16. #define ITEM_BOTTOM (1 << 3)
  17. #define ITEM_ROT (1 << 4)
  18. #define MAX_SCALING_LEVEL 32
  19. #define MAX_SCALING_AMOUNT 8.0f
  20. #define ZOOM_SENSITIVITY pow(MAX_SCALING_AMOUNT, 1.0f / MAX_SCALING_LEVEL)
  21. #define SPACER_LABEL_MARGIN 6.0f
  22. enum class ItemHandle : uint32_t {
  23. None = 0,
  24. TopLeft = ITEM_TOP | ITEM_LEFT,
  25. TopCenter = ITEM_TOP,
  26. TopRight = ITEM_TOP | ITEM_RIGHT,
  27. CenterLeft = ITEM_LEFT,
  28. CenterRight = ITEM_RIGHT,
  29. BottomLeft = ITEM_BOTTOM | ITEM_LEFT,
  30. BottomCenter = ITEM_BOTTOM,
  31. BottomRight = ITEM_BOTTOM | ITEM_RIGHT,
  32. Rot = ITEM_ROT
  33. };
  34. class OBSBasicPreview : public OBSQTDisplay {
  35. Q_OBJECT
  36. friend class SourceTree;
  37. friend class SourceTreeItem;
  38. private:
  39. obs_sceneitem_crop startCrop;
  40. vec2 startItemPos;
  41. vec2 cropSize;
  42. OBSSceneItem stretchGroup;
  43. OBSSceneItem stretchItem;
  44. ItemHandle stretchHandle = ItemHandle::None;
  45. float rotateAngle;
  46. vec2 rotatePoint;
  47. vec2 offsetPoint;
  48. vec2 stretchItemSize;
  49. matrix4 screenToItem;
  50. matrix4 itemToScreen;
  51. matrix4 invGroupTransform;
  52. gs_texture_t *overflow = nullptr;
  53. gs_vertbuffer_t *rectFill = nullptr;
  54. gs_vertbuffer_t *circleFill = nullptr;
  55. vec2 startPos;
  56. vec2 mousePos;
  57. vec2 lastMoveOffset;
  58. vec2 scrollingFrom;
  59. vec2 scrollingOffset;
  60. bool mouseDown = false;
  61. bool mouseMoved = false;
  62. bool mouseOverItems = false;
  63. bool cropping = false;
  64. bool locked = false;
  65. bool scrollMode = false;
  66. bool fixedScaling = false;
  67. bool selectionBox = false;
  68. bool overflowHidden = false;
  69. bool overflowSelectionHidden = false;
  70. bool overflowAlwaysVisible = false;
  71. int32_t scalingLevel = 0;
  72. float scalingAmount = 1.0f;
  73. float groupRot = 0.0f;
  74. bool updatingXScrollBar = false;
  75. bool updatingYScrollBar = false;
  76. std::vector<obs_sceneitem_t *> hoveredPreviewItems;
  77. std::vector<obs_sceneitem_t *> selectedItems;
  78. std::mutex selectMutex;
  79. static vec2 GetMouseEventPos(QMouseEvent *event);
  80. static bool FindSelected(obs_scene_t *scene, obs_sceneitem_t *item,
  81. void *param);
  82. static bool DrawSelectedOverflow(obs_scene_t *scene,
  83. obs_sceneitem_t *item, void *param);
  84. static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item,
  85. void *param);
  86. static bool DrawSelectionBox(float x1, float y1, float x2, float y2,
  87. gs_vertbuffer_t *box);
  88. static OBSSceneItem GetItemAtPos(const vec2 &pos, bool selectBelow);
  89. static bool SelectedAtPos(const vec2 &pos);
  90. static void DoSelect(const vec2 &pos);
  91. static void DoCtrlSelect(const vec2 &pos);
  92. static vec3 GetSnapOffset(const vec3 &tl, const vec3 &br);
  93. void GetStretchHandleData(const vec2 &pos, bool ignoreGroup);
  94. void UpdateCursor(uint32_t &flags);
  95. void SnapStretchingToScreen(vec3 &tl, vec3 &br);
  96. void ClampAspect(vec3 &tl, vec3 &br, vec2 &size, const vec2 &baseSize);
  97. vec3 CalculateStretchPos(const vec3 &tl, const vec3 &br);
  98. void CropItem(const vec2 &pos);
  99. void StretchItem(const vec2 &pos);
  100. void RotateItem(const vec2 &pos);
  101. static void SnapItemMovement(vec2 &offset);
  102. void MoveItems(const vec2 &pos);
  103. void BoxItems(const vec2 &startPos, const vec2 &pos);
  104. void ProcessClick(const vec2 &pos);
  105. OBSDataAutoRelease wrapper = nullptr;
  106. bool changed;
  107. private slots:
  108. void XScrollBarMoved(int value);
  109. void YScrollBarMoved(int value);
  110. public:
  111. OBSBasicPreview(QWidget *parent,
  112. Qt::WindowFlags flags = Qt::WindowFlags());
  113. ~OBSBasicPreview();
  114. void Init();
  115. static OBSBasicPreview *Get();
  116. virtual void keyPressEvent(QKeyEvent *event) override;
  117. virtual void keyReleaseEvent(QKeyEvent *event) override;
  118. virtual void wheelEvent(QWheelEvent *event) override;
  119. virtual void mousePressEvent(QMouseEvent *event) override;
  120. virtual void mouseReleaseEvent(QMouseEvent *event) override;
  121. virtual void mouseMoveEvent(QMouseEvent *event) override;
  122. virtual void leaveEvent(QEvent *event) override;
  123. void DrawOverflow();
  124. void DrawSceneEditing();
  125. inline void SetLocked(bool newLockedVal) { locked = newLockedVal; }
  126. inline void ToggleLocked() { locked = !locked; }
  127. inline bool Locked() const { return locked; }
  128. inline void SetFixedScaling(bool newFixedScalingVal)
  129. {
  130. if (fixedScaling == newFixedScalingVal)
  131. return;
  132. fixedScaling = newFixedScalingVal;
  133. emit fixedScalingChanged(fixedScaling);
  134. }
  135. inline bool IsFixedScaling() const { return fixedScaling; }
  136. void SetScalingLevel(int32_t newScalingLevelVal);
  137. void SetScalingAmount(float newScalingAmountVal);
  138. void SetScalingLevelAndAmount(int32_t newScalingLevelVal,
  139. float newScalingAmountVal);
  140. inline int32_t GetScalingLevel() const { return scalingLevel; }
  141. inline float GetScalingAmount() const { return scalingAmount; }
  142. void ResetScrollingOffset();
  143. inline void SetScrollingOffset(float x, float y)
  144. {
  145. vec2_set(&scrollingOffset, x, y);
  146. }
  147. inline float GetScrollX() const { return scrollingOffset.x; }
  148. inline float GetScrollY() const { return scrollingOffset.y; }
  149. inline void SetOverflowHidden(bool hidden) { overflowHidden = hidden; }
  150. inline void SetOverflowSelectionHidden(bool hidden)
  151. {
  152. overflowSelectionHidden = hidden;
  153. }
  154. inline void SetOverflowAlwaysVisible(bool visible)
  155. {
  156. overflowAlwaysVisible = visible;
  157. }
  158. inline bool GetOverflowSelectionHidden() const
  159. {
  160. return overflowSelectionHidden;
  161. }
  162. inline bool GetOverflowAlwaysVisible() const
  163. {
  164. return overflowAlwaysVisible;
  165. }
  166. /* use libobs allocator for alignment because the matrices itemToScreen
  167. * and screenToItem may contain SSE data, which will cause SSE
  168. * instructions to crash if the data is not aligned to at least a 16
  169. * byte boundary. */
  170. static inline void *operator new(size_t size) { return bmalloc(size); }
  171. static inline void operator delete(void *ptr) { bfree(ptr); }
  172. OBSSourceAutoRelease spacerLabel[4];
  173. int spacerPx[4] = {0};
  174. void DrawSpacingHelpers();
  175. void ClampScrollingOffsets();
  176. void UpdateXScrollBar(float cx);
  177. void UpdateYScrollBar(float cy);
  178. signals:
  179. void scalingChanged(float scalingAmount);
  180. void fixedScalingChanged(bool isFixed);
  181. };