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() | |||