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();
};
|