From 342263115257ebfcabd71385dc7c679095306e52 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 1 Aug 2015 20:38:12 -0700 Subject: [PATCH] UI: Refactor OBSQTDisplay for windowless context (Non-compiling commit: windowless-context branch) This makes it so that OBSQTDisplay now uses/controls an obs_display object directly (rather than having the owner have to associate an OBSDisplay with it). It was separated before because the main window for the basic UI would was using the "main preview" stuff before the windowless context and had to be handled differently, so you couldn't just associate an obs_display object with OBSQTDisplay, meaning that all "secondary" previews such as properties/filters/etc had to handle the obs_display alone, which caused a lot of needlessly duplicated code. Also adds a DisplayCreated signal to allow owners to be able to add callbacks and such on creation of the actual obs_display context. --- obs/CMakeLists.txt | 1 + obs/qt-display.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++ obs/qt-display.hpp | 28 +++++++-------- 3 files changed, 101 insertions(+), 16 deletions(-) create mode 100644 obs/qt-display.cpp diff --git a/obs/CMakeLists.txt b/obs/CMakeLists.txt index 273e04c81..bd41e6422 100644 --- a/obs/CMakeLists.txt +++ b/obs/CMakeLists.txt @@ -126,6 +126,7 @@ set(obs_SOURCES visibility-item-widget.cpp slider-absoluteset-style.cpp source-list-widget.cpp + qt-display.cpp crash-report.cpp hotkey-edit.cpp source-label.cpp diff --git a/obs/qt-display.cpp b/obs/qt-display.cpp new file mode 100644 index 000000000..90bd9bebd --- /dev/null +++ b/obs/qt-display.cpp @@ -0,0 +1,88 @@ +#include "qt-display.hpp" +#include "qt-wrappers.hpp" +#include "display-helpers.hpp" +#include +#include +#include +#include + +OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) + : QWidget(parent, flags) +{ + setAttribute(Qt::WA_PaintOnScreen); + setAttribute(Qt::WA_StaticContents); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_DontCreateNativeAncestors); + setAttribute(Qt::WA_NativeWindow); + + auto windowVisible = [this] (bool visible) + { + if (!visible) + return; + + if (!display) { + CreateDisplay(); + } else { + QSize size = GetPixelSize(this); + obs_display_resize(display, size.width(), size.height()); + } + }; + + auto sizeChanged = [this] (QScreen*) + { + CreateDisplay(); + + QSize size = GetPixelSize(this); + obs_display_resize(display, size.width(), size.height()); + }; + + connect(windowHandle(), &QWindow::visibleChanged, windowVisible); + connect(windowHandle(), &QWindow::screenChanged, sizeChanged); +} + +void OBSQTDisplay::CreateDisplay() +{ + if (display || !windowHandle()->isExposed()) + return; + + QSize size = GetPixelSize(this); + + gs_init_data info = {}; + info.cx = size.width(); + info.cy = size.height(); + info.format = GS_RGBA; + info.zsformat = GS_ZS_NONE; + + QTToGSWindow(winId(), info.window); + + display = obs_display_create(&info); + + emit DisplayCreated(this); +} + +void OBSQTDisplay::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + CreateDisplay(); + + if (isVisible() && display) { + QSize size = GetPixelSize(this); + obs_display_resize(display, size.width(), size.height()); + } + + emit DisplayResized(); +} + +void OBSQTDisplay::paintEvent(QPaintEvent *event) +{ + CreateDisplay(); + + QWidget::paintEvent(event); +} + +QPaintEngine *OBSQTDisplay::paintEngine() const +{ + return nullptr; +} diff --git a/obs/qt-display.hpp b/obs/qt-display.hpp index 9f5227a15..438100bf9 100644 --- a/obs/qt-display.hpp +++ b/obs/qt-display.hpp @@ -1,30 +1,26 @@ #pragma once #include +#include class OBSQTDisplay : public QWidget { Q_OBJECT - virtual void resizeEvent(QResizeEvent *event) override - { - emit DisplayResized(); - QWidget::resizeEvent(event); - } + OBSDisplay display; + + void CreateDisplay(); + + void resizeEvent(QResizeEvent *event) override; + void paintEvent(QPaintEvent *event) override; signals: + void DisplayCreated(OBSQTDisplay *window); void DisplayResized(); public: - inline OBSQTDisplay(QWidget *parent = 0, Qt::WindowFlags flags = 0) - : QWidget(parent, flags) - { - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_StaticContents); - setAttribute(Qt::WA_NoSystemBackground); - setAttribute(Qt::WA_OpaquePaintEvent); - setAttribute(Qt::WA_DontCreateNativeAncestors); - setAttribute(Qt::WA_NativeWindow); - } + OBSQTDisplay(QWidget *parent = 0, Qt::WindowFlags flags = 0); - virtual QPaintEngine *paintEngine() const override {return nullptr;} + virtual QPaintEngine *paintEngine() const override; + + inline obs_display_t *GetDisplay() const {return display;} };