File: window-basic-preview.hpp

package info (click to toggle)
obs-studio 30.2.3%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 47,852 kB
  • sloc: ansic: 202,137; cpp: 112,402; makefile: 868; python: 599; sh: 275; javascript: 19
file content (201 lines) | stat: -rw-r--r-- 5,691 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#pragma once

#include <obs.hpp>
#include <graphics/vec2.h>
#include <graphics/matrix4.h>
#include <util/threading.h>
#include <mutex>
#include <vector>
#include "qt-display.hpp"
#include "obs-app.hpp"

class OBSBasic;
class QMouseEvent;

#define ITEM_LEFT (1 << 0)
#define ITEM_RIGHT (1 << 1)
#define ITEM_TOP (1 << 2)
#define ITEM_BOTTOM (1 << 3)
#define ITEM_ROT (1 << 4)

#define MAX_SCALING_LEVEL 20
#define MAX_SCALING_AMOUNT 10.0f
#define ZOOM_SENSITIVITY pow(MAX_SCALING_AMOUNT, 1.0f / MAX_SCALING_LEVEL)

#define SPACER_LABEL_MARGIN 6.0f

enum class ItemHandle : uint32_t {
	None = 0,
	TopLeft = ITEM_TOP | ITEM_LEFT,
	TopCenter = ITEM_TOP,
	TopRight = ITEM_TOP | ITEM_RIGHT,
	CenterLeft = ITEM_LEFT,
	CenterRight = ITEM_RIGHT,
	BottomLeft = ITEM_BOTTOM | ITEM_LEFT,
	BottomCenter = ITEM_BOTTOM,
	BottomRight = ITEM_BOTTOM | ITEM_RIGHT,
	Rot = ITEM_ROT
};

class OBSBasicPreview : public OBSQTDisplay {
	Q_OBJECT

	friend class SourceTree;
	friend class SourceTreeItem;

private:
	obs_sceneitem_crop startCrop;
	vec2 startItemPos;
	vec2 cropSize;
	OBSSceneItem stretchGroup;
	OBSSceneItem stretchItem;
	ItemHandle stretchHandle = ItemHandle::None;
	float rotateAngle;
	vec2 rotatePoint;
	vec2 offsetPoint;
	vec2 stretchItemSize;
	matrix4 screenToItem;
	matrix4 itemToScreen;
	matrix4 invGroupTransform;

	gs_texture_t *overflow = nullptr;
	gs_vertbuffer_t *rectFill = nullptr;
	gs_vertbuffer_t *circleFill = nullptr;

	vec2 startPos;
	vec2 mousePos;
	vec2 lastMoveOffset;
	vec2 scrollingFrom;
	vec2 scrollingOffset;
	bool mouseDown = false;
	bool mouseMoved = false;
	bool mouseOverItems = false;
	bool cropping = false;
	bool locked = false;
	bool scrollMode = false;
	bool fixedScaling = false;
	bool selectionBox = false;
	bool overflowHidden = false;
	bool overflowSelectionHidden = false;
	bool overflowAlwaysVisible = false;
	int32_t scalingLevel = 0;
	float scalingAmount = 1.0f;
	float groupRot = 0.0f;

	std::vector<obs_sceneitem_t *> hoveredPreviewItems;
	std::vector<obs_sceneitem_t *> selectedItems;
	std::mutex selectMutex;

	static vec2 GetMouseEventPos(QMouseEvent *event);
	static bool FindSelected(obs_scene_t *scene, obs_sceneitem_t *item,
				 void *param);
	static bool DrawSelectedOverflow(obs_scene_t *scene,
					 obs_sceneitem_t *item, void *param);
	static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item,
				     void *param);
	static bool DrawSelectionBox(float x1, float y1, float x2, float y2,
				     gs_vertbuffer_t *box);

	static OBSSceneItem GetItemAtPos(const vec2 &pos, bool selectBelow);
	static bool SelectedAtPos(const vec2 &pos);

	static void DoSelect(const vec2 &pos);
	static void DoCtrlSelect(const vec2 &pos);

	static vec3 GetSnapOffset(const vec3 &tl, const vec3 &br);

	void GetStretchHandleData(const vec2 &pos, bool ignoreGroup);

	void UpdateCursor(uint32_t &flags);

	void SnapStretchingToScreen(vec3 &tl, vec3 &br);
	void ClampAspect(vec3 &tl, vec3 &br, vec2 &size, const vec2 &baseSize);
	vec3 CalculateStretchPos(const vec3 &tl, const vec3 &br);
	void CropItem(const vec2 &pos);
	void StretchItem(const vec2 &pos);
	void RotateItem(const vec2 &pos);

	static void SnapItemMovement(vec2 &offset);
	void MoveItems(const vec2 &pos);
	void BoxItems(const vec2 &startPos, const vec2 &pos);

	void ProcessClick(const vec2 &pos);

	OBSDataAutoRelease wrapper = nullptr;
	bool changed;

public:
	OBSBasicPreview(QWidget *parent,
			Qt::WindowFlags flags = Qt::WindowFlags());
	~OBSBasicPreview();

	static OBSBasicPreview *Get();

	virtual void keyPressEvent(QKeyEvent *event) override;
	virtual void keyReleaseEvent(QKeyEvent *event) override;

	virtual void wheelEvent(QWheelEvent *event) override;

	virtual void mousePressEvent(QMouseEvent *event) override;
	virtual void mouseReleaseEvent(QMouseEvent *event) override;
	virtual void mouseMoveEvent(QMouseEvent *event) override;
	virtual void leaveEvent(QEvent *event) override;

	void DrawOverflow();
	void DrawSceneEditing();

	inline void SetLocked(bool newLockedVal) { locked = newLockedVal; }
	inline void ToggleLocked() { locked = !locked; }
	inline bool Locked() const { return locked; }

	inline void SetFixedScaling(bool newFixedScalingVal)
	{
		fixedScaling = newFixedScalingVal;
	}
	inline bool IsFixedScaling() const { return fixedScaling; }

	void SetScalingLevel(int32_t newScalingLevelVal);
	void SetScalingAmount(float newScalingAmountVal);
	inline int32_t GetScalingLevel() const { return scalingLevel; }
	inline float GetScalingAmount() const { return scalingAmount; }

	void ResetScrollingOffset();
	inline void SetScrollingOffset(float x, float y)
	{
		vec2_set(&scrollingOffset, x, y);
	}
	inline float GetScrollX() const { return scrollingOffset.x; }
	inline float GetScrollY() const { return scrollingOffset.y; }

	inline void SetOverflowHidden(bool hidden) { overflowHidden = hidden; }
	inline void SetOverflowSelectionHidden(bool hidden)
	{
		overflowSelectionHidden = hidden;
	}
	inline void SetOverflowAlwaysVisible(bool visible)
	{
		overflowAlwaysVisible = visible;
	}

	inline bool GetOverflowSelectionHidden() const
	{
		return overflowSelectionHidden;
	}
	inline bool GetOverflowAlwaysVisible() const
	{
		return overflowAlwaysVisible;
	}

	/* use libobs allocator for alignment because the matrices itemToScreen
	 * and screenToItem may contain SSE data, which will cause SSE
	 * instructions to crash if the data is not aligned to at least a 16
	 * byte boundary. */
	static inline void *operator new(size_t size) { return bmalloc(size); }
	static inline void operator delete(void *ptr) { bfree(ptr); }

	OBSSourceAutoRelease spacerLabel[4];
	int spacerPx[4] = {0};

	void DrawSpacingHelpers();
	void ClampScrollingOffsets();
};