void OBSProjector::mousePressEvent(QMouseEvent *event) { OBSQTDisplay::mousePressEvent(event); if (event->button() == Qt::RightButton) { QMenu popup(this); popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered())); popup.exec(QCursor::pos()); } if (!mouseSwitching) return; if (event->button() == Qt::LeftButton) { int pos = getSourceByPosition(event->x(), event->y(), ratio); if (pos < 0 || pos >= (int)numSrcs) return; OBSSource src = OBSGetStrongRef(multiviewScenes[pos]); if (!src) return; OBSBasic *main = (OBSBasic*)obs_frontend_get_main_window(); if (main->GetCurrentSceneSource() != src) main->SetCurrentScene(src, false); } }
void AutoConfig::SaveSettings() { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); if (recordingEncoder != Encoder::Stream) config_set_string(main->Config(), "SimpleOutput", "RecEncoder", GetEncoderId(recordingEncoder)); const char *quality = recordingQuality == Quality::High ? "Small" : "Stream"; config_set_string(main->Config(), "Output", "Mode", "Simple"); config_set_string(main->Config(), "SimpleOutput", "RecQuality", quality); config_set_int(main->Config(), "Video", "BaseCX", baseResolutionCX); config_set_int(main->Config(), "Video", "BaseCY", baseResolutionCY); config_set_int(main->Config(), "Video", "OutputCX", idealResolutionCX); config_set_int(main->Config(), "Video", "OutputCY", idealResolutionCY); if (fpsType != FPSType::UseCurrent) { config_set_uint(main->Config(), "Video", "FPSType", 0); config_set_string(main->Config(), "Video", "FPSCommon", std::to_string(idealFPSNum).c_str()); } main->ResetVideo(); main->ResetOutputs(); config_save_safe(main->Config(), "tmp", nullptr); }
void OBSProjector::mouseDoubleClickEvent(QMouseEvent *event) { OBSQTDisplay::mouseDoubleClickEvent(event); if (!mouseSwitching) return; if (!transitionOnDoubleClick) return; OBSBasic *main = (OBSBasic*)obs_frontend_get_main_window(); if (!main->IsPreviewProgramMode()) return; if (event->button() == Qt::LeftButton) { int pos = getSourceByPosition(event->x(), event->y(), ratio); if (pos < 0 || pos >= (int)numSrcs) return; OBSSource src = OBSGetStrongRef(multiviewScenes[pos]); if (!src) return; if (main->GetProgramSource() != src) main->TransitionToScene(src); } }
void OBSBasicPreview::DrawSceneEditing() { if (locked) return; OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); vec4 color; vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f); gs_effect_set_vec4(gs_effect_get_param_by_name(solid, "color"), &color); gs_technique_begin(tech); gs_technique_begin_pass(tech, 0); OBSScene scene = main->GetCurrentScene(); if (scene) { gs_matrix_push(); gs_matrix_scale3f(main->previewScale, main->previewScale, 1.0f); obs_scene_enum_items(scene, DrawSelectedItem, this); gs_matrix_pop(); } gs_load_vertexbuffer(nullptr); gs_technique_end_pass(tech); gs_technique_end(tech); }
static void AddExisting(const char *name, bool visible, bool duplicate) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) return; obs_source_t *source = obs_get_source_by_name(name); if (source) { if (duplicate) { obs_source_t *from = source; char *new_name = get_new_source_name(name); source = obs_source_duplicate(from, new_name, false); bfree(new_name); obs_source_release(from); if (!source) return; } AddSourceData data; data.source = source; data.visible = visible; obs_enter_graphics(); obs_scene_atomic_update(scene, AddSource, &data); obs_leave_graphics(); obs_source_release(source); } }
void OBSBasicPreview::GetStretchHandleData(const vec2 &pos) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) return; float scale = main->previewScale / main->devicePixelRatio(); vec2 scaled_pos = pos; vec2_divf(&scaled_pos, &scaled_pos, scale); HandleFindData data(scaled_pos, scale); obs_scene_enum_items(scene, FindHandleAtPos, &data); stretchItem = std::move(data.item); stretchHandle = data.handle; if (stretchHandle != ItemHandle::None) { matrix4 boxTransform; vec3 itemUL; float itemRot; stretchItemSize = GetItemSize(stretchItem); obs_sceneitem_get_box_transform(stretchItem, &boxTransform); itemRot = obs_sceneitem_get_rot(stretchItem); vec3_from_vec4(&itemUL, &boxTransform.t); /* build the item space conversion matrices */ matrix4_identity(&itemToScreen); matrix4_rotate_aa4f(&itemToScreen, &itemToScreen, 0.0f, 0.0f, 1.0f, RAD(itemRot)); matrix4_translate3f(&itemToScreen, &itemToScreen, itemUL.x, itemUL.y, 0.0f); matrix4_identity(&screenToItem); matrix4_translate3f(&screenToItem, &screenToItem, -itemUL.x, -itemUL.y, 0.0f); matrix4_rotate_aa4f(&screenToItem, &screenToItem, 0.0f, 0.0f, 1.0f, RAD(-itemRot)); obs_sceneitem_get_crop(stretchItem, &startCrop); obs_sceneitem_get_pos(stretchItem, &startItemPos); obs_source_t *source = obs_sceneitem_get_source(stretchItem); cropSize.x = float(obs_source_get_width(source) - startCrop.left - startCrop.right); cropSize.y = float(obs_source_get_height(source) - startCrop.top - startCrop.bottom); stretchGroup = obs_sceneitem_get_group(scene, stretchItem); if (stretchGroup) { obs_sceneitem_get_draw_transform(stretchGroup, &invGroupTransform); matrix4_inv(&invGroupTransform, &invGroupTransform); obs_sceneitem_defer_group_resize_begin(stretchGroup); } } }
void OBSBasicPreview::DoSelect(const vec2 &pos) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); OBSSceneItem item = GetItemAtPos(pos, true); obs_scene_enum_items(scene, select_one, (obs_sceneitem_t*)item); }
OBSBasicAdvAudio::~OBSBasicAdvAudio() { OBSBasic *main = reinterpret_cast<OBSBasic*>(parent()); for (size_t i = 0; i < controls.size(); ++i) delete controls[i]; main->SaveProject(); }
void OBSBasic::SceneItemRemoved(void *data, calldata_t params) { OBSBasic *window = static_cast<OBSBasic*>(data); obs_scene_t scene = (obs_scene_t)calldata_ptr(params, "scene"); obs_sceneitem_t item = (obs_sceneitem_t)calldata_ptr(params, "item"); window->RemoveSceneItem(item); }
void OAuth::SaveInternal() { OBSBasic *main = OBSBasic::Get(); config_set_string(main->Config(), service(), "RefreshToken", refresh_token.c_str()); config_set_string(main->Config(), service(), "Token", token.c_str()); config_set_uint(main->Config(), service(), "ExpireTime", expire_time); config_set_int(main->Config(), service(), "ScopeVer", currentScopeVer); }
OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_) : QDialog (parent), ui (new Ui::OBSBasicSourceSelect), id (id_) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); ui->setupUi(this); ui->sourceList->setAttribute(Qt::WA_MacShowFocusRect, false); QString placeHolderText{QT_UTF8(GetSourceDisplayName(id))}; QString text{placeHolderText}; int i = 2; obs_source_t *source = nullptr; while ((source = obs_get_source_by_name(QT_TO_UTF8(text)))) { obs_source_release(source); text = QString("%1 %2").arg(placeHolderText).arg(i++); } ui->sourceName->setText(text); ui->sourceName->setFocus(); //Fixes deselect of text. ui->sourceName->selectAll(); installEventFilter(CreateShortcutFilter()); if (strcmp(id_, "scene") == 0) { OBSBasic *main = reinterpret_cast<OBSBasic*>( App()->GetMainWindow()); OBSSource curSceneSource = main->GetCurrentSceneSource(); ui->selectExisting->setChecked(true); ui->createNew->setChecked(false); ui->createNew->setEnabled(false); ui->sourceName->setEnabled(false); int count = main->ui->scenes->count(); for (int i = 0; i < count; i++) { QListWidgetItem *item = main->ui->scenes->item(i); OBSScene scene = GetOBSRef<OBSScene>(item); OBSSource sceneSource = obs_scene_get_source(scene); if (curSceneSource == sceneSource) continue; const char *name = obs_source_get_name(sceneSource); ui->sourceList->addItem(QT_UTF8(name)); } } else if (strcmp(id_, "group") == 0) { obs_enum_sources(EnumGroups, this); } else { obs_enum_sources(EnumSources, this); } }
void OBSBasic::RefreshSceneCollections() { QList<QAction*> menuActions = ui->sceneCollectionMenu->actions(); int count = 0; for (int i = 0; i < menuActions.count(); i++) { QVariant v = menuActions[i]->property("file_name"); if (v.typeName() != nullptr) delete menuActions[i]; } const char *cur_name = config_get_string(App()->GlobalConfig(), "Basic", "SceneCollection"); auto addCollection = [&](const char *name, const char *path) { std::string file = strrchr(path, '/') + 1; file.erase(file.size() - 5, 5); QAction *action = new QAction(QT_UTF8(name), this); action->setProperty("file_name", QT_UTF8(path)); connect(action, &QAction::triggered, this, &OBSBasic::ChangeSceneCollection); action->setCheckable(true); action->setChecked(strcmp(name, cur_name) == 0); ui->sceneCollectionMenu->addAction(action); count++; return true; }; EnumSceneCollections(addCollection); /* force saving of first scene collection on first run, otherwise * no scene collections will show up */ if (!count) { long prevDisableVal = disableSaving; disableSaving = 0; SaveProjectNow(); disableSaving = prevDisableVal; EnumSceneCollections(addCollection); } ui->actionRemoveSceneCollection->setEnabled(count > 1); OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); main->OpenSavedProjectors(); main->ui->actionPasteFilters->setEnabled(false); main->ui->actionPasteRef->setEnabled(false); main->ui->actionPasteDup->setEnabled(false); }
void MixerAuth::SaveInternal() { OBSBasic *main = OBSBasic::Get(); config_set_string(main->Config(), service(), "Name", name.c_str()); config_set_string(main->Config(), service(), "Id", id.c_str()); if (uiLoaded) { config_set_string(main->Config(), service(), "DockState", main->saveState().toBase64().constData()); } OAuthStreamKey::SaveInternal(); }
void OBSProjector::EscapeTriggered() { if (!isWindow) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); main->RemoveSavedProjectors(savedMonitor); } deleteLater(); }
void OBSBasic::AddDropSource(const char *data, DropType image) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); obs_data_t *settings = obs_data_create(); obs_source_t *source = nullptr; const char *type = nullptr; QString name; switch (image) { case DropType_RawText: obs_data_set_string(settings, "text", data); #ifdef _WIN32 type = "text_gdiplus"; #else type = "text_ft2_source"; #endif break; case DropType_Text: #ifdef _WIN32 obs_data_set_bool(settings, "read_from_file", true); obs_data_set_string(settings, "file", data); name = QUrl::fromLocalFile(QString(data)).fileName(); type = "text_gdiplus"; #else obs_data_set_bool(settings, "from_file", true); obs_data_set_string(settings, "text_file", data); type = "text_ft2_source"; #endif break; case DropType_Image: obs_data_set_string(settings, "file", data); name = QUrl::fromLocalFile(QString(data)).fileName(); type = "image_source"; break; case DropType_Media: obs_data_set_string(settings, "local_file", data); name = QUrl::fromLocalFile(QString(data)).fileName(); type = "ffmpeg_source"; break; } if (name.isEmpty()) name = obs_source_get_display_name(type); source = obs_source_create(type, GenerateSourceName(QT_TO_UTF8(name)).c_str(), settings, nullptr); if (source) { OBSScene scene = main->GetCurrentScene(); obs_scene_add(scene, source); obs_source_release(source); } obs_data_release(settings); }
void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy) { OBSProjector *window = reinterpret_cast<OBSProjector*>(data); if (!window->ready) return; OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSSource source = window->source; uint32_t targetCX; uint32_t targetCY; int x, y; int newCX, newCY; float scale; if (source) { targetCX = std::max(obs_source_get_width(source), 1u); targetCY = std::max(obs_source_get_height(source), 1u); } else { struct obs_video_info ovi; obs_get_video_info(&ovi); targetCX = ovi.base_width; targetCY = ovi.base_height; } GetScaleAndCenterPos(targetCX, targetCY, cx, cy, x, y, scale); newCX = int(scale * float(targetCX)); newCY = int(scale * float(targetCY)); startRegion(x, y, newCX, newCY, 0.0f, float(targetCX), 0.0f, float(targetCY)); if (window->type == ProjectorType::Preview && main->IsPreviewProgramMode()) { OBSSource curSource = main->GetCurrentSceneSource(); if (source != curSource) { obs_source_dec_showing(source); obs_source_inc_showing(curSource); source = curSource; window->source = source; } } if (source) obs_source_video_render(source); else obs_render_main_texture(); endRegion(); }
vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); float pixelRatio = main->devicePixelRatio(); float scale = pixelRatio / main->previewScale; vec2 pos; vec2_set(&pos, (float(event->x()) - main->previewX / pixelRatio) * scale, (float(event->y()) - main->previewY / pixelRatio) * scale); return pos; }
bool OBSBasicPreview::SelectedAtPos(const vec2 &pos) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) return false; SceneFindData data(pos, false); obs_scene_enum_items(scene, CheckItemSelected, &data); return !!data.item; }
OBSSceneItem OBSBasicPreview::GetItemAtPos(const vec2 &pos, bool selectBelow) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) return OBSSceneItem(); SceneFindData data(pos, selectBelow); obs_scene_enum_items(scene, FindItemAtPos, &data); return data.item; }
void OBSBasic::UpdateSources(obs_scene_t scene) { sources->Clear(); obs_scene_enum_items(scene, [] (obs_scene_t scene, obs_sceneitem_t item, void *p) { OBSBasic *window = static_cast<OBSBasic*>(p); window->AddSceneItem(item); return true; }, this); }
void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) { if (scrollMode && event->buttons() == Qt::LeftButton) { scrollingOffset.x += event->x() - scrollingFrom.x; scrollingOffset.y += event->y() - scrollingFrom.y; scrollingFrom.x = event->x(); scrollingFrom.y = event->y(); emit DisplayResized(); return; } if (locked) return; if (mouseDown) { vec2 pos = GetMouseEventPos(event); if (!mouseMoved && !mouseOverItems && stretchHandle == ItemHandle::None) { ProcessClick(startPos); mouseOverItems = SelectedAtPos(startPos); } pos.x = std::round(pos.x); pos.y = std::round(pos.y); if (stretchHandle != ItemHandle::None) { OBSBasic *main = reinterpret_cast<OBSBasic*>( App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); obs_sceneitem_t *group = obs_sceneitem_get_group( scene, stretchItem); if (group) { vec3 group_pos; vec3_set(&group_pos, pos.x, pos.y, 0.0f); vec3_transform(&group_pos, &group_pos, &invGroupTransform); pos.x = group_pos.x; pos.y = group_pos.y; } if (cropping) CropItem(pos); else StretchItem(pos); } else if (mouseOverItems) { MoveItems(pos); } mouseMoved = true; } }
void OBSBasicStatusBar::UpdateCPUUsage() { OBSBasic *main = qobject_cast<OBSBasic*>(parent()); if (!main) return; QString text; text += QString("CPU: ") + QString::number(main->GetCPUUsage(), 'f', 1) + QString("%"); cpuUsage->setText(text); cpuUsage->setMinimumWidth(cpuUsage->width()); }
void OBSBasicPreview::mousePressEvent(QMouseEvent *event) { if (scrollMode && IsFixedScaling() && event->button() == Qt::LeftButton) { setCursor(Qt::ClosedHandCursor); scrollingFrom.x = event->x(); scrollingFrom.y = event->y(); return; } if (event->button() == Qt::RightButton) { scrollMode = false; setCursor(Qt::ArrowCursor); } if (locked) { OBSQTDisplay::mousePressEvent(event); return; } 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(); bool altDown = (modifiers & Qt::AltModifier); OBSQTDisplay::mousePressEvent(event); if (event->button() != Qt::LeftButton && event->button() != Qt::RightButton) return; if (event->button() == Qt::LeftButton) mouseDown = true; if (altDown) cropping = true; vec2_set(&startPos, x, y); GetStretchHandleData(startPos); vec2_divf(&startPos, &startPos, main->previewScale / pixelRatio); startPos.x = std::round(startPos.x); startPos.y = std::round(startPos.y); mouseOverItems = SelectedAtPos(startPos); vec2_zero(&lastMoveOffset); }
void OAuthStreamKey::OnStreamConfig() { OBSBasic *main = OBSBasic::Get(); obs_service_t *service = main->GetService(); obs_data_t *settings = obs_service_get_settings(service); obs_data_set_string(settings, "key", key_.c_str()); obs_service_update(service, settings); obs_data_release(settings); }
bool OAuth::LoadInternal() { OBSBasic *main = OBSBasic::Get(); refresh_token = get_config_str(main, service(), "RefreshToken"); token = get_config_str(main, service(), "Token"); expire_time = config_get_uint(main->Config(), service(), "ExpireTime"); currentScopeVer = (int)config_get_int(main->Config(), service(), "ScopeVer"); return implicit ? !token.empty() : !refresh_token.empty(); }
void OBSBasic::UpdateSources(OBSScene scene) { ui->sources->clear(); obs_scene_enum_items(scene, [] (obs_scene_t scene, obs_sceneitem_t item, void *p) { OBSBasic *window = static_cast<OBSBasic*>(p); window->InsertSceneItem(item); UNUSED_PARAMETER(scene); return true; }, this); }
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, (float(event->x()) - main->previewX / pixelRatio) * scale, (float(event->y()) - main->previewY / pixelRatio) * scale); return pos; }
void OBSBasicPreview::SnapItemMovement(vec2 &offset) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); SelectedItemBounds data; obs_scene_enum_items(scene, AddItemBounds, &data); data.tl.x += offset.x; data.tl.y += offset.y; data.br.x += offset.x; data.br.y += offset.y; vec3 snapOffset = GetSnapOffset(data.tl, data.br); const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow", "SnappingEnabled"); const bool sourcesSnap = config_get_bool(GetGlobalConfig(), "BasicWindow", "SourceSnapping"); if (snap == false) return; if (sourcesSnap == false) { offset.x += snapOffset.x; offset.y += snapOffset.y; return; } const float clampDist = config_get_double(GetGlobalConfig(), "BasicWindow", "SnapDistance") / main->previewScale; OffsetData offsetData; offsetData.clampDist = clampDist; offsetData.tl = data.tl; offsetData.br = data.br; vec3_copy(&offsetData.offset, &snapOffset); obs_scene_enum_items(scene, GetSourceSnapOffset, &offsetData); if (fabsf(offsetData.offset.x) > EPSILON || fabsf(offsetData.offset.y) > EPSILON) { offset.x += offsetData.offset.x; offset.y += offsetData.offset.y; } else { offset.x += snapOffset.x; offset.y += snapOffset.y; } }
void OBSBasicPreview::SnapItemMovement(vec2 &offset) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); SelectedItemBounds data; obs_scene_enum_items(scene, AddItemBounds, &data); data.tl.x += offset.x; data.tl.y += offset.y; data.br.x += offset.x; data.br.y += offset.y; vec3 snapOffset = GetScreenSnapOffset(data.tl, data.br); offset.x += snapOffset.x; offset.y += snapOffset.y; }
void OBSBasicPreview::MoveItems(const vec2 &pos) { Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); vec2 offset, moveOffset; vec2_sub(&offset, &pos, &startPos); vec2_sub(&moveOffset, &offset, &lastMoveOffset); if (!(modifiers & Qt::ControlModifier)) SnapItemMovement(moveOffset); vec2_add(&lastMoveOffset, &lastMoveOffset, &moveOffset); obs_scene_enum_items(scene, move_items, &moveOffset); }