commit 05c6d04adbd2018ca50e8e41a4ddb2ce45c9bd89
parent d85c806875762976946faaae280233429645a49e
Author: falkTX <falktx@falktx.com>
Date: Mon, 3 May 2021 22:39:09 +0100
Add the needed bits to make window visible, setting size
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
14 files changed, 641 insertions(+), 384 deletions(-)
diff --git a/dgl/Application.hpp b/dgl/Application.hpp
@@ -22,11 +22,6 @@
START_NAMESPACE_DGL
// --------------------------------------------------------------------------------------------------------------------
-// Forward class names
-
-class Window;
-
-// --------------------------------------------------------------------------------------------------------------------
/**
Base DGL Application class.
diff --git a/dgl/Cairo.hpp b/dgl/Cairo.hpp
@@ -30,7 +30,7 @@ START_NAMESPACE_DGL
*/
struct CairoGraphicsContext : GraphicsContext
{
- cairo_t* cairo; // FIXME proper name..
+ cairo_t* handle;
};
// -----------------------------------------------------------------------
diff --git a/dgl/Window.hpp b/dgl/Window.hpp
@@ -56,7 +56,12 @@ public:
/**
Constructor for an embed Window, typically used in modules or plugins that run inside another host.
*/
- explicit Window(Application& app, uintptr_t parentWindowHandle, double scaling, bool resizable);
+ explicit Window(Application& app,
+ uintptr_t parentWindowHandle,
+ uint width,
+ uint height,
+ double scaling,
+ bool resizable);
/**
Destructor.
@@ -68,11 +73,33 @@ public:
*/
bool isEmbed() const noexcept;
+ /**
+ Check if this window is visible / mapped.
+ Invisible windows do not receive events except resize.
+ @see setVisible(bool)
+ */
bool isVisible() const noexcept;
+
+ /**
+ Set windows visible (or not) according to @a visible.
+ Only valid for standalones, embed windows are always visible.
+ @see isVisible(), hide(), show()
+ */
void setVisible(bool visible);
- inline void show() { setVisible(true); }
- inline void hide() { setVisible(true); }
+ /**
+ Show window.
+ This is the same as calling setVisible(true).
+ @see isVisible(), setVisible(bool)
+ */
+ void show();
+
+ /**
+ Hide window.
+ This is the same as calling setVisible(false).
+ @see isVisible(), setVisible(bool)
+ */
+ void hide();
/**
Hide window and notify application of a window close event.
@@ -86,6 +113,44 @@ public:
void close();
/**
+ Get width.
+ */
+ uint getWidth() const noexcept;
+
+ /**
+ Get height.
+ */
+ uint getHeight() const noexcept;
+
+ /**
+ Get size.
+ */
+ Size<uint> getSize() const noexcept;
+
+ /**
+ Set width.
+ */
+ void setWidth(uint width);
+
+ /**
+ Set height.
+ */
+ void setHeight(uint height);
+
+ /**
+ Set size using @a width and @a height values.
+ */
+ void setSize(uint width, uint height);
+
+ /**
+ Set size.
+ */
+ void setSize(const Size<uint>& size);
+
+ const char* getTitle() const noexcept;
+ void setTitle(const char* title);
+
+ /**
Get the "native" window handle.
Returned value depends on the platform:
- HaikuOS: This is a pointer to a `BView`.
@@ -95,6 +160,11 @@ public:
*/
uintptr_t getNativeWindowHandle() const noexcept;
+protected:
+ virtual void onDisplayBefore();
+ virtual void onDisplayAfter();
+ virtual void onReshape(uint width, uint height);
+
private:
struct PrivateData;
PrivateData* const pData;
@@ -180,15 +250,6 @@ END_NAMESPACE_DGL
bool getIgnoringKeyRepeat() const noexcept;
void setIgnoringKeyRepeat(bool ignore) noexcept;
- uint getWidth() const noexcept;
- uint getHeight() const noexcept;
- Size<uint> getSize() const noexcept;
- void setSize(uint width, uint height);
- void setSize(Size<uint> size);
-
- const char* getTitle() const noexcept;
- void setTitle(const char* title);
-
void setGeometryConstraints(uint width, uint height, bool aspect);
void setTransientWinId(uintptr_t winId);
@@ -206,9 +267,6 @@ END_NAMESPACE_DGL
protected:
- virtual void onDisplayBefore();
- virtual void onDisplayAfter();
- virtual void onReshape(uint width, uint height);
virtual void onClose();
#ifndef DGL_FILE_BROWSER_DISABLED
diff --git a/dgl/src/ApplicationPrivateData.cpp b/dgl/src/ApplicationPrivateData.cpp
@@ -21,6 +21,8 @@
START_NAMESPACE_DGL
+typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator;
+
// --------------------------------------------------------------------------------------------------------------------
Application::PrivateData::PrivateData(const bool standalone)
@@ -97,9 +99,9 @@ void Application::PrivateData::quit()
isQuitting = true;
#ifndef DPF_TEST_APPLICATION_CPP
- for (std::list<Window*>::reverse_iterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit)
+ for (WindowListReverseIterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit)
{
- Window* const window(*rit);
+ DGL_NAMESPACE::Window* const window(*rit);
window->close();
}
#endif
diff --git a/dgl/src/ApplicationPrivateData.hpp b/dgl/src/ApplicationPrivateData.hpp
@@ -47,10 +47,10 @@ struct Application::PrivateData {
uint visibleWindows;
/** List of windows for this application. Only used during `close`. */
- std::list<Window*> windows;
+ std::list<DGL_NAMESPACE::Window*> windows;
/** List of idle callbacks for this application. */
- std::list<IdleCallback*> idleCallbacks;
+ std::list<DGL_NAMESPACE::IdleCallback*> idleCallbacks;
/** Constructor and destructor */
PrivateData(const bool standalone);
diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp
@@ -29,8 +29,13 @@ START_NAMESPACE_DGL
Window::Window(Application& app)
: pData(new PrivateData(app.pData, this)) {}
-Window::Window(Application& app, const uintptr_t parentWindowHandle, const double scaling, const bool resizable)
- : pData(new PrivateData(app.pData, this, parentWindowHandle, scaling, resizable)) {}
+Window::Window(Application& app,
+ const uintptr_t parentWindowHandle,
+ const uint width,
+ const uint height,
+ const double scaling,
+ const bool resizable)
+ : pData(new PrivateData(app.pData, this, parentWindowHandle, width, height, scaling, resizable)) {}
Window::~Window()
{
@@ -49,7 +54,20 @@ bool Window::isVisible() const noexcept
void Window::setVisible(const bool visible)
{
- pData->setVisible(visible);
+ if (visible)
+ pData->show();
+ else
+ pData->hide();
+}
+
+void Window::show()
+{
+ pData->show();
+}
+
+void Window::hide()
+{
+ pData->hide();
}
void Window::close()
@@ -57,11 +75,77 @@ void Window::close()
pData->close();
}
+uint Window::getWidth() const noexcept
+{
+ return puglGetFrame(pData->view).width;
+}
+
+uint Window::getHeight() const noexcept
+{
+ return puglGetFrame(pData->view).height;
+}
+
+Size<uint> Window::getSize() const noexcept
+{
+ const PuglRect rect = puglGetFrame(pData->view);
+ return Size<uint>(rect.width, rect.height);
+}
+
+void Window::setWidth(const uint width)
+{
+ setSize(width, getHeight());
+}
+
+void Window::setHeight(const uint height)
+{
+ setSize(getWidth(), height);
+}
+
+void Window::setSize(const uint width, const uint height)
+{
+ DISTRHO_SAFE_ASSERT_UINT2_RETURN(width > 1 && height > 1, width, height,);
+
+ puglSetWindowSize(pData->view, width, height);
+}
+
+void Window::setSize(const Size<uint>& size)
+{
+ setSize(size.getWidth(), size.getHeight());
+}
+
+const char* Window::getTitle() const noexcept
+{
+ return puglGetWindowTitle(pData->view);
+}
+
+void Window::setTitle(const char* const title)
+{
+ puglSetWindowTitle(pData->view, title);
+}
+
uintptr_t Window::getNativeWindowHandle() const noexcept
{
return puglGetNativeWindow(pData->view);
}
+void Window::onDisplayBefore()
+{
+ const GraphicsContext& context(pData->getGraphicsContext());
+ PrivateData::Fallback::onDisplayBefore(context);
+}
+
+void Window::onDisplayAfter()
+{
+ const GraphicsContext& context(pData->getGraphicsContext());
+ PrivateData::Fallback::onDisplayAfter(context);
+}
+
+void Window::onReshape(const uint width, const uint height)
+{
+ const GraphicsContext& context(pData->getGraphicsContext());
+ PrivateData::Fallback::onReshape(context, width, height);
+}
+
#if 0
#if 0
void Window::exec(bool lockWait)
@@ -134,44 +218,6 @@ void Window::setGeometryConstraints(const uint width, const uint height, bool as
puglUpdateGeometryConstraints(pData->fView, width, height, aspect);
}
-uint Window::getWidth() const noexcept
-{
- return puglGetFrame(pData->fView).width;
-}
-
-uint Window::getHeight() const noexcept
-{
- return puglGetFrame(pData->fView).height;
-}
-
-Size<uint> Window::getSize() const noexcept
-{
- const PuglRect rect = puglGetFrame(pData->fView);
- return Size<uint>(rect.width, rect.height);
-}
-
-void Window::setSize(const uint width, const uint height)
-{
- DISTRHO_SAFE_ASSERT_INT2_RETURN(width > 1 && height > 1, width, height,);
-
- puglSetWindowSize(pData->fView, width, height);
-}
-
-void Window::setSize(const Size<uint> size)
-{
- setSize(size.getWidth(), size.getHeight());
-}
-
-const char* Window::getTitle() const noexcept
-{
- return puglGetWindowTitle(pData->fView);
-}
-
-void Window::setTitle(const char* const title)
-{
- puglSetWindowTitle(pData->fView, title);
-}
-
void Window::setTransientWinId(const uintptr_t winId)
{
puglSetTransientFor(pData->fView, winId);
@@ -189,17 +235,6 @@ Application& Window::getApp() const noexcept
}
#endif
-#if 0
-const GraphicsContext& Window::getGraphicsContext() const noexcept
-{
- GraphicsContext& context = pData->fContext;
-#ifdef DGL_CAIRO
- context.cairo = (cairo_t*)puglGetContext(pData->fView);
-#endif
- return context;
-}
-#endif
-
void Window::_setAutoScaling(double scaling) noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(scaling > 0.0,);
@@ -240,21 +275,6 @@ void Window::removeIdleCallback(IdleCallback* const callback)
// -----------------------------------------------------------------------
-void Window::onDisplayBefore()
-{
- PrivateData::Fallback::onDisplayBefore();
-}
-
-void Window::onDisplayAfter()
-{
- PrivateData::Fallback::onDisplayAfter();
-}
-
-void Window::onReshape(const uint width, const uint height)
-{
- PrivateData::Fallback::onReshape(width, height);
-}
-
void Window::onClose()
{
}
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -21,6 +21,21 @@
START_NAMESPACE_DGL
+#define DGL_DEBUG_EVENTS
+
+#if defined(DEBUG) && defined(DGL_DEBUG_EVENTS)
+# define DGL_DBG(msg) std::fprintf(stderr, "%s", msg);
+# define DGL_DBGp(...) std::fprintf(stderr, __VA_ARGS__);
+# define DGL_DBGF std::fflush(stderr);
+#else
+# define DGL_DBG(msg)
+# define DGL_DBGp(...)
+# define DGL_DBGF
+#endif
+
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+
// -----------------------------------------------------------------------
Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s)
@@ -31,7 +46,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
isVisible(false),
isEmbed(false)
{
- init(false);
+ init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false);
}
Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, Window& transientWindow)
@@ -42,13 +57,15 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
isVisible(false),
isEmbed(false)
{
- init(false);
+ init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false);
puglSetTransientFor(view, transientWindow.getNativeWindowHandle());
}
Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s,
- const uintptr_t parentWindowHandle, const double scaling, const bool resizable)
+ const uintptr_t parentWindowHandle,
+ const uint width, const uint height,
+ const double scaling, const bool resizable)
: appData(a),
self(s),
view(puglNewView(appData->world)),
@@ -56,11 +73,12 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
isVisible(parentWindowHandle != 0),
isEmbed(parentWindowHandle != 0)
{
- init(resizable);
+ init(width, height, resizable);
if (isEmbed)
{
appData->oneWindowShown();
+ puglSetDefaultSize(view, width, height);
puglSetParentWindow(view, parentWindowHandle);
puglShow(view);
}
@@ -85,16 +103,15 @@ Window::PrivateData::~PrivateData()
// -----------------------------------------------------------------------
-void Window::PrivateData::init(const bool resizable)
+void Window::PrivateData::init(const uint width, const uint height, const bool resizable)
{
appData->windows.push_back(self);
appData->idleCallbacks.push_back(this);
+ memset(graphicsContext, 0, sizeof(graphicsContext));
if (view == nullptr)
{
- /*
- DGL_DBG("Failed!\n");
- */
+ DGL_DBG("Failed to create Pugl view, everything will fail!\n");
return;
}
@@ -116,231 +133,144 @@ void Window::PrivateData::init(const bool resizable)
// puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback);
// #endif
- // DGL_DBG("Success!\n");
-}
-
-// -----------------------------------------------------------------------
-
-void Window::PrivateData::close()
-{
-// DGL_DBG("Window close\n");
-
- if (isEmbed || isClosed)
- return;
-
- isClosed = true;
- setVisible(false);
- appData->oneWindowClosed();
+ PuglRect rect = puglGetFrame(view);
+ rect.width = width;
+ rect.height = height;
+ puglSetFrame(view, rect);
}
// -----------------------------------------------------------------------
-void Window::PrivateData::setVisible(const bool visible)
+void Window::PrivateData::show()
{
- if (isVisible == visible)
+ if (isVisible)
{
-// DGL_DBG("Window setVisible matches current state, ignoring request\n");
+ DGL_DBG("Window show matches current visible state, ignoring request\n");
return;
}
if (isEmbed)
{
-// DGL_DBG("Window setVisible cannot be called when embedded\n");
+ DGL_DBG("Window show cannot be called when embedded\n");
return;
}
-// DGL_DBG("Window setVisible called\n");
+ DGL_DBG("Window show called\n");
- isVisible = visible;
+#if 0 && defined(DISTRHO_OS_MAC)
+// if (mWindow != nullptr)
+// {
+// if (mParentWindow != nullptr)
+// [mParentWindow addChildWindow:mWindow
+// ordered:NSWindowAbove];
+// }
+#endif
- if (visible)
+ if (isClosed)
{
-// #if 0 && defined(DISTRHO_OS_MAC)
-// if (mWindow != nullptr)
-// {
-// if (mParentWindow != nullptr)
-// [mParentWindow addChildWindow:mWindow
-// ordered:NSWindowAbove];
-// }
-// #endif
+ isClosed = false;
+ appData->oneWindowShown();
+
+ const PuglStatus status = puglRealize(view);
+ DISTRHO_SAFE_ASSERT_INT_RETURN(status == PUGL_SUCCESS, status, close());
- if (isClosed)
- {
- puglRealize(view);
#ifdef DISTRHO_OS_WINDOWS
- puglWin32ShowWindowCentered(view);
+ puglWin32ShowWindowCentered(view);
#else
- puglShow(view);
+ puglShow(view);
#endif
- appData->oneWindowShown();
- isClosed = false;
- }
- else
- {
+ }
+ else
+ {
#ifdef DISTRHO_OS_WINDOWS
- puglWin32RestoreWindow(view);
+ puglWin32RestoreWindow(view);
#else
- puglShow(view);
+ puglShow(view);
#endif
- }
}
- else
- {
-// #if 0 && defined(DISTRHO_OS_MAC)
-// if (mWindow != nullptr)
-// {
-// if (mParentWindow != nullptr)
-// [mParentWindow removeChildWindow:mWindow];
-// }
-// #endif
- puglHide(view);
+ isVisible = true;
+}
-// if (fModal.enabled)
-// exec_fini();
+void Window::PrivateData::hide()
+{
+ if (! isVisible)
+ {
+ DGL_DBG("Window hide matches current visible state, ignoring request\n");
+ return;
+ }
+ if (isEmbed)
+ {
+ DGL_DBG("Window hide cannot be called when embedded\n");
+ return;
}
-}
-// -----------------------------------------------------------------------
+ DGL_DBG("Window hide called\n");
-void Window::PrivateData::idleCallback()
-{
-// #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED)
-// if (fSelectedFile.isNotEmpty())
+#if 0 && defined(DISTRHO_OS_MAC)
+// if (mWindow != nullptr)
// {
-// char* const buffer = fSelectedFile.getAndReleaseBuffer();
-// fView->fileSelectedFunc(fView, buffer);
-// std::free(buffer);
+// if (mParentWindow != nullptr)
+// [mParentWindow removeChildWindow:mWindow];
// }
-// #endif
-//
-// if (fModal.enabled && fModal.parent != nullptr)
-// fModal.parent->windowSpecificIdle();
-}
-
-// -----------------------------------------------------------------------
-
-PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event)
-{
- Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view);
- return PUGL_SUCCESS;
-}
-
-// -----------------------------------------------------------------------
-
-END_NAMESPACE_DGL
-
-#if 0
-#ifdef DGL_CAIRO
-# define PUGL_CAIRO
-# include "../Cairo.hpp"
-#endif
-#ifdef DGL_OPENGL
-# define PUGL_OPENGL
-# include "../OpenGL.hpp"
#endif
-#ifndef DPF_TEST_WINDOW_CPP
-#include "WidgetPrivateData.hpp"
-#include "pugl-upstream/include/pugl/pugl.h"
-#include "pugl-extra/extras.h"
-#endif
+ puglHide(view);
-extern "C" {
-#include "pugl-upstream/src/implementation.c"
-#include "pugl-extra/extras.c"
-}
+// if (fModal.enabled)
+// exec_fini();
-#if defined(DISTRHO_OS_HAIKU)
-# define DGL_DEBUG_EVENTS
-# include "pugl-upstream/src/haiku.cpp"
-#elif defined(DISTRHO_OS_MAC)
-# include "pugl-upstream/src/mac.m"
-#elif defined(DISTRHO_OS_WINDOWS)
-# include "ppugl-upstream/src/win.c"
-# undef max
-# undef min
-#else
-# define DGL_PUGL_USING_X11
-extern "C" {
-# include "pugl-upstream/src/x11.c"
-// # ifdef DGL_CAIRO
-// # include "pugl-upstream/src/x11_cairo.c"
-// # endif
-# ifdef DGL_OPENGL
-# include "pugl-upstream/src/x11_gl.c"
-# endif
-# define PUGL_DETAIL_X11_H_INCLUDED
-# include "pugl-extra/x11.c"
+ isVisible = false;
}
-#endif
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#define FOR_EACH_WIDGET(it) \
- for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it)
-
-#define FOR_EACH_WIDGET_INV(rit) \
- for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit)
-
-#define DGL_DEBUG_EVENTS
+// -----------------------------------------------------------------------
-#if defined(DEBUG) && defined(DGL_DEBUG_EVENTS)
-# define DGL_DBG(msg) std::fprintf(stderr, "%s", msg);
-# define DGL_DBGp(...) std::fprintf(stderr, __VA_ARGS__);
-# define DGL_DBGF std::fflush(stderr);
-#else
-# define DGL_DBG(msg)
-# define DGL_DBGp(...)
-# define DGL_DBGF
-#endif
+void Window::PrivateData::close()
+{
+ DGL_DBG("Window close\n");
-START_NAMESPACE_DGL
+ if (isEmbed || isClosed)
+ return;
-// Fallback build-specific Window functions
-struct Fallback {
- static void onDisplayBefore();
- static void onDisplayAfter();
- static void onReshape(uint width, uint height);
-};
+ isClosed = true;
+ hide();
+ appData->oneWindowClosed();
+}
// -----------------------------------------------------------------------
-void Window::PrivateData::addWidget(Widget* const widget)
+const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{
- fWidgets.push_back(widget);
-}
-
-void Window::PrivateData::removeWidget(Widget* const widget)
-{
- fWidgets.remove(widget);
+ GraphicsContext& context((GraphicsContext&)graphicsContext);
+#ifdef DGL_CAIRO
+ ((CairoGraphicsContext&)context).handle = (cairo_t*)puglGetContext(view);
+#endif
+ return context;
}
// -----------------------------------------------------------------------
-void Window::PrivateData::onPuglClose()
+void Window::PrivateData::idleCallback()
{
- DGL_DBG("PUGL: onClose\n");
-
-// if (fModal.enabled)
-// exec_fini();
-
- fSelf->onClose();
-
- if (fModal.childFocus != nullptr)
- fModal.childFocus->fSelf->onClose();
-
- close();
+// #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED)
+// if (fSelectedFile.isNotEmpty())
+// {
+// char* const buffer = fSelectedFile.getAndReleaseBuffer();
+// fView->fileSelectedFunc(fView, buffer);
+// std::free(buffer);
+// }
+// #endif
+//
+// if (fModal.enabled && fModal.parent != nullptr)
+// fModal.parent->windowSpecificIdle();
}
+// -----------------------------------------------------------------------
+
void Window::PrivateData::onPuglDisplay()
{
- fSelf->onDisplayBefore();
+ self->onDisplayBefore();
+ /*
if (fWidgets.size() != 0)
{
const PuglRect rect = puglGetFrame(fView);
@@ -353,8 +283,9 @@ void Window::PrivateData::onPuglDisplay()
widget->pData->display(width, height, fAutoScaling, false);
}
}
+ */
- fSelf->onDisplayAfter();
+ self->onDisplayAfter();
}
void Window::PrivateData::onPuglReshape(const int width, const int height)
@@ -363,8 +294,9 @@ void Window::PrivateData::onPuglReshape(const int width, const int height)
DGL_DBGp("PUGL: onReshape : %i %i\n", width, height);
- fSelf->onReshape(width, height);
+ self->onReshape(width, height);
+ /*
FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);
@@ -372,35 +304,43 @@ void Window::PrivateData::onPuglReshape(const int width, const int height)
if (widget->pData->needsFullViewport)
widget->setSize(width, height);
}
+ */
}
-void Window::PrivateData::onPuglMouse(const Widget::MouseEvent& ev)
-{
- DGL_DBGp("PUGL: onMouse : %i %i %i %i\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY());
-
-// if (fModal.childFocus != nullptr)
-// return fModal.childFocus->focus();
+static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose);
- Widget::MouseEvent rev = ev;
- double x = ev.pos.getX() / fAutoScaling;
- double y = ev.pos.getY() / fAutoScaling;
+PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event)
+{
+ printEvent(event, "pugl event: ", true);
+ Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view);
- FOR_EACH_WIDGET_INV(rit)
+ switch (event->type)
{
- Widget* const widget(*rit);
+ ///< No event
+ case PUGL_NOTHING:
+ break;
- rev.pos = Point<double>(x - widget->getAbsoluteX(),
- y - widget->getAbsoluteY());
+ ///< View moved/resized, a #PuglEventConfigure
+ case PUGL_CONFIGURE:
+ pData->onPuglReshape(event->configure.width, event->configure.height);
+ break;
- if (widget->isVisible() && widget->onMouse(rev))
- break;
+ ///< View must be drawn, a #PuglEventExpose
+ case PUGL_EXPOSE:
+ pData->onPuglDisplay();
+ break;
+
+ // TODO
+ default:
+ break;
}
+
+ return PUGL_SUCCESS;
}
// -----------------------------------------------------------------------
-static inline int
-printModifiers(const uint32_t mods)
+static int printModifiers(const uint32_t mods)
{
return fprintf(stderr, "Modifiers:%s%s%s%s\n",
(mods & PUGL_MOD_SHIFT) ? " Shift" : "",
@@ -409,8 +349,7 @@ printModifiers(const uint32_t mods)
(mods & PUGL_MOD_SUPER) ? " Super" : "");
}
-static inline int
-printEvent(const PuglEvent* event, const char* prefix, const bool verbose)
+static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose)
{
#define FFMT "%6.1f"
#define PFMT FFMT " " FFMT
@@ -526,9 +465,156 @@ printEvent(const PuglEvent* event, const char* prefix, const bool verbose)
return 0;
}
+// -----------------------------------------------------------------------
+
+void Window::PrivateData::Fallback::onDisplayBefore(const GraphicsContext&)
+{
+#ifdef DGL_OPENGL
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+#endif
+}
+
+void Window::PrivateData::Fallback::onDisplayAfter(const GraphicsContext&)
+{
+}
+
+void Window::PrivateData::Fallback::onReshape(const GraphicsContext&, const uint width, const uint height)
+{
+#ifdef DGL_OPENGL
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0, static_cast<GLdouble>(width), static_cast<GLdouble>(height), 0.0, 0.0, 1.0);
+ glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+#else
+ // unused
+ (void)width;
+ (void)height;
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL
+
+#if 0
+#ifdef DGL_CAIRO
+# define PUGL_CAIRO
+# include "../Cairo.hpp"
+#endif
+#ifdef DGL_OPENGL
+# define PUGL_OPENGL
+# include "../OpenGL.hpp"
+#endif
+
+#ifndef DPF_TEST_WINDOW_CPP
+#include "WidgetPrivateData.hpp"
+#include "pugl-upstream/include/pugl/pugl.h"
+#include "pugl-extra/extras.h"
+#endif
+
+extern "C" {
+#include "pugl-upstream/src/implementation.c"
+#include "pugl-extra/extras.c"
+}
+
+#if defined(DISTRHO_OS_HAIKU)
+# define DGL_DEBUG_EVENTS
+# include "pugl-upstream/src/haiku.cpp"
+#elif defined(DISTRHO_OS_MAC)
+# include "pugl-upstream/src/mac.m"
+#elif defined(DISTRHO_OS_WINDOWS)
+# include "ppugl-upstream/src/win.c"
+# undef max
+# undef min
+#else
+# define DGL_PUGL_USING_X11
+extern "C" {
+# include "pugl-upstream/src/x11.c"
+// # ifdef DGL_CAIRO
+// # include "pugl-upstream/src/x11_cairo.c"
+// # endif
+# ifdef DGL_OPENGL
+# include "pugl-upstream/src/x11_gl.c"
+# endif
+# define PUGL_DETAIL_X11_H_INCLUDED
+# include "pugl-extra/x11.c"
+}
+#endif
+
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+START_NAMESPACE_DGL
+
+#define FOR_EACH_WIDGET(it) \
+ for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it)
+
+#define FOR_EACH_WIDGET_INV(rit) \
+ for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit)
+
+// -----------------------------------------------------------------------
+
+void Window::PrivateData::addWidget(Widget* const widget)
+{
+ fWidgets.push_back(widget);
+}
+
+void Window::PrivateData::removeWidget(Widget* const widget)
+{
+ fWidgets.remove(widget);
+}
+
+// -----------------------------------------------------------------------
+
+void Window::PrivateData::onPuglClose()
+{
+ DGL_DBG("PUGL: onClose\n");
+
+// if (fModal.enabled)
+// exec_fini();
+
+ fSelf->onClose();
+
+ if (fModal.childFocus != nullptr)
+ fModal.childFocus->fSelf->onClose();
+
+ close();
+}
+
+void Window::PrivateData::onPuglMouse(const Widget::MouseEvent& ev)
+{
+ DGL_DBGp("PUGL: onMouse : %i %i %i %i\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY());
+
+// if (fModal.childFocus != nullptr)
+// return fModal.childFocus->focus();
+
+ Widget::MouseEvent rev = ev;
+ double x = ev.pos.getX() / fAutoScaling;
+ double y = ev.pos.getY() / fAutoScaling;
+
+ FOR_EACH_WIDGET_INV(rit)
+ {
+ Widget* const widget(*rit);
+
+ rev.pos = Point<double>(x - widget->getAbsoluteX(),
+ y - widget->getAbsoluteY());
+
+ if (widget->isVisible() && widget->onMouse(rev))
+ break;
+ }
+}
+
PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event)
{
- printEvent(event, "", true);
Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view);
switch (event->type)
@@ -607,37 +693,5 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu
// -----------------------------------------------------------------------
-void Window::PrivateData::Fallback::onDisplayBefore()
-{
-#ifdef DGL_OPENGL
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
-#endif
-}
-
-void Window::PrivateData::Fallback::onDisplayAfter()
-{
-}
-
-void Window::PrivateData::Fallback::onReshape(const uint width, const uint height)
-{
-#ifdef DGL_OPENGL
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0, static_cast<GLdouble>(width), static_cast<GLdouble>(height), 0.0, 0.0, 1.0);
- glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-#else
- // unused
- (void)width;
- (void)height;
-#endif
-}
-
-// -----------------------------------------------------------------------
-
END_NAMESPACE_DGL
#endif
diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp
@@ -40,6 +40,9 @@ struct Window::PrivateData : IdleCallback {
/** Pugl view instance. */
PuglView* const view;
+ /** Reserved space for graphics context. */
+ mutable uint8_t graphicsContext[sizeof(void*)];
+
/** Whether this Window is closed (not visible or counted in the Application it is tied to).
Defaults to true unless embed (embed windows are never closed). */
bool isClosed;
@@ -57,13 +60,17 @@ struct Window::PrivateData : IdleCallback {
PrivateData(AppData* appData, Window* self, Window& transientWindow);
/** Constructor for an embed Window, with a few extra hints from the host side. */
- PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable);
+ PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle,
+ uint width, uint height, double scaling, bool resizable);
/** Destructor. */
~PrivateData() override;
/** Helper initialization function called at the end of all this class constructors. */
- void init(bool resizable);
+ void init(uint width, uint height, bool resizable);
+
+ void show();
+ void hide();
/** Hide window and notify application of a window close event.
* Does nothing if window is embed (that is, not standalone).
@@ -74,12 +81,24 @@ struct Window::PrivateData : IdleCallback {
*/
void close();
- void setVisible(bool visible);
+ const GraphicsContext& getGraphicsContext() const noexcept;
void idleCallback() override;
+ // pugl events
+ void onPuglDisplay();
+ void onPuglReshape(int width, int height);
+
+ // Pugl event handling entry point
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);
+ // Fallback build-specific Window functions
+ struct Fallback {
+ static void onDisplayBefore(const GraphicsContext& context);
+ static void onDisplayAfter(const GraphicsContext& context);
+ static void onReshape(const GraphicsContext& context, uint width, uint height);
+ };
+
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};
@@ -161,8 +180,6 @@ END_NAMESPACE_DGL
// -------------------------------------------------------------------
void onPuglClose();
- void onPuglDisplay();
- void onPuglReshape(const int width, const int height);
void onPuglMouse(const Widget::MouseEvent& ev);
// -------------------------------------------------------------------
diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp
@@ -35,6 +35,10 @@
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/keysym.h>
+# ifdef HAVE_XCURSOR
+# include <X11/Xcursor/Xcursor.h>
+# include <X11/cursorfont.h>
+# endif
# ifdef HAVE_XRANDR
# include <X11/extensions/Xrandr.h>
# endif
@@ -42,10 +46,6 @@
# include <X11/extensions/sync.h>
# include <X11/extensions/syncconst.h>
# endif
-# ifdef HAVE_XCURSOR
-# include <X11/Xcursor/Xcursor.h>
-# include <X11/cursorfont.h>
-# endif
# ifdef DGL_CAIRO
# include <cairo.h>
# include <cairo-xlib.h>
@@ -86,5 +86,73 @@ START_NAMESPACE_DGL
#include "pugl-upstream/src/implementation.c"
// --------------------------------------------------------------------------------------------------------------------
+// missing in pugl, directly returns title char* pointer
+
+const char* puglGetWindowTitle(const PuglView* view)
+{
+ return view->title;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// set window size without changing frame x/y position
+
+PuglStatus puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height)
+{
+#if defined(DISTRHO_OS_HAIKU) || defined(DISTRHO_OS_MAC)
+ // TODO
+ const PuglRect frame = { 0.0, 0.0, (double)width, (double)height };
+ return puglSetFrame(view, frame);
+#elif defined(DISTRHO_OS_WINDOWS)
+ // matches upstream pugl, except we add SWP_NOMOVE flag
+ if (view->impl->hwnd)
+ {
+ RECT rect = { (long)frame.x,
+ (long)frame.y,
+ (long)frame.x + (long)frame.width,
+ (long)frame.y + (long)frame.height };
+
+ AdjustWindowRectEx(&rect, puglWinGetWindowFlags(view), FALSE, puglWinGetWindowExFlags(view));
+
+ if (! SetWindowPos(view->impl->hwnd,
+ HWND_TOP,
+ rect.left,
+ rect.top,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER))
+ return PUGL_UNKNOWN_ERROR;
+ }
+#else
+ // matches upstream pugl, except we use XResizeWindow instead of XMoveResizeWindow
+ if (view->impl->win)
+ {
+ if (! XResizeWindow(view->world->impl->display, view->impl->win, width, height))
+ return PUGL_UNKNOWN_ERROR;
+#if 0
+ if (! fResizable)
+ {
+ XSizeHints sizeHints;
+ memset(&sizeHints, 0, sizeof(sizeHints));
+
+ sizeHints.flags = PSize|PMinSize|PMaxSize;
+ sizeHints.width = static_cast<int>(width);
+ sizeHints.height = static_cast<int>(height);
+ sizeHints.min_width = static_cast<int>(width);
+ sizeHints.min_height = static_cast<int>(height);
+ sizeHints.max_width = static_cast<int>(width);
+ sizeHints.max_height = static_cast<int>(height);
+
+ XSetWMNormalHints(xDisplay, xWindow, &sizeHints);
+ }
+#endif
+ }
+#endif
+
+ view->frame.width = width;
+ view->frame.height = height;
+ return PUGL_SUCCESS;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
END_NAMESPACE_DGL
diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp
@@ -31,6 +31,18 @@ START_NAMESPACE_DGL
#define PUGL_DISABLE_DEPRECATED
#include "pugl-upstream/include/pugl/pugl.h"
+PUGL_BEGIN_DECLS
+
+// missing in pugl, directly returns title char* pointer
+PUGL_API const char*
+puglGetWindowTitle(const PuglView* view);
+
+// set window size without changing frame x/y position
+PUGL_API PuglStatus
+puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height);
+
+PUGL_END_DECLS
+
// --------------------------------------------------------------------------------------------------------------------
END_NAMESPACE_DGL
diff --git a/tests/Application.cpp b/tests/Application.cpp
@@ -21,34 +21,10 @@
#include "dgl/src/Application.cpp"
#include "dgl/src/ApplicationPrivateData.cpp"
-#include "distrho/extra/Thread.hpp"
-
START_NAMESPACE_DGL
// --------------------------------------------------------------------------------------------------------------------
-class ApplicationQuitter : public Thread
-{
- Application& app;
-
-public:
- ApplicationQuitter(Application& a)
- : Thread("ApplicationQuitter"),
- app(a)
- {
- startThread();
- }
-
-private:
- void run() override
- {
- d_sleep(2);
- app.quit();
- }
-};
-
-// --------------------------------------------------------------------------------------------------------------------
-
struct IdleCallbackCounter : IdleCallback
{
int counter;
diff --git a/tests/Makefile b/tests/Makefile
@@ -45,39 +45,32 @@ endif
ifeq ($(HAVE_OPENGL),true)
endif
+ifeq ($(HAVE_VULKAN),true)
+endif
+
# ---------------------------------------------------------------------------------------------------------------------
all: $(TARGETS)
# ---------------------------------------------------------------------------------------------------------------------
-../build/tests/%: ../build/tests/%.cpp.o
- @echo "Linking $*"
- $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) -o $@
- @echo "Running test for $*"
- $(SILENT)$@
+define RUN_TEST
+
+ ${1}
+endef
+
# valgrind --leak-check=full $@
-../build/tests/%.cairo: ../build/tests/%.cpp.cairo.o
- @echo "Linking $*"
- $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(CAIRO_LIBS) -o $@
- @echo "Running test for $*"
- $(SILENT)$@
+run: $(TARGETS)
+ $(foreach TEST,$(TARGETS),$(call RUN_TEST,$(TEST)))
-../build/tests/%.opengl: ../build/tests/%.cpp.opengl.o
- @echo "Linking $*"
- $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@
- @echo "Running test for $*"
- $(SILENT) $@
-# gdb -ex run
+# ---------------------------------------------------------------------------------------------------------------------
-../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o
- @echo "Linking $*"
- $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(VULKAN_LIBS) -o $@
- @echo "Running test for $*"
- $(SILENT)$@
+clean:
+ rm -rf ../build/tests
# ---------------------------------------------------------------------------------------------------------------------
+# building steps
../build/tests/%.c.o: %.c
-@mkdir -p ../build/tests
@@ -105,9 +98,23 @@ all: $(TARGETS)
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_VULKAN -c -o $@
# ---------------------------------------------------------------------------------------------------------------------
+# linking steps
-clean:
- rm -rf ../build/tests
+../build/tests/%: ../build/tests/%.cpp.o
+ @echo "Linking $*"
+ $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) -o $@
+
+../build/tests/%.cairo: ../build/tests/%.cpp.cairo.o
+ @echo "Linking $*"
+ $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(CAIRO_LIBS) -o $@
+
+../build/tests/%.opengl: ../build/tests/%.cpp.opengl.o
+ @echo "Linking $*"
+ $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@
+
+../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o
+ @echo "Linking $*"
+ $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(VULKAN_LIBS) -o $@
# ---------------------------------------------------------------------------------------------------------------------
diff --git a/tests/Window.cpp b/tests/Window.cpp
@@ -21,9 +21,11 @@
#include "tests.hpp"
#define DPF_TEST_WINDOW_CPP
+#define DPF_TEST_POINT_CPP
#include "dgl/src/pugl.cpp"
#include "dgl/src/Application.cpp"
#include "dgl/src/ApplicationPrivateData.cpp"
+#include "dgl/src/Geometry.cpp"
#include "dgl/src/Window.cpp"
#include "dgl/src/WindowPrivateData.cpp"
@@ -35,11 +37,27 @@ int main()
using DGL_NAMESPACE::Window;
- // creating simple window
+ // creating and destroying simple window
{
Application app(true);
Window win(app);
- app.idle();
+ }
+
+ // creating and destroying simple window, with a delay
+ {
+ Application app(true);
+ ApplicationQuitter appQuitter(app);
+ Window win(app);
+ app.exec();
+ }
+
+ // showing and closing simple window, MUST be visible on screen
+ {
+ Application app(true);
+ ApplicationQuitter appQuitter(app);
+ Window win(app);
+ win.show();
+ app.exec();
}
// TODO
diff --git a/tests/tests.hpp b/tests/tests.hpp
@@ -14,10 +14,40 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "dgl/Base.hpp"
+#include "dgl/Application.hpp"
+
+#include "distrho/extra/Thread.hpp"
#define DISTRHO_ASSERT_EQUAL(v1, v2, msg) \
if (v1 != v2) { d_stderr2("Test condition failed: %s; file:%s line:%i", msg, __FILE__, __LINE__); return 1; }
#define DISTRHO_ASSERT_NOT_EQUAL(v1, v2, msg) \
if (v1 == v2) { d_stderr2("Test condition failed: %s; file:%s line:%i", msg, __FILE__, __LINE__); return 1; }
+
+START_NAMESPACE_DGL
+
+// --------------------------------------------------------------------------------------------------------------------
+
+class ApplicationQuitter : public Thread
+{
+ Application& app;
+
+public:
+ ApplicationQuitter(Application& a)
+ : Thread("ApplicationQuitter"),
+ app(a)
+ {
+ startThread();
+ }
+
+private:
+ void run() override
+ {
+ d_sleep(2);
+ app.quit();
+ }
+};
+
+// --------------------------------------------------------------------------------------------------------------------
+
+END_NAMESPACE_DGL