13#include <score/widgets/PluginWindow.hpp>
15#include <pluginterfaces/gui/iplugview.h>
16#include <pluginterfaces/gui/iplugviewcontentscalesupport.h>
25 return Steinberg::kPlatformTypeNSView;
27 return Steinberg::kPlatformTypeHWND;
28#elif (!(defined(__APPLE__) || defined(_WIN32))) && __has_include(<xcb/xcb.h>)
29 return Steinberg::kPlatformTypeX11EmbedWindowID;
37inline bool applyContentScaleFactor(Steinberg::IPlugView& view,
const QWidget& w)
44 Steinberg::IPlugViewContentScaleSupport* scaling{};
45 if(view.queryInterface(Steinberg::IPlugViewContentScaleSupport::iid, (
void**)&scaling)
46 != Steinberg::kResultOk
50 const auto res = scaling->setContentScaleFactor(w.devicePixelRatioF());
52 return res == Steinberg::kResultTrue;
67 std::chrono::steady_clock::time_point when;
69 std::vector<Asked> asked;
87 std::shared_ptr<EditorSize> size = std::make_shared<EditorSize>();
104 static int toQt(
int editorPixels,
double scale)
noexcept
106 return std::max(1,
int(std::lround(editorPixels * scale)));
108 static int toEditor(
int qtPixels,
double scale)
noexcept
110 return std::max(1,
int(std::lround(qtPixels / scale)));
113 static bool sameSize(
const Steinberg::ViewRect& a,
const Steinberg::ViewRect& b)
noexcept
115 return a.getWidth() == b.getWidth() && a.getHeight() == b.getHeight();
122 Steinberg::IPlugView& view,
int qw,
int qh, QDialog& parentWindow)
const
125 const bool was = s.resizingWindow;
126 s.resizingWindow =
true;
127 const QSize sz{qw, qh};
128 if(parentWindow.size() != sz)
130 s.asked.push_back({sz, std::chrono::steady_clock::now()});
131 if(s.asked.size() > 8)
132 s.asked.erase(s.asked.begin());
134 if(view.canResize() == Steinberg::kResultTrue)
136 if(parentWindow.size() != sz)
137 parentWindow.resize(sz);
141 parentWindow.setFixedSize(sz);
143 if(qwindow && qwindow->size() != sz)
145 qwindow->resize(qw, qh);
149 container->move(0, 0);
150 container->setFixedSize(qw, qh);
152 s.resizingWindow = was;
156 void sendSize(Steinberg::IPlugView& view, Steinberg::ViewRect r)
const
176 if(s.current.getWidth() > 0 && s.current.getHeight() > 0)
182 Steinberg::IPlugView& view,
const Steinberg::ViewRect& r,
183 QDialog& parentWindow)
const
186 int w = r.getWidth();
187 int h = r.getHeight();
191 return std::make_pair(w, h);
197 return std::make_pair(w, h);
209 if(!s.attached || s.resizingWindow)
211 if(view.canResize() != Steinberg::kResultTrue)
213 if(sz.width() <= 0 || sz.height() <= 0)
220 const auto now = std::chrono::steady_clock::now();
221 auto it = std::find_if(s.asked.begin(), s.asked.end(), [&](
const auto& a) {
222 return a.size == sz && now - a.when < std::chrono::seconds(1);
224 if(it != s.asked.end())
226 s.asked.erase(s.asked.begin(), it + 1);
234 if(s.current.getWidth() > 0 && s.current.getHeight() > 0
235 && sz.width() ==
toQt(s.current.getWidth(), scale)
236 && sz.height() ==
toQt(s.current.getHeight(), scale))
239 const Steinberg::ViewRect asked{
240 0, 0, toEditor(sz.width(), scale), toEditor(sz.height(), scale)};
241 Steinberg::ViewRect r = asked;
243 view.checkSizeConstraint(&r);
244 if(r.getWidth() <= 0 || r.getHeight() <= 0)
246 r = Steinberg::ViewRect{0, 0, r.getWidth(), r.getHeight()};
250 if(!sameSize(r, asked))
254 container->move(0, 0);
255 container->setFixedSize(sz);
259 if(sameSize(r, s.current))
268 Steinberg::IPlugView& view, Steinberg::ViewRect& r, QDialog& parentWindow)
const
272 const int w = r.getWidth();
273 const int h = r.getHeight();
280 if(s.onSizeDepth > 0 && sameSize(r, s.current))
285 s.current = Steinberg::ViewRect{0, 0, w, h};
static double editorPixelRatio(const QWidget &w)
Definition PluginWindow.cpp:16
Definition PlugFrame.hpp:14
QString currentPlatform() noexcept
"windows", "macos", "linux", "bsd", "android", "ios" or "web".
Definition Platforms.cpp:9
Definition WindowContainer.hpp:65
Definition WindowContainer.hpp:59
bool resizingWindow
The window is being resized here: the resize events it sends are ours.
Definition WindowContainer.hpp:76
Steinberg::ViewRect current
The size the editor was last given or asked for, in its own pixels.
Definition WindowContainer.hpp:61
int onSizeDepth
How many onSize() sent from here the editor is in.
Definition WindowContainer.hpp:78
bool pending
The plug-in asked for a size before attached(): it gets it once attached.
Definition WindowContainer.hpp:74
bool attached
Definition WindowContainer.hpp:72
Definition WindowContainer.hpp:82
void resizeWindow(Steinberg::IPlugView &view, int qw, int qh, QDialog &parentWindow) const
Definition WindowContainer.hpp:121
void setSizeFromUser(Steinberg::IPlugView &view, const QSize &sz, QDialog &parentWindow)
Definition WindowContainer.hpp:204
auto setSizeFromQt(Steinberg::IPlugView &view, const Steinberg::ViewRect &r, QDialog &parentWindow) const
The window takes the size the editor says it has (getSize)
Definition WindowContainer.hpp:181
static double qtScaleFactor(const QWidget &w) noexcept
Definition WindowContainer.hpp:97
void sendPendingSize(Steinberg::IPlugView &view) const
To call once attached(): the size the plug-in asked for before.
Definition WindowContainer.hpp:170
static int toQt(int editorPixels, double scale) noexcept
Definition WindowContainer.hpp:104
static constexpr int maxOnSizeDepth
Definition WindowContainer.hpp:92
void sendSize(Steinberg::IPlugView &view, Steinberg::ViewRect r) const
The editor takes the size r.
Definition WindowContainer.hpp:156
bool setSizeFromVst(Steinberg::IPlugView &view, Steinberg::ViewRect &r, QDialog &parentWindow) const
Definition WindowContainer.hpp:267
void setAttached() const noexcept
Definition WindowContainer.hpp:167