1 /****************************************************************************** 2 Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 ******************************************************************************/ 17 18 #pragma once 19 20 #include <QBuffer> 21 #include <QAction> 22 #include <QThread> 23 #include <QWidgetAction> 24 #include <QSystemTrayIcon> 25 #include <QStyledItemDelegate> 26 #include <obs.hpp> 27 #include <vector> 28 #include <memory> 29 #include "window-main.hpp" 30 #include "window-basic-interaction.hpp" 31 #include "window-basic-properties.hpp" 32 #include "window-basic-transform.hpp" 33 #include "window-basic-adv-audio.hpp" 34 #include "window-basic-filters.hpp" 35 #include "window-missing-files.hpp" 36 #include "window-projector.hpp" 37 #include "window-basic-about.hpp" 38 #include "auth-base.hpp" 39 #include "log-viewer.hpp" 40 #include "undo-stack-obs.hpp" 41 42 #include <obs-frontend-internal.hpp> 43 44 #include <util/platform.h> 45 #include <util/threading.h> 46 #include <util/util.hpp> 47 48 #include <QPointer> 49 50 class QMessageBox; 51 class QListWidgetItem; 52 class VolControl; 53 class OBSBasicStats; 54 55 #include "ui_OBSBasic.h" 56 #include "ui_ColorSelect.h" 57 58 #define DESKTOP_AUDIO_1 Str("DesktopAudioDevice1") 59 #define DESKTOP_AUDIO_2 Str("DesktopAudioDevice2") 60 #define AUX_AUDIO_1 Str("AuxAudioDevice1") 61 #define AUX_AUDIO_2 Str("AuxAudioDevice2") 62 #define AUX_AUDIO_3 Str("AuxAudioDevice3") 63 #define AUX_AUDIO_4 Str("AuxAudioDevice4") 64 65 #define SIMPLE_ENCODER_X264 "x264" 66 #define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu" 67 #define SIMPLE_ENCODER_QSV "qsv" 68 #define SIMPLE_ENCODER_NVENC "nvenc" 69 #define SIMPLE_ENCODER_AMD "amd" 70 71 #define PREVIEW_EDGE_SIZE 10 72 73 struct BasicOutputHandler; 74 75 enum class QtDataRole { 76 OBSRef = Qt::UserRole, 77 OBSSignals, 78 }; 79 80 struct SavedProjectorInfo { 81 ProjectorType type; 82 int monitor; 83 std::string geometry; 84 std::string name; 85 bool alwaysOnTop; 86 bool alwaysOnTopOverridden; 87 }; 88 89 struct QuickTransition { 90 QPushButton *button = nullptr; 91 OBSSource source; 92 obs_hotkey_id hotkey = OBS_INVALID_HOTKEY_ID; 93 int duration = 0; 94 int id = 0; 95 bool fadeToBlack = false; 96 QuickTransitionQuickTransition97 inline QuickTransition() {} QuickTransitionQuickTransition98 inline QuickTransition(OBSSource source_, int duration_, int id_, 99 bool fadeToBlack_ = false) 100 : source(source_), 101 duration(duration_), 102 id(id_), 103 fadeToBlack(fadeToBlack_), 104 renamedSignal(std::make_shared<OBSSignal>( 105 obs_source_get_signal_handler(source), "rename", 106 SourceRenamed, this)) 107 { 108 } 109 110 private: 111 static void SourceRenamed(void *param, calldata_t *data); 112 std::shared_ptr<OBSSignal> renamedSignal; 113 }; 114 115 class ColorSelect : public QWidget { 116 117 public: 118 explicit ColorSelect(QWidget *parent = 0); 119 120 private: 121 std::unique_ptr<Ui::ColorSelect> ui; 122 }; 123 124 class OBSBasic : public OBSMainWindow { 125 Q_OBJECT 126 Q_PROPERTY(QIcon imageIcon READ GetImageIcon WRITE SetImageIcon 127 DESIGNABLE true) 128 Q_PROPERTY(QIcon colorIcon READ GetColorIcon WRITE SetColorIcon 129 DESIGNABLE true) 130 Q_PROPERTY(QIcon slideshowIcon READ GetSlideshowIcon WRITE 131 SetSlideshowIcon DESIGNABLE true) 132 Q_PROPERTY(QIcon audioInputIcon READ GetAudioInputIcon WRITE 133 SetAudioInputIcon DESIGNABLE true) 134 Q_PROPERTY(QIcon audioOutputIcon READ GetAudioOutputIcon WRITE 135 SetAudioOutputIcon DESIGNABLE true) 136 Q_PROPERTY(QIcon desktopCapIcon READ GetDesktopCapIcon WRITE 137 SetDesktopCapIcon DESIGNABLE true) 138 Q_PROPERTY(QIcon windowCapIcon READ GetWindowCapIcon WRITE 139 SetWindowCapIcon DESIGNABLE true) 140 Q_PROPERTY(QIcon gameCapIcon READ GetGameCapIcon WRITE SetGameCapIcon 141 DESIGNABLE true) 142 Q_PROPERTY(QIcon cameraIcon READ GetCameraIcon WRITE SetCameraIcon 143 DESIGNABLE true) 144 Q_PROPERTY(QIcon textIcon READ GetTextIcon WRITE SetTextIcon 145 DESIGNABLE true) 146 Q_PROPERTY(QIcon mediaIcon READ GetMediaIcon WRITE SetMediaIcon 147 DESIGNABLE true) 148 Q_PROPERTY(QIcon browserIcon READ GetBrowserIcon WRITE SetBrowserIcon 149 DESIGNABLE true) 150 Q_PROPERTY(QIcon groupIcon READ GetGroupIcon WRITE SetGroupIcon 151 DESIGNABLE true) 152 Q_PROPERTY(QIcon sceneIcon READ GetSceneIcon WRITE SetSceneIcon 153 DESIGNABLE true) 154 Q_PROPERTY(QIcon defaultIcon READ GetDefaultIcon WRITE SetDefaultIcon 155 DESIGNABLE true) 156 157 friend class OBSAbout; 158 friend class OBSBasicPreview; 159 friend class OBSBasicStatusBar; 160 friend class OBSBasicSourceSelect; 161 friend class OBSBasicTransform; 162 friend class OBSBasicSettings; 163 friend class Auth; 164 friend class AutoConfig; 165 friend class AutoConfigStreamPage; 166 friend class RecordButton; 167 friend class ReplayBufferButton; 168 friend class ExtraBrowsersModel; 169 friend class ExtraBrowsersDelegate; 170 friend class DeviceCaptureToolbar; 171 friend class DeviceToolbarPropertiesThread; 172 friend class OBSBasicSourceSelect; 173 friend class OBSYoutubeActions; 174 friend struct BasicOutputHandler; 175 friend struct OBSStudioAPI; 176 177 enum class MoveDir { Up, Down, Left, Right }; 178 179 enum DropType { 180 DropType_RawText, 181 DropType_Text, 182 DropType_Image, 183 DropType_Media, 184 DropType_Html, 185 DropType_Url, 186 }; 187 188 private: 189 obs_frontend_callbacks *api = nullptr; 190 191 std::shared_ptr<Auth> auth; 192 193 std::vector<VolControl *> volumes; 194 195 std::vector<OBSSignal> signalHandlers; 196 197 QList<QPointer<QDockWidget>> extraDocks; 198 199 bool loaded = false; 200 long disableSaving = 1; 201 bool projectChanged = false; 202 bool previewEnabled = true; 203 204 std::list<const char *> copyStrings; 205 const char *copyFiltersString = nullptr; 206 bool copyVisible = true; 207 208 bool closing = false; 209 QScopedPointer<QThread> devicePropertiesThread; 210 QScopedPointer<QThread> whatsNewInitThread; 211 QScopedPointer<QThread> updateCheckThread; 212 QScopedPointer<QThread> introCheckThread; 213 QScopedPointer<QThread> logUploadThread; 214 215 QPointer<OBSBasicInteraction> interaction; 216 QPointer<OBSBasicProperties> properties; 217 QPointer<OBSBasicTransform> transformWindow; 218 QPointer<OBSBasicAdvAudio> advAudioWindow; 219 QPointer<OBSBasicFilters> filters; 220 QPointer<QDockWidget> statsDock; 221 QPointer<OBSAbout> about; 222 QPointer<OBSMissingFiles> missDialog; 223 QPointer<OBSLogViewer> logView; 224 225 QPointer<QTimer> cpuUsageTimer; 226 QPointer<QTimer> diskFullTimer; 227 228 QPointer<QTimer> nudge_timer; 229 bool recent_nudge = false; 230 231 os_cpu_usage_info_t *cpuUsageInfo = nullptr; 232 233 OBSService service; 234 std::unique_ptr<BasicOutputHandler> outputHandler; 235 bool streamingStopping = false; 236 bool recordingStopping = false; 237 bool replayBufferStopping = false; 238 239 gs_vertbuffer_t *box = nullptr; 240 gs_vertbuffer_t *boxLeft = nullptr; 241 gs_vertbuffer_t *boxTop = nullptr; 242 gs_vertbuffer_t *boxRight = nullptr; 243 gs_vertbuffer_t *boxBottom = nullptr; 244 gs_vertbuffer_t *circle = nullptr; 245 246 gs_vertbuffer_t *actionSafeMargin = nullptr; 247 gs_vertbuffer_t *graphicsSafeMargin = nullptr; 248 gs_vertbuffer_t *fourByThreeSafeMargin = nullptr; 249 gs_vertbuffer_t *leftLine = nullptr; 250 gs_vertbuffer_t *topLine = nullptr; 251 gs_vertbuffer_t *rightLine = nullptr; 252 253 int previewX = 0, previewY = 0; 254 int previewCX = 0, previewCY = 0; 255 float previewScale = 0.0f; 256 257 ConfigFile basicConfig; 258 259 std::vector<SavedProjectorInfo *> savedProjectorsArray; 260 std::vector<OBSProjector *> projectors; 261 262 QPointer<QWidget> stats; 263 QPointer<QWidget> remux; 264 QPointer<QWidget> extraBrowsers; 265 QPointer<QWidget> importer; 266 267 QPointer<QMenu> startStreamMenu; 268 269 QPointer<QPushButton> transitionButton; 270 QPointer<QPushButton> replayBufferButton; 271 QPointer<QHBoxLayout> replayLayout; 272 QScopedPointer<QPushButton> pause; 273 QScopedPointer<QPushButton> replay; 274 275 QPointer<QPushButton> vcamButton; 276 bool vcamEnabled = false; 277 278 QScopedPointer<QSystemTrayIcon> trayIcon; 279 QPointer<QAction> sysTrayStream; 280 QPointer<QAction> sysTrayRecord; 281 QPointer<QAction> sysTrayReplayBuffer; 282 QPointer<QAction> sysTrayVirtualCam; 283 QPointer<QAction> showHide; 284 QPointer<QAction> exit; 285 QPointer<QMenu> trayMenu; 286 QPointer<QMenu> previewProjector; 287 QPointer<QMenu> studioProgramProjector; 288 QPointer<QMenu> multiviewProjectorMenu; 289 QPointer<QMenu> previewProjectorSource; 290 QPointer<QMenu> previewProjectorMain; 291 QPointer<QMenu> sceneProjectorMenu; 292 QPointer<QMenu> sourceProjector; 293 QPointer<QMenu> scaleFilteringMenu; 294 QPointer<QMenu> colorMenu; 295 QPointer<QWidgetAction> colorWidgetAction; 296 QPointer<ColorSelect> colorSelect; 297 QPointer<QMenu> deinterlaceMenu; 298 QPointer<QMenu> perSceneTransitionMenu; 299 QPointer<QObject> shortcutFilter; 300 QPointer<QAction> renameScene; 301 QPointer<QAction> renameSource; 302 303 QPointer<QWidget> programWidget; 304 QPointer<QVBoxLayout> programLayout; 305 QPointer<QLabel> programLabel; 306 307 QScopedPointer<QThread> patronJsonThread; 308 std::string patronJson; 309 310 void UpdateMultiviewProjectorMenu(); 311 312 void DrawBackdrop(float cx, float cy); 313 314 void SetupEncoders(); 315 316 void CreateFirstRunSources(); 317 void CreateDefaultScene(bool firstStart); 318 319 void UpdateVolumeControlsDecayRate(); 320 void UpdateVolumeControlsPeakMeterType(); 321 void ClearVolumeControls(); 322 323 void UploadLog(const char *subdir, const char *file, const bool crash); 324 325 void Save(const char *file); 326 void LoadData(obs_data_t *data, const char *file); 327 void Load(const char *file); 328 329 void InitHotkeys(); 330 void CreateHotkeys(); 331 void ClearHotkeys(); 332 333 bool InitService(); 334 335 bool InitBasicConfigDefaults(); 336 void InitBasicConfigDefaults2(); 337 bool InitBasicConfig(); 338 339 void InitOBSCallbacks(); 340 341 void InitPrimitives(); 342 343 void OnFirstLoad(); 344 345 OBSSceneItem GetSceneItem(QListWidgetItem *item); 346 OBSSceneItem GetCurrentSceneItem(); 347 348 bool QueryRemoveSource(obs_source_t *source); 349 350 void TimedCheckForUpdates(); 351 void CheckForUpdates(bool manualUpdate); 352 353 void GetFPSCommon(uint32_t &num, uint32_t &den) const; 354 void GetFPSInteger(uint32_t &num, uint32_t &den) const; 355 void GetFPSFraction(uint32_t &num, uint32_t &den) const; 356 void GetFPSNanoseconds(uint32_t &num, uint32_t &den) const; 357 void GetConfigFPS(uint32_t &num, uint32_t &den) const; 358 359 void UpdatePreviewScalingMenu(); 360 361 void LoadSceneListOrder(obs_data_array_t *array); 362 obs_data_array_t *SaveSceneListOrder(); 363 void ChangeSceneIndex(bool relative, int idx, int invalidIdx); 364 365 void TempFileOutput(const char *path, int vBitrate, int aBitrate); 366 void TempStreamOutput(const char *url, const char *key, int vBitrate, 367 int aBitrate); 368 369 void CloseDialogs(); 370 void ClearSceneData(); 371 void ClearProjectors(); 372 373 void Nudge(int dist, MoveDir dir); 374 375 OBSProjector *OpenProjector(obs_source_t *source, int monitor, 376 ProjectorType type); 377 378 void GetAudioSourceFilters(); 379 void GetAudioSourceProperties(); 380 void VolControlContextMenu(); 381 void ToggleVolControlLayout(); 382 void ToggleMixerLayout(bool vertical); 383 384 void RefreshSceneCollections(); 385 void ChangeSceneCollection(); 386 void LogScenes(); 387 388 void ResetProfileData(); 389 bool AddProfile(bool create_new, const char *title, const char *text, 390 const char *init_text = nullptr, bool rename = false); 391 bool CreateProfile(const std::string &newName, bool create_new, 392 bool showWizardChecked, bool rename = false); 393 void DeleteProfile(const char *profile_name, const char *profile_dir); 394 void RefreshProfiles(); 395 void ChangeProfile(); 396 void CheckForSimpleModeX264Fallback(); 397 398 void SaveProjectNow(); 399 400 int GetTopSelectedSourceItem(); 401 402 QModelIndexList GetAllSelectedSourceItems(); 403 404 obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, pauseHotkeys, 405 replayBufHotkeys, vcamHotkeys, togglePreviewHotkeys, 406 contextBarHotkeys; 407 obs_hotkey_id forceStreamingStopHotkey; 408 409 void InitDefaultTransitions(); 410 void InitTransition(obs_source_t *transition); 411 obs_source_t *FindTransition(const char *name); 412 OBSSource GetCurrentTransition(); 413 obs_data_array_t *SaveTransitions(); 414 void LoadTransitions(obs_data_array_t *transitions, 415 obs_load_source_cb cb, void *private_data); 416 417 obs_source_t *fadeTransition; 418 obs_source_t *cutTransition; 419 420 void CreateProgramDisplay(); 421 void CreateProgramOptions(); 422 int TransitionCount(); 423 int AddTransitionBeforeSeparator(const QString &name, 424 obs_source_t *source); 425 void AddQuickTransitionId(int id); 426 void AddQuickTransition(); 427 void AddQuickTransitionHotkey(QuickTransition *qt); 428 void RemoveQuickTransitionHotkey(QuickTransition *qt); 429 void LoadQuickTransitions(obs_data_array_t *array); 430 obs_data_array_t *SaveQuickTransitions(); 431 void ClearQuickTransitionWidgets(); 432 void RefreshQuickTransitions(); 433 void DisableQuickTransitionWidgets(); 434 void EnableTransitionWidgets(bool enable); 435 void CreateDefaultQuickTransitions(); 436 437 QMenu *CreatePerSceneTransitionMenu(); 438 QMenu *CreateVisibilityTransitionMenu(bool visible); 439 440 QuickTransition *GetQuickTransition(int id); 441 int GetQuickTransitionIdx(int id); 442 QMenu *CreateTransitionMenu(QWidget *parent, QuickTransition *qt); 443 void ClearQuickTransitions(); 444 void QuickTransitionClicked(); 445 void QuickTransitionChange(); 446 void QuickTransitionChangeDuration(int value); 447 void QuickTransitionRemoveClicked(); 448 449 void SetPreviewProgramMode(bool enabled); 450 void ResizeProgram(uint32_t cx, uint32_t cy); 451 void SetCurrentScene(obs_scene_t *scene, bool force = false); 452 static void RenderProgram(void *data, uint32_t cx, uint32_t cy); 453 454 std::vector<QuickTransition> quickTransitions; 455 QPointer<QWidget> programOptions; 456 QPointer<OBSQTDisplay> program; 457 OBSWeakSource lastScene; 458 OBSWeakSource swapScene; 459 OBSWeakSource programScene; 460 bool editPropertiesMode = false; 461 bool sceneDuplicationMode = true; 462 bool swapScenesMode = true; 463 volatile bool previewProgramMode = false; 464 obs_hotkey_id togglePreviewProgramHotkey = 0; 465 obs_hotkey_id transitionHotkey = 0; 466 obs_hotkey_id statsHotkey = 0; 467 obs_hotkey_id screenshotHotkey = 0; 468 obs_hotkey_id sourceScreenshotHotkey = 0; 469 int quickTransitionIdCounter = 1; 470 bool overridingTransition = false; 471 472 int programX = 0, programY = 0; 473 int programCX = 0, programCY = 0; 474 float programScale = 0.0f; 475 476 int disableOutputsRef = 0; 477 478 inline void OnActivate(); 479 inline void OnDeactivate(); 480 481 void AddDropSource(const char *file, DropType image); 482 void AddDropURL(const char *url, QString &name, obs_data_t *settings, 483 const obs_video_info &ovi); 484 void ConfirmDropUrl(const QString &url); 485 void dragEnterEvent(QDragEnterEvent *event) override; 486 void dragLeaveEvent(QDragLeaveEvent *event) override; 487 void dragMoveEvent(QDragMoveEvent *event) override; 488 void dropEvent(QDropEvent *event) override; 489 490 void ReplayBufferClicked(); 491 492 bool sysTrayMinimizeToTray(); 493 494 void EnumDialogs(); 495 496 QList<QDialog *> visDialogs; 497 QList<QDialog *> modalDialogs; 498 QList<QMessageBox *> visMsgBoxes; 499 500 QList<QPoint> visDlgPositions; 501 502 QByteArray startingDockLayout; 503 504 obs_data_array_t *SaveProjectors(); 505 void LoadSavedProjectors(obs_data_array_t *savedProjectors); 506 507 void ReceivedIntroJson(const QString &text); 508 void ShowWhatsNew(const QString &url); 509 510 #ifdef BROWSER_AVAILABLE 511 QList<QSharedPointer<QDockWidget>> extraBrowserDocks; 512 QList<QSharedPointer<QAction>> extraBrowserDockActions; 513 QStringList extraBrowserDockTargets; 514 515 void ClearExtraBrowserDocks(); 516 void LoadExtraBrowserDocks(); 517 void SaveExtraBrowserDocks(); 518 void ManageExtraBrowserDocks(); 519 void AddExtraBrowserDock(const QString &title, const QString &url, 520 bool firstCreate); 521 #endif 522 523 QIcon imageIcon; 524 QIcon colorIcon; 525 QIcon slideshowIcon; 526 QIcon audioInputIcon; 527 QIcon audioOutputIcon; 528 QIcon desktopCapIcon; 529 QIcon windowCapIcon; 530 QIcon gameCapIcon; 531 QIcon cameraIcon; 532 QIcon textIcon; 533 QIcon mediaIcon; 534 QIcon browserIcon; 535 QIcon groupIcon; 536 QIcon sceneIcon; 537 QIcon defaultIcon; 538 539 QIcon GetImageIcon() const; 540 QIcon GetColorIcon() const; 541 QIcon GetSlideshowIcon() const; 542 QIcon GetAudioInputIcon() const; 543 QIcon GetAudioOutputIcon() const; 544 QIcon GetDesktopCapIcon() const; 545 QIcon GetWindowCapIcon() const; 546 QIcon GetGameCapIcon() const; 547 QIcon GetCameraIcon() const; 548 QIcon GetTextIcon() const; 549 QIcon GetMediaIcon() const; 550 QIcon GetBrowserIcon() const; 551 QIcon GetDefaultIcon() const; 552 553 QSlider *tBar; 554 bool tBarActive = false; 555 556 OBSSource GetOverrideTransition(OBSSource source); 557 int GetOverrideTransitionDuration(OBSSource source); 558 559 void UpdateProjectorHideCursor(); 560 void UpdateProjectorAlwaysOnTop(bool top); 561 void ResetProjectors(); 562 563 QPointer<QObject> screenshotData; 564 565 void MoveSceneItem(enum obs_order_movement movement, 566 const QString &action_name); 567 568 bool autoStartBroadcast = true; 569 bool autoStopBroadcast = true; 570 bool broadcastActive = false; 571 bool broadcastReady = false; 572 QPointer<QThread> youtubeStreamCheckThread; 573 #if YOUTUBE_ENABLED 574 void YoutubeStreamCheck(const std::string &key); 575 void ShowYouTubeAutoStartWarning(); 576 void YouTubeActionDialogOk(const QString &id, const QString &key, 577 bool autostart, bool autostop, 578 bool start_now); 579 #endif 580 void BroadcastButtonClicked(); 581 void SetBroadcastFlowEnabled(bool enabled); 582 583 void UpdatePreviewSafeAreas(); 584 bool drawSafeAreas = false; 585 586 public slots: 587 void DeferSaveBegin(); 588 void DeferSaveEnd(); 589 590 void DisplayStreamStartError(); 591 592 void SetupBroadcast(); 593 594 void StartStreaming(); 595 void StopStreaming(); 596 void ForceStopStreaming(); 597 598 void StreamDelayStarting(int sec); 599 void StreamDelayStopping(int sec); 600 601 void StreamingStart(); 602 void StreamStopping(); 603 void StreamingStop(int errorcode, QString last_error); 604 605 void StartRecording(); 606 void StopRecording(); 607 608 void RecordingStart(); 609 void RecordStopping(); 610 void RecordingStop(int code, QString last_error); 611 612 void ShowReplayBufferPauseWarning(); 613 void StartReplayBuffer(); 614 void StopReplayBuffer(); 615 616 void ReplayBufferStart(); 617 void ReplayBufferSave(); 618 void ReplayBufferSaved(); 619 void ReplayBufferStopping(); 620 void ReplayBufferStop(int code); 621 622 void StartVirtualCam(); 623 void StopVirtualCam(); 624 625 void OnVirtualCamStart(); 626 void OnVirtualCamStop(int code); 627 628 void SaveProjectDeferred(); 629 void SaveProject(); 630 631 void SetTransition(OBSSource transition); 632 void OverrideTransition(OBSSource transition); 633 void TransitionToScene(OBSScene scene, bool force = false); 634 void TransitionToScene(OBSSource scene, bool force = false, 635 bool quickTransition = false, 636 int quickDuration = 0, bool black = false, 637 bool manual = false); 638 void SetCurrentScene(OBSSource scene, bool force = false); 639 640 bool AddSceneCollection(bool create_new, 641 const QString &name = QString()); 642 643 bool NewProfile(const QString &name); 644 bool DuplicateProfile(const QString &name); 645 void DeleteProfile(const QString &profileName); 646 647 void UpdatePatronJson(const QString &text, const QString &error); 648 649 void ShowContextBar(); 650 void HideContextBar(); 651 void PauseRecording(); 652 void UnpauseRecording(); 653 654 private slots: 655 656 void on_actionMainUndo_triggered(); 657 void on_actionMainRedo_triggered(); 658 659 void AddSceneItem(OBSSceneItem item); 660 void AddScene(OBSSource source); 661 void RemoveScene(OBSSource source); 662 void RenameSources(OBSSource source, QString newName, QString prevName); 663 664 void ActivateAudioSource(OBSSource source); 665 void DeactivateAudioSource(OBSSource source); 666 667 void DuplicateSelectedScene(); 668 void RemoveSelectedScene(); 669 670 void ToggleAlwaysOnTop(); 671 672 void ReorderSources(OBSScene scene); 673 void RefreshSources(OBSScene scene); 674 675 void ProcessHotkey(obs_hotkey_id id, bool pressed); 676 677 void AddTransition(QString id); 678 void RenameTransition(); 679 void TransitionClicked(); 680 void TransitionStopped(); 681 void TransitionFullyStopped(); 682 void TriggerQuickTransition(int id); 683 684 void SetDeinterlacingMode(); 685 void SetDeinterlacingOrder(); 686 687 void SetScaleFilter(); 688 689 void IconActivated(QSystemTrayIcon::ActivationReason reason); 690 void SetShowing(bool showing); 691 692 void ToggleShowHide(); 693 694 void HideAudioControl(); 695 void UnhideAllAudioControls(); 696 void ToggleHideMixer(); 697 698 void MixerRenameSource(); 699 700 void on_vMixerScrollArea_customContextMenuRequested(); 701 void on_hMixerScrollArea_customContextMenuRequested(); 702 703 void on_actionCopySource_triggered(); 704 void on_actionPasteRef_triggered(); 705 void on_actionPasteDup_triggered(); 706 707 void on_actionCopyFilters_triggered(); 708 void on_actionPasteFilters_triggered(); 709 710 void ColorChange(); 711 712 SourceTreeItem *GetItemWidgetFromSceneItem(obs_sceneitem_t *sceneItem); 713 714 void on_actionShowAbout_triggered(); 715 716 void AudioMixerCopyFilters(); 717 void AudioMixerPasteFilters(); 718 719 void EnablePreview(); 720 void DisablePreview(); 721 722 void SceneCopyFilters(); 723 void ScenePasteFilters(); 724 725 void CheckDiskSpaceRemaining(); 726 void OpenSavedProjector(SavedProjectorInfo *info); 727 728 void ScenesReordered(); 729 730 void ResetStatsHotkey(); 731 732 void SetImageIcon(const QIcon &icon); 733 void SetColorIcon(const QIcon &icon); 734 void SetSlideshowIcon(const QIcon &icon); 735 void SetAudioInputIcon(const QIcon &icon); 736 void SetAudioOutputIcon(const QIcon &icon); 737 void SetDesktopCapIcon(const QIcon &icon); 738 void SetWindowCapIcon(const QIcon &icon); 739 void SetGameCapIcon(const QIcon &icon); 740 void SetCameraIcon(const QIcon &icon); 741 void SetTextIcon(const QIcon &icon); 742 void SetMediaIcon(const QIcon &icon); 743 void SetBrowserIcon(const QIcon &icon); 744 void SetGroupIcon(const QIcon &icon); 745 void SetSceneIcon(const QIcon &icon); 746 void SetDefaultIcon(const QIcon &icon); 747 748 void TBarChanged(int value); 749 void TBarReleased(); 750 751 void LockVolumeControl(bool lock); 752 753 private: 754 /* OBS Callbacks */ 755 static void SceneReordered(void *data, calldata_t *params); 756 static void SceneRefreshed(void *data, calldata_t *params); 757 static void SceneItemAdded(void *data, calldata_t *params); 758 static void SourceCreated(void *data, calldata_t *params); 759 static void SourceRemoved(void *data, calldata_t *params); 760 static void SourceActivated(void *data, calldata_t *params); 761 static void SourceDeactivated(void *data, calldata_t *params); 762 static void SourceAudioActivated(void *data, calldata_t *params); 763 static void SourceAudioDeactivated(void *data, calldata_t *params); 764 static void SourceRenamed(void *data, calldata_t *params); 765 static void RenderMain(void *data, uint32_t cx, uint32_t cy); 766 767 void ResizePreview(uint32_t cx, uint32_t cy); 768 769 void AddSource(const char *id); 770 QMenu *CreateAddSourcePopupMenu(); 771 void AddSourcePopupMenu(const QPoint &pos); 772 void copyActionsDynamicProperties(); 773 774 static void HotkeyTriggered(void *data, obs_hotkey_id id, bool pressed); 775 776 void AutoRemux(QString input); 777 778 void UpdatePause(bool activate = true); 779 void UpdateReplayBuffer(bool activate = true); 780 781 bool OutputPathValid(); 782 void OutputPathInvalidMessage(); 783 784 bool LowDiskSpace(); 785 void DiskSpaceMessage(); 786 787 OBSSource prevFTBSource = nullptr; 788 789 public: 790 undo_stack undo_s; 791 OBSSource GetProgramSource(); 792 OBSScene GetCurrentScene(); 793 794 void SysTrayNotify(const QString &text, QSystemTrayIcon::MessageIcon n); 795 GetCurrentSceneSource()796 inline OBSSource GetCurrentSceneSource() 797 { 798 OBSScene curScene = GetCurrentScene(); 799 return OBSSource(obs_scene_get_source(curScene)); 800 } 801 802 obs_service_t *GetService(); 803 void SetService(obs_service_t *service); 804 805 int GetTransitionDuration(); 806 int GetTbarPosition(); 807 IsPreviewProgramMode() const808 inline bool IsPreviewProgramMode() const 809 { 810 return os_atomic_load_bool(&previewProgramMode); 811 } 812 VCamEnabled() const813 inline bool VCamEnabled() const { return vcamEnabled; } 814 815 bool StreamingActive() const; 816 bool Active() const; 817 818 void ResetUI(); 819 int ResetVideo(); 820 bool ResetAudio(); 821 822 void AddVCamButton(); 823 void ResetOutputs(); 824 825 void ResetAudioDevice(const char *sourceId, const char *deviceId, 826 const char *deviceDesc, int channel); 827 828 void NewProject(); 829 void LoadProject(); 830 GetDisplayRect(int & x,int & y,int & cx,int & cy)831 inline void GetDisplayRect(int &x, int &y, int &cx, int &cy) 832 { 833 x = previewX; 834 y = previewY; 835 cx = previewCX; 836 cy = previewCY; 837 } 838 SavingDisabled() const839 inline bool SavingDisabled() const { return disableSaving; } 840 GetCPUUsage() const841 inline double GetCPUUsage() const 842 { 843 return os_cpu_usage_info_query(cpuUsageInfo); 844 } 845 846 void SaveService(); 847 bool LoadService(); 848 GetAuth()849 inline Auth *GetAuth() { return auth.get(); } 850 EnableOutputs(bool enable)851 inline void EnableOutputs(bool enable) 852 { 853 if (enable) { 854 if (--disableOutputsRef < 0) 855 disableOutputsRef = 0; 856 } else { 857 disableOutputsRef++; 858 } 859 } 860 861 QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source); 862 QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item); 863 QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction, 864 ColorSelect *select, 865 obs_sceneitem_t *item); 866 void CreateSourcePopupMenu(int idx, bool preview); 867 868 void UpdateTitleBar(); 869 870 void SystemTrayInit(); 871 void SystemTray(bool firstStarted); 872 873 void OpenSavedProjectors(); 874 875 void CreateInteractionWindow(obs_source_t *source); 876 void CreatePropertiesWindow(obs_source_t *source); 877 void CreateFiltersWindow(obs_source_t *source); 878 879 QAction *AddDockWidget(QDockWidget *dock); 880 881 static OBSBasic *Get(); 882 883 const char *GetCurrentOutputPath(); 884 885 void DeleteProjector(OBSProjector *projector); 886 void AddProjectorMenuMonitors(QMenu *parent, QObject *target, 887 const char *slot); 888 889 QIcon GetSourceIcon(const char *id) const; 890 QIcon GetGroupIcon() const; 891 QIcon GetSceneIcon() const; 892 893 OBSWeakSource copyFilter = nullptr; 894 895 void ShowStatusBarMessage(const QString &message); 896 897 static OBSData 898 BackupScene(obs_scene_t *scene, 899 std::vector<obs_source_t *> *sources = nullptr); 900 void CreateSceneUndoRedoAction(const QString &action_name, 901 OBSData undo_data, OBSData redo_data); 902 903 static inline OBSData BackupScene(obs_source_t * scene_source,std::vector<obs_source_t * > * sources=nullptr)904 BackupScene(obs_source_t *scene_source, 905 std::vector<obs_source_t *> *sources = nullptr) 906 { 907 obs_scene_t *scene = obs_scene_from_source(scene_source); 908 return BackupScene(scene, sources); 909 } 910 911 void CreateFilterPasteUndoRedoAction(const QString &text, 912 obs_source_t *source, 913 obs_data_array_t *undo_array, 914 obs_data_array_t *redo_array); 915 916 protected: 917 virtual void closeEvent(QCloseEvent *event) override; 918 virtual void changeEvent(QEvent *event) override; 919 920 private slots: 921 void on_actionFullscreenInterface_triggered(); 922 923 void on_actionShow_Recordings_triggered(); 924 void on_actionRemux_triggered(); 925 void on_action_Settings_triggered(); 926 void on_actionShowMissingFiles_triggered(); 927 void on_actionAdvAudioProperties_triggered(); 928 void AdvAudioPropsClicked(); 929 void AdvAudioPropsDestroyed(); 930 void on_actionShowLogs_triggered(); 931 void on_actionUploadCurrentLog_triggered(); 932 void on_actionUploadLastLog_triggered(); 933 void on_actionViewCurrentLog_triggered(); 934 void on_actionCheckForUpdates_triggered(); 935 936 void on_actionShowCrashLogs_triggered(); 937 void on_actionUploadLastCrashLog_triggered(); 938 939 void on_actionEditTransform_triggered(); 940 void on_actionCopyTransform_triggered(); 941 void on_actionPasteTransform_triggered(); 942 void on_actionRotate90CW_triggered(); 943 void on_actionRotate90CCW_triggered(); 944 void on_actionRotate180_triggered(); 945 void on_actionFlipHorizontal_triggered(); 946 void on_actionFlipVertical_triggered(); 947 void on_actionFitToScreen_triggered(); 948 void on_actionStretchToScreen_triggered(); 949 void on_actionCenterToScreen_triggered(); 950 void on_actionVerticalCenter_triggered(); 951 void on_actionHorizontalCenter_triggered(); 952 953 void on_customContextMenuRequested(const QPoint &pos); 954 955 void on_scenes_currentItemChanged(QListWidgetItem *current, 956 QListWidgetItem *prev); 957 void on_scenes_customContextMenuRequested(const QPoint &pos); 958 void GridActionClicked(); 959 void on_actionAddScene_triggered(); 960 void on_actionRemoveScene_triggered(); 961 void on_actionSceneUp_triggered(); 962 void on_actionSceneDown_triggered(); 963 void on_sources_customContextMenuRequested(const QPoint &pos); 964 void on_scenes_itemDoubleClicked(QListWidgetItem *item); 965 void on_actionAddSource_triggered(); 966 void on_actionRemoveSource_triggered(); 967 void on_actionInteract_triggered(); 968 void on_actionSourceProperties_triggered(); 969 void on_actionSourceUp_triggered(); 970 void on_actionSourceDown_triggered(); 971 972 void on_actionMoveUp_triggered(); 973 void on_actionMoveDown_triggered(); 974 void on_actionMoveToTop_triggered(); 975 void on_actionMoveToBottom_triggered(); 976 977 void on_actionLockPreview_triggered(); 978 979 void on_scalingMenu_aboutToShow(); 980 void on_actionScaleWindow_triggered(); 981 void on_actionScaleCanvas_triggered(); 982 void on_actionScaleOutput_triggered(); 983 984 void on_streamButton_clicked(); 985 void on_recordButton_clicked(); 986 void VCamButtonClicked(); 987 void on_settingsButton_clicked(); 988 void Screenshot(OBSSource source_ = nullptr); 989 void ScreenshotSelectedSource(); 990 void ScreenshotProgram(); 991 void ScreenshotScene(); 992 993 void on_actionHelpPortal_triggered(); 994 void on_actionWebsite_triggered(); 995 void on_actionDiscord_triggered(); 996 997 void on_preview_customContextMenuRequested(const QPoint &pos); 998 void ProgramViewContextMenuRequested(const QPoint &pos); 999 void PreviewDisabledMenu(const QPoint &pos); 1000 1001 void on_actionNewSceneCollection_triggered(); 1002 void on_actionDupSceneCollection_triggered(); 1003 void on_actionRenameSceneCollection_triggered(); 1004 void on_actionRemoveSceneCollection_triggered(); 1005 void on_actionImportSceneCollection_triggered(); 1006 void on_actionExportSceneCollection_triggered(); 1007 1008 void on_actionNewProfile_triggered(); 1009 void on_actionDupProfile_triggered(); 1010 void on_actionRenameProfile_triggered(); 1011 void on_actionRemoveProfile_triggered(bool skipConfirmation = false); 1012 void on_actionImportProfile_triggered(); 1013 void on_actionExportProfile_triggered(); 1014 1015 void on_actionShowSettingsFolder_triggered(); 1016 void on_actionShowProfileFolder_triggered(); 1017 1018 void on_actionAlwaysOnTop_triggered(); 1019 1020 void on_toggleListboxToolbars_toggled(bool visible); 1021 void on_toggleContextBar_toggled(bool visible); 1022 void on_toggleStatusBar_toggled(bool visible); 1023 void on_toggleSourceIcons_toggled(bool visible); 1024 1025 void on_transitions_currentIndexChanged(int index); 1026 void RemoveTransitionClicked(); 1027 void on_transitionProps_clicked(); 1028 void on_transitionDuration_valueChanged(int value); 1029 void on_tbar_position_valueChanged(int value); 1030 1031 void on_actionShowTransitionProperties_triggered(); 1032 void on_actionHideTransitionProperties_triggered(); 1033 1034 void on_modeSwitch_clicked(); 1035 1036 // Source Context Buttons 1037 void on_sourcePropertiesButton_clicked(); 1038 void on_sourceFiltersButton_clicked(); 1039 void on_sourceInteractButton_clicked(); 1040 1041 void on_autoConfigure_triggered(); 1042 void on_stats_triggered(); 1043 1044 void on_resetUI_triggered(); 1045 void on_lockUI_toggled(bool lock); 1046 1047 void PauseToggled(); 1048 1049 void logUploadFinished(const QString &text, const QString &error); 1050 void crashUploadFinished(const QString &text, const QString &error); 1051 void openLogDialog(const QString &text, const bool crash); 1052 1053 void updateCheckFinished(); 1054 1055 void AddSourceFromAction(); 1056 1057 void MoveSceneToTop(); 1058 void MoveSceneToBottom(); 1059 1060 void EditSceneName(); 1061 void EditSceneItemName(); 1062 1063 void SceneNameEdited(QWidget *editor, 1064 QAbstractItemDelegate::EndEditHint endHint); 1065 1066 void OpenSceneFilters(); 1067 void OpenFilters(OBSSource source = nullptr); 1068 void OpenProperties(OBSSource source = nullptr); 1069 1070 void EnablePreviewDisplay(bool enable); 1071 void TogglePreview(); 1072 1073 void NudgeUp(); 1074 void NudgeDown(); 1075 void NudgeLeft(); 1076 void NudgeRight(); 1077 1078 void OpenStudioProgramProjector(); 1079 void OpenPreviewProjector(); 1080 void OpenSourceProjector(); 1081 void OpenMultiviewProjector(); 1082 void OpenSceneProjector(); 1083 1084 void OpenStudioProgramWindow(); 1085 void OpenPreviewWindow(); 1086 void OpenSourceWindow(); 1087 void OpenMultiviewWindow(); 1088 void OpenSceneWindow(); 1089 1090 void DeferredSysTrayLoad(int requeueCount); 1091 1092 void StackedMixerAreaContextMenuRequested(); 1093 1094 void ResizeOutputSizeOfSource(); 1095 1096 public slots: 1097 void on_actionResetTransform_triggered(); 1098 1099 bool StreamingActive(); 1100 bool RecordingActive(); 1101 bool ReplayBufferActive(); 1102 1103 void ClearContextBar(); 1104 void UpdateContextBar(bool force = false); 1105 void UpdateContextBarDeferred(bool force = false); 1106 1107 public: 1108 explicit OBSBasic(QWidget *parent = 0); 1109 virtual ~OBSBasic(); 1110 1111 virtual void OBSInit() override; 1112 1113 virtual config_t *Config() const override; 1114 1115 virtual int GetProfilePath(char *path, size_t size, 1116 const char *file) const override; 1117 1118 static void InitBrowserPanelSafeBlock(); 1119 1120 private: 1121 std::unique_ptr<Ui::OBSBasic> ui; 1122 }; 1123 1124 class SceneRenameDelegate : public QStyledItemDelegate { 1125 Q_OBJECT 1126 1127 public: 1128 SceneRenameDelegate(QObject *parent); 1129 virtual void setEditorData(QWidget *editor, 1130 const QModelIndex &index) const override; 1131 1132 protected: 1133 virtual bool eventFilter(QObject *editor, QEvent *event) override; 1134 }; 1135