Browse Source

Start coupling widget and window

Signed-off-by: falkTX <falktx@falktx.com>
pull/272/head
falkTX 4 years ago
parent
commit
272e1bbfbd
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
12 changed files with 266 additions and 145 deletions
  1. +18
    -15
      dgl/Makefile
  2. +28
    -0
      dgl/TopLevelWidget.hpp
  3. +11
    -11
      dgl/Widget.hpp
  4. +3
    -7
      dgl/Window.hpp
  5. +24
    -1
      dgl/src/TopLevelWidget.cpp
  6. +68
    -0
      dgl/src/TopLevelWidgetPrivateData.cpp
  7. +7
    -5
      dgl/src/TopLevelWidgetPrivateData.hpp
  8. +0
    -18
      dgl/src/Window.cpp
  9. +23
    -86
      dgl/src/WindowPrivateData.cpp
  10. +7
    -2
      dgl/src/WindowPrivateData.hpp
  11. +65
    -0
      dgl/src/pugl.cpp
  12. +12
    -0
      dgl/src/pugl.hpp

+ 18
- 15
dgl/Makefile View File

@@ -10,7 +10,7 @@ include ../Makefile.base.mk

BUILD_C_FLAGS += $(DGL_FLAGS) -I. -Isrc
BUILD_CXX_FLAGS += $(DGL_FLAGS) -I. -Isrc -DDONT_SET_USING_DGL_NAMESPACE -Wno-unused-parameter
# -Isrc/pugl-upstream/include
BUILD_CXX_FLAGS += -Isrc/pugl-upstream/include
LINK_FLAGS += $(DGL_LIBS)

# TODO fix these after pugl-upstream is done
@@ -27,22 +27,24 @@ OBJS_common = \
../build/dgl/Application.cpp.o \
../build/dgl/ApplicationPrivateData.cpp.o \
../build/dgl/Color.cpp.o \
../build/dgl/Geometry.cpp.o
../build/dgl/Geometry.cpp.o \
../build/dgl/TopLevelWidget.cpp.o \
../build/dgl/Window.cpp.o \
../build/dgl/WindowPrivateData.cpp.o
# ../build/dgl/ImageBase.cpp.o \
# ../build/dgl/Resources.cpp.o\
# ../build/dgl/StandaloneWindow.cpp.o \
# ../build/dgl/Widget.cpp.o \
# ../build/dgl/Window.cpp.o\
# ../build/dgl/WindowFileBrowser.cpp.o

# TODO: ImageWidgets.cpp

# ---------------------------------------------------------------------------------------------------------------------

OBJS_cairo = $(OBJS_common)
OBJS_cairo = $(OBJS_common) \
../build/dgl/pugl.cpp.cairo.o
# ../build/dgl/Cairo.cpp.cairo.o \
# ../build/dgl/WidgetPrivateData.cpp.cairo.o \
# ../build/dgl/WindowPrivateData.cpp.cairo.o
# ../build/dgl/WidgetPrivateData.cpp.cairo.o

# ifeq ($(MACOS),true)
# OBJS_cairo += ../build/dgl/Window.mm.cairo.o
@@ -52,7 +54,8 @@ OBJS_cairo = $(OBJS_common)

# ---------------------------------------------------------------------------------------------------------------------

OBJS_opengl = $(OBJS_common)
OBJS_opengl = $(OBJS_common) \
../build/dgl/pugl.cpp.opengl.o
# ../build/dgl/OpenGL.cpp.opengl.o \
# ../build/dgl/Image.cpp.opengl.o \
# ../build/dgl/ImageWidgets.cpp.opengl.o \
@@ -115,10 +118,10 @@ all: $(TARGETS)

# ---------------------------------------------------------------------------------------------------------------------

# ../build/dgl/%.cpp.cairo.o: src/%.cpp
# -@mkdir -p ../build/dgl
# @echo "Compiling $< (Cairo variant)"
# $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(CAIRO_FLAGS) -DDGL_CAIRO -c -o $@
../build/dgl/%.cpp.cairo.o: src/%.cpp
-@mkdir -p ../build/dgl
@echo "Compiling $< (Cairo variant)"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(CAIRO_FLAGS) -DDGL_CAIRO -c -o $@

# ../build/dgl/Window.cpp.cairo.o: src/Window.cpp src/sofd/* src/pugl-upstream/*
# -@mkdir -p ../build/dgl
@@ -132,10 +135,10 @@ all: $(TARGETS)

