New upstream version 23.2.1+dfsg1
This commit is contained in:
parent
cdc9a9fc87
commit
b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions
|
|
@ -3,14 +3,19 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <graphics/vec4.h>
|
||||
#include <graphics/matrix4.h>
|
||||
#include "window-basic-preview.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "platform.hpp"
|
||||
|
||||
#define HANDLE_RADIUS 4.0f
|
||||
#define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
#define SUPPORTS_FRACTIONAL_SCALING
|
||||
#endif
|
||||
|
||||
/* TODO: make C++ math classes and clean up code here later */
|
||||
|
||||
|
|
@ -21,10 +26,23 @@ OBSBasicPreview::OBSBasicPreview(QWidget *parent, Qt::WindowFlags flags)
|
|||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
OBSBasicPreview::~OBSBasicPreview()
|
||||
{
|
||||
if (overflow) {
|
||||
obs_enter_graphics();
|
||||
gs_texture_destroy(overflow);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
}
|
||||
|
||||
vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
|
||||
{
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
#ifdef SUPPORTS_FRACTIONAL_SCALING
|
||||
float pixelRatio = main->devicePixelRatioF();
|
||||
#else
|
||||
float pixelRatio = main->devicePixelRatio();
|
||||
#endif
|
||||
float scale = pixelRatio / main->previewScale;
|
||||
vec2 pos;
|
||||
vec2_set(&pos,
|
||||
|
|
@ -369,7 +387,11 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
|
|||
if (!scene)
|
||||
return;
|
||||
|
||||
#ifdef SUPPORTS_FRACTIONAL_SCALING
|
||||
float scale = main->previewScale / main->devicePixelRatioF();
|
||||
#else
|
||||
float scale = main->previewScale / main->devicePixelRatio();
|
||||
#endif
|
||||
vec2 scaled_pos = pos;
|
||||
vec2_divf(&scaled_pos, &scaled_pos, scale);
|
||||
HandleFindData data(scaled_pos, scale);
|
||||
|
|
@ -491,7 +513,11 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event)
|
|||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
#ifdef SUPPORTS_FRACTIONAL_SCALING
|
||||
float pixelRatio = main->devicePixelRatioF();
|
||||
#else
|
||||
float pixelRatio = main->devicePixelRatio();
|
||||
#endif
|
||||
float x = float(event->x()) - main->previewX / pixelRatio;
|
||||
float y = float(event->y()) - main->previewY / pixelRatio;
|
||||
Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers();
|
||||
|
|
@ -588,6 +614,9 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
|
|||
mouseDown = false;
|
||||
mouseMoved = false;
|
||||
cropping = false;
|
||||
|
||||
OBSSceneItem item = GetItemAtPos(pos, true);
|
||||
hoveredPreviewItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1134,6 +1163,8 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
|
|||
return;
|
||||
|
||||
if (mouseDown) {
|
||||
hoveredPreviewItem = nullptr;
|
||||
|
||||
vec2 pos = GetMouseEventPos(event);
|
||||
|
||||
if (!mouseMoved && !mouseOverItems &&
|
||||
|
|
@ -1170,10 +1201,22 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
|
|||
}
|
||||
|
||||
mouseMoved = true;
|
||||
} else {
|
||||
vec2 pos = GetMouseEventPos(event);
|
||||
OBSSceneItem item = GetItemAtPos(pos, true);
|
||||
|
||||
hoveredPreviewItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawCircleAtPos(float x, float y)
|
||||
void OBSBasicPreview::leaveEvent(QEvent *event)
|
||||
{
|
||||
hoveredPreviewItem = nullptr;
|
||||
|
||||
UNUSED_PARAMETER(event);
|
||||
}
|
||||
|
||||
static void DrawSquareAtPos(float x, float y)
|
||||
{
|
||||
struct vec3 pos;
|
||||
vec3_set(&pos, x, y, 0.0f);
|
||||
|
|
@ -1185,11 +1228,68 @@ static void DrawCircleAtPos(float x, float y)
|
|||
gs_matrix_push();
|
||||
gs_matrix_identity();
|
||||
gs_matrix_translate(&pos);
|
||||
gs_matrix_scale3f(HANDLE_RADIUS, HANDLE_RADIUS, 1.0f);
|
||||
gs_draw(GS_LINESTRIP, 0, 0);
|
||||
|
||||
gs_matrix_translate3f(-HANDLE_RADIUS, -HANDLE_RADIUS, 0.0f);
|
||||
gs_matrix_scale3f(HANDLE_RADIUS*2, HANDLE_RADIUS*2, 1.0f);
|
||||
gs_draw(GS_TRISTRIP, 0, 0);
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
||||
static void DrawLine(float x1, float y1, float x2, float y2, float thickness,
|
||||
vec2 scale)
|
||||
{
|
||||
float ySide = (y1 == y2) ? (y1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
|
||||
float xSide = (x1 == x2) ? (x1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
|
||||
|
||||
gs_render_start(true);
|
||||
|
||||
gs_vertex2f(x1, y1);
|
||||
gs_vertex2f(x1 + (xSide * (thickness / scale.x)),
|
||||
y1 + (ySide * (thickness / scale.y)));
|
||||
gs_vertex2f(x2 + (xSide * (thickness / scale.x)),
|
||||
y2 + (ySide * (thickness / scale.y)));
|
||||
gs_vertex2f(x2, y2);
|
||||
gs_vertex2f(x1, y1);
|
||||
|
||||
gs_vertbuffer_t *line = gs_render_save();
|
||||
|
||||
gs_load_vertexbuffer(line);
|
||||
gs_draw(GS_TRISTRIP, 0, 0);
|
||||
gs_vertexbuffer_destroy(line);
|
||||
}
|
||||
|
||||
static void DrawRect(float thickness, vec2 scale)
|
||||
{
|
||||
gs_render_start(true);
|
||||
|
||||
gs_vertex2f(0.0f, 0.0f);
|
||||
gs_vertex2f(0.0f + (thickness / scale.x), 0.0f);
|
||||
gs_vertex2f(0.0f + (thickness / scale.x), 1.0f);
|
||||
gs_vertex2f(0.0f, 1.0f);
|
||||
gs_vertex2f(0.0f, 0.0f);
|
||||
gs_vertex2f(0.0f, 1.0f);
|
||||
gs_vertex2f(0.0f, 1.0f - (thickness / scale.y));
|
||||
gs_vertex2f(1.0f, 1.0f - (thickness / scale.y));
|
||||
gs_vertex2f(1.0f, 1.0f);
|
||||
gs_vertex2f(0.0f, 1.0f);
|
||||
gs_vertex2f(1.0f, 1.0f);
|
||||
gs_vertex2f(1.0f - (thickness / scale.x), 1.0f);
|
||||
gs_vertex2f(1.0f - (thickness / scale.x), 0.0f);
|
||||
gs_vertex2f(1.0f, 0.0f);
|
||||
gs_vertex2f(1.0f, 1.0f);
|
||||
gs_vertex2f(1.0f, 0.0f);
|
||||
gs_vertex2f(1.0f, 0.0f + (thickness / scale.y));
|
||||
gs_vertex2f(0.0f, 0.0f + (thickness / scale.y));
|
||||
gs_vertex2f(0.0f, 0.0f);
|
||||
gs_vertex2f(1.0f, 0.0f);
|
||||
|
||||
gs_vertbuffer_t *rect = gs_render_save();
|
||||
|
||||
gs_load_vertexbuffer(rect);
|
||||
gs_draw(GS_TRISTRIP, 0, 0);
|
||||
gs_vertexbuffer_destroy(rect);
|
||||
}
|
||||
|
||||
static inline bool crop_enabled(const obs_sceneitem_crop *crop)
|
||||
{
|
||||
return crop->left > 0 ||
|
||||
|
|
@ -1198,6 +1298,96 @@ static inline bool crop_enabled(const obs_sceneitem_crop *crop)
|
|||
crop->bottom > 0;
|
||||
}
|
||||
|
||||
bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
|
||||
obs_sceneitem_t *item, void *param)
|
||||
{
|
||||
if (obs_sceneitem_locked(item))
|
||||
return true;
|
||||
|
||||
if (!SceneItemHasVideo(item))
|
||||
return true;
|
||||
|
||||
bool select = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"OverflowSelectionHidden");
|
||||
|
||||
if (!select && !obs_sceneitem_visible(item))
|
||||
return true;
|
||||
|
||||
if (obs_sceneitem_is_group(item)) {
|
||||
matrix4 mat;
|
||||
obs_sceneitem_get_draw_transform(item, &mat);
|
||||
|
||||
gs_matrix_push();
|
||||
gs_matrix_mul(&mat);
|
||||
obs_sceneitem_group_enum_items(item, DrawSelectedOverflow, param);
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
||||
bool always = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"OverflowAlwaysVisible");
|
||||
|
||||
if (!always && !obs_sceneitem_selected(item))
|
||||
return true;
|
||||
|
||||
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
|
||||
|
||||
matrix4 boxTransform;
|
||||
matrix4 invBoxTransform;
|
||||
obs_sceneitem_get_box_transform(item, &boxTransform);
|
||||
matrix4_inv(&invBoxTransform, &boxTransform);
|
||||
|
||||
vec3 bounds[] = {
|
||||
{{{0.f, 0.f, 0.f}}},
|
||||
{{{1.f, 0.f, 0.f}}},
|
||||
{{{0.f, 1.f, 0.f}}},
|
||||
{{{1.f, 1.f, 0.f}}},
|
||||
};
|
||||
|
||||
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
|
||||
[&](const vec3 &b)
|
||||
{
|
||||
vec3 pos;
|
||||
vec3_transform(&pos, &b, &boxTransform);
|
||||
vec3_transform(&pos, &pos, &invBoxTransform);
|
||||
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
|
||||
});
|
||||
|
||||
if (!visible)
|
||||
return true;
|
||||
|
||||
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSelectedOverflow");
|
||||
|
||||
obs_transform_info info;
|
||||
obs_sceneitem_get_info(item, &info);
|
||||
|
||||
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT);
|
||||
gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image");
|
||||
gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale");
|
||||
|
||||
vec2 s;
|
||||
vec2_set(&s, boxTransform.x.x / 96, boxTransform.y.y / 96);
|
||||
|
||||
gs_effect_set_vec2(scale, &s);
|
||||
gs_effect_set_texture(image, prev->overflow);
|
||||
|
||||
gs_matrix_push();
|
||||
gs_matrix_mul(&boxTransform);
|
||||
|
||||
obs_sceneitem_crop crop;
|
||||
obs_sceneitem_get_crop(item, &crop);
|
||||
|
||||
while (gs_effect_loop(solid, "Draw")) {
|
||||
gs_draw_sprite(prev->overflow, 0, 1, 1);
|
||||
}
|
||||
|
||||
gs_matrix_pop();
|
||||
|
||||
GS_DEBUG_MARKER_END();
|
||||
|
||||
UNUSED_PARAMETER(scene);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
|
||||
obs_sceneitem_t *item, void *param)
|
||||
{
|
||||
|
|
@ -1217,10 +1407,15 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
|
|||
gs_matrix_pop();
|
||||
}
|
||||
|
||||
if (!obs_sceneitem_selected(item))
|
||||
return true;
|
||||
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
bool hovered = prev->hoveredPreviewItem == item ||
|
||||
prev->hoveredListItem == item;
|
||||
bool selected = obs_sceneitem_selected(item);
|
||||
|
||||
if (!selected && !hovered)
|
||||
return true;
|
||||
|
||||
matrix4 boxTransform;
|
||||
matrix4 invBoxTransform;
|
||||
|
|
@ -1234,6 +1429,14 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
|
|||
{{{1.f, 1.f, 0.f}}},
|
||||
};
|
||||
|
||||
vec4 red;
|
||||
vec4 green;
|
||||
vec4 blue;
|
||||
|
||||
vec4_set(&red, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
vec4_set(&green, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
vec4_set(&blue, 0.0f, 0.5f, 1.0f, 1.0f);
|
||||
|
||||
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
|
||||
[&](const vec3 &b)
|
||||
{
|
||||
|
|
@ -1246,62 +1449,115 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
|
|||
if (!visible)
|
||||
return true;
|
||||
|
||||
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSelectedItem");
|
||||
|
||||
matrix4 curTransform;
|
||||
vec2 boxScale;
|
||||
gs_matrix_get(&curTransform);
|
||||
obs_sceneitem_get_box_scale(item, &boxScale);
|
||||
boxScale.x *= curTransform.x.x;
|
||||
boxScale.y *= curTransform.y.y;
|
||||
|
||||
obs_transform_info info;
|
||||
obs_sceneitem_get_info(item, &info);
|
||||
|
||||
gs_load_vertexbuffer(main->circle);
|
||||
|
||||
gs_matrix_push();
|
||||
gs_matrix_mul(&boxTransform);
|
||||
|
||||
DrawCircleAtPos(0.0f, 0.0f);
|
||||
DrawCircleAtPos(0.0f, 1.0f);
|
||||
DrawCircleAtPos(1.0f, 0.0f);
|
||||
DrawCircleAtPos(1.0f, 1.0f);
|
||||
DrawCircleAtPos(0.5f, 0.0f);
|
||||
DrawCircleAtPos(0.0f, 0.5f);
|
||||
DrawCircleAtPos(0.5f, 1.0f);
|
||||
DrawCircleAtPos(1.0f, 0.5f);
|
||||
|
||||
obs_sceneitem_crop crop;
|
||||
obs_sceneitem_get_crop(item, &crop);
|
||||
|
||||
gs_effect_t *eff = gs_get_effect();
|
||||
gs_eparam_t *colParam = gs_effect_get_param_by_name(eff, "color");
|
||||
|
||||
if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) {
|
||||
vec4 color;
|
||||
gs_effect_t *eff = gs_get_effect();
|
||||
gs_eparam_t *param = gs_effect_get_param_by_name(eff, "color");
|
||||
#define DRAW_SIDE(side, x1, y1, x2, y2) \
|
||||
if (hovered && !selected) \
|
||||
gs_effect_set_vec4(colParam, &blue); \
|
||||
else if (crop.side > 0) \
|
||||
gs_effect_set_vec4(colParam, &green); \
|
||||
DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \
|
||||
gs_effect_set_vec4(colParam, &red);
|
||||
|
||||
#define DRAW_SIDE(side, vb) \
|
||||
if (crop.side > 0) \
|
||||
vec4_set(&color, 0.0f, 1.0f, 0.0f, 1.0f); \
|
||||
else \
|
||||
vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f); \
|
||||
gs_effect_set_vec4(param, &color); \
|
||||
gs_load_vertexbuffer(main->vb); \
|
||||
gs_draw(GS_LINESTRIP, 0, 0);
|
||||
|
||||
DRAW_SIDE(left, boxLeft);
|
||||
DRAW_SIDE(top, boxTop);
|
||||
DRAW_SIDE(right, boxRight);
|
||||
DRAW_SIDE(bottom, boxBottom);
|
||||
DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f);
|
||||
DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f);
|
||||
DRAW_SIDE(bottom, 0.0f, 1.0f, 1.0f, 1.0f);
|
||||
#undef DRAW_SIDE
|
||||
} else {
|
||||
gs_load_vertexbuffer(main->box);
|
||||
gs_draw(GS_LINESTRIP, 0, 0);
|
||||
if (!selected) {
|
||||
gs_effect_set_vec4(colParam, &blue);
|
||||
DrawRect(HANDLE_RADIUS / 2, boxScale);
|
||||
} else {
|
||||
DrawRect(HANDLE_RADIUS / 2, boxScale);
|
||||
}
|
||||
}
|
||||
|
||||
gs_load_vertexbuffer(main->box);
|
||||
gs_effect_set_vec4(colParam, &red);
|
||||
|
||||
if (selected) {
|
||||
DrawSquareAtPos(0.0f, 0.0f);
|
||||
DrawSquareAtPos(0.0f, 1.0f);
|
||||
DrawSquareAtPos(1.0f, 0.0f);
|
||||
DrawSquareAtPos(1.0f, 1.0f);
|
||||
DrawSquareAtPos(0.5f, 0.0f);
|
||||
DrawSquareAtPos(0.0f, 0.5f);
|
||||
DrawSquareAtPos(0.5f, 1.0f);
|
||||
DrawSquareAtPos(1.0f, 0.5f);
|
||||
}
|
||||
|
||||
gs_matrix_pop();
|
||||
|
||||
GS_DEBUG_MARKER_END();
|
||||
|
||||
UNUSED_PARAMETER(scene);
|
||||
UNUSED_PARAMETER(param);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OBSBasicPreview::DrawOverflow()
|
||||
{
|
||||
if (locked)
|
||||
return;
|
||||
|
||||
bool hidden = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"OverflowHidden");
|
||||
|
||||
if (hidden)
|
||||
return;
|
||||
|
||||
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawOverflow");
|
||||
|
||||
if (!overflow) {
|
||||
std::string path;
|
||||
GetDataFilePath("images/overflow.png", path);
|
||||
overflow = gs_texture_create_from_file(path.c_str());
|
||||
}
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
|
||||
OBSScene scene = main->GetCurrentScene();
|
||||
|
||||
if (scene) {
|
||||
gs_matrix_push();
|
||||
gs_matrix_scale3f(main->previewScale, main->previewScale, 1.0f);
|
||||
obs_scene_enum_items(scene, DrawSelectedOverflow, this);
|
||||
gs_matrix_pop();
|
||||
}
|
||||
|
||||
gs_load_vertexbuffer(nullptr);
|
||||
|
||||
GS_DEBUG_MARKER_END();
|
||||
}
|
||||
|
||||
void OBSBasicPreview::DrawSceneEditing()
|
||||
{
|
||||
if (locked)
|
||||
return;
|
||||
|
||||
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSceneEditing");
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
|
||||
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
|
||||
|
|
@ -1327,6 +1583,8 @@ void OBSBasicPreview::DrawSceneEditing()
|
|||
|
||||
gs_technique_end_pass(tech);
|
||||
gs_technique_end(tech);
|
||||
|
||||
GS_DEBUG_MARKER_END();
|
||||
}
|
||||
|
||||
void OBSBasicPreview::ResetScrollingOffset()
|
||||
|
|
@ -1345,3 +1603,8 @@ void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal) {
|
|||
scrollingOffset.y *= newScalingAmountVal / scalingAmount;
|
||||
scalingAmount = newScalingAmountVal;
|
||||
}
|
||||
|
||||
OBSBasicPreview *OBSBasicPreview::Get()
|
||||
{
|
||||
return OBSBasic::Get()->ui->preview;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue