mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-19 20:32:15 +02:00
UI: Add preview scrollbars
This adds scrollbars to the preview, so users can move around the preview without using the spacebar + clicking. Co-Authored-By: Clayton Groeneveld <19962531+cg2121@users.noreply.github.com>
This commit is contained in:
parent
71509ad00c
commit
81fa608cde
@ -211,6 +211,8 @@ target_sources(
|
||||
menu-button.hpp
|
||||
mute-checkbox.hpp
|
||||
noncheckable-button.hpp
|
||||
preview-controls.cpp
|
||||
preview-controls.hpp
|
||||
remote-text.cpp
|
||||
remote-text.hpp
|
||||
scene-tree.cpp
|
||||
|
@ -58,6 +58,8 @@ target_sources(
|
||||
menu-button.hpp
|
||||
mute-checkbox.hpp
|
||||
noncheckable-button.hpp
|
||||
preview-controls.cpp
|
||||
preview-controls.hpp
|
||||
remote-text.cpp
|
||||
remote-text.hpp
|
||||
scene-tree.cpp
|
||||
|
@ -785,6 +785,7 @@ Basic.MainMenu.Edit.Scale="Preview &Scaling"
|
||||
Basic.MainMenu.Edit.Scale.Window="Scale to Window"
|
||||
Basic.MainMenu.Edit.Scale.Canvas="Canvas (%1x%2)"
|
||||
Basic.MainMenu.Edit.Scale.Output="Output (%1x%2)"
|
||||
Basic.MainMenu.Edit.Scale.Manual="Scaled (%1x%2)"
|
||||
Basic.MainMenu.Edit.Transform="&Transform"
|
||||
Basic.MainMenu.Edit.Transform.EditTransform="&Edit Transform..."
|
||||
Basic.MainMenu.Edit.Transform.CopyTransform="Copy Transform"
|
||||
|
@ -105,6 +105,7 @@
|
||||
|
||||
--font_base: calc(1pt * var(--font_base_value));
|
||||
--font_small: calc(0.9pt * var(--font_base_value));
|
||||
--font_xsmall: calc(0.85pt * var(--font_base_value));
|
||||
--font_large: calc(1.1pt * var(--font_base_value));
|
||||
--font_xlarge: calc(1.5pt * var(--font_base_value));
|
||||
|
||||
@ -634,6 +635,11 @@ QScrollBar::handle:horizontal {
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
QScrollBar::handle:disabled {
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
/* Source Context Bar */
|
||||
|
||||
#contextContainer {
|
||||
@ -1963,3 +1969,50 @@ OBSBasicStats {
|
||||
OBSBasicAdvAudio #scrollAreaWidgetContents {
|
||||
background: var(--bg_base);
|
||||
}
|
||||
|
||||
#previewScalePercent,
|
||||
#previewScalingMode {
|
||||
background: transparent;
|
||||
color: var(--text_muted);
|
||||
font-size: var(--font_xsmall);
|
||||
height: 14px;
|
||||
max-height: 14px;
|
||||
padding: 0px var(--padding_xlarge);
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#previewXContainer {
|
||||
border: 1px solid var(--grey6);
|
||||
}
|
||||
|
||||
#previewScalingMode {
|
||||
border: 1px solid var(--grey6);
|
||||
}
|
||||
|
||||
#previewScalingMode:hover,
|
||||
#previewScalingMode:focus {
|
||||
border-color: var(--input_border_hover);
|
||||
}
|
||||
|
||||
#previewXScrollBar,
|
||||
#previewYScrollBar {
|
||||
background: transparent;
|
||||
border: 1px solid var(--grey6);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#previewXScrollBar {
|
||||
border-left: none;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#previewXScrollBar::handle,
|
||||
#previewYScrollBar::handle {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
#previewYScrollBar {
|
||||
width: 16px;
|
||||
}
|
@ -69,6 +69,21 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
@ -152,10 +167,23 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="previewContainer" native="true">
|
||||
<layout class="QVBoxLayout" name="previewTextLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="previewLabel">
|
||||
<property name="sizePolicy">
|
||||
@ -176,6 +204,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="OBSBasicPreview" name="preview" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
@ -198,7 +231,87 @@
|
||||
<addaction name="actionRemoveSource"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QWidget" name="previewXContainer" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="OBSPreviewScalingLabel" name="previewScalePercent">
|
||||
<property name="text">
|
||||
<string>100%</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="OBSPreviewScalingComboBox" name="previewScalingMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Basic.MainMenu.Edit.Scale.Window</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Basic.MainMenu.Edit.Scale.Canvas</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollBar" name="previewXScrollBar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-200</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QScrollBar" name="previewYScrollBar">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -2150,6 +2263,16 @@
|
||||
<header>window-dock.hpp</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>OBSPreviewScalingLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>preview-controls.hpp</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>OBSPreviewScalingComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>preview-controls.hpp</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="obs.qrc"/>
|
||||
|
137
UI/preview-controls.cpp
Normal file
137
UI/preview-controls.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
/******************************************************************************
|
||||
Copyright (C) 2024 by Taylor Giampaolo <warchamp7@obsproject.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#include "preview-controls.hpp"
|
||||
#include <obs-app.hpp>
|
||||
|
||||
/* Preview Scale Label */
|
||||
void OBSPreviewScalingLabel::PreviewScaleChanged(float scale)
|
||||
{
|
||||
previewScale = scale;
|
||||
UpdateScaleLabel();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingLabel::UpdateScaleLabel()
|
||||
{
|
||||
float previewScalePercent = floor(100.0f * previewScale);
|
||||
setText(QString::number(previewScalePercent) + "%");
|
||||
}
|
||||
|
||||
/* Preview Scaling ComboBox */
|
||||
void OBSPreviewScalingComboBox::PreviewFixedScalingChanged(bool fixed)
|
||||
{
|
||||
if (fixedScaling == fixed)
|
||||
return;
|
||||
|
||||
fixedScaling = fixed;
|
||||
UpdateSelection();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::CanvasResized(uint32_t width, uint32_t height)
|
||||
{
|
||||
SetCanvasSize(width, height);
|
||||
UpdateCanvasText();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::OutputResized(uint32_t width, uint32_t height)
|
||||
{
|
||||
SetOutputSize(width, height);
|
||||
|
||||
bool canvasMatchesOutput = output_width == canvas_width &&
|
||||
output_height == canvas_height;
|
||||
|
||||
SetScaleOutputEnabled(!canvasMatchesOutput);
|
||||
UpdateOutputText();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::PreviewScaleChanged(float scale)
|
||||
{
|
||||
previewScale = scale;
|
||||
|
||||
if (fixedScaling) {
|
||||
UpdateSelection();
|
||||
UpdateAllText();
|
||||
} else {
|
||||
UpdateScaledText();
|
||||
}
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::SetScaleOutputEnabled(bool show)
|
||||
{
|
||||
if (scaleOutputEnabled == show)
|
||||
return;
|
||||
|
||||
scaleOutputEnabled = show;
|
||||
|
||||
if (scaleOutputEnabled) {
|
||||
addItem(QTStr("Basic.MainMenu.Edit.Scale.Output"));
|
||||
} else {
|
||||
removeItem(2);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateAllText()
|
||||
{
|
||||
UpdateCanvasText();
|
||||
UpdateOutputText();
|
||||
UpdateScaledText();
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateCanvasText()
|
||||
{
|
||||
QString text = QTStr("Basic.MainMenu.Edit.Scale.Canvas");
|
||||
text = text.arg(QString::number(canvas_width),
|
||||
QString::number(canvas_height));
|
||||
setItemText(1, text);
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateOutputText()
|
||||
{
|
||||
if (scaleOutputEnabled) {
|
||||
QString text = QTStr("Basic.MainMenu.Edit.Scale.Output");
|
||||
text = text.arg(QString::number(output_width),
|
||||
QString::number(output_height));
|
||||
setItemText(2, text);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateScaledText()
|
||||
{
|
||||
QString text = QTStr("Basic.MainMenu.Edit.Scale.Manual");
|
||||
text = text.arg(QString::number(floor(canvas_width * previewScale)),
|
||||
QString::number(floor(canvas_height * previewScale)));
|
||||
setPlaceholderText(text);
|
||||
}
|
||||
|
||||
void OBSPreviewScalingComboBox::UpdateSelection()
|
||||
{
|
||||
QSignalBlocker sb(this);
|
||||
float outputScale = float(output_width) / float(canvas_width);
|
||||
|
||||
if (!fixedScaling) {
|
||||
setCurrentIndex(0);
|
||||
} else {
|
||||
if (previewScale == 1.0f) {
|
||||
setCurrentIndex(1);
|
||||
} else if (scaleOutputEnabled &&
|
||||
(previewScale == outputScale)) {
|
||||
setCurrentIndex(2);
|
||||
} else {
|
||||
setCurrentIndex(-1);
|
||||
}
|
||||
}
|
||||
}
|
81
UI/preview-controls.hpp
Normal file
81
UI/preview-controls.hpp
Normal file
@ -0,0 +1,81 @@
|
||||
/******************************************************************************
|
||||
Copyright (C) 2024 by Taylor Giampaolo <warchamp7@obsproject.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
|
||||
class OBSPreviewScalingLabel : public QLabel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OBSPreviewScalingLabel(QWidget *parent = nullptr) : QLabel(parent) {}
|
||||
|
||||
public slots:
|
||||
void PreviewScaleChanged(float scale);
|
||||
|
||||
private:
|
||||
float previewScale = 0.0f;
|
||||
void UpdateScaleLabel();
|
||||
};
|
||||
|
||||
class OBSPreviewScalingComboBox : public QComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OBSPreviewScalingComboBox(QWidget *parent = nullptr) : QComboBox(parent)
|
||||
{
|
||||
}
|
||||
|
||||
inline void SetCanvasSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
canvas_width = width;
|
||||
canvas_height = height;
|
||||
};
|
||||
inline void SetOutputSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
output_width = width;
|
||||
output_height = height;
|
||||
};
|
||||
void UpdateAllText();
|
||||
|
||||
public slots:
|
||||
void PreviewScaleChanged(float scale);
|
||||
void PreviewFixedScalingChanged(bool fixed);
|
||||
void CanvasResized(uint32_t width, uint32_t height);
|
||||
void OutputResized(uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
uint32_t canvas_width = 0;
|
||||
uint32_t canvas_height = 0;
|
||||
|
||||
uint32_t output_width = 0;
|
||||
uint32_t output_height = 0;
|
||||
|
||||
float previewScale = 0.0f;
|
||||
|
||||
bool fixedScaling = false;
|
||||
|
||||
bool scaleOutputEnabled = false;
|
||||
void SetScaleOutputEnabled(bool show);
|
||||
|
||||
void UpdateCanvasText();
|
||||
void UpdateOutputText();
|
||||
void UpdateScaledText();
|
||||
void UpdateSelection();
|
||||
};
|
@ -464,6 +464,7 @@ OBSBasic::OBSBasic(QWidget *parent)
|
||||
ResizePreview(ovi.base_width, ovi.base_height);
|
||||
|
||||
UpdateContextBarVisibility();
|
||||
UpdatePreviewScrollbars();
|
||||
dpi = devicePixelRatioF();
|
||||
};
|
||||
dpi = devicePixelRatioF();
|
||||
@ -471,6 +472,30 @@ OBSBasic::OBSBasic(QWidget *parent)
|
||||
connect(windowHandle(), &QWindow::screenChanged, displayResize);
|
||||
connect(ui->preview, &OBSQTDisplay::DisplayResized, displayResize);
|
||||
|
||||
/* TODO: Move these into window-basic-preview */
|
||||
/* Preview Scaling label */
|
||||
connect(ui->preview, &OBSBasicPreview::scalingChanged,
|
||||
ui->previewScalePercent,
|
||||
&OBSPreviewScalingLabel::PreviewScaleChanged);
|
||||
|
||||
/* Preview Scaling dropdown */
|
||||
connect(ui->preview, &OBSBasicPreview::scalingChanged,
|
||||
ui->previewScalingMode,
|
||||
&OBSPreviewScalingComboBox::PreviewScaleChanged);
|
||||
|
||||
connect(ui->preview, &OBSBasicPreview::fixedScalingChanged,
|
||||
ui->previewScalingMode,
|
||||
&OBSPreviewScalingComboBox::PreviewFixedScalingChanged);
|
||||
|
||||
connect(ui->previewScalingMode,
|
||||
&OBSPreviewScalingComboBox::currentIndexChanged, this,
|
||||
&OBSBasic::PreviewScalingModeChanged);
|
||||
|
||||
connect(this, &OBSBasic::CanvasResized, ui->previewScalingMode,
|
||||
&OBSPreviewScalingComboBox::CanvasResized);
|
||||
connect(this, &OBSBasic::OutputResized, ui->previewScalingMode,
|
||||
&OBSPreviewScalingComboBox::OutputResized);
|
||||
|
||||
delete shortcutFilter;
|
||||
shortcutFilter = CreateShortcutFilter();
|
||||
installEventFilter(shortcutFilter);
|
||||
@ -1386,6 +1411,7 @@ retryScene:
|
||||
ui->preview->SetScrollingOffset(scrollOffX, scrollOffY);
|
||||
}
|
||||
ui->preview->SetFixedScaling(fixedScaling);
|
||||
|
||||
emit ui->preview->DisplayResized();
|
||||
|
||||
if (vcamEnabled) {
|
||||
@ -2176,6 +2202,7 @@ void OBSBasic::OBSInit()
|
||||
|
||||
InitOBSCallbacks();
|
||||
InitHotkeys();
|
||||
ui->preview->Init();
|
||||
|
||||
/* hack to prevent elgato from loading its own QtNetwork that it tries
|
||||
* to ship with */
|
||||
@ -4924,6 +4951,9 @@ int OBSBasic::ResetVideo()
|
||||
obs_set_video_levels(sdr_white_level, hdr_nominal_peak_level);
|
||||
OBSBasicStats::InitializeValues();
|
||||
OBSProjector::UpdateMultiviewProjectors();
|
||||
|
||||
emit CanvasResized(ovi.base_width, ovi.base_height);
|
||||
emit OutputResized(ovi.output_width, ovi.output_height);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -5013,8 +5043,10 @@ void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy)
|
||||
obs_get_video_info(&ovi);
|
||||
|
||||
if (isFixedScaling) {
|
||||
ui->preview->ClampScrollingOffsets();
|
||||
previewScale = ui->preview->GetScalingAmount();
|
||||
|
||||
ui->preview->ClampScrollingOffsets();
|
||||
|
||||
GetCenterPosFromFixedScale(
|
||||
int(cx), int(cy),
|
||||
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
|
||||
@ -5031,6 +5063,8 @@ void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy)
|
||||
previewX, previewY, previewScale);
|
||||
}
|
||||
|
||||
ui->preview->SetScalingAmount(previewScale);
|
||||
|
||||
previewX += float(PREVIEW_EDGE_SIZE);
|
||||
previewY += float(PREVIEW_EDGE_SIZE);
|
||||
}
|
||||
@ -9169,7 +9203,7 @@ void OBSBasic::on_actionHorizontalCenter_triggered()
|
||||
void OBSBasic::EnablePreviewDisplay(bool enable)
|
||||
{
|
||||
obs_display_set_enabled(ui->preview->GetDisplay(), enable);
|
||||
ui->preview->setVisible(enable);
|
||||
ui->previewContainer->setVisible(enable);
|
||||
ui->previewDisabledWidget->setVisible(!enable);
|
||||
}
|
||||
|
||||
@ -9765,6 +9799,7 @@ void OBSBasic::on_actionScaleWindow_triggered()
|
||||
{
|
||||
ui->preview->SetFixedScaling(false);
|
||||
ui->preview->ResetScrollingOffset();
|
||||
|
||||
emit ui->preview->DisplayResized();
|
||||
}
|
||||
|
||||
@ -9772,6 +9807,7 @@ void OBSBasic::on_actionScaleCanvas_triggered()
|
||||
{
|
||||
ui->preview->SetFixedScaling(true);
|
||||
ui->preview->SetScalingLevel(0);
|
||||
|
||||
emit ui->preview->DisplayResized();
|
||||
}
|
||||
|
||||
@ -9785,8 +9821,8 @@ void OBSBasic::on_actionScaleOutput_triggered()
|
||||
// log base ZOOM_SENSITIVITY of x = log(x) / log(ZOOM_SENSITIVITY)
|
||||
int32_t approxScalingLevel =
|
||||
int32_t(round(log(scalingAmount) / log(ZOOM_SENSITIVITY)));
|
||||
ui->preview->SetScalingLevel(approxScalingLevel);
|
||||
ui->preview->SetScalingAmount(scalingAmount);
|
||||
ui->preview->SetScalingLevelAndAmount(approxScalingLevel,
|
||||
scalingAmount);
|
||||
emit ui->preview->DisplayResized();
|
||||
}
|
||||
|
||||
@ -11093,3 +11129,36 @@ void OBSBasic::OnEvent(enum obs_frontend_event event)
|
||||
if (api)
|
||||
api->on_event(event);
|
||||
}
|
||||
|
||||
void OBSBasic::UpdatePreviewScrollbars()
|
||||
{
|
||||
if (!ui->preview->IsFixedScaling()) {
|
||||
ui->previewXScrollBar->setRange(0, 0);
|
||||
ui->previewYScrollBar->setRange(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasic::on_previewXScrollBar_valueChanged(int value)
|
||||
{
|
||||
emit PreviewXScrollBarMoved(value);
|
||||
}
|
||||
|
||||
void OBSBasic::on_previewYScrollBar_valueChanged(int value)
|
||||
{
|
||||
emit PreviewYScrollBarMoved(value);
|
||||
}
|
||||
|
||||
void OBSBasic::PreviewScalingModeChanged(int value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
on_actionScaleWindow_triggered();
|
||||
break;
|
||||
case 1:
|
||||
on_actionScaleCanvas_triggered();
|
||||
break;
|
||||
case 2:
|
||||
on_actionScaleOutput_triggered();
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
@ -670,6 +670,7 @@ private:
|
||||
std::string lastReplay;
|
||||
|
||||
void UpdatePreviewOverflowSettings();
|
||||
void UpdatePreviewScrollbars();
|
||||
|
||||
bool streamingStarting = false;
|
||||
|
||||
@ -810,6 +811,11 @@ private slots:
|
||||
void AudioMixerPasteFilters();
|
||||
void SourcePasteFilters(OBSSource source, OBSSource dstSource);
|
||||
|
||||
void on_previewXScrollBar_valueChanged(int value);
|
||||
void on_previewYScrollBar_valueChanged(int value);
|
||||
|
||||
void PreviewScalingModeChanged(int value);
|
||||
|
||||
void ColorChange();
|
||||
|
||||
SourceTreeItem *GetItemWidgetFromSceneItem(obs_sceneitem_t *sceneItem);
|
||||
@ -1292,6 +1298,12 @@ signals:
|
||||
|
||||
/* Studio Mode signal */
|
||||
void PreviewProgramModeChanged(bool enabled);
|
||||
void CanvasResized(uint32_t width, uint32_t height);
|
||||
void OutputResized(uint32_t width, uint32_t height);
|
||||
|
||||
/* Preview signals */
|
||||
void PreviewXScrollBarMoved(int value);
|
||||
void PreviewYScrollBarMoved(int value);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::OBSBasic> ui;
|
||||
|
@ -39,6 +39,15 @@ OBSBasicPreview::~OBSBasicPreview()
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
void OBSBasicPreview::Init()
|
||||
{
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
connect(main, &OBSBasic::PreviewXScrollBarMoved, this,
|
||||
&OBSBasicPreview::XScrollBarMoved);
|
||||
connect(main, &OBSBasic::PreviewYScrollBarMoved, this,
|
||||
&OBSBasicPreview::YScrollBarMoved);
|
||||
}
|
||||
|
||||
vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
|
||||
{
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
|
||||
@ -2327,7 +2336,21 @@ void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal)
|
||||
{
|
||||
scrollingOffset.x *= newScalingAmountVal / scalingAmount;
|
||||
scrollingOffset.y *= newScalingAmountVal / scalingAmount;
|
||||
|
||||
if (scalingAmount == newScalingAmountVal)
|
||||
return;
|
||||
|
||||
scalingAmount = newScalingAmountVal;
|
||||
emit scalingChanged(scalingAmount);
|
||||
}
|
||||
|
||||
void OBSBasicPreview::SetScalingLevelAndAmount(int32_t newScalingLevelVal,
|
||||
float newScalingAmountVal)
|
||||
{
|
||||
newScalingLevelVal = std::clamp(newScalingLevelVal, -MAX_SCALING_LEVEL,
|
||||
MAX_SCALING_LEVEL);
|
||||
scalingLevel = newScalingLevelVal;
|
||||
SetScalingAmount(newScalingAmountVal);
|
||||
}
|
||||
|
||||
OBSBasicPreview *OBSBasicPreview::Get()
|
||||
@ -2689,4 +2712,65 @@ void OBSBasicPreview::ClampScrollingOffsets()
|
||||
|
||||
scrollingOffset.x = std::clamp(scrollingOffset.x, -offset.x, offset.x);
|
||||
scrollingOffset.y = std::clamp(scrollingOffset.y, -offset.y, offset.y);
|
||||
|
||||
UpdateXScrollBar(offset.x);
|
||||
UpdateYScrollBar(offset.y);
|
||||
}
|
||||
|
||||
void OBSBasicPreview::XScrollBarMoved(int value)
|
||||
{
|
||||
updatingXScrollBar = true;
|
||||
scrollingOffset.x = float(-value);
|
||||
|
||||
emit DisplayResized();
|
||||
updatingXScrollBar = false;
|
||||
}
|
||||
|
||||
void OBSBasicPreview::YScrollBarMoved(int value)
|
||||
{
|
||||
updatingYScrollBar = true;
|
||||
scrollingOffset.y = float(-value);
|
||||
|
||||
emit DisplayResized();
|
||||
updatingYScrollBar = false;
|
||||
}
|
||||
|
||||
void OBSBasicPreview::UpdateXScrollBar(float cx)
|
||||
{
|
||||
if (updatingXScrollBar)
|
||||
return;
|
||||
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
|
||||
if (!main->ui->previewXScrollBar->isVisible())
|
||||
return;
|
||||
|
||||
main->ui->previewXScrollBar->setRange(int(-cx), int(cx));
|
||||
|
||||
QSize targetSize = GetPixelSize(this);
|
||||
main->ui->previewXScrollBar->setPageStep(targetSize.width() /
|
||||
std::min(scalingAmount, 1.0f));
|
||||
|
||||
QSignalBlocker sig(main->ui->previewXScrollBar);
|
||||
main->ui->previewXScrollBar->setValue(int(-scrollingOffset.x));
|
||||
}
|
||||
|
||||
void OBSBasicPreview::UpdateYScrollBar(float cy)
|
||||
{
|
||||
if (updatingYScrollBar)
|
||||
return;
|
||||
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
|
||||
if (!main->ui->previewYScrollBar->isVisible())
|
||||
return;
|
||||
|
||||
main->ui->previewYScrollBar->setRange(int(-cy), int(cy));
|
||||
|
||||
QSize targetSize = GetPixelSize(this);
|
||||
main->ui->previewYScrollBar->setPageStep(targetSize.height() /
|
||||
std::min(scalingAmount, 1.0f));
|
||||
|
||||
QSignalBlocker sig(main->ui->previewYScrollBar);
|
||||
main->ui->previewYScrollBar->setValue(int(-scrollingOffset.y));
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <vector>
|
||||
#include "qt-display.hpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "preview-controls.hpp"
|
||||
|
||||
class OBSBasic;
|
||||
class QMouseEvent;
|
||||
@ -18,8 +19,8 @@ class QMouseEvent;
|
||||
#define ITEM_BOTTOM (1 << 3)
|
||||
#define ITEM_ROT (1 << 4)
|
||||
|
||||
#define MAX_SCALING_LEVEL 20
|
||||
#define MAX_SCALING_AMOUNT 10.0f
|
||||
#define MAX_SCALING_LEVEL 32
|
||||
#define MAX_SCALING_AMOUNT 8.0f
|
||||
#define ZOOM_SENSITIVITY pow(MAX_SCALING_AMOUNT, 1.0f / MAX_SCALING_LEVEL)
|
||||
|
||||
#define SPACER_LABEL_MARGIN 6.0f
|
||||
@ -81,6 +82,8 @@ private:
|
||||
int32_t scalingLevel = 0;
|
||||
float scalingAmount = 1.0f;
|
||||
float groupRot = 0.0f;
|
||||
bool updatingXScrollBar = false;
|
||||
bool updatingYScrollBar = false;
|
||||
|
||||
std::vector<obs_sceneitem_t *> hoveredPreviewItems;
|
||||
std::vector<obs_sceneitem_t *> selectedItems;
|
||||
@ -124,11 +127,17 @@ private:
|
||||
OBSDataAutoRelease wrapper = nullptr;
|
||||
bool changed;
|
||||
|
||||
private slots:
|
||||
void XScrollBarMoved(int value);
|
||||
void YScrollBarMoved(int value);
|
||||
|
||||
public:
|
||||
OBSBasicPreview(QWidget *parent,
|
||||
Qt::WindowFlags flags = Qt::WindowFlags());
|
||||
~OBSBasicPreview();
|
||||
|
||||
void Init();
|
||||
|
||||
static OBSBasicPreview *Get();
|
||||
|
||||
virtual void keyPressEvent(QKeyEvent *event) override;
|
||||
@ -150,12 +159,18 @@ public:
|
||||
|
||||
inline void SetFixedScaling(bool newFixedScalingVal)
|
||||
{
|
||||
if (fixedScaling == newFixedScalingVal)
|
||||
return;
|
||||
|
||||
fixedScaling = newFixedScalingVal;
|
||||
emit fixedScalingChanged(fixedScaling);
|
||||
}
|
||||
inline bool IsFixedScaling() const { return fixedScaling; }
|
||||
|
||||
void SetScalingLevel(int32_t newScalingLevelVal);
|
||||
void SetScalingAmount(float newScalingAmountVal);
|
||||
void SetScalingLevelAndAmount(int32_t newScalingLevelVal,
|
||||
float newScalingAmountVal);
|
||||
inline int32_t GetScalingLevel() const { return scalingLevel; }
|
||||
inline float GetScalingAmount() const { return scalingAmount; }
|
||||
|
||||
@ -198,4 +213,10 @@ public:
|
||||
|
||||
void DrawSpacingHelpers();
|
||||
void ClampScrollingOffsets();
|
||||
void UpdateXScrollBar(float cx);
|
||||
void UpdateYScrollBar(float cy);
|
||||
|
||||
signals:
|
||||
void scalingChanged(float scalingAmount);
|
||||
void fixedScalingChanged(bool isFixed);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user