# ---------------------------------------------------------------------------------------------------------------------

# ../build/dgl/%.cpp.opengl.o: src/%.cpp
# -@mkdir -p ../build/dgl
# @echo "Compiling $< (OpenGL variant)"
# $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@
../build/dgl/%.cpp.opengl.o: src/%.cpp
-@mkdir -p ../build/dgl
@echo "Compiling $< (OpenGL variant)"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@

# ../build/dgl/Window.cpp.opengl.o: src/Window.cpp src/sofd/* src/pugl-upstream/*
# -@mkdir -p ../build/dgl


+ 28
- 0
dgl/TopLevelWidget.hpp View File

@@ -21,6 +21,8 @@

START_NAMESPACE_DGL

class Window;

// -----------------------------------------------------------------------

/**
@@ -31,6 +33,9 @@ START_NAMESPACE_DGL
This widget takes the full size of the Window it is mapped to.
Sub-widgets can be added on top of this top-level widget, by creating them with this class as parent.
Doing so allows for custom position and sizes.

This class is used as the type for DPF Plugin UIs.
So anything that a plugin UI might need that does not belong in a simple Widget will go here.
*/
class TopLevelWidget : public Widget
{
@@ -45,9 +50,32 @@ public:
*/
virtual ~TopLevelWidget();

protected:
/**
A function called before any draw operations begin (in the current event-loop cycle).
Can be used to setup any resources for needed drawing.
The default implementation simply paints the full Widget contents black.
*/
virtual void onDisplayBefore();

/**
A function called after all draw operations have ended (in the current event-loop cycle).
Can be used to clear any resources setup during onDisplayBefore().
The default implementation does nothing.
*/
virtual void onDisplayAfter();

/**
A function called when the widget is resized.
Reimplemented from Widget::onResize.
*/
void onResize(const ResizeEvent&) override;

private:
struct PrivateData;
PrivateData* const pData;
friend class Window;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TopLevelWidget)
};



+ 11
- 11
dgl/Widget.hpp View File

@@ -22,19 +22,19 @@
// -----------------------------------------------------------------------
// Forward class names

#ifdef DISTRHO_DEFINES_H_INCLUDED
START_NAMESPACE_DISTRHO
class UI;
END_NAMESPACE_DISTRHO
#endif
// #ifdef DISTRHO_DEFINES_H_INCLUDED
// START_NAMESPACE_DISTRHO
// class UI;
// END_NAMESPACE_DISTRHO
// #endif

START_NAMESPACE_DGL

// class Application;
// class NanoWidget;
class Window;
// class Window;
// class StandaloneWindow;
class SubWidget;
// class SubWidget;
class TopLevelWidget;

using namespace Events;
@@ -208,10 +208,10 @@ private:
// friend class NanoWidget;
// friend class Window;
// friend class StandaloneWindow;
friend class SubWidget;
#ifdef DISTRHO_DEFINES_H_INCLUDED
friend class DISTRHO_NAMESPACE::UI;
#endif
friend class TopLevelWidget;
// #ifdef DISTRHO_DEFINES_H_INCLUDED
// friend class DISTRHO_NAMESPACE::UI;
// #endif

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
};


+ 3
- 7
dgl/Window.hpp View File

@@ -37,12 +37,13 @@ class Application;
Typically the event handling functions as following:
Application -> Window -> Top-Level-Widget -> SubWidgets

...

Please note that, unlike many other graphical toolkits out there,
DGL makes a clear distinction between a Window and a Widget.
You cannot directly draw in a Window, you need to create a Widget for that.

Also, a Window MUST have a single top-level Widget.
The Window will take care of global screen positioning and resizing, everything else is sent for widgets to handle.

...
*/
class Window
@@ -160,11 +161,6 @@ 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;


+ 24
- 1
dgl/src/TopLevelWidget.cpp View File

@@ -15,11 +15,34 @@
*/

#include "TopLevelWidgetPrivateData.hpp"
#include "pugl.hpp"

START_NAMESPACE_DGL

// -----------------------------------------------------------------------

TopLevelWidget::TopLevelWidget(Window& windowToMapTo)
: pData(new PrivateData(this, windowToMapTo)) {}
: Widget(*this),
pData(new PrivateData(this, windowToMapTo)) {}

TopLevelWidget::~TopLevelWidget()
{
delete pData;
}

