Просмотр исходного кода

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.
jp9000 10 лет назад
Родитель
Сommit
3422631152
3 измененных файлов с 102 добавлено и 17 удалено
  1. 1 0
      obs/CMakeLists.txt
  2. 88 0
      obs/qt-display.cpp
  3. 13 17
      obs/qt-display.hpp

+ 1 - 0
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

+ 88 - 0
obs/qt-display.cpp

@@ -0,0 +1,88 @@
+#include "qt-display.hpp"
+#include "qt-wrappers.hpp"
+#include "display-helpers.hpp"
+#include <QWindow>
+#include <QScreen>
+#include <QResizeEvent>
+#include <QShowEvent>
+
+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;
+}

+ 13 - 17
obs/qt-display.hpp

@@ -1,30 +1,26 @@
 #pragma once
 
 #include <QWidget>
+#include <obs.hpp>
 
 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);
-	}
-
-	virtual QPaintEngine *paintEngine() const override {return nullptr;}
+	OBSQTDisplay(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+
+	virtual QPaintEngine *paintEngine() const override;
+
+	inline obs_display_t *GetDisplay() const {return display;}
 };