diff --git a/source/modules/distrho/dgl/CairoWidget.hpp b/source/modules/distrho/dgl/CairoWidget.hpp new file mode 100644 index 000000000..ba94bb852 --- /dev/null +++ b/source/modules/distrho/dgl/CairoWidget.hpp @@ -0,0 +1,141 @@ +/* + * DISTRHO Plugin Toolkit (DPT) + * Copyright (C) 2012-2013 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_CAIRO_WIDGET_HPP_INCLUDED +#define DGL_CAIRO_WIDGET_HPP_INCLUDED + +#include "Widget.hpp" + +#include + +START_NAMESPACE_DGL + +// ----------------------------------------------------------------------- + +class CairoWidget : public Widget +{ +public: + CairoWidget(Window& parent) + : Widget(parent), + fContext(nullptr), + fSurface(nullptr), + fTextureId(0) + { + } + +protected: + virtual void cairoDisplay(cairo_t* const context) = 0; + +private: + void onReshape(int width, int height) override + { + // handle resize + Widget::onReshape(width, height); + + // free previous if needed + onClose(); + + // create new + fSurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height); + fContext = cairo_create(fSurface); + + glGenTextures(1, &fTextureId); + } + + void onClose() override + { + if (fContext != nullptr) + { + cairo_destroy(fContext); + fContext = nullptr; + } + + if (fSurface != nullptr) + { + cairo_surface_destroy(fSurface); + fSurface = nullptr; + } + + if (fTextureId != 0) + { + glDeleteTextures(1, &fTextureId); + fTextureId = 0; + } + } + + void onDisplay() override + { + // wait for first resize + if (fSurface == nullptr || fContext == nullptr) + { + glClear(GL_COLOR_BUFFER_BIT); + return; + } + + const int width = getWidth(); + const int height = getHeight(); + + // draw cairo stuff + cairoDisplay(fContext); + + // get cairo surface data (RGB24) + unsigned char* const surfaceData = cairo_image_surface_get_data(fSurface); + + // enable GL texture + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + // set texture params + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // bind texture to surface data + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fTextureId); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, surfaceData); + + // draw the texture + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBegin(GL_QUADS); + glTexCoord2i(0, height); + glVertex2i(0, height); + + glTexCoord2i(width, height); + glVertex2i(width, height); + + glTexCoord2i(width, 0); + glVertex2i(width, 0); + + glTexCoord2i(0, 0); + glVertex2i(0, 0); + glEnd(); + + // cleanup + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + } + +private: + cairo_t* fContext; + cairo_surface_t* fSurface; + GLuint fTextureId; +}; + +// ----------------------------------------------------------------------- + +END_NAMESPACE_DGL + +#endif // DGL_CAIRO_WIDGET_HPP_INCLUDED diff --git a/source/modules/distrho/dgl/StandaloneWindow.hpp b/source/modules/distrho/dgl/StandaloneWindow.hpp index c4348228f..a3de65eaa 100644 --- a/source/modules/distrho/dgl/StandaloneWindow.hpp +++ b/source/modules/distrho/dgl/StandaloneWindow.hpp @@ -18,7 +18,6 @@ #define DGL_STANDALONE_WINDOW_HPP_INCLUDED #include "App.hpp" -#include "Widget.hpp" #include "Window.hpp" START_NAMESPACE_DGL @@ -30,16 +29,16 @@ class StandaloneWindow public: StandaloneWindow() : fApp(), - fWindow(&fApp) + fWindow(fApp) { } - App& getApp() const noexcept + App& getApp() noexcept { return fApp; } - Window& getWindow() const noexcept + Window& getWindow() noexcept { return fWindow; } diff --git a/source/modules/distrho/dgl/Widget.hpp b/source/modules/distrho/dgl/Widget.hpp index c4336cf16..477a5bd39 100644 --- a/source/modules/distrho/dgl/Widget.hpp +++ b/source/modules/distrho/dgl/Widget.hpp @@ -76,7 +76,7 @@ public: void repaint(); protected: - virtual void onDisplay(); + virtual void onDisplay() = 0; virtual bool onKeyboard(bool press, uint32_t key); virtual bool onMouse(int button, bool press, int x, int y); virtual bool onMotion(int x, int y); diff --git a/source/modules/distrho/dgl/src/ImageKnob.cpp b/source/modules/distrho/dgl/src/ImageKnob.cpp index 12447eec9..71536e01e 100644 --- a/source/modules/distrho/dgl/src/ImageKnob.cpp +++ b/source/modules/distrho/dgl/src/ImageKnob.cpp @@ -209,7 +209,7 @@ void ImageKnob::onDisplay() const GLint w2 = getWidth()/2; const GLint h2 = getHeight()/2; - glTranslatef(getX()+w2, getY()+h2, 0.f); + glTranslatef(getX()+w2, getY()+h2, 0.0f); glRotatef(normValue*fRotationAngle, 0.0f, 0.0f, 1.0f); glBegin(GL_QUADS); diff --git a/source/modules/distrho/dgl/src/Widget.cpp b/source/modules/distrho/dgl/src/Widget.cpp index 024929f74..47e5587e7 100644 --- a/source/modules/distrho/dgl/src/Widget.cpp +++ b/source/modules/distrho/dgl/src/Widget.cpp @@ -197,10 +197,6 @@ void Widget::repaint() fParent.repaint(); } -void Widget::onDisplay() -{ -} - bool Widget::onKeyboard(bool, uint32_t) { return false; diff --git a/source/modules/distrho/dgl/src/Window.cpp b/source/modules/distrho/dgl/src/Window.cpp index 17bd0ae6f..0878b640e 100644 --- a/source/modules/distrho/dgl/src/Window.cpp +++ b/source/modules/distrho/dgl/src/Window.cpp @@ -554,6 +554,7 @@ protected: FOR_EACH_WIDGET(it) { Widget* const widget(*it); + widget->fArea.setSize(width, height); widget->onReshape(width, height); } }