void TopLevelWidget::onDisplayBefore()
{
}

void TopLevelWidget::onDisplayAfter()
{
}

void TopLevelWidget::onResize(const ResizeEvent& ev)
{
Widget::onResize(ev);
}

// -----------------------------------------------------------------------

END_NAMESPACE_DGL

+ 68
- 0
dgl/src/TopLevelWidgetPrivateData.cpp View File

@@ -0,0 +1,68 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "TopLevelWidgetPrivateData.hpp"
#include "../Window.hpp"
// #include "pugl.hpp"

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)

// -----------------------------------------------------------------------

TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w)
: self(s),
window(w),
widgets() {}

void TopLevelWidget::PrivateData::display()
{
if (widgets.size() == 0)
return;

const Size<uint> size(window.getSize());
// const int width = rect.width;
// const int height = rect.height;

FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);
widget->pData->display(width, height, fAutoScaling, false);
}
}

void TopLevelWidget::PrivateData::resize(const uint width, const uint height)
{
if (widgets.size() == 0)
return;

FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);

if (widget->pData->needsFullViewport)
widget->setSize(width, height);
}
}

// -----------------------------------------------------------------------

END_NAMESPACE_DGL

+ 7
- 5
dgl/src/TopLevelWidgetPrivateData.hpp View File

@@ -18,7 +18,8 @@
#define DGL_TOP_LEVEL_WIDGET_PRIVATE_DATA_HPP_INCLUDED

#include "../TopLevelWidget.hpp"
// #include "../WidgetPrivateData.hpp"

#include <list>

START_NAMESPACE_DGL

@@ -27,12 +28,13 @@ START_NAMESPACE_DGL
struct TopLevelWidget::PrivateData {
TopLevelWidget* const self;
Window& window;
std::list<Widget*> widgets;

PrivateData(TopLevelWidget* const s, Window& w)
: self(s),
window(w) {}
PrivateData(TopLevelWidget* const s, Window& w);
void display();
void resize(uint width, uint height);

DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData)
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};

// -----------------------------------------------------------------------


+ 0
- 18
dgl/src/Window.cpp View File

@@ -128,24 +128,6 @@ 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)


+ 23
- 86
dgl/src/WindowPrivateData.cpp View File

@@ -15,10 +15,12 @@
*/

#include "WindowPrivateData.hpp"
#include "../Widget.hpp"
#include "../TopLevelWidget.hpp"

#include "pugl.hpp"

#include <cinttypes>

START_NAMESPACE_DGL

#define DGL_DEBUG_EVENTS
@@ -42,6 +44,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
: appData(a),
self(s),
view(puglNewView(appData->world)),
topLevelWidget(nullptr),
isClosed(true),
isVisible(false),
isEmbed(false)
@@ -53,6 +56,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
: appData(a),
self(s),
view(puglNewView(appData->world)),
topLevelWidget(nullptr),
isClosed(true),
isVisible(false),
isEmbed(false)
@@ -69,6 +73,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
: appData(a),
self(s),
view(puglNewView(appData->world)),
topLevelWidget(nullptr),
isClosed(parentWindowHandle == 0),
isVisible(parentWindowHandle != 0),
isEmbed(parentWindowHandle != 0)
@@ -115,15 +120,7 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r
return;
}

#ifdef DGL_CAIRO
puglSetBackend(view, puglCairoBackend());
#endif
#ifdef DGL_OPENGL
puglSetBackend(view, puglGlBackend());
#endif
#ifdef DGL_Vulkan
puglSetBackend(view, puglVulkanBackend());
#endif
puglSetMatchingBackendForCurrentBuild(view);

puglSetHandle(view, this);
puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE);
@@ -238,17 +235,6 @@ void Window::PrivateData::close()

// -----------------------------------------------------------------------

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{
GraphicsContext& context((GraphicsContext&)graphicsContext);
#ifdef DGL_CAIRO
((CairoGraphicsContext&)context).handle = (cairo_t*)puglGetContext(view);
#endif
return context;
}

// -----------------------------------------------------------------------

