Loading...
Searching...
No Matches
WindowContainer.hpp
1#pragma once
2#include <QApplication>
3#include <QDebug>
4#include <QDialog>
5#include <QWindow>
6
7#include <pluginterfaces/gui/iplugview.h>
8#include <pluginterfaces/gui/iplugviewcontentscalesupport.h>
9
10namespace vst3
11{
12class PlugFrame;
13
14inline const char* currentPlatform()
15{
16#if defined(__APPLE__)
17 return Steinberg::kPlatformTypeNSView;
18#elif defined(_WIN32)
19 return Steinberg::kPlatformTypeHWND;
20#elif (!(defined(__APPLE__) || defined(_WIN32))) && __has_include(<xcb/xcb.h>)
21 return Steinberg::kPlatformTypeX11EmbedWindowID;
22#endif
23 return "";
24}
25
29inline bool applyContentScaleFactor(Steinberg::IPlugView& view, const QWidget& w)
30{
31#if defined(__APPLE__)
32 // NSViews are scaled by the system: there is nothing for the plug-in to do
33 return false;
34#else
35 // On Windows and X11 the plug-in has no way to find this out by itself
36 Steinberg::IPlugViewContentScaleSupport* scaling{};
37 if(view.queryInterface(Steinberg::IPlugViewContentScaleSupport::iid, (void**)&scaling)
38 != Steinberg::kResultOk
39 || !scaling)
40 return false;
41
42 const auto res = scaling->setContentScaleFactor(w.devicePixelRatioF());
43 scaling->release();
44 return res == Steinberg::kResultTrue;
45#endif
46}
47
49{
50 WId nativeId{};
51 QWindow* qwindow{};
52 QWidget* container{};
53 vst3::PlugFrame* frame{};
54
57 static double qtScaleFactor(const QWidget& w) noexcept
58 {
59#if defined(__APPLE__)
60 // Cocoa view rects are in points, which is exactly Qt's logical pixel:
61 // only an explicit QT_SCALE_FACTOR breaks that 1:1 mapping
62 const double r = qEnvironmentVariable("QT_SCALE_FACTOR").toDouble();
63 return r > 0.1 ? 1. / r : 1.;
64#else
65 // Everywhere else the plug-in sizes its window in device pixels. Handing
66 // those numbers to Qt as-is makes the container devicePixelRatio times too
67 // big on a hidpi screen, with the actual UI sitting in a corner of it.
68 // Note: devicePixelRatioF() already accounts for QT_SCALE_FACTOR.
69 const double dpr = w.devicePixelRatioF();
70 return dpr > 0.1 ? 1. / dpr : 1.;
71#endif
72 }
73
74 auto setSizeFromQt(
75 Steinberg::IPlugView& view, const Steinberg::ViewRect& r,
76 QDialog& parentWindow) const
77 {
78 const double scale = qtScaleFactor(parentWindow);
79 int w = r.getWidth();
80 int h = r.getHeight();
81 int qw = r.getWidth() * scale;
82 int qh = r.getHeight() * scale;
83
84 if(w == 0 || h == 0)
85 {
86 return std::make_pair(w, h);
87 }
88
89 if(view.canResize() == Steinberg::kResultTrue)
90 {
91 parentWindow.resize(QSize{qw, qh});
92 }
93 else
94 {
95 parentWindow.setFixedSize(QSize{qw, qh});
96 }
97 if(qwindow)
98 {
99 qwindow->resize(qw, qh);
100 }
101 if(container)
102 {
103 container->move(0, 0);
104 container->setFixedSize(qw, qh);
105 }
106
107 return std::make_pair(w, h);
108 }
109
110 void
111 setSizeFromUser(Steinberg::IPlugView& view, const QSize& sz, QDialog& parentWindow)
112 {
113 if(view.canResize() != Steinberg::kResultTrue)
114 return;
115 return;
116
117 const double scale = qtScaleFactor(parentWindow);
118 int qw = sz.width();
119 int qh = sz.height();
120 Steinberg::ViewRect r;
121 r.top = 0;
122 r.left = 0;
123 r.right = sz.width() / scale;
124 r.bottom = sz.height() / scale;
125 view.checkSizeConstraint(&r);
126
127 parentWindow.resize(QSize(qw, qh));
128
129 if(qwindow)
130 {
131 qwindow->resize(qw, qh);
132 }
133
134 if(container)
135 {
136 container->move(0, 0);
137 container->setFixedSize(qw, qh);
138 }
139
140 view.onSize(&r);
141 }
142
143 auto setSizeFromVst(
144 Steinberg::IPlugView& view, Steinberg::ViewRect& r, QDialog& parentWindow)
145 {
146 const double scale = qtScaleFactor(parentWindow);
147 int w = r.getWidth();
148 int h = r.getHeight();
149 int qw = r.getWidth() * scale;
150 int qh = r.getHeight() * scale;
151
152 if(w == 0 || h == 0)
153 {
154 view.onSize(&r);
155 return std::make_pair(qw, qh);
156 }
157
158 if(view.canResize() == Steinberg::kResultTrue)
159 {
160 parentWindow.resize(QSize{qw, qh});
161 }
162 else
163 {
164 parentWindow.setFixedSize(QSize{qw, qh});
165 }
166
167 if(qwindow)
168 {
169 qwindow->resize(qw, qh);
170 }
171 if(container)
172 {
173 container->move(0, 0);
174 container->setFixedSize(qw, qh);
175 }
176
177 view.onSize(&r);
178
179 return std::make_pair(qw, qh);
180 }
181};
182
183class Window;
184}
Definition PlugFrame.hpp:14
@ Window
A separate top-level window.
Definition WindowContainer.hpp:49
static double qtScaleFactor(const QWidget &w) noexcept
Definition WindowContainer.hpp:57