UI: Allow zoom with the scroll wheel

Adds the ability to zoom into the preview when fixed scaling mode is
enabled.

(Edit by Jim: Also now saves zoom and scroll position)

Closes jp9000/obs-studio#917
This commit is contained in:
Joseph El-Khouri 2017-05-13 13:13:55 -04:00 • committed by jp9000
commit 8942c18695
3 changed files with 103 additions and 52 deletions

View file

@ -430,8 +430,14 @@ void OBSBasic::Save(const char *file)
savedPreviewProjectorList);
obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked());
obs_data_set_int(saveData, "scaling_mode",
static_cast<uint32_t>(ui->preview->GetScalingMode()));
obs_data_set_bool(saveData, "scaling_enabled",
ui->preview->IsFixedScaling());
obs_data_set_int(saveData, "scaling_level",
ui->preview->GetScalingLevel());
obs_data_set_double(saveData, "scaling_off_x",
ui->preview->GetScrollX());
obs_data_set_double(saveData, "scaling_off_y",
ui->preview->GetScrollY());
if (api) {
obs_data_t *moduleObj = obs_data_create();
@ -771,18 +777,20 @@ retryScene:
ui->preview->SetLocked(previewLocked);
ui->actionLockPreview->setChecked(previewLocked);
ScalingMode previewScaling = static_cast<ScalingMode>(
obs_data_get_int(data, "scaling_mode"));
switch (previewScaling) {
case ScalingMode::Window:
case ScalingMode::Canvas:
case ScalingMode::Output:
break;
default:
previewScaling = ScalingMode::Window;
}
/* ---------------------- */
ui->preview->SetScaling(previewScaling);
bool fixedScaling = obs_data_get_bool(data, "scaling_enabled");
int scalingLevel = (int)obs_data_get_int(data, "scaling_level");
float scrollOffX = (float)obs_data_get_double(data, "scaling_off_x");
float scrollOffY = (float)obs_data_get_double(data, "scaling_off_y");
if (fixedScaling) {
ui->preview->SetScalingLevel(scalingLevel);
ui->preview->SetScrollingOffset(scrollOffX, scrollOffY);
}
ui->preview->SetFixedScaling(fixedScaling);
/* ---------------------- */
if (api) {
obs_data_t *modulesObj = obs_data_get_obj(data, "modules");
@ -1848,13 +1856,22 @@ OBSSceneItem OBSBasic::GetCurrentSceneItem()
void OBSBasic::UpdatePreviewScalingMenu()
{
ScalingMode scalingMode = ui->preview->GetScalingMode();
ui->actionScaleWindow->setChecked(
scalingMode == ScalingMode::Window);
ui->actionScaleCanvas->setChecked(
scalingMode == ScalingMode::Canvas);
bool fixedScaling = ui->preview->IsFixedScaling();
float scalingAmount = ui->preview->GetScalingAmount();
if (!fixedScaling) {
ui->actionScaleWindow->setChecked(true);
ui->actionScaleCanvas->setChecked(false);
ui->actionScaleOutput->setChecked(false);
return;
}
obs_video_info ovi;
obs_get_video_info(&ovi);
ui->actionScaleWindow->setChecked(false);
ui->actionScaleCanvas->setChecked(scalingAmount == 1.0f);
ui->actionScaleOutput->setChecked(
scalingMode == ScalingMode::Output);
scalingAmount == float(ovi.output_width) / float(ovi.base_width));
}
void OBSBasic::UpdateSources(OBSScene scene)
@ -2844,32 +2861,23 @@ void OBSBasic::ResetAudioDevice(const char *sourceId, const char *deviceId,
void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy)
{
QSize targetSize;
ScalingMode scalingMode;
bool isFixedScaling;
obs_video_info ovi;
/* resize preview panel to fix to the top section of the window */
targetSize = GetPixelSize(ui->preview);
scalingMode = ui->preview->GetScalingMode();
isFixedScaling = ui->preview->IsFixedScaling();
obs_get_video_info(&ovi);
if (scalingMode == ScalingMode::Canvas) {
previewScale = 1.0f;
if (isFixedScaling) {
previewScale = ui->preview->GetScalingAmount();
GetCenterPosFromFixedScale(int(cx), int(cy),
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
targetSize.height() - PREVIEW_EDGE_SIZE * 2,
previewX, previewY, previewScale);
previewX += ui->preview->ScrollX();
previewY += ui->preview->ScrollY();
} else if (scalingMode == ScalingMode::Output) {
previewScale = float(ovi.output_width) / float(ovi.base_width);
GetCenterPosFromFixedScale(int(cx), int(cy),
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
targetSize.height() - PREVIEW_EDGE_SIZE * 2,
previewX, previewY, previewScale);
previewX += ui->preview->ScrollX();
previewY += ui->preview->ScrollY();
previewX += ui->preview->GetScrollX();
previewY += ui->preview->GetScrollY();
} else {
GetScaleAndCenterPos(int(cx), int(cy),
@ -5290,26 +5298,38 @@ void OBSBasic::on_scalingMenu_aboutToShow()
text = text.arg(QString::number(ovi.output_width),
QString::number(ovi.output_height));
action->setText(text);
action->setVisible(!(ovi.output_width == ovi.base_width &&
ovi.output_height == ovi.base_height));
UpdatePreviewScalingMenu();
}
void OBSBasic::on_actionScaleWindow_triggered()
{
ui->preview->SetScaling(ScalingMode::Window);
ui->preview->SetFixedScaling(false);
ui->preview->ResetScrollingOffset();
emit ui->preview->DisplayResized();
}
void OBSBasic::on_actionScaleCanvas_triggered()
{
ui->preview->SetScaling(ScalingMode::Canvas);
ui->preview->SetFixedScaling(true);
ui->preview->SetScalingLevel(0);
emit ui->preview->DisplayResized();
}
void OBSBasic::on_actionScaleOutput_triggered()
{
ui->preview->SetScaling(ScalingMode::Output);
obs_video_info ovi;
obs_get_video_info(&ovi);
ui->preview->SetFixedScaling(true);
float scalingAmount = float(ovi.output_width) / float(ovi.base_width);
// 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);
emit ui->preview->DisplayResized();
}