diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini index bceab1d32..50dd9cf62 100644 --- a/obs/data/locale/en-US.ini +++ b/obs/data/locale/en-US.ini @@ -355,6 +355,9 @@ Basic.Settings.General.Theme="Theme" Basic.Settings.General.Language="Language" Basic.Settings.General.WarnBeforeStartingStream="Show confirmation dialog when starting streams" Basic.Settings.General.WarnBeforeStoppingStream="Show confirmation dialog when stopping streams" +Basic.Settings.General.Snapping="Source Alignment Snapping" +Basic.Settings.General.ScreenSnapping="Snap Sources to edge of screen" +Basic.Settings.General.SnapDistance="Snap Sensitivity" # basic mode 'stream' settings Basic.Settings.Stream="Stream" diff --git a/obs/forms/OBSBasicSettings.ui b/obs/forms/OBSBasicSettings.ui index fae897a91..bd38e2185 100644 --- a/obs/forms/OBSBasicSettings.ui +++ b/obs/forms/OBSBasicSettings.ui @@ -185,6 +185,86 @@ + + + + Qt::Horizontal + + + + + + + true + + + + 0 + 0 + + + + Basic.Settings.General.Snapping + + + false + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Enable + + + true + + + + + + + Basic.Settings.General.ScreenSnapping + + + true + + + + + + + 1 + + + 0.500000000000000 + + + 10.000000000000000 + + + + + + + + 170 + 0 + + + + Basic.Settings.General.SnapDistance + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + @@ -3485,8 +3565,56 @@ setEnabled(bool) - 517 - 267 + 690 + 454 + + + 690 + 506 + + + + + snappingEnabled + toggled(bool) + label_9 + setEnabled(bool) + + + 376 + 196 + + + 305 + 224 + + + + + snappingEnabled + toggled(bool) + snapDistance + setEnabled(bool) + + + 417 + 204 + + + 434 + 234 + + + + + snappingEnabled + toggled(bool) + screenSnapping + setEnabled(bool) + + + 476 + 202 777 diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp index da24ce8a9..86368e714 100644 --- a/obs/obs-app.cpp +++ b/obs/obs-app.cpp @@ -339,6 +339,12 @@ bool OBSApp::InitGlobalConfigDefaults() "SceneDuplicationMode", true); config_set_default_bool(globalConfig, "BasicWindow", "SwapScenesMode", true); + config_set_default_bool(globalConfig, "BasicWindow", + "SnappingEnabled", true); + config_set_default_bool(globalConfig, "BasicWindow", + "ScreenSnapping", true); + config_set_default_double(globalConfig, "BasicWindow", + "SnapDistance", 10.0); #ifdef __APPLE__ config_set_default_bool(globalConfig, "Video", "DisableOSXVSync", true); diff --git a/obs/window-basic-preview.cpp b/obs/window-basic-preview.cpp index 5d3017698..cdc25e17f 100644 --- a/obs/window-basic-preview.cpp +++ b/obs/window-basic-preview.cpp @@ -11,7 +11,6 @@ #define HANDLE_RADIUS 4.0f #define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f) -#define CLAMP_DISTANCE 10.0f /* TODO: make C++ math classes and clean up code here later */ @@ -133,7 +132,7 @@ static inline vec2 GetOBSScreenSize() return size; } -vec3 OBSBasicPreview::GetScreenSnapOffset(const vec3 &tl, const vec3 &br) +vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br) { OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); vec2 screenSize = GetOBSScreenSize(); @@ -141,17 +140,34 @@ vec3 OBSBasicPreview::GetScreenSnapOffset(const vec3 &tl, const vec3 &br) vec3_zero(&clampOffset); - const float clampDist = CLAMP_DISTANCE / main->previewScale; + const bool snap = config_get_bool(GetGlobalConfig(), + "BasicWindow", "SnappingEnabled"); + if (snap == false) + return clampOffset; - if (fabsf(tl.x) < clampDist) + const bool screenSnap = config_get_bool(GetGlobalConfig(), + "BasicWindow", "ScreenSnapping"); + + const float clampDist = config_get_double(GetGlobalConfig(), + "BasicWindow", "SnapDistance") / main->previewScale; + + // Left screen edge. + if (screenSnap && + fabsf(tl.x) < clampDist) clampOffset.x = -tl.x; - if (fabsf(clampOffset.x) < EPSILON && + // Right screen edge. + if (screenSnap && + fabsf(clampOffset.x) < EPSILON && fabsf(screenSize.x - br.x) < clampDist) clampOffset.x = screenSize.x - br.x; - if (fabsf(tl.y) < clampDist) + // Top screen edge. + if (screenSnap && + fabsf(tl.y) < clampDist) clampOffset.y = -tl.y; - if (fabsf(clampOffset.y) < EPSILON && + // Bottom screen edge. + if (screenSnap && + fabsf(clampOffset.y) < EPSILON && fabsf(screenSize.y - br.y) < clampDist) clampOffset.y = screenSize.y - br.y; @@ -485,7 +501,13 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset) data.br.x += offset.x; data.br.y += offset.y; - vec3 snapOffset = GetScreenSnapOffset(data.tl, data.br); + vec3 snapOffset = GetSnapOffset(data.tl, data.br); + + const bool snap = config_get_bool(GetGlobalConfig(), + "BasicWindow", "SnappingEnabled"); + if (snap == false) + return; + offset.x += snapOffset.x; offset.y += snapOffset.y; } @@ -606,7 +628,7 @@ void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br) vec3_max(&boundingBR, &boundingBR, &newBL); vec3_max(&boundingBR, &boundingBR, &newBR); - vec3 offset = GetScreenSnapOffset(boundingTL, boundingBR); + vec3 offset = GetSnapOffset(boundingTL, boundingBR); vec3_add(&offset, &offset, &newTL); vec3_transform(&offset, &offset, &screenToItem); vec3_sub(&offset, &offset, &tl); diff --git a/obs/window-basic-preview.hpp b/obs/window-basic-preview.hpp index 4507f61b2..1a2524532 100644 --- a/obs/window-basic-preview.hpp +++ b/obs/window-basic-preview.hpp @@ -56,7 +56,7 @@ private: static void DoSelect(const vec2 &pos); static void DoCtrlSelect(const vec2 &pos); - static vec3 GetScreenSnapOffset(const vec3 &tl, const vec3 &br); + static vec3 GetSnapOffset(const vec3 &tl, const vec3 &br); void GetStretchHandleData(const vec2 &pos); diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp index 86d459330..52f5a3c85 100644 --- a/obs/window-basic-settings.cpp +++ b/obs/window-basic-settings.cpp @@ -266,6 +266,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->theme, COMBO_CHANGED, GENERAL_CHANGED); HookWidget(ui->warnBeforeStreamStart,CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->warnBeforeStreamStop, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->snappingEnabled, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->screenSnapping, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->snapDistance, SCROLL_CHANGED, GENERAL_CHANGED); HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->streamType, COMBO_CHANGED, STREAM1_CHANGED); HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED); @@ -763,6 +766,19 @@ void OBSBasicSettings::LoadGeneralSettings() LoadLanguageList(); LoadThemeList(); + bool snappingEnabled = config_get_bool(GetGlobalConfig(), + "BasicWindow", "SnappingEnabled"); + ui->snappingEnabled->setChecked(snappingEnabled); + + bool screenSnapping = config_get_bool(GetGlobalConfig(), + "BasicWindow", "ScreenSnapping"); + ui->screenSnapping->setChecked(screenSnapping); + + double snapDistance = config_get_double(GetGlobalConfig(), + "BasicWindow", "SnapDistance"); + ui->snapDistance->setValue(snapDistance); + + bool warnBeforeStreamStart = config_get_bool(GetGlobalConfig(), "BasicWindow", "WarnBeforeStartingStream"); ui->warnBeforeStreamStart->setChecked(warnBeforeStreamStart); @@ -2038,6 +2054,19 @@ void OBSBasicSettings::SaveGeneralSettings() App()->SetTheme(theme); } + if (WidgetChanged(ui->snappingEnabled)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "SnappingEnabled", + ui->snappingEnabled->isChecked()); + if (WidgetChanged(ui->screenSnapping)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "ScreenSnapping", + ui->screenSnapping->isChecked()); + if (WidgetChanged(ui->snapDistance)) + config_set_double(GetGlobalConfig(), "BasicWindow", + "SnapDistance", + ui->snapDistance->value()); + config_set_bool(GetGlobalConfig(), "BasicWindow", "WarnBeforeStartingStream", ui->warnBeforeStreamStart->isChecked());