Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -19,10 +19,10 @@ | |||
#include "Base.hpp" | |||
START_NAMESPACE_DGL | |||
struct NVGcolor; | |||
START_NAMESPACE_DGL | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
/** | |||
@@ -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 | |||
@@ -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(); | |||
} | |||
@@ -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 | |||
{ | |||
@@ -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"); | |||
} | |||
@@ -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 |