commit 5b10613f6e2191a7c38cd67ec62d9517837cb039
parent c10f6b543833019372d265d0220c1cedbf62fd37
Author: falkTX <falktx@falktx.com>
Date: Sun, 9 May 2021 17:13:12 +0100
Start working on nanovg and text, mostly works
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
6 files changed, 152 insertions(+), 79 deletions(-)
diff --git a/dgl/Color.hpp b/dgl/Color.hpp
@@ -19,10 +19,10 @@
#include "Base.hpp"
-START_NAMESPACE_DGL
-
struct NVGcolor;
+START_NAMESPACE_DGL
+
// --------------------------------------------------------------------------------------------------------------------
/**
diff --git a/dgl/NanoVG.hpp b/dgl/NanoVG.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
+ * 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
@@ -19,7 +19,9 @@
#include "Color.hpp"
#include "OpenGL.hpp"
-#include "Widget.hpp"
+#include "SubWidget.hpp"
+#include "TopLevelWidget.hpp"
+#include "StandaloneWindow.hpp"
#ifndef DGL_NO_SHARED_RESOURCES
# define NANOVG_DEJAVU_SANS_TTF "__dpf_dejavusans_ttf__"
@@ -853,7 +855,7 @@ public:
/**
Load DPF's internal shared resources for this NanoVG class.
*/
- virtual void loadSharedResources();
+ virtual bool loadSharedResources();
#endif
private:
@@ -875,25 +877,28 @@ private:
The drawing function onDisplay() is implemented internally but a
new onNanoDisplay() needs to be overridden instead.
*/
-class NanoWidget : public Widget,
+template <class BaseWidget>
+class NanoWidget : public BaseWidget,
public NanoVG
{
public:
/**
- Constructor.
+ Constructor for a NanoSubWidget.
@see CreateFlags
*/
- explicit NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS);
+ explicit NanoWidget(Widget* const parentGroupWidget, int flags = CREATE_ANTIALIAS);
/**
- Constructor for a subwidget.
+ Constructor for a NanoTopLevelWidget.
+ @see CreateFlags
*/
- explicit NanoWidget(Widget* groupWidget, int flags = CREATE_ANTIALIAS);
+ explicit NanoWidget(Window& windowToMapTo, int flags = CREATE_ANTIALIAS);
/**
- Constructor for a subwidget, reusing a NanoVG context.
+ Constructor for a NanoStandaloneWindow.
+ @see CreateFlags
*/
- explicit NanoWidget(NanoWidget* groupWidget);
+ explicit NanoWidget(Application& app, int flags = CREATE_ANTIALIAS);
/**
Destructor.
@@ -927,6 +932,10 @@ private:
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget)
};
+typedef NanoWidget<SubWidget> NanoSubWidget;
+typedef NanoWidget<TopLevelWidget> NanoTopLevelWidget;
+typedef NanoWidget<StandaloneWindow> NanoStandaloneWindow;
+
// -----------------------------------------------------------------------
END_NAMESPACE_DGL
diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
+ * 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
@@ -257,25 +257,25 @@ NanoVG::~NanoVG()
void NanoVG::beginFrame(const uint width, const uint height, const float scaleFactor)
{
- fInFrame = true;
if (fContext == nullptr) return;
DISTRHO_SAFE_ASSERT_RETURN(scaleFactor > 0.0f,);
DISTRHO_SAFE_ASSERT_RETURN(! fInFrame,);
+ fInFrame = true;
nvgBeginFrame(fContext, static_cast<int>(width), static_cast<int>(height), scaleFactor);
}
void NanoVG::beginFrame(Widget* const widget)
{
- fInFrame = true;
DISTRHO_SAFE_ASSERT_RETURN(widget != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(! fInFrame,);
+ fInFrame = true;
if (fContext == nullptr)
return;
- Window& window(widget->getParentWindow());
- nvgBeginFrame(fContext, static_cast<int>(window.getWidth()), static_cast<int>(window.getHeight()), 1.0f);
+ if (TopLevelWidget* const tlw = widget->getTopLevelWidget())
+ nvgBeginFrame(fContext, static_cast<int>(tlw->getWidth()), static_cast<int>(tlw->getHeight()), 1.0f);
}
void NanoVG::cancelFrame()
@@ -771,26 +771,26 @@ void NanoVG::stroke()
NanoVG::FontId NanoVG::createFontFromFile(const char* name, const char* filename)
{
- if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1);
DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', -1);
+ DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr, -1);
return nvgCreateFont(fContext, name, filename);
}
NanoVG::FontId NanoVG::createFontFromMemory(const char* name, const uchar* data, uint dataSize, bool freeData)
{
- if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1);
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, -1);
+ DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr, -1);
return nvgCreateFontMem(fContext, name, const_cast<uchar*>(data), static_cast<int>(dataSize), freeData);
}
NanoVG::FontId NanoVG::findFont(const char* name)
{
- if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1);
+ DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr, -1);
return nvgFindFont(fContext, name);
}
@@ -912,35 +912,62 @@ int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWi
}
#ifndef DGL_NO_SHARED_RESOURCES
-void NanoVG::loadSharedResources()
+bool NanoVG::loadSharedResources()
{
- if (fContext == nullptr) return;
+ if (fContext == nullptr) return false;
if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0)
- return;
+ return true;
using namespace dpf_resources;
- nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0);
+ return nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF,
+ (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0) >= 0;
}
#endif
// -----------------------------------------------------------------------
-struct NanoWidget::PrivateData {
- NanoWidget* const self;
- std::vector<NanoWidget*> subWidgets;
+template <class BaseWidget>
+struct NanoWidget<BaseWidget>::PrivateData {
+ NanoWidget<BaseWidget>* const self;
- PrivateData(NanoWidget* const s)
- : self(s),
- subWidgets() {}
+ PrivateData(NanoWidget<BaseWidget>* const s)
+ : self(s) {}
~PrivateData()
{
- subWidgets.clear();
}
};
+// SubWidget
+template <class BaseWidget>
+NanoWidget<BaseWidget>::NanoWidget(Widget* const parent, int flags)
+ : BaseWidget(parent),
+ NanoVG(flags),
+ nData(new PrivateData(this))
+{
+}
+
+// TopLevelWidget
+template <class BaseWidget>
+NanoWidget<BaseWidget>::NanoWidget(Window& windowToMapTo, int flags)
+ : BaseWidget(windowToMapTo),
+ NanoVG(flags),
+ nData(new PrivateData(this))
+{
+}
+
+// StandaloneWindow
+template <class BaseWidget>
+NanoWidget<BaseWidget>::NanoWidget(Application& app, int flags)
+ : BaseWidget(app),
+ NanoVG(flags),
+ nData(new PrivateData(this))
+{
+}
+
+/*
NanoWidget::NanoWidget(Window& parent, int flags)
: Widget(parent),
NanoVG(flags),
@@ -957,7 +984,6 @@ NanoWidget::NanoWidget(Widget* groupWidget, int flags)
pData->needsScaling = true;
}
-/*
NanoWidget::NanoWidget(NanoWidget* groupWidget)
: Widget(groupWidget, false),
NanoVG(groupWidget),
@@ -969,21 +995,25 @@ NanoWidget::NanoWidget(NanoWidget* groupWidget)
}
*/
-NanoWidget::~NanoWidget()
+template <class BaseWidget>
+NanoWidget<BaseWidget>::~NanoWidget()
{
delete nData;
}
-void NanoWidget::onDisplay()
+template <class BaseWidget>
+void NanoWidget<BaseWidget>::onDisplay()
{
- NanoVG::beginFrame(getWidth(), getHeight());
+ NanoVG::beginFrame(BaseWidget::getWidth(), BaseWidget::getHeight());
onNanoDisplay();
+ /*
for (std::vector<NanoWidget*>::iterator it = nData->subWidgets.begin(); it != nData->subWidgets.end(); ++it)
{
NanoWidget* const widget(*it);
widget->onNanoDisplay();
}
+ */
NanoVG::endFrame();
}
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -90,13 +90,17 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
autoScaling(1.0),
pendingVisibility(kPendingVisibilityNone)
{
+ if (isEmbed)
+ {
+ puglSetDefaultSize(view, width, height);
+ puglSetParentWindow(view, parentWindowHandle);
+ }
+
init(width, height, resizable);
if (isEmbed)
{
appData->oneWindowShown();
- puglSetDefaultSize(view, width, height);
- puglSetParentWindow(view, parentWindowHandle);
puglShow(view);
}
}
@@ -137,7 +141,7 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r
puglSetHandle(view, this);
puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE);
puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE);
- puglSetViewHint(view, PUGL_DEPTH_BITS, 8);
+ puglSetViewHint(view, PUGL_DEPTH_BITS, 16);
puglSetViewHint(view, PUGL_STENCIL_BITS, 8);
// PUGL_SAMPLES ??
puglSetEventFunc(view, puglEventCallback);
@@ -149,6 +153,10 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r
rect.width = width;
rect.height = height;
puglSetFrame(view, rect);
+
+ // FIXME this is bad
+ puglRealize(view);
+ puglX11GlEnter(view, NULL);
}
// -----------------------------------------------------------------------
@@ -182,9 +190,16 @@ void Window::PrivateData::show()
isClosed = false;
appData->oneWindowShown();
+#ifdef DISTRHO_OS_WINDOWS
+ puglWin32ShowWindowCentered(view);
+#else
+ puglShow(view);
+#endif
+ /*
pendingVisibility = kPendingVisibilityShow;
const PuglStatus status = puglRealize(view);
DISTRHO_SAFE_ASSERT_INT_RETURN(status == PUGL_SUCCESS, status, close());
+ */
}
else
{
diff --git a/tests/Demo.cpp b/tests/Demo.cpp
@@ -21,12 +21,16 @@
#include "tests.hpp"
// #define DPF_TEST_POINT_CPP
+#include "dgl/OpenGL.hpp"
#include "dgl/src/pugl.cpp"
#include "dgl/src/Application.cpp"
#include "dgl/src/ApplicationPrivateData.cpp"
+#include "dgl/src/Color.cpp"
#include "dgl/src/Geometry.cpp"
#include "dgl/src/ImageBase.cpp"
+#include "dgl/src/NanoVG.cpp"
#include "dgl/src/OpenGL.cpp"
+#include "dgl/src/Resources.cpp"
#include "dgl/src/SubWidget.cpp"
#include "dgl/src/SubWidgetPrivateData.cpp"
#include "dgl/src/TopLevelWidget.cpp"
@@ -40,6 +44,7 @@
#include "widgets/ExampleColorWidget.hpp"
#include "widgets/ExampleImagesWidget.hpp"
#include "widgets/ExampleRectanglesWidget.hpp"
+#include "widgets/ExampleTextWidget.hpp"
#include "widgets/ExampleShapesWidget.hpp"
#include "demo_res/DemoArtwork.cpp"
@@ -68,10 +73,8 @@ public:
curPage(0),
curHover(-1)
{
-#if 0
// for text
- font = nvg.createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf");
-#endif
+ nvg.loadSharedResources();
using namespace DemoArtwork;
img1.loadFromMemory(ico1Data, ico1Width, ico1Height, GL_BGR);
@@ -123,7 +126,6 @@ protected:
img4.drawAt(pad, pad + 9 + iconSize*3);
img5.drawAt(pad, pad + 12 + iconSize*4);
-#if 0
// draw some text
nvg.beginFrame(this);
@@ -136,7 +138,6 @@ protected:
nvg.textBox(15, 440, iconSize, "Look!", nullptr);
nvg.endFrame();
-#endif
}
bool onMouse(const MouseEvent& ev) override
@@ -222,11 +223,8 @@ private:
Line<int> lineSep;
OpenGLImage img1, img2, img3, img4, img5;
-#if 0
// for text
- NanoVG nvg;D
- NanoVG::FontId font;
-#endif
+ NanoVG nvg;
};
// --------------------------------------------------------------------------------------------------------------------
@@ -246,6 +244,7 @@ public:
wImages(this),
wRects(this),
wShapes(this),
+ wText(this),
wLeft(this, this),
curWidget(nullptr)
{
@@ -253,14 +252,14 @@ public:
wImages.hide();
wRects.hide();
wShapes.hide();
-// wText.hide();
+ wText.hide();
// //wPerf.hide();
wColor.setAbsoluteX(kSidebarWidth);
wImages.setAbsoluteX(kSidebarWidth);
wRects.setAbsoluteX(kSidebarWidth);
wShapes.setAbsoluteX(kSidebarWidth);
-// wText.setAbsoluteX(kSidebarWidth);
+ wText.setAbsoluteX(kSidebarWidth);
wLeft.setAbsolutePos(2, 2);
// wPerf.setAbsoluteY(5);
@@ -290,9 +289,9 @@ protected:
case 3:
curWidget = &wShapes;
break;
-// case 4:
-// curWidget = &wText;
-// break;
+ case 4:
+ curWidget = &wText;
+ break;
default:
curWidget = nullptr;
break;
@@ -318,7 +317,7 @@ protected:
wImages.setSize(size);
wRects.setSize(size);
wShapes.setSize(size);
-// wText.setSize(size);
+ wText.setSize(size);
wLeft.setSize(kSidebarWidth-4, height-4);
//wRezHandle.setAbsoluteX(width-wRezHandle.getWidth());
@@ -332,7 +331,7 @@ private:
ExampleImagesSubWidget wImages;
ExampleRectanglesSubWidget wRects;
ExampleShapesSubWidget wShapes;
-// ExampleTextWidget wText;
+ ExampleTextSubWidget wText;
LeftSideWidget wLeft;
//ResizeHandle wRezHandle;
// NanoPerfWidget wPerf;
@@ -376,6 +375,8 @@ int main(int argc, char* argv[])
createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app);
else if (std::strcmp(argv[1], "shapes") == 0)
createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app);
+ else if (std::strcmp(argv[1], "text") == 0)
+ createAndShowExampleWidgetStandaloneWindow<ExampleTextStandaloneWindow>(app);
else
d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes");
}
diff --git a/tests/widgets/ExampleTextWidget.hpp b/tests/widgets/ExampleTextWidget.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
+ * 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
@@ -20,51 +20,69 @@
// ------------------------------------------------------
// DGL Stuff
-#include "NanoVG.hpp"
+#include "../../dgl/NanoVG.hpp"
+
+START_NAMESPACE_DGL
// ------------------------------------------------------
// our widget
-class ExampleTextWidget : public NanoWidget
+template <class BaseWidget>
+class ExampleTextWidget : public BaseWidget
{
public:
- ExampleTextWidget(Window& parent)
- : NanoWidget(parent),
- fFont(createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf"))
+ static constexpr const char* kExampleWidgetName = "Text";
+
+ // SubWidget
+ explicit ExampleTextWidget(Widget* const parent)
+ : BaseWidget(parent)
+ {
+ NanoVG::loadSharedResources();
+ BaseWidget::setSize(500, 300);
+ }
+
+ // TopLevelWidget
+ explicit ExampleTextWidget(Window& windowToMapTo)
+ : BaseWidget(windowToMapTo)
{
- setSize(500, 300);
+ NanoVG::loadSharedResources();
+ BaseWidget::setSize(500, 300);
}
- ExampleTextWidget(Widget* groupWidget)
- : NanoWidget(groupWidget),
- fFont(createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf"))
+ // StandaloneWindow
+ explicit ExampleTextWidget(Application& app)
+ : BaseWidget(app)
{
- setSize(500, 300);
+ NanoVG::loadSharedResources();
+ BaseWidget::setSize(500, 300);
}
protected:
void onNanoDisplay() override
{
- const int width = getWidth();
- const int height = getHeight();
+ const int width = BaseWidget::getWidth();
+ const int height = BaseWidget::getHeight();
- fontSize(40.0f);
- textAlign(Align(ALIGN_CENTER|ALIGN_MIDDLE));
- textLineHeight(20.0f);
+ NanoVG::fontSize(40.0f);
+ NanoVG::textAlign(NanoVG::Align(NanoVG::ALIGN_CENTER|NanoVG::ALIGN_MIDDLE));
+ NanoVG::textLineHeight(20.0f);
- beginPath();
- fillColor(220,220,220,255);
- roundedRect(10, height/4+10, width-20, height/2-20, 3);
- fill();
+ NanoVG::beginPath();
+ NanoVG::fillColor(220,220,220,255);
+ NanoVG::roundedRect(10, height/4+10, width-20, height/2-20, 3);
+ NanoVG::fill();
- fillColor(0,200,0,220);
- textBox(10, height/2, width-20, "Hello World!", nullptr);
+ NanoVG::fillColor(0,150,0,220);
+ NanoVG::textBox(10, height/2, width-20, "Hello World!", nullptr);
}
-
-private:
- FontId fFont;
};
+typedef ExampleTextWidget<NanoSubWidget> ExampleTextSubWidget;
+typedef ExampleTextWidget<NanoTopLevelWidget> ExampleTextTopLevelWidget;
+typedef ExampleTextWidget<NanoStandaloneWindow> ExampleTextStandaloneWindow;
+
// ------------------------------------------------------
+END_NAMESPACE_DGL
+
#endif // EXAMPLE_TEXT_WIDGET_HPP_INCLUDED