From 8d66fbcd2666624a01efa5f90048d7d868064976 Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 5 May 2015 03:54:07 +0200 Subject: [PATCH] Add initial NanoWidgets code; Fix nanovg for constness --- dgl/ImageWidgets.hpp | 16 +-- dgl/Makefile | 1 + dgl/NanoWidgets.hpp | 70 +++++++++++++ dgl/src/ImageWidgets.cpp | 5 +- dgl/src/NanoVG.cpp | 2 - dgl/src/NanoWidgets.cpp | 194 +++++++++++++++++++++++++++++++++++++ dgl/src/nanovg/fontstash.h | 12 +-- dgl/src/nanovg/nanovg.c | 4 +- dgl/src/nanovg/nanovg.h | 4 +- 9 files changed, 286 insertions(+), 22 deletions(-) create mode 100644 dgl/NanoWidgets.hpp create mode 100644 dgl/src/NanoWidgets.cpp diff --git a/dgl/ImageWidgets.hpp b/dgl/ImageWidgets.hpp index 0ba72169..66c99322 100644 --- a/dgl/ImageWidgets.hpp +++ b/dgl/ImageWidgets.hpp @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef DGL_WIDGETS_HPP_INCLUDED -#define DGL_WIDGETS_HPP_INCLUDED +#ifndef DGL_IMAGE_WIDGETS_HPP_INCLUDED +#define DGL_IMAGE_WIDGETS_HPP_INCLUDED #include "Image.hpp" #include "Widget.hpp" @@ -74,11 +74,11 @@ protected: bool onMotion(const MotionEvent&) override; private: - Image fImageNormal; - Image fImageHover; - Image fImageDown; - int fCurButton; - int fCurState; + Image fImageNormal; + Image fImageHover; + Image fImageDown; + int fCurButton; + int fCurState; Callback* fCallback; @@ -270,4 +270,4 @@ private: END_NAMESPACE_DGL -#endif // DGL_WIDGETS_HPP_INCLUDED +#endif // DGL_IMAGE_WIDGETS_HPP_INCLUDED diff --git a/dgl/Makefile b/dgl/Makefile index 5ef399b0..295bbdad 100644 --- a/dgl/Makefile +++ b/dgl/Makefile @@ -21,6 +21,7 @@ OBJS = \ src/Image.cpp.o \ src/ImageWidgets.cpp.o \ src/NanoVG.cpp.o \ + src/NanoWidgets.cpp.o \ src/Widget.cpp.o ifeq ($(MACOS),true) diff --git a/dgl/NanoWidgets.hpp b/dgl/NanoWidgets.hpp new file mode 100644 index 00000000..e58e8c1f --- /dev/null +++ b/dgl/NanoWidgets.hpp @@ -0,0 +1,70 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2015 Filipe Coelho + * + * 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. + */ + +#ifndef DGL_NANO_WIDGETS_HPP_INCLUDED +#define DGL_NANO_WIDGETS_HPP_INCLUDED + +#include "NanoVG.hpp" +#include "../distrho/extra/String.hpp" + +START_NAMESPACE_DGL + +// ----------------------------------------------------------------------- + +class BlendishButton : public NanoWidget +{ +public: + class Callback + { + public: + virtual ~Callback() {} + virtual void blendishButtonClicked(BlendishButton* blendishButton, int button) = 0; + }; + + explicit BlendishButton(Window& parent, const char* text = "", int iconId = -1) noexcept; + explicit BlendishButton(NanoWidget* widget, const char* text = "", int iconId = -1) noexcept; + + int getIconId() const noexcept; + void setIconId(int iconId) noexcept; + + const char* getText() const noexcept; + void setText(const char* text) noexcept; + + void setCallback(Callback* callback) noexcept; + +protected: + void onNanoDisplay() override; + bool onMouse(const MouseEvent&) override; + bool onMotion(const MotionEvent&) override; + +private: + int fCurButton; + int fCurState; + int fIconId; + DISTRHO_NAMESPACE::String fText; + + Callback* fCallback; + + void _updateBounds(); + + DISTRHO_LEAK_DETECTOR(BlendishButton) +}; + +// ----------------------------------------------------------------------- + +END_NAMESPACE_DGL + +#endif // DGL_NANO_WIDGETS_HPP_INCLUDED diff --git a/dgl/src/ImageWidgets.cpp b/dgl/src/ImageWidgets.cpp index afc6a7f3..87a07384 100644 --- a/dgl/src/ImageWidgets.cpp +++ b/dgl/src/ImageWidgets.cpp @@ -203,12 +203,13 @@ bool ImageButton::onMouse(const MouseEvent& ev) DISTRHO_SAFE_ASSERT(fCurState == 2); // release button + const int button = fCurButton; fCurButton = -1; // cursor was moved outside the button bounds, ignore click if (! contains(ev.pos)) { - fCurState = 0; + fCurState = 0; repaint(); return true; } @@ -218,7 +219,7 @@ bool ImageButton::onMouse(const MouseEvent& ev) repaint(); if (fCallback != nullptr) - fCallback->imageButtonClicked(this, fCurButton); + fCallback->imageButtonClicked(this, button); return true; } diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp index 92c0a976..d9d6d286 100644 --- a/dgl/src/NanoVG.cpp +++ b/dgl/src/NanoVG.cpp @@ -44,10 +44,8 @@ // Include NanoVG OpenGL implementation //#define STB_IMAGE_STATIC -#define BLENDISH_IMPLEMENTATION #define NANOVG_GL2_IMPLEMENTATION #include "nanovg/nanovg_gl.h" -#include "oui-blendish/blendish.h" #if defined(NANOVG_GL2) # define nvgCreateGL nvgCreateGL2 diff --git a/dgl/src/NanoWidgets.cpp b/dgl/src/NanoWidgets.cpp new file mode 100644 index 00000000..364976ff --- /dev/null +++ b/dgl/src/NanoWidgets.cpp @@ -0,0 +1,194 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2015 Filipe Coelho + * + * 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 "../NanoWidgets.hpp" + +#define BLENDISH_IMPLEMENTATION +#include "nanovg/nanovg.h" +#include "oui-blendish/blendish.h" +#include "oui-blendish/blendish_resources.h" + +START_NAMESPACE_DGL + +// ----------------------------------------------------------------------- + +static void registerBlendishResourcesIfNeeded(NVGcontext* const context) +{ + if (nvgFindFont(context, "__dpf_blendish__") >= 0) + return; + + using namespace blendish_resources; + + bndSetFont(nvgCreateFontMem(context, "__dpf_blendish__", (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0)); + bndSetIconImage(nvgCreateImageMem(context, 0, (const uchar*)blender_icons16_png, blender_icons16_png_size)); +} + +// ----------------------------------------------------------------------- + +BlendishButton::BlendishButton(Window& parent, const char* text, int iconId) noexcept + : NanoWidget(parent), + fCurButton(-1), + fCurState(0), + fIconId(iconId), + fText(text), + fCallback(nullptr), + leakDetector_BlendishButton() +{ + registerBlendishResourcesIfNeeded(getContext()); + _updateBounds(); +} + +BlendishButton::BlendishButton(NanoWidget* widget, const char* text, int iconId) noexcept + : NanoWidget(widget), + fCurButton(-1), + fCurState(0), + fIconId(iconId), + fText(text), + fCallback(nullptr), + leakDetector_BlendishButton() +{ + registerBlendishResourcesIfNeeded(getContext()); + _updateBounds(); +} + +int BlendishButton::getIconId() const noexcept +{ + return fIconId; +} + +void BlendishButton::setIconId(int iconId) noexcept +{ + if (fIconId == iconId) + return; + + fIconId = iconId; + _updateBounds(); + repaint(); +} + +const char* BlendishButton::getText() const noexcept +{ + return fText; +} + +void BlendishButton::setText(const char* text) noexcept +{ + if (fText == text) + return; + + fText = text; + _updateBounds(); + repaint(); +} + +void BlendishButton::setCallback(Callback* callback) noexcept +{ + fCallback = callback; +} + +void BlendishButton::onNanoDisplay() +{ + bndToolButton(getContext(), + getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight(), + 0, static_cast(fCurState), fIconId, fText); +} + +bool BlendishButton::onMouse(const MouseEvent& ev) +{ + // button was released, handle it now + if (fCurButton != -1 && ! ev.press) + { + DISTRHO_SAFE_ASSERT(fCurState == 2); + + // release button + const int button = fCurButton; + fCurButton = -1; + + // cursor was moved outside the button bounds, ignore click + if (! contains(ev.pos)) + { + fCurState = 0; + repaint(); + return true; + } + + // still on bounds, register click + fCurState = 1; + repaint(); + + if (fCallback != nullptr) + fCallback->blendishButtonClicked(this, button); + + return true; + } + + // button was pressed, wait for release + if (ev.press && contains(ev.pos)) + { + fCurButton = ev.button; + fCurState = 2; + repaint(); + return true; + } + + return false; +} + +bool BlendishButton::onMotion(const MotionEvent& ev) +{ + // keep pressed + if (fCurButton != -1) + return true; + + if (contains(ev.pos)) + { + // check if entering hover + if (fCurState == 0) + { + fCurState = 1; + repaint(); + return true; + } + } + else + { + // check if exiting hover + if (fCurState == 1) + { + fCurState = 0; + repaint(); + return true; + } + } + + return false; +} + +void BlendishButton::_updateBounds() +{ + const float width = bndLabelWidth (getContext(), fIconId, fText); + const float height = bndLabelHeight(getContext(), fIconId, fText, width); + + setSize(width, height); +} + +// ----------------------------------------------------------------------- + +END_NAMESPACE_DGL + +#include "oui-blendish/blendish_resources.cpp" + +// ----------------------------------------------------------------------- diff --git a/dgl/src/nanovg/fontstash.h b/dgl/src/nanovg/fontstash.h index b368d0d1..79e2f82d 100644 --- a/dgl/src/nanovg/fontstash.h +++ b/dgl/src/nanovg/fontstash.h @@ -97,7 +97,7 @@ int fonsResetAtlas(FONScontext* stash, int width, int height); // Add fonts int fonsAddFont(FONScontext* s, const char* name, const char* path); -int fonsAddFontMem(FONScontext* s, const char* name, unsigned char* data, int ndata, int freeData); +int fonsAddFontMem(FONScontext* s, const char* name, const unsigned char* data, int ndata, int freeData); int fonsGetFontByName(FONScontext* s, const char* name); // State handling @@ -161,7 +161,7 @@ int fons__tt_init(FONScontext *context) return ftError == 0; } -int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize) +int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, const unsigned char *data, int dataSize) { FT_Error ftError; FONS_NOTUSED(context); @@ -256,7 +256,7 @@ int fons__tt_init(FONScontext *context) return 1; } -int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize) +int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, const unsigned char *data, int dataSize) { int stbError; FONS_NOTUSED(dataSize); @@ -361,7 +361,7 @@ struct FONSfont { FONSttFontImpl font; char name[64]; - unsigned char* data; + const unsigned char* data; int dataSize; unsigned char freeData; float ascender; @@ -818,7 +818,7 @@ static void fons__freeFont(FONSfont* font) { if (font == NULL) return; if (font->glyphs) free(font->glyphs); - if (font->freeData && font->data) free(font->data); + if (font->freeData && font->data) free((void*)font->data); free(font); } @@ -878,7 +878,7 @@ error: FONS_NOTUSED(ignore); } -int fonsAddFontMem(FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData) +int fonsAddFontMem(FONScontext* stash, const char* name, const unsigned char* data, int dataSize, int freeData) { int i, ascent, descent, fh, lineGap; FONSfont* font; diff --git a/dgl/src/nanovg/nanovg.c b/dgl/src/nanovg/nanovg.c index 44cf25f8..315be351 100644 --- a/dgl/src/nanovg/nanovg.c +++ b/dgl/src/nanovg/nanovg.c @@ -719,7 +719,7 @@ int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags) return image; } -int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata) +int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, const unsigned char* data, int ndata) { int w, h, n, image; unsigned char* img = stbi_load_from_memory(data, ndata, &w, &h, &n, 4); @@ -2159,7 +2159,7 @@ int nvgCreateFont(NVGcontext* ctx, const char* name, const char* path) return fonsAddFont(ctx->fs, name, path); } -int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData) +int nvgCreateFontMem(NVGcontext* ctx, const char* name, const unsigned char* data, int ndata, int freeData) { return fonsAddFontMem(ctx->fs, name, data, ndata, freeData); } diff --git a/dgl/src/nanovg/nanovg.h b/dgl/src/nanovg/nanovg.h index 410ce660..5b27c9b7 100644 --- a/dgl/src/nanovg/nanovg.h +++ b/dgl/src/nanovg/nanovg.h @@ -317,7 +317,7 @@ int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags); // Creates image by loading it from the specified chunk of memory. // Returns handle to the image. -int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata); +int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, const unsigned char* data, int ndata); // Creates image from specified image data. // Returns handle to the image. @@ -489,7 +489,7 @@ int nvgCreateFont(NVGcontext* ctx, const char* name, const char* filename); // Creates image by loading it from the specified memory chunk. // Returns handle to the font. -int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData); +int nvgCreateFontMem(NVGcontext* ctx, const char* name, const unsigned char* data, int ndata, int freeData); // Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found. int nvgFindFont(NVGcontext* ctx, const char* name);