Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -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<uint>& rect) noexcept; | |||
| void setGeometryConstraints(uint minimumWidth, | |||
| uint minimumHeight, | |||
| bool keepAspectRatio = false, | |||
| bool automaticallyScale = false); | |||
| // TODO deprecated | |||
| Application& getParentApp() const noexcept { return getApp(); } | |||
| @@ -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<uint>& 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<uint>& 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 | |||
| @@ -65,7 +65,7 @@ void Rectangle<T>::_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); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -327,7 +327,7 @@ void OpenGLImage::drawAt(const Point<int>& 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<uint> 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); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -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) | |||
| }; | |||
| @@ -50,6 +50,14 @@ void TopLevelWidget::repaint(const Rectangle<uint>& 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 | |||
| @@ -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 | |||
| @@ -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); | |||
| } | |||
| } | |||
| @@ -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); | |||
| @@ -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<uint>& 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<uint> 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); | |||
| @@ -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<double>(width) / static_cast<double>(minWidth); | |||
| const double scaleVertical = static_cast<double>(height) / static_cast<double>(minHeight); | |||
| autoScaleFactor = scaleHorizontal < scaleVertical ? scaleHorizontal : scaleVertical; | |||
| } | |||
| self->onReshape(width, height); | |||
| #ifndef DPF_TEST_WINDOW_CPP | |||
| @@ -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; | |||
| @@ -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 | |||
| @@ -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); | |||
| @@ -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 */ | |||
| @@ -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 */ | |||
| @@ -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<double>(width) / static_cast<double>(uiData->minWidth); | |||
| const double scaleVertical = static_cast<double>(height) / static_cast<double>(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() | |||