Browse Source

Start working on nanovg and text, mostly works

Signed-off-by: falkTX <falktx@falktx.com>
pull/272/head
falkTX 4 years ago
parent
commit
5b10613f6e
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
6 changed files with 152 additions and 79 deletions
  1. +2
    -2
      dgl/Color.hpp
  2. +19
    -10
      dgl/NanoVG.hpp
  3. +53
    -23
      dgl/src/NanoVG.cpp
  4. +18
    -3
      dgl/src/WindowPrivateData.cpp
  5. +17
    -16
      tests/Demo.cpp
  6. +43
    -25
      tests/widgets/ExampleTextWidget.hpp

+ 2
- 2
dgl/Color.hpp View File

@@ -19,10 +19,10 @@

#include "Base.hpp"

START_NAMESPACE_DGL

struct NVGcolor;

START_NAMESPACE_DGL

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

/**


+ 19
- 10
dgl/NanoVG.hpp View File

@@ -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


+ 53
- 23
dgl/src/NanoVG.cpp View File

@@ -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();
}


+ 18
- 3
dgl/src/WindowPrivateData.cpp View File

@@ -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
{


+ 17
- 16
tests/Demo.cpp View File

@@ -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");
}


+ 43
- 25
tests/widgets/ExampleTextWidget.hpp View File

@@ -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

Loading…
Cancel
Save