diff --git a/dgl/TopLevelWidget.hpp b/dgl/TopLevelWidget.hpp index 51e25ca4..deca78bf 100644 --- a/dgl/TopLevelWidget.hpp +++ b/dgl/TopLevelWidget.hpp @@ -66,8 +66,13 @@ public: */ Window& getWindow() const noexcept; + // TODO group stuff after here, convenience functions present in Window class void repaint() noexcept; void repaint(const Rectangle& rect) noexcept; + void setGeometryConstraints(uint minimumWidth, + uint minimumHeight, + bool keepAspectRatio = false, + bool automaticallyScale = false); // TODO deprecated Application& getParentApp() const noexcept { return getApp(); } diff --git a/dgl/Window.hpp b/dgl/Window.hpp index 9f24dea6..7bfe1c90 100644 --- a/dgl/Window.hpp +++ b/dgl/Window.hpp @@ -124,6 +124,9 @@ public: */ void close(); + bool isResizable() const noexcept; + void setResizable(bool resizable); + /** Get width. */ @@ -159,9 +162,28 @@ public: */ void setSize(const Size& size); + /** + Get the title of the window previously set with setTitle(). + */ const char* getTitle() const noexcept; + + /** + Set the title of the window, typically displayed in the title bar or in window switchers. + + This only makes sense for non-embedded windows. + */ void setTitle(const char* title); + /** + Check if key repeat events are ignored. + */ + bool isIgnoringKeyRepeat() const noexcept; + + /** + Set to ignore (or not) key repeat events according to @a ignore. + */ + void setIgnoringKeyRepeat(bool ignore) noexcept; + /** Get the application associated with this window. */ @@ -177,9 +199,47 @@ public: */ uintptr_t getNativeWindowHandle() const noexcept; + /** + Get the scale factor requested for this window. + This is purely informational, and up to developers to choose what to do with it. + + If you do not want to deal with this yourself, + consider using setGeometryConstraints() where you can specify to automatically scale the window contents. + @see setGeometryConstraints + */ + double getScaleFactor() const noexcept; + + /** + Grab the keyboard input focus. + */ + void focus(); + + /** + Request repaint of this window, for the entire area. + */ void repaint() noexcept; + + /** + Request partial repaint of this window, with bounds according to @a rect. + */ void repaint(const Rectangle& rect) noexcept; + /** + Set geometry constraints for the Window when resized by the user, and optionally scale contents automatically. + */ + void setGeometryConstraints(uint minimumWidth, + uint minimumHeight, + bool keepAspectRatio = false, + bool automaticallyScale = false); + + /* + void setTransientWinId(uintptr_t winId); + */ + + // TODO deprecated + inline bool getIgnoringKeyRepeat() const noexcept { return isIgnoringKeyRepeat(); } + inline double getScaling() const noexcept { return getScaling(); } + protected: /** A function called when the window is resized. @@ -266,28 +326,15 @@ END_NAMESPACE_DGL void exec(bool lockWait = false); - void focus(); - -#ifndef DGL_FILE_BROWSER_DISABLED - bool openFileBrowser(const FileBrowserOptions& options); -#endif - - bool isResizable() const noexcept; - void setResizable(bool resizable); - - bool getIgnoringKeyRepeat() const noexcept; - void setIgnoringKeyRepeat(bool ignore) noexcept; - - void setGeometryConstraints(uint width, uint height, bool aspect); - void setTransientWinId(uintptr_t winId); - - double getScaling() const noexcept; - const GraphicsContext& getGraphicsContext() const noexcept; void addIdleCallback(IdleCallback* const callback); void removeIdleCallback(IdleCallback* const callback); +#ifndef DGL_FILE_BROWSER_DISABLED + bool openFileBrowser(const FileBrowserOptions& options); +#endif + protected: #ifndef DGL_FILE_BROWSER_DISABLED diff --git a/dgl/src/Cairo.cpp b/dgl/src/Cairo.cpp index 303244e9..1f423c0d 100644 --- a/dgl/src/Cairo.cpp +++ b/dgl/src/Cairo.cpp @@ -65,7 +65,7 @@ void Rectangle::_draw(const bool outline) // ----------------------------------------------------------------------- -void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaling) +void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) { /* if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible) @@ -83,7 +83,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const cairo_set_matrix(cr, &matrix); -// displaySubWidgets(width, height, autoScaling); +// displaySubWidgets(width, height, autoScaleFactor); } // ----------------------------------------------------------------------- diff --git a/dgl/src/OpenGL.cpp b/dgl/src/OpenGL.cpp index 0beb3f45..13021068 100644 --- a/dgl/src/OpenGL.cpp +++ b/dgl/src/OpenGL.cpp @@ -327,7 +327,7 @@ void OpenGLImage::drawAt(const Point& pos) #if 0 void Widget::PrivateData::display(const uint width, const uint height, - const double autoScaling, + const double autoScaleFactor, const bool renderingSubWidget) { printf("Widget::PrivateData::display INIT\n"); @@ -346,9 +346,9 @@ void Widget::PrivateData::display(const uint width, { // full viewport size glViewport(0, - -(height * autoScaling - height), - width * autoScaling, - height * autoScaling); + -(height * autoScaleFactor - height), + width * autoScaleFactor, + height * autoScaleFactor); } #if 0 else if (needsScaling) @@ -362,16 +362,16 @@ void Widget::PrivateData::display(const uint width, else { // only set viewport pos - glViewport(absolutePos.getX() * autoScaling, - -std::round((height * autoScaling - height) + (absolutePos.getY() * autoScaling)), - std::round(width * autoScaling), - std::round(height * autoScaling)); + glViewport(absolutePos.getX() * autoScaleFactor, + -std::round((height * autoScaleFactor - height) + (absolutePos.getY() * autoScaleFactor)), + std::round(width * autoScaleFactor), + std::round(height * autoScaleFactor)); // then cut the outer bounds - glScissor(absolutePos.getX() * autoScaling, - height - std::round((self->getHeight() + absolutePos.getY()) * autoScaling), - std::round(self->getWidth() * autoScaling), - std::round(self->getHeight() * autoScaling)); + glScissor(absolutePos.getX() * autoScaleFactor, + height - std::round((self->getHeight() + absolutePos.getY()) * autoScaleFactor), + std::round(self->getWidth() * autoScaleFactor), + std::round(self->getHeight() * autoScaleFactor)); glEnable(GL_SCISSOR_TEST); needsDisableScissor = true; @@ -387,11 +387,11 @@ void Widget::PrivateData::display(const uint width, needsDisableScissor = false; } - displaySubWidgets(width, height, autoScaling); + displaySubWidgets(width, height, autoScaleFactor); } #endif -void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaling) +void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) { bool needsDisableScissor = false; @@ -399,9 +399,9 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const { // full viewport size glViewport(0, - -(height * autoScaling - height), - width * autoScaling, - height * autoScaling); + -(height * autoScaleFactor - height), + width * autoScaleFactor, + height * autoScaleFactor); } else if (needsViewportScaling) { @@ -414,16 +414,16 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const else { // only set viewport pos - glViewport(absolutePos.getX() * autoScaling, - -std::round((height * autoScaling - height) + (absolutePos.getY() * autoScaling)), - std::round(width * autoScaling), - std::round(height * autoScaling)); + glViewport(absolutePos.getX() * autoScaleFactor, + -std::round((height * autoScaleFactor - height) + (absolutePos.getY() * autoScaleFactor)), + std::round(width * autoScaleFactor), + std::round(height * autoScaleFactor)); // then cut the outer bounds - glScissor(absolutePos.getX() * autoScaling, - height - std::round((self->getHeight() + absolutePos.getY()) * autoScaling), - std::round(self->getWidth() * autoScaling), - std::round(self->getHeight() * autoScaling)); + glScissor(absolutePos.getX() * autoScaleFactor, + height - std::round((self->getHeight() + absolutePos.getY()) * autoScaleFactor), + std::round(self->getWidth() * autoScaleFactor), + std::round(self->getHeight() * autoScaleFactor)); glEnable(GL_SCISSOR_TEST); needsDisableScissor = true; @@ -438,7 +438,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const needsDisableScissor = false; } -// displaySubWidgets(width, height, autoScaling); +// displaySubWidgets(width, height, autoScaleFactor); } // ----------------------------------------------------------------------- @@ -446,18 +446,22 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const void TopLevelWidget::PrivateData::display() { const Size size(window.getSize()); - const uint width = size.getWidth(); - const uint height = size.getHeight(); - const double autoScaling = window.pData->autoScaling; + const uint width = size.getWidth(); + const uint height = size.getHeight(); + + const double autoScaleFactor = window.pData->autoScaleFactor; // full viewport size - glViewport(0, -(height * autoScaling - height), width * autoScaling, height * autoScaling); + if (window.pData->autoScaling) + glViewport(0, -height, width, height); + else + glViewport(0, -(height * autoScaleFactor - height), width * autoScaleFactor, height * autoScaleFactor); // main widget drawing self->onDisplay(); // now draw subwidgets if there are any - selfw->pData->displaySubWidgets(width, height, autoScaling); + selfw->pData->displaySubWidgets(width, height, autoScaleFactor); } // ----------------------------------------------------------------------- diff --git a/dgl/src/SubWidgetPrivateData.hpp b/dgl/src/SubWidgetPrivateData.hpp index 5e0e5cf5..8a219f52 100644 --- a/dgl/src/SubWidgetPrivateData.hpp +++ b/dgl/src/SubWidgetPrivateData.hpp @@ -33,7 +33,7 @@ struct SubWidget::PrivateData { ~PrivateData(); // NOTE display function is different depending on build type, must call displaySubWidgets at the end - void display(uint width, uint height, double autoScaling); + void display(uint width, uint height, double autoScaleFactor); DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) }; diff --git a/dgl/src/TopLevelWidget.cpp b/dgl/src/TopLevelWidget.cpp index 6b9bb825..85612ef5 100644 --- a/dgl/src/TopLevelWidget.cpp +++ b/dgl/src/TopLevelWidget.cpp @@ -50,6 +50,14 @@ void TopLevelWidget::repaint(const Rectangle& rect) noexcept pData->window.repaint(rect); } +void TopLevelWidget::setGeometryConstraints(const uint minimumWidth, + const uint minimumHeight, + const bool keepAspectRatio, + const bool automaticallyScale) +{ + pData->window.setGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, automaticallyScale); +} + // ----------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/src/TopLevelWidgetPrivateData.cpp b/dgl/src/TopLevelWidgetPrivateData.cpp index 9f19cd1c..9edc6646 100644 --- a/dgl/src/TopLevelWidgetPrivateData.cpp +++ b/dgl/src/TopLevelWidgetPrivateData.cpp @@ -41,12 +41,12 @@ void TopLevelWidget::PrivateData::mouseEvent(const Events::MouseEvent& ev) { Events::MouseEvent rev = ev; - const double autoScaling = window.pData->autoScaling; - - if (autoScaling != 1.0) + if (window.pData->autoScaling) { - rev.pos.setX(ev.pos.getX() / autoScaling); - rev.pos.setY(ev.pos.getY() / autoScaling); + const double autoScaleFactor = window.pData->autoScaleFactor; + + rev.pos.setX(ev.pos.getX() / autoScaleFactor); + rev.pos.setY(ev.pos.getY() / autoScaleFactor); } // give top-level widget chance to catch this event first diff --git a/dgl/src/WidgetPrivateData.cpp b/dgl/src/WidgetPrivateData.cpp index 300f8112..8ee47b22 100644 --- a/dgl/src/WidgetPrivateData.cpp +++ b/dgl/src/WidgetPrivateData.cpp @@ -53,7 +53,7 @@ Widget::PrivateData::~PrivateData() subWidgets.clear(); } -void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double scaling) +void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double autoScaleFactor) { if (subWidgets.size() == 0) return; @@ -63,7 +63,7 @@ void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, SubWidget* const subwidget(*it); if (subwidget->isVisible()) - subwidget->pData->display(width, height, scaling); + subwidget->pData->display(width, height, autoScaleFactor); } } diff --git a/dgl/src/WidgetPrivateData.hpp b/dgl/src/WidgetPrivateData.hpp index fa2e6f87..2fcf64e7 100644 --- a/dgl/src/WidgetPrivateData.hpp +++ b/dgl/src/WidgetPrivateData.hpp @@ -41,7 +41,7 @@ struct Widget::PrivateData { explicit PrivateData(Widget* const s, Widget* const pw); ~PrivateData(); - void displaySubWidgets(uint width, uint height, double autoScaling); + void displaySubWidgets(uint width, uint height, double autoScaleFactor); void giveMouseEventForSubWidgets(Events::MouseEvent& ev); static TopLevelWidget* findTopLevelWidget(Widget* const w); diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp index 9750c773..afa7e187 100644 --- a/dgl/src/Window.cpp +++ b/dgl/src/Window.cpp @@ -81,6 +81,16 @@ void Window::close() pData->close(); } +bool Window::isResizable() const noexcept +{ + return puglGetViewHint(pData->view, PUGL_RESIZABLE) == PUGL_TRUE; +} + +void Window::setResizable(const bool resizable) +{ + pData->setResizable(resizable); +} + uint Window::getWidth() const noexcept { return puglGetFrame(pData->view).width; @@ -129,6 +139,16 @@ void Window::setTitle(const char* const title) puglSetWindowTitle(pData->view, title); } +bool Window::isIgnoringKeyRepeat() const noexcept +{ + return puglGetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT) == PUGL_TRUE; +} + +void Window::setIgnoringKeyRepeat(const bool ignore) noexcept +{ + puglSetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT, ignore); +} + Application& Window::getApp() const noexcept { return pData->app; @@ -139,6 +159,19 @@ uintptr_t Window::getNativeWindowHandle() const noexcept return puglGetNativeWindow(pData->view); } +double Window::getScaleFactor() const noexcept +{ + return pData->scaleFactor; +} + +void Window::focus() +{ + if (! pData->isEmbed) + puglRaiseWindow(pData->view); + + puglGrabFocus(pData->view); +} + void Window::repaint() noexcept { puglPostRedisplay(pData->view); @@ -155,82 +188,64 @@ void Window::repaint(const Rectangle& rect) noexcept puglPostRedisplayRect(pData->view, prect); } -void Window::onReshape(uint, uint) +void Window::setGeometryConstraints(const uint minimumWidth, + const uint minimumHeight, + const bool keepAspectRatio, + const bool automaticallyScale) { - puglFallbackOnResize(pData->view); -} + DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,); + DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,); -bool Window::onClose() -{ - return true; -} - -#if 0 -#if 0 -void Window::exec(bool lockWait) -{ - pData->exec(lockWait); -} -#endif + if (pData->isEmbed) { + // Did you forget to set DISTRHO_UI_USER_RESIZABLE ? + DISTRHO_SAFE_ASSERT_RETURN(isResizable(),); + } else if (! isResizable()) { + setResizable(true); + } -void Window::focus() -{ - if (! pData->fUsingEmbed) - puglRaiseWindow(pData->fView); + pData->minWidth = minimumWidth; + pData->minHeight = minimumHeight; + pData->autoScaling = automaticallyScale; - puglGrabFocus(pData->fView); -} + const double scaleFactor = pData->scaleFactor; -bool Window::isResizable() const noexcept -{ - return puglGetViewHint(pData->fView, PUGL_RESIZABLE) == PUGL_TRUE; -} + puglSetGeometryConstraints(pData->view, + minimumWidth * scaleFactor, + minimumHeight * scaleFactor, + keepAspectRatio); -void Window::setResizable(const bool resizable) -{ - DISTRHO_SAFE_ASSERT_RETURN(pData->fUsingEmbed,); - if (pData->fUsingEmbed) + if (scaleFactor != 1.0) { - DGL_DBG("Window setResizable cannot be called when embedded\n"); - return; - } + const Size size(getSize()); - DGL_DBG("Window setResizable called\n"); - - puglSetViewHint(pData->fView, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); -#ifdef DISTRHO_OS_WINDOWS - puglWin32SetWindowResizable(pData->fView, resizable); -#endif + setSize(size.getWidth() * scaleFactor, + size.getHeight() * scaleFactor); + } } -bool Window::getIgnoringKeyRepeat() const noexcept +void Window::onReshape(uint, uint) { - return puglGetViewHint(pData->fView, PUGL_IGNORE_KEY_REPEAT) == PUGL_TRUE; + puglFallbackOnResize(pData->view); } -void Window::setIgnoringKeyRepeat(const bool ignore) noexcept +bool Window::onClose() { - puglSetViewHint(pData->fView, PUGL_IGNORE_KEY_REPEAT, ignore); + return true; } -void Window::setGeometryConstraints(const uint width, const uint height, bool aspect) +#if 0 +#if 0 +void Window::exec(bool lockWait) { - // Did you forget to set DISTRHO_UI_USER_RESIZABLE ? - DISTRHO_SAFE_ASSERT_RETURN(isResizable(),); - - puglUpdateGeometryConstraints(pData->fView, width, height, aspect); + pData->exec(lockWait); } +#endif void Window::setTransientWinId(const uintptr_t winId) { puglSetTransientFor(pData->fView, winId); } -double Window::getScaling() const noexcept -{ - return pData->fScaling; -} - #if 0 Application& Window::getApp() const noexcept { @@ -238,13 +253,6 @@ Application& Window::getApp() const noexcept } #endif -void Window::_setAutoScaling(double scaling) noexcept -{ - DISTRHO_SAFE_ASSERT_RETURN(scaling > 0.0,); - - pData->fAutoScaling = scaling; -} - void Window::_addWidget(Widget* const widget) { pData->addWidget(widget); diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index c7491347..fc92e4ea 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -49,8 +49,11 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) isClosed(true), isVisible(false), isEmbed(false), - scaling(1.0), - autoScaling(1.0), + scaleFactor(1.0), + autoScaling(false), + autoScaleFactor(1.0), + minWidth(0), + minHeight(0), pendingVisibility(kPendingVisibilityNone) { init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); @@ -65,8 +68,11 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, Window& transi isClosed(true), isVisible(false), isEmbed(false), - scaling(1.0), - autoScaling(1.0), + scaleFactor(1.0), + autoScaling(false), + autoScaleFactor(1.0), + minWidth(0), + minHeight(0), pendingVisibility(kPendingVisibilityNone) { init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); @@ -85,8 +91,11 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, isClosed(parentWindowHandle == 0), isVisible(parentWindowHandle != 0), isEmbed(parentWindowHandle != 0), - scaling(scale), - autoScaling(1.0), + scaleFactor(scale), + autoScaling(false), + autoScaleFactor(1.0), + minWidth(0), + minHeight(0), pendingVisibility(kPendingVisibilityNone) { if (isEmbed) @@ -116,8 +125,11 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, isClosed(parentWindowHandle == 0), isVisible(parentWindowHandle != 0), isEmbed(parentWindowHandle != 0), - scaling(scale), - autoScaling(1.0), + scaleFactor(scale), + autoScaling(false), + autoScaleFactor(1.0), + minWidth(0), + minHeight(0), pendingVisibility(kPendingVisibilityNone) { if (isEmbed) @@ -293,6 +305,20 @@ void Window::PrivateData::close() // ----------------------------------------------------------------------- +void Window::PrivateData::setResizable(const bool resizable) +{ + DISTRHO_SAFE_ASSERT_RETURN(! isEmbed,); + + DGL_DBG("Window setResizable called\n"); + + puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); +#ifdef DISTRHO_OS_WINDOWS + puglWin32SetWindowResizable(view, resizable); +#endif +} + +// ----------------------------------------------------------------------- + void Window::PrivateData::idleCallback() { // #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED) @@ -329,6 +355,13 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) DGL_DBGp("PUGL: onReshape : %i %i\n", width, height); + if (autoScaling) + { + const double scaleHorizontal = static_cast(width) / static_cast(minWidth); + const double scaleVertical = static_cast(height) / static_cast(minHeight); + autoScaleFactor = scaleHorizontal < scaleVertical ? scaleHorizontal : scaleVertical; + } + self->onReshape(width, height); #ifndef DPF_TEST_WINDOW_CPP diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp index 01ce4048..78c6f50c 100644 --- a/dgl/src/WindowPrivateData.hpp +++ b/dgl/src/WindowPrivateData.hpp @@ -58,11 +58,15 @@ struct Window::PrivateData : IdleCallback { /** Whether this Window is embed into another (usually not DGL-controlled) Window. */ const bool isEmbed; - /** Scaling to report to widgets on request, purely informational. */ - double scaling; + /** Scale factor to report to widgets on request, purely informational. */ + double scaleFactor; /** Automatic scaling to apply on widgets, implemented internally. */ - double autoScaling; + bool autoScaling; + double autoScaleFactor; + + /** Pugl minWidth, minHeight access. */ + uint minWidth, minHeight; /** Pending state of visility, used for the action to be triggered during Pugl create events. */ enum PendingVisibility { @@ -102,6 +106,8 @@ struct Window::PrivateData : IdleCallback { */ void close(); + void setResizable(bool resizable); + const GraphicsContext& getGraphicsContext() const noexcept; void idleCallback() override; diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp index 507c0411..49bb29ca 100644 --- a/dgl/src/pugl.cpp +++ b/dgl/src/pugl.cpp @@ -85,6 +85,14 @@ START_NAMESPACE_DGL #include "pugl-upstream/src/implementation.c" +// -------------------------------------------------------------------------------------------------------------------- +// expose backend enter + +void puglBackendEnter(PuglView* view) +{ + view->backend->enter(view, NULL); +} + // -------------------------------------------------------------------------------------------------------------------- // missing in pugl, directly returns title char* pointer @@ -94,11 +102,68 @@ const char* puglGetWindowTitle(const PuglView* view) } // -------------------------------------------------------------------------------------------------------------------- -// expose backend enter +// bring view window into the foreground, aka "raise" window -void puglBackendEnter(PuglView* view) +void puglRaiseWindow(PuglView* view) { - view->backend->enter(view, NULL); +#if defined(DISTRHO_OS_HAIKU) || defined(DISTRHO_OS_MAC) + // nothing here yet +#elif defined(DISTRHO_OS_WINDOWS) + SetForegroundWindow(view->impl->hwnd); + SetActiveWindow(view->impl->hwnd); +#else + XRaiseWindow(view->impl->display, view->impl->win); +#endif +} + +// -------------------------------------------------------------------------------------------------------------------- +// set backend that matches current build + +void puglSetMatchingBackendForCurrentBuild(PuglView* view) +{ +#ifdef DGL_CAIRO + puglSetBackend(view, puglCairoBackend()); +#endif +#ifdef DGL_OPENGL + puglSetBackend(view, puglGlBackend()); +#endif +#ifdef DGL_Vulkan + puglSetBackend(view, puglVulkanBackend()); +#endif +} + +// -------------------------------------------------------------------------------------------------------------------- +// Combine puglSetMinSize and puglSetAspectRatio + +PuglStatus puglSetGeometryConstraints(PuglView* view, unsigned int width, unsigned int height, bool aspect) +{ + view->minWidth = width; + view->minHeight = height; + + if (aspect) { + view->minAspectX = width; + view->minAspectY = height; + view->maxAspectX = width; + view->maxAspectY = height; + } + +#if defined(DISTRHO_OS_HAIKU) + // nothing? +#elif defined(DISTRHO_OS_MAC) + if (view->impl->window) + { + [view->impl->window setContentMinSize:sizePoints(view, view->minWidth, view->minHeight)]; + + if (aspect) + [view->impl->window setContentAspectRatio:sizePoints(view, view->minAspectX, view->minAspectY)]; + } +#elif defined(DISTRHO_OS_WINDOWS) + // nothing +#else + return updateSizeHints(view); +#endif + + return PUGL_SUCCESS; } // -------------------------------------------------------------------------------------------------------------------- @@ -161,22 +226,6 @@ PuglStatus puglSetWindowSize(PuglView* view, unsigned int width, unsigned int he return PUGL_SUCCESS; } -// -------------------------------------------------------------------------------------------------------------------- -// set backend that matches current build - -void puglSetMatchingBackendForCurrentBuild(PuglView* view) -{ -#ifdef DGL_CAIRO - puglSetBackend(view, puglCairoBackend()); -#endif -#ifdef DGL_OPENGL - puglSetBackend(view, puglGlBackend()); -#endif -#ifdef DGL_Vulkan - puglSetBackend(view, puglVulkanBackend()); -#endif -} - // -------------------------------------------------------------------------------------------------------------------- // DGL specific, build-specific drawing prepare diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp index 959ce560..1bc9a632 100644 --- a/dgl/src/pugl.hpp +++ b/dgl/src/pugl.hpp @@ -33,22 +33,30 @@ START_NAMESPACE_DGL PUGL_BEGIN_DECLS +// expose backend enter +PUGL_API void +puglBackendEnter(PuglView* view); + // missing in pugl, directly returns title char* pointer PUGL_API const char* puglGetWindowTitle(const PuglView* view); -// expose backend enter +// bring view window into the foreground, aka "raise" window PUGL_API void -puglBackendEnter(PuglView* view); - -// set window size without changing frame x/y position -PUGL_API PuglStatus -puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height); +puglRaiseWindow(PuglView* view); // DGL specific, assigns backend that matches current DGL build PUGL_API void puglSetMatchingBackendForCurrentBuild(PuglView* view); +// Combine puglSetMinSize and puglSetAspectRatio +PUGL_API PuglStatus +puglSetGeometryConstraints(PuglView* view, unsigned int width, unsigned int height, bool aspect); + +// set window size without changing frame x/y position +PUGL_API PuglStatus +puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height); + // DGL specific, build-specific drawing prepare PUGL_API void puglOnDisplayPrepare(PuglView* view); diff --git a/distrho/DistrhoUI.hpp b/distrho/DistrhoUI.hpp index 009f0f82..9db5cd41 100644 --- a/distrho/DistrhoUI.hpp +++ b/distrho/DistrhoUI.hpp @@ -69,15 +69,6 @@ public: */ virtual ~UI(); -#if DISTRHO_UI_USER_RESIZABLE && !DISTRHO_PLUGIN_HAS_EXTERNAL_UI - /** - Set geometry constraints for the UI when resized by the user, and optionally scale UI automatically. - @see Window::setGeometryConstraints(uint,uint,bool) - @see Window::setScaling(double) - */ - void setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale = false); -#endif - /* -------------------------------------------------------------------------------------------------------- * Host state */ diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp index 474d8832..c6a07a31 100644 --- a/distrho/src/DistrhoUI.cpp +++ b/distrho/src/DistrhoUI.cpp @@ -87,28 +87,6 @@ UI::~UI() delete uiData; } -#if DISTRHO_UI_USER_RESIZABLE && !DISTRHO_PLUGIN_HAS_EXTERNAL_UI -void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale) -{ - DISTRHO_SAFE_ASSERT_RETURN(minWidth > 0,); - DISTRHO_SAFE_ASSERT_RETURN(minHeight > 0,); - - uiData->automaticallyScale = automaticallyScale; - uiData->minWidth = minWidth; - uiData->minHeight = minHeight; - -#if 0 /* TODO */ - Window& window(getParentWindow()); - - const double uiScaleFactor = window.getScaling(); - window.setGeometryConstraints(minWidth * uiScaleFactor, minHeight * uiScaleFactor, keepAspectRatio); - - if (d_isNotZero(uiScaleFactor - 1.0)) - setSize(getWidth() * uiScaleFactor, getHeight() * uiScaleFactor); -#endif -} -#endif - /* ------------------------------------------------------------------------------------------------------------ * Host state */ diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp index a9073268..73b923ad 100644 --- a/distrho/src/DistrhoUIInternal.hpp +++ b/distrho/src/DistrhoUIInternal.hpp @@ -95,15 +95,6 @@ protected: UI::PrivateData* const uiData = fUI->uiData; DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr,); -#if 0 /* TODO */ - if (uiData->automaticallyScale) - { - const double scaleHorizontal = static_cast(width) / static_cast(uiData->minWidth); - const double scaleVertical = static_cast(height) / static_cast(uiData->minHeight); - _setAutoScaling(scaleHorizontal < scaleVertical ? scaleHorizontal : scaleVertical); - } -#endif - uiData->resizeInProgress = true; fUI->setSize(width, height); uiData->resizeInProgress = false; @@ -342,9 +333,7 @@ public: void focus() { -#if 0 /* TODO */ glWindow.focus(); -#endif } bool idle()