New upstream version 23.2.1+dfsg1

This commit is contained in:
Simon Chopin 2019-07-27 14:47:10 +02:00
parent cdc9a9fc87
commit b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions

View file

@ -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;
}