void Window::PrivateData::idleCallback()
{
// #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED)
@@ -268,24 +254,18 @@ void Window::PrivateData::idleCallback()

void Window::PrivateData::onPuglDisplay()
{
self->onDisplayBefore();

/*
if (fWidgets.size() != 0)
#ifndef DPF_TEST_WINDOW_CPP
if (topLevelWidget != nullptr)
{
const PuglRect rect = puglGetFrame(fView);
const int width = rect.width;
const int height = rect.height;

FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);
widget->pData->display(width, height, fAutoScaling, false);
}
topLevelWidget->onDisplayBefore();
topLevelWidget->onDisplay();
topLevelWidget->onDisplayAfter();
}
else
#endif
{
puglFallbackOnDisplay(view);
}
*/

self->onDisplayAfter();
}

void Window::PrivateData::onPuglReshape(const int width, const int height)
@@ -294,17 +274,12 @@ void Window::PrivateData::onPuglReshape(const int width, const int height)

DGL_DBGp("PUGL: onReshape : %i %i\n", width, height);

self->onReshape(width, height);

/*
FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);

if (widget->pData->needsFullViewport)
widget->setSize(width, height);
}
*/
#ifndef DPF_TEST_WINDOW_CPP
if (topLevelWidget != nullptr)
topLevelWidget->setSize(width, height);
else
#endif
puglFallbackOnResize(view);
}

static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose);
@@ -467,38 +442,6 @@ static int printEvent(const PuglEvent* event, const char* prefix, const bool ver

// -----------------------------------------------------------------------

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
@@ -555,12 +498,6 @@ extern "C" {

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)


+ 7
- 2
dgl/src/WindowPrivateData.hpp View File

@@ -18,12 +18,13 @@
#define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED

#include "../Window.hpp"
#include "ApplicationPrivateData.hpp"

#include "pugl.hpp"

START_NAMESPACE_DGL

class Widget;
class TopLevelWidget;

// -----------------------------------------------------------------------

@@ -43,6 +44,9 @@ struct Window::PrivateData : IdleCallback {
/** Reserved space for graphics context. */
mutable uint8_t graphicsContext[sizeof(void*)];

/** The top-level widget associated with this Window. */
TopLevelWidget* topLevelWidget;

/** 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;
@@ -92,12 +96,14 @@ struct Window::PrivateData : IdleCallback {
// Pugl event handling entry point
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);

#if 0
// 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);
};
#endif

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};
@@ -115,7 +121,6 @@ END_NAMESPACE_DGL
bool fUsingEmbed;
double fScaling;
double fAutoScaling;
std::list<Widget*> fWidgets;

struct Modal {
bool enabled;


+ 65
- 0
dgl/src/pugl.cpp View File

@@ -154,5 +154,70 @@ PuglStatus puglSetWindowSize(PuglView* view, unsigned int width, unsigned int he
}

// --------------------------------------------------------------------------------------------------------------------
// 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 fallback drawing
void puglFallbackOnDisplay(PuglView*)
{
#ifdef DGL_OPENGL
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
#endif
}

// --------------------------------------------------------------------------------------------------------------------
// DGL specific, build-specific fallback resize

void puglFallbackOnResize(PuglView* view)
{
#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>(view->frame.width), static_cast<GLdouble>(view->frame.height), 0.0, 0.0, 1.0);
glViewport(0, 0, static_cast<GLsizei>(view->frame.width), static_cast<GLsizei>(view->frame.height));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
#endif
}

END_NAMESPACE_DGL

// --------------------------------------------------------------------------------------------------------------------
// extra, build-specific stuff

#include "WindowPrivateData.hpp"

#ifdef DGL_CAIRO
# include "../Cairo.hpp"
#endif

START_NAMESPACE_DGL

const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept
{
GraphicsContext& context((GraphicsContext&)graphicsContext);
#ifdef DGL_CAIRO
((CairoGraphicsContext&)context).handle = (cairo_t*)puglGetContext(view);
#endif
return context;
}

END_NAMESPACE_DGL

// --------------------------------------------------------------------------------------------------------------------

+ 12
- 0
dgl/src/pugl.hpp View File

@@ -41,6 +41,18 @@ puglGetWindowTitle(const PuglView* view);
PUGL_API PuglStatus
puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height);

// DGL specific, assigns backend that matches current DGL build
PUGL_API void
puglSetMatchingBackendForCurrentBuild(PuglView* view);

// DGL specific, build-specific fallback drawing
PUGL_API void
puglFallbackOnDisplay(PuglView* view);

// DGL specific, build-specific fallback resize
PUGL_API void
puglFallbackOnResize(PuglView* view);

PUGL_END_DECLS

// --------------------------------------------------------------------------------------------------------------------


Loading…
Cancel
Save