summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfalkTX <falktx@gmail.com>2015-02-16 15:35:53 +0000
committerfalkTX <falktx@gmail.com>2015-02-16 15:35:53 +0000
commitddfcc4af8f2bbb6e2546894d3ded991122461a8c (patch)
tree9babf74313503cad5a92eca8cedaa016a091bef8
parent9baf523196128b5c847a578d93b4e71cabdacaa6 (diff)
Update dgl libs
Remove NTK specific code, now a separate project Start of file-browser code Cross-platform fixes (win & osx should be working nicely now) Misc cleanup, fixes and documentation
-rw-r--r--libs/dgl/App.hpp7
-rw-r--r--libs/dgl/Base.hpp20
-rw-r--r--libs/dgl/CairoWidget.hpp208
-rw-r--r--libs/dgl/Color.hpp29
-rw-r--r--libs/dgl/Geometry.hpp142
-rw-r--r--libs/dgl/ImageAboutWindow.hpp3
-rw-r--r--libs/dgl/ImageKnob.hpp15
-rw-r--r--libs/dgl/ImageSlider.hpp8
-rw-r--r--libs/dgl/ImageSwitch.hpp8
-rw-r--r--libs/dgl/NanoVG.hpp7
-rw-r--r--libs/dgl/Widget.hpp73
-rw-r--r--libs/dgl/Window.hpp45
-rw-r--r--libs/dgl/ntk/NtkApp.hpp291
-rw-r--r--libs/dgl/ntk/NtkWidget.hpp202
-rw-r--r--libs/dgl/ntk/NtkWindow.hpp215
-rw-r--r--libs/dgl/src/Color.cpp222
-rw-r--r--libs/dgl/src/Geometry.cpp130
-rw-r--r--libs/dgl/src/Image.cpp6
-rw-r--r--libs/dgl/src/ImageAboutWindow.cpp8
-rw-r--r--libs/dgl/src/ImageKnob.cpp60
-rw-r--r--libs/dgl/src/ImageSlider.cpp36
-rw-r--r--libs/dgl/src/ImageSwitch.cpp18
-rw-r--r--libs/dgl/src/NanoVG.cpp84
-rw-r--r--libs/dgl/src/Widget.cpp11
-rw-r--r--libs/dgl/src/Window.cpp251
-rw-r--r--libs/dgl/src/nanovg/fontstash.h8
-rw-r--r--libs/dgl/src/pugl/pugl.h36
-rw-r--r--libs/dgl/src/pugl/pugl_internal.h20
-rw-r--r--libs/dgl/src/pugl/pugl_osx.m283
-rw-r--r--libs/dgl/src/pugl/pugl_win.cpp76
-rw-r--r--libs/dgl/src/pugl/pugl_x11.c99
31 files changed, 1216 insertions, 1405 deletions
diff --git a/libs/dgl/App.hpp b/libs/dgl/App.hpp
index b6fce01..4babf1f 100644
--- a/libs/dgl/App.hpp
+++ b/libs/dgl/App.hpp
@@ -21,6 +21,9 @@
START_NAMESPACE_DGL
+// -----------------------------------------------------------------------
+// Forward class names
+
class Window;
// -----------------------------------------------------------------------
@@ -50,7 +53,7 @@ public:
/**
Idle function.
- This calls all this app Windows' idle functions and idle callbacks.
+ This runs the application event-loop once.
*/
void idle();
@@ -69,7 +72,7 @@ public:
/**
Check if the application is about to quit.
- Returning true means there's no event-loop running at the moment.
+ Returning true means there's no event-loop running at the moment (or it's just about to stop).
*/
bool isQuiting() const noexcept;
diff --git a/libs/dgl/Base.hpp b/libs/dgl/Base.hpp
index 0d62d72..edefbcf 100644
--- a/libs/dgl/Base.hpp
+++ b/libs/dgl/Base.hpp
@@ -127,6 +127,16 @@ enum Char {
};
/**
+ Keyboard modifier flags.
+ */
+enum Modifier {
+ MODIFIER_SHIFT = 1 << 0, /**< Shift key */
+ MODIFIER_CTRL = 1 << 1, /**< Control key */
+ MODIFIER_ALT = 1 << 2, /**< Alt/Option key */
+ MODIFIER_SUPER = 1 << 3 /**< Mod4/Command/Windows key */
+};
+
+/**
Special (non-Unicode) keyboard keys.
*/
enum Key {
@@ -157,16 +167,6 @@ enum Key {
KEY_SUPER
};
-/**
- Keyboard modifier flags.
- */
-enum Modifier {
- MODIFIER_SHIFT = 1 << 0, /**< Shift key */
- MODIFIER_CTRL = 1 << 1, /**< Control key */
- MODIFIER_ALT = 1 << 2, /**< Alt/Option key */
- MODIFIER_SUPER = 1 << 3 /**< Mod4/Command/Windows key */
-};
-
// -----------------------------------------------------------------------
// Base DGL classes
diff --git a/libs/dgl/CairoWidget.hpp b/libs/dgl/CairoWidget.hpp
deleted file mode 100644
index 9ebfe8f..0000000
--- a/libs/dgl/CairoWidget.hpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2014 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
- * 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 <cairo.h>
-
-#include <cstdio>
-
-START_NAMESPACE_DGL
-
-// -----------------------------------------------------------------------
-
-class CairoWidget : public Widget
-{
-public:
- CairoWidget(Window& parent)
- : Widget(parent),
- fContext(nullptr),
- fSurface(nullptr),
- fTextureId(0)
- {
- }
-
- virtual void setWidth(int width) override
- {
- if (fArea.getWidth() == width)
- return;
-
- Widget::setWidth(width);
- _recreateSurface();
- }
-
- virtual void setHeight(int height) override
- {
- if (fArea.getHeight() == height)
- return;
-
- Widget::setHeight(height);
- _recreateSurface();
- }
-
- virtual void setSize(const Size<int>& size) override
- {
- if (fArea.getSize() == size)
- return;
-
- Widget::setSize(size);
- _recreateSurface();
- }
-
- void setSize(int width, int height)
- {
- setSize(Size<int>(width, height));
- }
-
-protected:
- virtual void cairoDisplay(cairo_t* const context) = 0;
-
-private:
- void onDisplay() override
- {
- // wait for sizing
- if (fSurface == nullptr || fContext == nullptr)
- {
- printf("invalid surface\n");
- return;
- }
-
- if (fTextureId == 0)
- glGenTextures(1, &fTextureId);
- if (fTextureId == 0)
- {
- // TODO: invalidate widget
- printf("invalid texture\n");
- return;
- }
-
-#if 1
- const int x = getX();
- const int y = getY();
- const int width = getWidth();
- const int height = getHeight();
-
- // draw cairo stuff
- cairoDisplay(fContext);
-
- // get cairo surface data (RGB24)
- uchar* 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
-
-// glBegin(GL_QUADS);
-// glTexCoord2f(0.0f, 0.0f);
-// glVertex2i(x, y);
-//
-// glTexCoord2f(1.0f, 0.0f);
-// glVertex2i(x+width, y);
-//
-// glTexCoord2f(1.0f, 1.0f);
-// glVertex2i(x+width, y+height);
-//
-// glTexCoord2f(0.0f, 1.0f);
-// glVertex2i(x, y+height);
-// glEnd();
-
- glBegin(GL_QUADS);
- //glTexCoord2i(x, y);
- glTexCoord2i(0, 0);
- glVertex2i(x, y);
-
- //glTexCoord2i(x+width, y);
- glTexCoord2i(width, 0);
- glVertex2i(x+width, y);
-
- //glTexCoord2i(x+width, y+height);
- glTexCoord2i(width, height);
- glVertex2i(x+width, y+height);
-
- //glTexCoord2i(x, y+height);
- glTexCoord2i(0, height);
- glVertex2i(x, y+height);
- glEnd();
-
- // cleanup
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- glDisable(GL_TEXTURE_RECTANGLE_ARB);
-#endif
- }
-
- 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 _recreateSurface()
- {
- if (fContext != nullptr)
- cairo_destroy(fContext);
-
- if (fSurface != nullptr)
- cairo_surface_destroy(fSurface);
-
- fSurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, fArea.getWidth(), fArea.getHeight());
-
- if (fSurface != nullptr)
- fContext = cairo_create(fSurface);
- else
- fContext = nullptr;
- }
-
-private:
- cairo_t* fContext;
- cairo_surface_t* fSurface;
- GLuint fTextureId;
-
- DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoWidget)
-};
-
-// -----------------------------------------------------------------------
-
-END_NAMESPACE_DGL
-
-#endif // DGL_CAIRO_WIDGET_HPP_INCLUDED
diff --git a/libs/dgl/Color.hpp b/libs/dgl/Color.hpp
index dbe2cd1..d47f354 100644
--- a/libs/dgl/Color.hpp
+++ b/libs/dgl/Color.hpp
@@ -28,7 +28,7 @@ START_NAMESPACE_DGL
// TODO: create color from "#333" and "#112233" like strings
/**
- A color made from red, green, blue and alpha floating-point values in [0..1] range.
+ A color made from red, green, blue and alpha floating-point values in [0..1] range.
*/
struct Color {
/**
@@ -48,13 +48,13 @@ struct Color {
Create a color from red, green, blue and alpha numeric values.
Values must be in [0..255] range.
*/
- Color(const int red, const int green, const int blue, const int alpha = 255) noexcept;
+ Color(int red, int green, int blue, int alpha = 255) noexcept;
/**
Create a color from red, green, blue and alpha floating-point values.
Values must in [0..1] range.
*/
- Color(const float red, const float green, const float blue, const float alpha = 1.0f) noexcept;
+ Color(float red, float green, float blue, float alpha = 1.0f) noexcept;
/**
Create a color by copying another color.
@@ -65,26 +65,39 @@ struct Color {
/**
Create a color by linearly interpolating two other colors.
*/
- Color(const Color& color1, const Color& color2, const float u) noexcept;
+ Color(const Color& color1, const Color& color2, float u) noexcept;
/**
- Create a color specified by hue, saturation, lightness and alpha.
- HSL values are all in [0..1] range, alpha in [0..255] range.
+ Create a color specified by hue, saturation and lightness.
+ Values must in [0..1] range.
+ */
+ static Color fromHSL(float hue, float saturation, float lightness, float alpha = 1.0f);
+
+ /**
+ Create a color from a HTML string like "#333" or "#112233".
*/
- static Color HSL(const float hue, const float saturation, const float lightness, const int alpha = 255);
+ static Color fromHTML(const char* rgb, float alpha = 1.0f);
/**
Linearly interpolate this color against another.
*/
- void interpolate(const Color& other, const float u) noexcept;
+ void interpolate(const Color& other, float u) noexcept;
/**
Check if this color matches another.
+ @note: Comparison is forced within 8-bit color values.
*/
+ bool isEqual(const Color& color, bool withAlpha = true) noexcept;
+ bool isNotEqual(const Color& color, bool withAlpha = true) noexcept;
bool operator==(const Color& color) noexcept;
bool operator!=(const Color& color) noexcept;
/**
+ Fix color bounds if needed.
+ */
+ void fixBounds() noexcept;
+
+ /**
@internal
Needed for NanoVG compatibility.
*/
diff --git a/libs/dgl/Geometry.hpp b/libs/dgl/Geometry.hpp
index 117c0a9..725a15e 100644
--- a/libs/dgl/Geometry.hpp
+++ b/libs/dgl/Geometry.hpp
@@ -30,8 +30,12 @@ template<typename> class Triangle;
template<typename> class Rectangle;
// -----------------------------------------------------------------------
-// Point
+/**
+ DGL Point class.
+
+ This class describes a single point in space, defined by an X and Y value.
+ */
template<typename T>
class Point
{
@@ -62,17 +66,17 @@ public:
const T& getY() const noexcept;
/**
- Set X value as @a x.
+ Set X value to @a x.
*/
void setX(const T& x) noexcept;
/**
- Set Y value as @a y.
+ Set Y value to @a y.
*/
void setY(const T& y) noexcept;
/**
- Set X and Y values as @a x and @a y respectively.
+ Set X and Y values to @a x and @a y respectively.
*/
void setPos(const T& x, const T& y) noexcept;
@@ -96,6 +100,11 @@ public:
*/
bool isZero() const noexcept;
+ /**
+ Return true if point is not (0, 0).
+ */
+ bool isNotZero() const noexcept;
+
Point<T> operator+(const Point<T>& pos) noexcept;
Point<T> operator-(const Point<T>& pos) noexcept;
Point<T>& operator=(const Point<T>& pos) noexcept;
@@ -113,8 +122,12 @@ private:
};
// -----------------------------------------------------------------------
-// Size
+/**
+ DGL Size class.
+
+ This class describes a size, defined by a width and height value.
+ */
template<typename T>
class Size
{
@@ -155,7 +168,7 @@ public:
void setHeight(const T& height) noexcept;
/**
- Set size using @a width and @a height.
+ Set size to @a width and @a height.
*/
void setSize(const T& width, const T& height) noexcept;
@@ -167,30 +180,43 @@ public:
/**
Grow size by @a multiplier.
*/
- void growBy(const T& multiplier) noexcept;
+ void growBy(double multiplier) noexcept;
/**
Shrink size by @a divider.
*/
- void shrinkBy(const T& divider) noexcept;
+ void shrinkBy(double divider) noexcept;
/**
Return true if size is null (0x0).
+ An null size is also invalid.
*/
bool isNull() const noexcept;
/**
Return true if size is not null (0x0).
+ A non-null size is still invalid if its width or height is negative.
*/
bool isNotNull() const noexcept;
+ /**
+ Return true if size is valid (width and height are higher than zero).
+ */
+ bool isValid() const noexcept;
+
+ /**
+ Return true if size is invalid (width or height are lower or equal to zero).
+ An invalid size might not be null under some circumstances.
+ */
+ bool isInvalid() const noexcept;
+
Size<T> operator+(const Size<T>& size) noexcept;
Size<T> operator-(const Size<T>& size) noexcept;
Size<T>& operator=(const Size<T>& size) noexcept;
Size<T>& operator+=(const Size<T>& size) noexcept;
Size<T>& operator-=(const Size<T>& size) noexcept;
- Size<T>& operator*=(const T& m) noexcept;
- Size<T>& operator/=(const T& d) noexcept;
+ Size<T>& operator*=(double m) noexcept;
+ Size<T>& operator/=(double d) noexcept;
bool operator==(const Size<T>& size) const noexcept;
bool operator!=(const Size<T>& size) const noexcept;
@@ -200,14 +226,18 @@ private:
};
// -----------------------------------------------------------------------
-// Line
+/**
+ DGL Line class.
+
+ This class describes a line, defined by two points.
+ */
template<typename T>
class Line
{
public:
/**
- Constructor for a null line ([0, 0] to [0, 0]).
+ Constructor for a null line ([0,0] to [0,0]).
*/
Line() noexcept;
@@ -217,7 +247,7 @@ public:
Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept;
/**
- Constructor using custom start X, start Y, end pos values.
+ Constructor using custom start X, start Y and end pos values.
*/
Line(const T& startX, const T& startY, const Point<T>& endPos) noexcept;
@@ -267,17 +297,17 @@ public:
const Point<T>& getEndPos() const noexcept;
/**
- Set start X value as @a x.
+ Set start X value to @a x.
*/
void setStartX(const T& x) noexcept;
/**
- Set start Y value as @a y.
+ Set start Y value to @a y.
*/
void setStartY(const T& y) noexcept;
/**
- Set start X and Y values as @a x and @a y respectively.
+ Set start X and Y values to @a x and @a y respectively.
*/
void setStartPos(const T& x, const T& y) noexcept;
@@ -287,17 +317,17 @@ public:
void setStartPos(const Point<T>& pos) noexcept;
/**
- Set end X value as @a x.
+ Set end X value to @a x.
*/
void setEndX(const T& x) noexcept;
/**
- Set end Y value as @a y.
+ Set end Y value to @a y.
*/
void setEndY(const T& y) noexcept;
/**
- Set end X and Y values as @a x and @a y respectively.
+ Set end X and Y values to @a x and @a y respectively.
*/
void setEndPos(const T& x, const T& y) noexcept;
@@ -321,6 +351,16 @@ public:
*/
void draw();
+ /**
+ Return true if line is null (start and end pos are equal).
+ */
+ bool isNull() const noexcept;
+
+ /**
+ Return true if line is not null (start and end pos are different).
+ */
+ bool isNotNull() const noexcept;
+
Line<T>& operator=(const Line<T>& line) noexcept;
bool operator==(const Line<T>& line) const noexcept;
bool operator!=(const Line<T>& line) const noexcept;
@@ -330,8 +370,15 @@ private:
};
// -----------------------------------------------------------------------
-// Circle
+/**
+ DGL Circle class.
+
+ This class describes a circle, defined by position, size and a minimum of 3 segments.
+
+ TODO: report if circle starts at top-left, bottom-right or center.
+ and size grows from which point?
+ */
template<typename T>
class Circle
{
@@ -372,17 +419,17 @@ public:
const Point<T>& getPos() const noexcept;
/**
- Set X value as @a x.
+ Set X value to @a x.
*/
void setX(const T& x) noexcept;
/**
- Set Y value as @a y.
+ Set Y value to @a y.
*/
void setY(const T& y) noexcept;
/**
- Set X and Y values as @a x and @a y respectively.
+ Set X and Y values to @a x and @a y respectively.
*/
void setPos(const T& x, const T& y) noexcept;
@@ -435,12 +482,16 @@ private:
// cached values
float fTheta, fCos, fSin;
- void _draw(const bool isOutline);
+ void _draw(const bool outline);
};
// -----------------------------------------------------------------------
-// Triangle
+/**
+ DGL Triangle class.
+
+ This class describes a triangle, defined by 3 points.
+ */
template<typename T>
class Triangle
{
@@ -475,6 +526,29 @@ public:
*/
void drawOutline();
+ /**
+ Return true if triangle is null (all its points are equal).
+ An null triangle is also invalid.
+ */
+ bool isNull() const noexcept;
+
+ /**
+ Return true if triangle is not null (one its points is different from the others).
+ A non-null triangle is still invalid if two of its points are equal.
+ */
+ bool isNotNull() const noexcept;
+
+ /**
+ Return true if triangle is valid (all its points are different).
+ */
+ bool isValid() const noexcept;
+
+ /**
+ Return true if triangle is invalid (one or two of its points are equal).
+ An invalid triangle might not be null under some circumstances.
+ */
+ bool isInvalid() const noexcept;
+
Triangle<T>& operator=(const Triangle<T>& tri) noexcept;
bool operator==(const Triangle<T>& tri) const noexcept;
bool operator!=(const Triangle<T>& tri) const noexcept;
@@ -482,12 +556,16 @@ public:
private:
Point<T> fPos1, fPos2, fPos3;
- void _draw(const bool isOutline);
+ void _draw(const bool outline);
};
// -----------------------------------------------------------------------
-// Rectangle
+/**
+ DGL Rectangle class.
+
+ This class describes a rectangle, defined by a starting point and a size.
+ */
template<typename T>
class Rectangle
{
@@ -605,12 +683,12 @@ public:
/**
Grow size by @a multiplier.
*/
- void growBy(const T& multiplier) noexcept;
+ void growBy(double multiplier) noexcept;
/**
Shrink size by @a divider.
*/
- void shrinkBy(const T& divider) noexcept;
+ void shrinkBy(double divider) noexcept;
/**
Set rectangle using @a pos and @a size.
@@ -653,8 +731,8 @@ public:
void drawOutline();
Rectangle<T>& operator=(const Rectangle<T>& rect) noexcept;
- Rectangle<T>& operator*=(const T& m) noexcept;
- Rectangle<T>& operator/=(const T& d) noexcept;
+ Rectangle<T>& operator*=(double m) noexcept;
+ Rectangle<T>& operator/=(double d) noexcept;
bool operator==(const Rectangle<T>& size) const noexcept;
bool operator!=(const Rectangle<T>& size) const noexcept;
@@ -662,7 +740,7 @@ private:
Point<T> fPos;
Size<T> fSize;
- void _draw(const bool isOutline);
+ void _draw(const bool outline);
};
// -----------------------------------------------------------------------
diff --git a/libs/dgl/ImageAboutWindow.hpp b/libs/dgl/ImageAboutWindow.hpp
index 5a72ea2..2ffc0de 100644
--- a/libs/dgl/ImageAboutWindow.hpp
+++ b/libs/dgl/ImageAboutWindow.hpp
@@ -43,7 +43,8 @@ protected:
private:
Image fImgBackground;
- DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ImageAboutWindow)
+ DISTRHO_DECLARE_NON_COPY_CLASS(ImageAboutWindow)
+ //DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ImageAboutWindow)
};
// -----------------------------------------------------------------------
diff --git a/libs/dgl/ImageKnob.hpp b/libs/dgl/ImageKnob.hpp
index 3563824..2dd2669 100644
--- a/libs/dgl/ImageKnob.hpp
+++ b/libs/dgl/ImageKnob.hpp
@@ -41,15 +41,12 @@ public:
virtual void imageKnobValueChanged(ImageKnob* imageKnob, float value) = 0;
};
- explicit ImageKnob(Window& parent, const Image& image, Orientation orientation = Vertical, int id = 0) noexcept;
- explicit ImageKnob(Widget* widget, const Image& image, Orientation orientation = Vertical, int id = 0) noexcept;
+ explicit ImageKnob(Window& parent, const Image& image, Orientation orientation = Vertical) noexcept;
+ explicit ImageKnob(Widget* widget, const Image& image, Orientation orientation = Vertical) noexcept;
explicit ImageKnob(const ImageKnob& imageKnob);
ImageKnob& operator=(const ImageKnob& imageKnob);
~ImageKnob() override;
- int getId() const noexcept;
- void setId(int id) noexcept;
-
float getValue() const noexcept;
void setDefault(float def) noexcept;
@@ -70,7 +67,6 @@ protected:
private:
Image fImage;
- int fId;
float fMinimum;
float fMaximum;
float fStep;
@@ -89,11 +85,10 @@ private:
Callback* fCallback;
bool fIsImgVertical;
- int fImgLayerSize;
- int fImgLayerCount;
- Rectangle<int> fKnobArea;
- GLuint fTextureId;
+ uint fImgLayerSize;
+ uint fImgLayerCount;
bool fIsReady;
+ GLuint fTextureId;
float _logscale(float value) const;
float _invlogscale(float value) const;
diff --git a/libs/dgl/ImageSlider.hpp b/libs/dgl/ImageSlider.hpp
index 613b25c..e6f2716 100644
--- a/libs/dgl/ImageSlider.hpp
+++ b/libs/dgl/ImageSlider.hpp
@@ -36,14 +36,11 @@ public:
virtual void imageSliderValueChanged(ImageSlider* imageSlider, float value) = 0;
};
- explicit ImageSlider(Window& parent, const Image& image, int id = 0) noexcept;
- explicit ImageSlider(Widget* widget, const Image& image, int id = 0) noexcept;
+ explicit ImageSlider(Window& parent, const Image& image) noexcept;
+ explicit ImageSlider(Widget* widget, const Image& image) noexcept;
explicit ImageSlider(const ImageSlider& imageSlider) noexcept;
ImageSlider& operator=(const ImageSlider& imageSlider) noexcept;
- int getId() const noexcept;
- void setId(int id) noexcept;
-
float getValue() const noexcept;
void setStartPos(const Point<int>& startPos) noexcept;
@@ -65,7 +62,6 @@ protected:
private:
Image fImage;
- int fId;
float fMinimum;
float fMaximum;
float fStep;
diff --git a/libs/dgl/ImageSwitch.hpp b/libs/dgl/ImageSwitch.hpp
index bb963ac..172d61c 100644
--- a/libs/dgl/ImageSwitch.hpp
+++ b/libs/dgl/ImageSwitch.hpp
@@ -34,14 +34,11 @@ public:
virtual void imageSwitchClicked(ImageSwitch* imageButton, bool down) = 0;
};
- explicit ImageSwitch(Window& parent, const Image& imageNormal, const Image& imageDown, int id = 0) noexcept;
- explicit ImageSwitch(Widget* widget, const Image& imageNormal, const Image& imageDown, int id = 0) noexcept;
+ explicit ImageSwitch(Window& parent, const Image& imageNormal, const Image& imageDown) noexcept;
+ explicit ImageSwitch(Widget* widget, const Image& imageNormal, const Image& imageDown) noexcept;
explicit ImageSwitch(const ImageSwitch& imageSwitch) noexcept;
ImageSwitch& operator=(const ImageSwitch& imageSwitch) noexcept;
- int getId() const noexcept;
- void setId(int id) noexcept;
-
bool isDown() const noexcept;
void setDown(bool down) noexcept;
@@ -55,7 +52,6 @@ private:
Image fImageNormal;
Image fImageDown;
bool fIsDown;
- int fId;
Callback* fCallback;
diff --git a/libs/dgl/NanoVG.hpp b/libs/dgl/NanoVG.hpp
index 32d467d..1135f55 100644
--- a/libs/dgl/NanoVG.hpp
+++ b/libs/dgl/NanoVG.hpp
@@ -258,7 +258,7 @@ public:
/**
Destructor.
*/
- ~NanoVG();
+ virtual ~NanoVG();
/**
Get the NanoVG context.
@@ -641,7 +641,7 @@ public:
Creates font by loading it from the specified memory chunk.
Returns handle to the font.
*/
- FontId createFontMem(const char* name, uchar* data, int ndata, bool freeData);
+ FontId createFontMem(const char* name, const uchar* data, int ndata, bool freeData);
/**
Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found.
@@ -761,7 +761,8 @@ public:
*/
NanoWidget(Window& parent)
: Widget(parent),
- NanoVG()
+ NanoVG(),
+ leakDetector_NanoWidget()
{
setNeedsScaling(true);
}
diff --git a/libs/dgl/Widget.hpp b/libs/dgl/Widget.hpp
index 86c42d4..faed6b5 100644
--- a/libs/dgl/Widget.hpp
+++ b/libs/dgl/Widget.hpp
@@ -26,6 +26,7 @@ START_NAMESPACE_DGL
class App;
class Window;
+class StandaloneWindow;
// -----------------------------------------------------------------------
@@ -52,12 +53,17 @@ class Widget
public:
/**
Base event data.
- @a mod The currently active modifiers.
- @a time The timestamp (if any) of the currently-processing event.
+ @a mod The currently active keyboard modifiers, @see Modifier.
+ @a time The timestamp (if any).
*/
struct BaseEvent {
- Modifier mod;
+ uint mod;
uint32_t time;
+
+ /** Constuctor */
+ BaseEvent() noexcept : mod(0x0), time(0) {}
+ /** Destuctor */
+ virtual ~BaseEvent() noexcept {}
};
/**
@@ -69,6 +75,12 @@ public:
struct KeyboardEvent : BaseEvent {
bool press;
uint key;
+
+ /** Constuctor */
+ KeyboardEvent() noexcept
+ : BaseEvent(),
+ press(false),
+ key(0) {}
};
/**
@@ -79,7 +91,13 @@ public:
*/
struct SpecialEvent : BaseEvent {
bool press;
- Key key;
+ Key key;
+
+ /** Constuctor */
+ SpecialEvent() noexcept
+ : BaseEvent(),
+ press(false),
+ key(Key(0)) {}
};
/**
@@ -90,9 +108,16 @@ public:
@see onMouse
*/
struct MouseEvent : BaseEvent {
- int button;
+ int button;
bool press;
Point<int> pos;
+
+ /** Constuctor */
+ MouseEvent() noexcept
+ : BaseEvent(),
+ button(0),
+ press(false),
+ pos(0, 0) {}
};
/**
@@ -102,6 +127,11 @@ public:
*/
struct MotionEvent : BaseEvent {
Point<int> pos;
+
+ /** Constuctor */
+ MotionEvent() noexcept
+ : BaseEvent(),
+ pos(0, 0) {}
};
/**
@@ -113,6 +143,12 @@ public:
struct ScrollEvent : BaseEvent {
Point<int> pos;
Point<float> delta;
+
+ /** Constuctor */
+ ScrollEvent() noexcept
+ : BaseEvent(),
+ pos(0, 0),
+ delta(0.0f, 0.0f) {}
};
/**
@@ -124,6 +160,11 @@ public:
struct ResizeEvent {
Size<uint> size;
Size<uint> oldSize;
+
+ /** Constuctor */
+ ResizeEvent() noexcept
+ : size(0, 0),
+ oldSize(0, 0) {}
};
/**
@@ -177,22 +218,22 @@ public:
/**
Set width.
*/
- virtual void setWidth(uint width) noexcept;
+ void setWidth(uint width) noexcept;
/**
Set height.
*/
- virtual void setHeight(uint height) noexcept;
+ void setHeight(uint height) noexcept;
/**
Set size using @a width and @a height values.
*/
- virtual void setSize(uint width, uint height) noexcept;
+ void setSize(uint width, uint height) noexcept;
/**
Set size.
*/
- virtual void setSize(const Size<uint>& size) noexcept;
+ void setSize(const Size<uint>& size) noexcept;
/**
Get absolute X.
@@ -255,6 +296,18 @@ public:
*/
void repaint() noexcept;
+ /**
+ Get the Id associated with this widget.
+ @see setId
+ */
+ uint getId() const noexcept;
+
+ /**
+ Set an Id to be associated with this widget.
+ @see getId
+ */
+ void setId(uint id) noexcept;
+
protected:
/**
A function called to draw the view contents with OpenGL.
@@ -317,10 +370,10 @@ private:
bool fNeedsFullViewport;
bool fNeedsScaling;
bool fVisible;
+ uint fId;
Point<int> fAbsolutePos;
Size<uint> fSize;
- friend class CairoWidget;
friend class Window;
friend class StandaloneWindow;
diff --git a/libs/dgl/Window.hpp b/libs/dgl/Window.hpp
index 89e91de..37ae278 100644
--- a/libs/dgl/Window.hpp
+++ b/libs/dgl/Window.hpp
@@ -25,10 +25,48 @@ START_NAMESPACE_DGL
class App;
class Widget;
+class StandaloneWindow;
class Window
{
public:
+ /**
+ File browser options.
+ */
+ struct FileBrowserOptions {
+ const char* startDir;
+ const char* title;
+ uint width;
+ uint height;
+
+ /**
+ File browser buttons.
+
+ 0 means hidden.
+ 1 means visible and unchecked.
+ 2 means visible and checked.
+ */
+ struct Buttons {
+ uint listAllFiles;
+ uint showHidden;
+ uint showPlaces;
+
+ /** Constuctor for default values */
+ Buttons()
+ : listAllFiles(2),
+ showHidden(1),
+ showPlaces(1) {}
+ } buttons;
+
+ /** Constuctor for default values */
+ FileBrowserOptions()
+ : startDir(nullptr),
+ title(nullptr),
+ width(0),
+ height(0),
+ buttons() {}
+ };
+
explicit Window(App& app);
explicit Window(App& app, Window& parent);
explicit Window(App& app, intptr_t parentId);
@@ -42,6 +80,8 @@ public:
void focus();
void repaint() noexcept;
+ bool openFileBrowser(const FileBrowserOptions& options);
+
bool isVisible() const noexcept;
void setVisible(bool yesNo);
@@ -54,9 +94,10 @@ public:
void setSize(uint width, uint height);
void setSize(Size<uint> size);
+ const char* getTitle() const noexcept;
void setTitle(const char* title);
- void setTransientWinId(intptr_t winId);
+ void setTransientWinId(uintptr_t winId);
App& getApp() const noexcept;
intptr_t getWindowId() const noexcept;
@@ -70,6 +111,8 @@ protected:
virtual void onReshape(uint width, uint height);
virtual void onClose();
+ virtual void fileBrowserSelected(const char* filename);
+
private:
struct PrivateData;
PrivateData* const pData;
diff --git a/libs/dgl/ntk/NtkApp.hpp b/libs/dgl/ntk/NtkApp.hpp
deleted file mode 100644
index 2c32d56..0000000
--- a/libs/dgl/ntk/NtkApp.hpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2014 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
- * 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_NTK_APP_HPP_INCLUDED
-#define DGL_NTK_APP_HPP_INCLUDED
-
-#include "../Base.hpp"
-#include "../../distrho/DistrhoUI.hpp"
-#include "../../distrho/extra/d_thread.hpp"
-
-#ifdef override
-# define override_defined
-# undef override
-#endif
-
-#include <list>
-#include <FL/Fl.H>
-#include <FL/Fl_Double_Window.H>
-#include <FL/Fl_Shared_Image.H>
-#include <FL/x.H>
-
-#ifdef override_defined
-# define override
-# undef override_defined
-#endif
-
-struct ScopedDisplayLock {
- ScopedDisplayLock()
- {
-#ifdef DISTRHO_OS_LINUX
- XLockDisplay(fl_display);
-#endif
- }
-
- ~ScopedDisplayLock()
- {
-#ifdef DISTRHO_OS_LINUX
- XUnlockDisplay(fl_display);
-#endif
- }
-};
-
-// -----------------------------------------------------------------------
-
-namespace DISTRHO_NAMESPACE {
- class UI;
-}
-
-START_NAMESPACE_DGL
-
-class NtkWindow;
-
-typedef DISTRHO_NAMESPACE::Mutex d_Mutex;
-typedef DISTRHO_NAMESPACE::MutexLocker d_MutexLocker;
-typedef DISTRHO_NAMESPACE::Thread d_Thread;
-typedef DISTRHO_NAMESPACE::UI d_UI;
-
-// -----------------------------------------------------------------------
-
-/**
- DGL compatible App class that uses NTK instead of OpenGL.
- @see App
- */
-class NtkApp : d_Thread
-{
-public:
- /**
- Constructor.
- */
- NtkApp()
- : d_Thread("NtkApp"),
- fWindows(),
- fWindowMutex(),
- fNextUI(),
- fDoNextUI(false),
- fInitialized(false)
- {
-#ifdef DISTRHO_OS_LINUX
- //XInitThreads();
-#endif
-
- startThread();
-
- for (; ! fInitialized;)
- d_msleep(10);
- }
-
- /**
- Destructor.
- */
- ~NtkApp()
- {
- stopThread(-1);
- fWindows.clear();
- }
-
- /**
- Idle function.
- This calls does nothing.
- */
- void idle() {}
-
- /**
- Run the application event-loop until all Windows are closed.
- @note: This function is meant for standalones only, *never* call this from plugins.
- */
- void exec()
- {
- while (isThreadRunning() && ! shouldThreadExit())
- d_sleep(1);
- }
-
- /**
- Quit the application.
- This stops the event-loop and closes all Windows.
- */
- void quit()
- {
- signalThreadShouldExit();
- }
-
- /**
- Check if the application is about to quit.
- Returning true means there's no event-loop running at the moment.
- */
- bool isQuiting() const noexcept
- {
- if (isThreadRunning() && ! shouldThreadExit())
- return false;
- return true;
- }
-
- // -------------------------------------------------------------------
-
- /**
- Create UI on our separate thread.
- Blocks until the UI is created and returns it.
- */
- d_UI* createUI(void* const func)
- {
- DISTRHO_SAFE_ASSERT_RETURN(isThreadRunning(), nullptr);
- DISTRHO_SAFE_ASSERT_RETURN(! fDoNextUI, nullptr);
-
- fNextUI.create = true;
- fNextUI.func = (NextUI::UiFunc)func;
- fDoNextUI = true;
-
- for (; fDoNextUI;)
- d_msleep(10);
-
- return fNextUI.ui;
- }
-
- /**
- Delete UI on our separate thread.
- Blocks until the UI is deleted.
- */
- void deleteUI(d_UI* const ui)
- {
- DISTRHO_SAFE_ASSERT_RETURN(! fDoNextUI,);
-
- fNextUI.create = false;
- fNextUI.ui = ui;
- fDoNextUI = true;
-
- if (isThreadRunning())
- {
- for (; fDoNextUI;)
- d_msleep(10);
- }
- else
- {
- fNextUI.run();
- fDoNextUI = false;
- }
- }
-
- // -------------------------------------------------------------------
-
-private:
- struct NextUI {
- typedef d_UI* (*UiFunc)();
-
- bool create;
-
- union {
- UiFunc func;
- d_UI* ui;
- };
-
- NextUI()
- : create(false),
- func(nullptr) {}
-
- void run();
- };
-
- std::list<Fl_Double_Window*> fWindows;
- d_Mutex fWindowMutex;
- NextUI fNextUI;
- volatile bool fDoNextUI;
- volatile bool fInitialized;
-
- /** @internal used by NtkWindow. */
- void addWindow(Fl_Double_Window* const window)
- {
- DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,);
-
- if (fWindows.size() == 0 && ! isThreadRunning())
- startThread();
-
- const d_MutexLocker sl(fWindowMutex);
- fWindows.push_back(window);
- }
-
- /** @internal used by NtkWindow. */
- void removeWindow(Fl_Double_Window* const window)
- {
- DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,);
-
- const d_MutexLocker sl(fWindowMutex);
- fWindows.remove(window);
-
- if (fWindows.size() == 0)
- signalThreadShouldExit();
- }
-
- /** @internal */
- void run() override
- {
- static bool initialized = false;
-
- if (! initialized)
- {
- initialized = true;
- fl_register_images();
-#ifdef DISTRHO_OS_LINUX
- fl_open_display();
-#endif
- }
-
- fInitialized = true;
-
- for (; ! shouldThreadExit();)
- {
- if (fDoNextUI)
- {
- const ScopedDisplayLock csdl;
- fNextUI.run();
- fDoNextUI = false;
- }
-
- const ScopedDisplayLock csdl;
- Fl::check();
- Fl::flush();
-
- d_msleep(20);
- }
-
- const d_MutexLocker sl(fWindowMutex);
- const ScopedDisplayLock csdl;
-
- for (std::list<Fl_Double_Window*>::reverse_iterator rit = fWindows.rbegin(), rite = fWindows.rend(); rit != rite; ++rit)
- {
- Fl_Double_Window* const window(*rit);
- window->hide();
- }
- }
-
- friend class NtkWindow;
-
- DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NtkApp)
-};
-// -----------------------------------------------------------------------
-
-END_NAMESPACE_DGL
-
-#endif // DGL_NTK_APP_HPP_INCLUDED
diff --git a/libs/dgl/ntk/NtkWidget.hpp b/libs/dgl/ntk/NtkWidget.hpp
deleted file mode 100644
index 2247be3..0000000
--- a/libs/dgl/ntk/NtkWidget.hpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2014 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
- * 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_NTK_WIDGET_HPP_INCLUDED
-#define DGL_NTK_WIDGET_HPP_INCLUDED
-
-#include "NtkWindow.hpp"
-
-START_NAMESPACE_DGL
-
-// -----------------------------------------------------------------------
-
-/**
- DGL compatible Widget class that uses NTK instead of OpenGL.
- @see Widget
- */
-class NtkWidget : public Fl_Double_Window
-{
-public:
- /**
- Constructor.
- */
- explicit NtkWidget(NtkWindow& parent)
- : Fl_Double_Window(100, 100),
- fParent(parent)
- {
- fParent.add(this);
- show();
- }
-
- /**
- Destructor.
- */
- ~NtkWidget() override
- {
- hide();
- fParent.remove(this);
- }
-
- /**
- Check if this widget is visible within its parent window.
- Invisible widgets do not receive events except resize.
- */
- bool isVisible() const
- {
- return visible();
- }
-
- /**
- Set widget visible (or not) according to @a yesNo.
- */
- void setVisible(bool yesNo)
- {
- if (yesNo)
- show();
- else
- hide();
- }
-
- /**
- Get width.
- */
- int getWidth() const
- {
- return w();
- }
-
- /**
- Get height.
- */
- int getHeight() const
- {
- return h();
- }
-
- /**
- Set width.
- */
- void setWidth(int width)
- {
- resize(x(), y(), width, h());
- }
-
- /**
- Set height.
- */
- void setHeight(int height)
- {
- resize(x(), y(), w(), height);
- }
-
- /**
- Set size using @a width and @a height values.
- */
- void setSize(int width, int height)
- {
- resize(x(), y(), width, height);
- }
-
- /**
- Get absolute X.
- */
- int getAbsoluteX() const
- {
- return x();
- }
-
- /**
- Get absolute Y.
- */
- int getAbsoluteY() const
- {
- return y();
- }
-
- /**
- Set absolute X.
- */
- void setAbsoluteX(int x)
- {
- resize(x, y(), w(), h());
- }
-
- /**
- Set absolute Y.
- */
- void setAbsoluteY(int y)
- {
- resize(x(), y, w(), h());
- }
-
- /**
- Set absolute position using @a x and @a y values.
- */
- void setAbsolutePos(int x, int y)
- {
- resize(x, y, w(), h());
- }
-
- /**
- Get this widget's window application.
- Same as calling getParentWindow().getApp().
- */
- NtkApp& getParentApp() const noexcept
- {
- return fParent.getApp();
- }
-
- /**
- Get parent window, as passed in the constructor.
- */
- NtkWindow& getParentWindow() const noexcept
- {
- return fParent;
- }
-
- /**
- Check if this widget contains the point defined by @a x and @a y.
- */
- bool contains(int x, int y) const
- {
- return (x >= 0 && y >= 0 && x < w() && y < h());
- }
-
- /**
- Tell this widget's window to repaint itself.
- */
- void repaint()
- {
- redraw();
- }
-
-protected:
- /** @internal used for DGL compatibility. */
- void setNeedsFullViewport(bool) noexcept {}
- /** @internal used for DGL compatibility. */
- void setNeedsScaling(bool) noexcept {}
-
-private:
- NtkWindow& fParent;
-
- DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NtkWidget)
-};
-
-// -----------------------------------------------------------------------
-
-END_NAMESPACE_DGL
-
-#endif // DGL_NTK_WIDGET_HPP_INCLUDED
diff --git a/libs/dgl/ntk/NtkWindow.hpp b/libs/dgl/ntk/NtkWindow.hpp
deleted file mode 100644
index 47e9f10..0000000
--- a/libs/dgl/ntk/NtkWindow.hpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2014 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
- * 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_NTK_WINDOW_HPP_INCLUDED
-#define DGL_NTK_WINDOW_HPP_INCLUDED
-
-#include "NtkApp.hpp"
-
-START_NAMESPACE_DGL
-
-class NtkWidget;
-
-// -----------------------------------------------------------------------
-
-class NtkWindow : public Fl_Double_Window
-{
-public:
- explicit NtkWindow(NtkApp& app)
- : Fl_Double_Window(100, 100),
- fApp(app),
- fIsVisible(false),
- fUsingEmbed(false),
- fParent(nullptr) {}
-
- explicit NtkWindow(NtkApp& app, NtkWindow& parent)
- : Fl_Double_Window(100, 100),
- fApp(app),
- fIsVisible(false),
- fUsingEmbed(false),
- fParent(&parent) {}
-
- explicit NtkWindow(NtkApp& app, intptr_t parentId)
- : Fl_Double_Window(100, 100),
- fApp(app),
- fIsVisible(parentId != 0),
- fUsingEmbed(parentId != 0),
- fParent(nullptr)
- {
- if (fUsingEmbed)
- {
- fl_embed(this, (Window)parentId);
- Fl_Double_Window::show();
- fApp.addWindow(this);
- }
- }
-
- ~NtkWindow() override
- {
- if (fUsingEmbed)
- {
- fApp.removeWindow(this);
- Fl_Double_Window::hide();
- }
- }
-
- void show() override
- {
- if (fUsingEmbed || fIsVisible)
- return;
-
- Fl_Double_Window::show();
- fApp.addWindow(this);
- fIsVisible = true;
-
- if (fParent != nullptr)
- setTransientWinId((intptr_t)fl_xid(fParent));
- }
-
- void hide() override
- {
- if (fUsingEmbed || ! fIsVisible)
- return;
-
- fIsVisible = false;
- fApp.removeWindow(this);
- Fl_Double_Window::hide();
- }
-
- void close()
- {
- hide();
- }
-
- bool isVisible() const
- {
- return visible();
- }
-
- void setVisible(bool yesNo)
- {
- if (yesNo)
- show();
- else
- hide();
- }
-
- bool isResizable() const
- {
- // TODO
- return false;
- }
-
- void setResizable(bool /*yesNo*/)
- {
- // TODO
- }
-
- int getWidth() const noexcept
- {
- return w();
- }
-
- int getHeight() const noexcept
- {
- return h();
- }
-
- void setSize(uint width, uint height)
- {
- resize(x(), y(), width, height);
- }
-
- void setTitle(const char* title)
- {
- label(title);
- }
-
- void setTransientWinId(intptr_t winId)
- {
- DISTRHO_SAFE_ASSERT_RETURN(winId != 0,);
-
-#ifdef DISTRHO_OS_LINUX
- DISTRHO_SAFE_ASSERT_RETURN(fl_display != nullptr,);
-
- const ::Window ourWindow(fl_xid(this));
- DISTRHO_SAFE_ASSERT_RETURN(ourWindow != 0,);
-
- XSetTransientForHint(fl_display, ourWindow, winId);
-#endif
- }
-
- NtkApp& getApp() const noexcept
- {
- return fApp;
- }
-
- intptr_t getWindowId() const
- {
- return (intptr_t)fl_xid(this);
- }
-
- void addIdleCallback(IdleCallback* const callback)
- {
- DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,);
-
- if (fIdleCallbacks.size() == 0)
- Fl::add_idle(_idleHandler, this);
-
- fIdleCallbacks.push_back(callback);
- }
-
- void removeIdleCallback(IdleCallback* const callback)
- {
- DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,);
-
- fIdleCallbacks.remove(callback);
-
- if (fIdleCallbacks.size() == 0)
- Fl::remove_idle(_idleHandler, this);
- }
-
-private:
- NtkApp& fApp;
- bool fIsVisible;
- bool fUsingEmbed;
-
- // transient parent, may be null
- NtkWindow* const fParent;
-
- std::list<IdleCallback*> fIdleCallbacks;
-
- friend class NtkWidget;
-
- static void _idleHandler(void* data)
- {
- NtkWindow* const self((NtkWindow*)data);
-
- for (std::list<IdleCallback*>::iterator it=self->fIdleCallbacks.begin(), ite=self->fIdleCallbacks.end(); it != ite; ++it)
- {
- IdleCallback* const idleCallback(*it);
- idleCallback->idleCallback();
- }
- }
-
- DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NtkWindow)
-};
-
-// -----------------------------------------------------------------------
-
-END_NAMESPACE_DGL
-
-#endif // DGL_NTK_WINDOW_HPP_INCLUDED
diff --git a/libs/dgl/src/Color.cpp b/libs/dgl/src/Color.cpp
index 46b7ad3..57b8c07 100644
--- a/libs/dgl/src/Color.cpp
+++ b/libs/dgl/src/Color.cpp
@@ -22,51 +22,66 @@ START_NAMESPACE_DGL
// -----------------------------------------------------------------------
-Color::Color() noexcept
- : red(1.0f), green(1.0f), blue(1.0f), alpha(1.0f) {}
-
-Color::Color(const int r, const int g, const int b, const int a) noexcept
- : red(static_cast<float>(r)/255.0f), green(static_cast<float>(g)/255.0f), blue(static_cast<float>(b)/255.0f), alpha(static_cast<float>(a)/255.0f) {}
-
-Color::Color(const float r, const float g, const float b, const float a) noexcept
- : red(r), green(g), blue(b), alpha(a) {}
-
-Color::Color(const Color& color) noexcept
- : red(color.red), green(color.green), blue(color.blue), alpha(color.alpha) {}
-
-Color::Color(const Color& color1, const Color& color2, const float u) noexcept
- : red(color1.red), green(color1.green), blue(color1.blue), alpha(color1.alpha)
+static void fixRange(float& value)
{
- interpolate(color2, u);
+ /**/ if (value < 0.0f)
+ value = 0.0f;
+ else if (value > 1.0f)
+ value = 1.0f;
}
-void Color::interpolate(const Color& other, const float u) noexcept
+static float getFixedRange(const float& value)
{
- const float u2 = (u < 0.0f) ? 0.0f : ((u > 1.0f) ? 1.0f : u);
- const float oneMinusU = 1.0f - u;
+ if (value <= 0.0f)
+ return 0.0f;
+ if (value >= 1.0f)
+ return 1.0f;
+ return value;
+}
- red = red * oneMinusU + other.red * u2;
- green = green * oneMinusU + other.green * u2;
- blue = blue * oneMinusU + other.blue * u2;
- alpha = alpha * oneMinusU + other.alpha * u2;
+static uchar getFixedRange2(const float& value)
+{
+ const float value2(getFixedRange(value)*255.0f);
+ if (value2 <= 0.0f)
+ return 0;
+ if (value2 >= 255.0f)
+ return 255;
+ return static_cast<uchar>(value2);
}
-Color Color::HSL(const float hue, const float saturation, const float lightness, const int alpha)
+// -----------------------------------------------------------------------
+
+Color::Color() noexcept
+ : red(1.0f),
+ green(1.0f),
+ blue(1.0f),
+ alpha(1.0f) {}
+
+Color::Color(int r, int g, int b, int a) noexcept
+ : red(static_cast<float>(r)/255.0f),
+ green(static_cast<float>(g)/255.0f),
+ blue(static_cast<float>(b)/255.0f),
+ alpha(static_cast<float>(a)/255.0f)
{
- return nvgHSLA(hue, saturation, lightness, alpha);
+ fixBounds();
}
-Color::Color(const NVGcolor& c) noexcept
- : red(c.r), green(c.g), blue(c.b), alpha(c.a) {}
+Color::Color(float r, float g, float b, float a) noexcept
+ : red(r),
+ green(g),
+ blue(b),
+ alpha(a)
+{
+ fixBounds();
+}
-Color::operator NVGcolor() const noexcept
+Color::Color(const Color& color) noexcept
+ : red(color.red),
+ green(color.green),
+ blue(color.blue),
+ alpha(color.alpha)
{
- NVGcolor nc;
- nc.r = red;
- nc.g = green;
- nc.b = blue;
- nc.a = alpha;
- return nc;
+ fixBounds();
}
Color& Color::operator=(const Color& color) noexcept
@@ -75,17 +90,154 @@ Color& Color::operator=(const Color& color) noexcept
green = color.green;
blue = color.blue;
alpha = color.alpha;
+ fixBounds();
return *this;
}
+Color::Color(const Color& color1, const Color& color2, float u) noexcept
+ : red(color1.red),
+ green(color1.green),
+ blue(color1.blue),
+ alpha(color1.alpha)
+{
+ interpolate(color2, u);
+}
+
+Color Color::fromHSL(float hue, float saturation, float lightness, float alpha)
+{
+ return nvgHSLA(hue, saturation, lightness, static_cast<uchar>(getFixedRange(alpha)*255.0f));
+}
+
+Color Color::fromHTML(const char* rgb, float alpha)
+{
+ Color fallback;
+ DISTRHO_SAFE_ASSERT_RETURN(rgb != nullptr && rgb[0] != '\0', fallback);
+
+ if (rgb[0] == '#') ++rgb;
+ DISTRHO_SAFE_ASSERT_RETURN(rgb[0] != '\0', fallback);
+
+ std::size_t rgblen(std::strlen(rgb));
+ DISTRHO_SAFE_ASSERT_RETURN(rgblen == 3 || rgblen == 6, fallback);
+
+ char rgbtmp[3] = { '\0', '\0', '\0' };
+ int r, g, b;
+
+ if (rgblen == 3)
+ {
+ rgbtmp[0] = rgb[0];
+ r = static_cast<int>(std::strtol(rgbtmp, nullptr, 16));
+
+ rgbtmp[0] = rgb[1];
+ g = static_cast<int>(std::strtol(rgbtmp, nullptr, 16));
+
+ rgbtmp[0] = rgb[2];
+ b = static_cast<int>(std::strtol(rgbtmp, nullptr, 16));
+ }
+ else
+ {
+ rgbtmp[0] = rgb[0];
+ rgbtmp[1] = rgb[1];
+ r = static_cast<int>(std::strtol(rgbtmp, nullptr, 16));
+
+ rgbtmp[0] = rgb[2];
+ rgbtmp[1] = rgb[3];
+ g = static_cast<int>(std::strtol(rgbtmp, nullptr, 16));
+
+ rgbtmp[0] = rgb[4];
+ rgbtmp[1] = rgb[5];
+ b = static_cast<int>(std::strtol(rgbtmp, nullptr, 16));
+ }
+
+ return Color(r, g, b, static_cast<int>(getFixedRange(alpha)*255.0f));
+}
+
+void Color::interpolate(const Color& other, float u) noexcept
+{
+ fixRange(u);
+ const float oneMinusU(1.0f - u);
+
+ red = red * oneMinusU + other.red * u;
+ green = green * oneMinusU + other.green * u;
+ blue = blue * oneMinusU + other.blue * u;
+ alpha = alpha * oneMinusU + other.alpha * u;
+
+ fixBounds();
+}
+
+// -----------------------------------------------------------------------
+
+bool Color::isEqual(const Color& color, bool withAlpha) noexcept
+{
+ const uchar r1 = getFixedRange2(rgba[0]);
+ const uchar g1 = getFixedRange2(rgba[1]);
+ const uchar b1 = getFixedRange2(rgba[2]);
+ const uchar a1 = getFixedRange2(rgba[3]);
+
+ const uchar r2 = getFixedRange2(color.rgba[0]);
+ const uchar g2 = getFixedRange2(color.rgba[1]);
+ const uchar b2 = getFixedRange2(color.rgba[2]);
+ const uchar a2 = getFixedRange2(color.rgba[3]);
+
+ if (withAlpha)
+ return (r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2);
+ else
+ return (r1 == r2 && g1 == g2 && b1 == b2);
+}
+
+bool Color::isNotEqual(const Color& color, bool withAlpha) noexcept
+{
+ const uchar r1 = getFixedRange2(rgba[0]);
+ const uchar g1 = getFixedRange2(rgba[1]);
+ const uchar b1 = getFixedRange2(rgba[2]);
+ const uchar a1 = getFixedRange2(rgba[3]);
+
+ const uchar r2 = getFixedRange2(color.rgba[0]);
+ const uchar g2 = getFixedRange2(color.rgba[1]);
+ const uchar b2 = getFixedRange2(color.rgba[2]);
+ const uchar a2 = getFixedRange2(color.rgba[3]);
+
+ if (withAlpha)
+ return (r1 != r2 || g1 != g2 || b1 != b2 || a1 != a2);
+ else
+ return (r1 != r2 || g1 != g2 || b1 != b2);
+}
+
bool Color::operator==(const Color& color) noexcept
{
- return (red == color.red && green == color.green && blue == color.blue && alpha == color.alpha);
+ return isEqual(color, true);
}
bool Color::operator!=(const Color& color) noexcept
{
- return (red != color.red || green != color.green || blue != color.blue || alpha != color.alpha);
+ return isNotEqual(color, true);
+}
+
+// -----------------------------------------------------------------------
+
+void Color::fixBounds() noexcept
+{
+ fixRange(red);
+ fixRange(green);
+ fixRange(blue);
+ fixRange(alpha);
+}
+
+// -----------------------------------------------------------------------
+
+Color::Color(const NVGcolor& c) noexcept
+ : red(c.r), green(c.g), blue(c.b), alpha(c.a)
+{
+ fixBounds();
+}
+
+Color::operator NVGcolor() const noexcept
+{
+ NVGcolor nc;
+ nc.r = red;
+ nc.g = green;
+ nc.b = blue;
+ nc.a = alpha;
+ return nc;
}
// -----------------------------------------------------------------------
diff --git a/libs/dgl/src/Geometry.cpp b/libs/dgl/src/Geometry.cpp
index a7565fa..6964816 100644
--- a/libs/dgl/src/Geometry.cpp
+++ b/libs/dgl/src/Geometry.cpp
@@ -99,6 +99,12 @@ bool Point<T>::isZero() const noexcept
}
template<typename T>
+bool Point<T>::isNotZero() const noexcept
+{
+ return fX != 0 || fY != 0;
+}
+
+template<typename T>
Point<T> Point<T>::operator+(const Point<T>& pos) noexcept
{
return Point<T>(fX+pos.fX, fY+pos.fY);
@@ -203,17 +209,17 @@ void Size<T>::setSize(const Size<T>& size) noexcept
}
template<typename T>
-void Size<T>::growBy(const T& multiplier) noexcept
+void Size<T>::growBy(double multiplier) noexcept
{
- fWidth = static_cast<T>(fWidth*multiplier);
- fHeight = static_cast<T>(fHeight*multiplier);
+ fWidth = static_cast<T>(static_cast<double>(fWidth)*multiplier);
+ fHeight = static_cast<T>(static_cast<double>(fHeight)*multiplier);
}
template<typename T>
-void Size<T>::shrinkBy(const T& divider) noexcept
+void Size<T>::shrinkBy(double divider) noexcept
{
- fWidth = static_cast<T>(fWidth/divider);
- fHeight = static_cast<T>(fHeight/divider);
+ fWidth = static_cast<T>(static_cast<double>(fWidth)/divider);
+ fHeight = static_cast<T>(static_cast<double>(fHeight)/divider);
}
template<typename T>
@@ -228,6 +234,17 @@ bool Size<T>::isNotNull() const noexcept
return fWidth != 0 || fHeight != 0;
}
+template<typename T>
+bool Size<T>::isValid() const noexcept
+{
+ return fWidth > 1 && fHeight > 1;
+}
+
+template<typename T>
+bool Size<T>::isInvalid() const noexcept
+{
+ return fWidth <= 0 || fHeight <= 0;
+}
template<typename T>
Size<T> Size<T>::operator+(const Size<T>& size) noexcept
@@ -266,18 +283,18 @@ Size<T>& Size<T>::operator-=(const Size<T>& size) noexcept
}
template<typename T>
-Size<T>& Size<T>::operator*=(const T& m) noexcept
+Size<T>& Size<T>::operator*=(double m) noexcept
{
- fWidth = static_cast<T>(fWidth*m);
- fHeight = static_cast<T>(fHeight*m);
+ fWidth = static_cast<T>(static_cast<double>(fWidth)*m);
+ fHeight = static_cast<T>(static_cast<double>(fHeight)*m);
return *this;
}
template<typename T>
-Size<T>& Size<T>::operator/=(const T& d) noexcept
+Size<T>& Size<T>::operator/=(double d) noexcept
{
- fWidth = static_cast<T>(fWidth/d);
- fHeight = static_cast<T>(fHeight/d);
+ fWidth = static_cast<T>(static_cast<double>(fWidth)/d);
+ fHeight = static_cast<T>(static_cast<double>(fHeight)/d);
return *this;
}
@@ -427,17 +444,31 @@ void Line<T>::moveBy(const Point<T>& pos) noexcept
template<typename T>
void Line<T>::draw()
{
+ DISTRHO_SAFE_ASSERT_RETURN(fPosStart != fPosEnd,);
+
glBegin(GL_LINES);
{
- glVertex2i(fPosStart.fX, fPosStart.fY);
- glVertex2i(fPosEnd.fX, fPosEnd.fY);
+ glVertex2d(fPosStart.fX, fPosStart.fY);
+ glVertex2d(fPosEnd.fX, fPosEnd.fY);
}
glEnd();
}
template<typename T>
+bool Line<T>::isNull() const noexcept
+{
+ return fPosStart == fPosEnd;
+}
+
+template<typename T>
+bool Line<T>::isNotNull() const noexcept
+{
+ return fPosStart != fPosEnd;
+}
+
+template<typename T>
Line<T>& Line<T>::operator=(const Line<T>& line) noexcept
{
fPosStart = line.fPosStart;
@@ -610,24 +641,23 @@ Circle<T>& Circle<T>::operator=(const Circle<T>& cir) noexcept
template<typename T>
bool Circle<T>::operator==(const Circle<T>& cir) const noexcept
{
- return (fPos == cir.fPos && fSize == cir.fSize && fNumSegments == cir.fNumSegments);
+ return (fPos == cir.fPos && d_isEqual(fSize, cir.fSize) && fNumSegments == cir.fNumSegments);
}
template<typename T>
bool Circle<T>::operator!=(const Circle<T>& cir) const noexcept
{
- return (fPos != cir.fPos || fSize != cir.fSize || fNumSegments != cir.fNumSegments);
+ return (fPos != cir.fPos || d_isNotEqual(fSize, cir.fSize) || fNumSegments != cir.fNumSegments);
}
template<typename T>
-void Circle<T>::_draw(const bool isOutline)
+void Circle<T>::_draw(const bool outline)
{
- if (fNumSegments < 3 || fSize <= 0.0f)
- return;
+ DISTRHO_SAFE_ASSERT_RETURN(fNumSegments >= 3 && fSize > 0.0f,);
- float t, x = fSize, y = 0;
+ float t, x = fSize, y = 0.0f;
- glBegin(isOutline ? GL_LINE_LOOP : GL_POLYGON);
+ glBegin(outline ? GL_LINE_LOOP : GL_POLYGON);
for (uint i=0; i<fNumSegments; ++i)
{
@@ -681,6 +711,30 @@ void Triangle<T>::drawOutline()
}
template<typename T>
+bool Triangle<T>::isNull() const noexcept
+{
+ return fPos1 == fPos2 && fPos1 == fPos3;
+}
+
+template<typename T>
+bool Triangle<T>::isNotNull() const noexcept
+{
+ return fPos1 != fPos2 || fPos1 != fPos3;
+}
+
+template<typename T>
+bool Triangle<T>::isValid() const noexcept
+{
+ return fPos1 != fPos2 && fPos1 != fPos3;
+}
+
+template<typename T>
+bool Triangle<T>::isInvalid() const noexcept
+{
+ return fPos1 == fPos2 || fPos1 == fPos3;
+}
+
+template<typename T>
Triangle<T>& Triangle<T>::operator=(const Triangle<T>& tri) noexcept
{
fPos1 = tri.fPos1;
@@ -702,14 +756,16 @@ bool Triangle<T>::operator!=(const Triangle<T>& tri) const noexcept
}
template<typename T>
-void Triangle<T>::_draw(const bool isOutline)
+void Triangle<T>::_draw(const bool outline)
{
- glBegin(isOutline ? GL_LINE_LOOP : GL_TRIANGLES);
+ DISTRHO_SAFE_ASSERT_RETURN(fPos1 != fPos2 && fPos1 != fPos3,);
+
+ glBegin(outline ? GL_LINE_LOOP : GL_TRIANGLES);
{
- glVertex2i(fPos1.fX, fPos1.fY);
- glVertex2i(fPos2.fX, fPos2.fY);
- glVertex2i(fPos3.fX, fPos3.fY);
+ glVertex2d(fPos1.fX, fPos1.fY);
+ glVertex2d(fPos2.fX, fPos2.fY);
+ glVertex2d(fPos3.fX, fPos3.fY);
}
glEnd();
@@ -847,13 +903,13 @@ void Rectangle<T>::setSize(const Size<T>& size) noexcept
}
template<typename T>
-void Rectangle<T>::growBy(const T& multiplier) noexcept
+void Rectangle<T>::growBy(double multiplier) noexcept
{
fSize.growBy(multiplier);
}
template<typename T>
-void Rectangle<T>::shrinkBy(const T& divider) noexcept
+void Rectangle<T>::shrinkBy(double divider) noexcept
{
fSize.shrinkBy(divider);
}
@@ -917,14 +973,14 @@ Rectangle<T>& Rectangle<T>::operator=(const Rectangle<T>& rect) noexcept
}
template<typename T>
-Rectangle<T>& Rectangle<T>::operator*=(const T& m) noexcept
+Rectangle<T>& Rectangle<T>::operator*=(double m) noexcept
{
fSize *= m;
return *this;
}
template<typename T>
-Rectangle<T>& Rectangle<T>::operator/=(const T& d) noexcept
+Rectangle<T>& Rectangle<T>::operator/=(double d) noexcept
{
fSize /= d;
return *this;
@@ -943,22 +999,24 @@ bool Rectangle<T>::operator!=(const Rectangle<T>& rect) const noexcept
}
template<typename T>
-void Rectangle<T>::_draw(const bool isOutline)
+void Rectangle<T>::_draw(const bool outline)
{
- glBegin(isOutline ? GL_LINE_LOOP : GL_QUADS);
+ DISTRHO_SAFE_ASSERT_RETURN(fSize.isValid(),);
+
+ glBegin(outline ? GL_LINE_LOOP : GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f);
- glVertex2i(fPos.fX, fPos.fY);
+ glVertex2d(fPos.fX, fPos.fY);
glTexCoord2f(1.0f, 0.0f);
- glVertex2i(fPos.fX+fSize.fWidth, fPos.fY);
+ glVertex2d(fPos.fX+fSize.fWidth, fPos.fY);
glTexCoord2f(1.0f, 1.0f);
- glVertex2i(fPos.fX+fSize.fWidth, fPos.fY+fSize.fHeight);
+ glVertex2d(fPos.fX+fSize.fWidth, fPos.fY+fSize.fHeight);
glTexCoord2f(0.0f, 1.0f);
- glVertex2i(fPos.fX, fPos.fY+fSize.fHeight);
+ glVertex2d(fPos.fX, fPos.fY+fSize.fHeight);
}
glEnd();
diff --git a/libs/dgl/src/Image.cpp b/libs/dgl/src/Image.cpp
index 55ee0af..74dceed 100644
--- a/libs/dgl/src/Image.cpp
+++ b/libs/dgl/src/Image.cpp
@@ -152,12 +152,14 @@ void Image::drawAt(const Point<int>& pos)
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fSize.getWidth(), fSize.getHeight(), 0, fFormat, fType, fRawData);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ static_cast<GLsizei>(fSize.getWidth()), static_cast<GLsizei>(fSize.getHeight()), 0,
+ fFormat, fType, fRawData);
fIsReady = true;
}
- Rectangle<int>(pos, fSize.getWidth(), fSize.getHeight()).draw();
+ Rectangle<int>(pos, static_cast<int>(fSize.getWidth()), static_cast<int>(fSize.getHeight())).draw();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
diff --git a/libs/dgl/src/ImageAboutWindow.cpp b/libs/dgl/src/ImageAboutWindow.cpp
index a12aa57..9e90f29 100644
--- a/libs/dgl/src/ImageAboutWindow.cpp
+++ b/libs/dgl/src/ImageAboutWindow.cpp
@@ -23,8 +23,8 @@ START_NAMESPACE_DGL
ImageAboutWindow::ImageAboutWindow(Window& parent, const Image& image)
: Window(parent.getApp(), parent),
Widget((Window&)*this),
- fImgBackground(image),
- leakDetector_ImageAboutWindow()
+ fImgBackground(image)/*,
+ leakDetector_ImageAboutWindow()*/
{
Window::setResizable(false);
Window::setSize(static_cast<uint>(image.getWidth()), static_cast<uint>(image.getHeight()));
@@ -34,8 +34,8 @@ ImageAboutWindow::ImageAboutWindow(Window& parent, const Image& image)
ImageAboutWindow::ImageAboutWindow(Widget* widget, const Image& image)
: Window(widget->getParentApp(), widget->getParentWindow()),
Widget((Window&)*this),
- fImgBackground(image),
- leakDetector_ImageAboutWindow()
+ fImgBackground(image)/*,
+ leakDetector_ImageAboutWindow()*/
{
Window::setResizable(false);
Window::setSize(static_cast<uint>(image.getWidth()), static_cast<uint>(image.getHeight()));
diff --git a/libs/dgl/src/ImageKnob.cpp b/libs/dgl/src/ImageKnob.cpp
index 0fc8c69..57dae6a 100644
--- a/libs/dgl/src/ImageKnob.cpp
+++ b/libs/dgl/src/ImageKnob.cpp
@@ -22,10 +22,9 @@ START_NAMESPACE_DGL
// -----------------------------------------------------------------------
-ImageKnob::ImageKnob(Window& parent, const Image& image, Orientation orientation, int id) noexcept
+ImageKnob::ImageKnob(Window& parent, const Image& image, Orientation orientation) noexcept
: Widget(parent),
fImage(image),
- fId(id),
fMinimum(0.0f),
fMaximum(1.0f),
fStep(0.0f),
@@ -43,19 +42,17 @@ ImageKnob::ImageKnob(Window& parent, const Image& image, Orientation orientation
fIsImgVertical(image.getHeight() > image.getWidth()),
fImgLayerSize(fIsImgVertical ? image.getWidth() : image.getHeight()),
fImgLayerCount(fIsImgVertical ? image.getHeight()/fImgLayerSize : image.getWidth()/fImgLayerSize),
- fKnobArea(0, 0, fImgLayerSize, fImgLayerSize),
- fTextureId(0),
fIsReady(false),
+ fTextureId(0),
leakDetector_ImageKnob()
{
glGenTextures(1, &fTextureId);
setSize(fImgLayerSize, fImgLayerSize);
}
-ImageKnob::ImageKnob(Widget* widget, const Image& image, Orientation orientation, int id) noexcept
+ImageKnob::ImageKnob(Widget* widget, const Image& image, Orientation orientation) noexcept
: Widget(widget->getParentWindow()),
fImage(image),
- fId(id),
fMinimum(0.0f),
fMaximum(1.0f),
fStep(0.0f),
@@ -73,9 +70,8 @@ ImageKnob::ImageKnob(Widget* widget, const Image& image, Orientation orientation
fIsImgVertical(image.getHeight() > image.getWidth()),
fImgLayerSize(fIsImgVertical ? image.getWidth() : image.getHeight()),
fImgLayerCount(fIsImgVertical ? image.getHeight()/fImgLayerSize : image.getWidth()/fImgLayerSize),
- fKnobArea(0, 0, fImgLayerSize, fImgLayerSize),
- fTextureId(0),
fIsReady(false),
+ fTextureId(0),
leakDetector_ImageKnob()
{
glGenTextures(1, &fTextureId);
@@ -85,7 +81,6 @@ ImageKnob::ImageKnob(Widget* widget, const Image& image, Orientation orientation
ImageKnob::ImageKnob(const ImageKnob& imageKnob)
: Widget(imageKnob.getParentWindow()),
fImage(imageKnob.fImage),
- fId(imageKnob.fId),
fMinimum(imageKnob.fMinimum),
fMaximum(imageKnob.fMaximum),
fStep(imageKnob.fStep),
@@ -103,9 +98,8 @@ ImageKnob::ImageKnob(const ImageKnob& imageKnob)
fIsImgVertical(imageKnob.fIsImgVertical),
fImgLayerSize(imageKnob.fImgLayerSize),
fImgLayerCount(imageKnob.fImgLayerCount),
- fKnobArea(imageKnob.fKnobArea),
- fTextureId(0),
fIsReady(false),
+ fTextureId(0),
leakDetector_ImageKnob()
{
glGenTextures(1, &fTextureId);
@@ -115,7 +109,6 @@ ImageKnob::ImageKnob(const ImageKnob& imageKnob)
ImageKnob& ImageKnob::operator=(const ImageKnob& imageKnob)
{
fImage = imageKnob.fImage;
- fId = imageKnob.fId;
fMinimum = imageKnob.fMinimum;
fMaximum = imageKnob.fMaximum;
fStep = imageKnob.fStep;
@@ -133,7 +126,6 @@ ImageKnob& ImageKnob::operator=(const ImageKnob& imageKnob)
fIsImgVertical = imageKnob.fIsImgVertical;
fImgLayerSize = imageKnob.fImgLayerSize;
fImgLayerCount = imageKnob.fImgLayerCount;
- fKnobArea = imageKnob.fKnobArea;
fIsReady = false;
if (fTextureId != 0)
@@ -157,16 +149,6 @@ ImageKnob::~ImageKnob()
}
}
-int ImageKnob::getId() const noexcept
-{
- return fId;
-}
-
-void ImageKnob::setId(int id) noexcept
-{
- fId = id;
-}
-
float ImageKnob::getValue() const noexcept
{
return fValue;
@@ -220,12 +202,12 @@ void ImageKnob::setStep(float step) noexcept
// NOTE: value is assumed to be scaled if using log
void ImageKnob::setValue(float value, bool sendCallback) noexcept
{
- if (fValue == value)
+ if (d_isEqual(fValue, value))
return;
fValue = value;
- if (fStep == 0.0f)
+ if (d_isZero(fStep))
fValueTmp = value;
if (fRotationAngle == 0)
@@ -288,36 +270,44 @@ void ImageKnob::onDisplay()
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- int imageDataOffset = 0;
+ uint imageDataOffset = 0;
if (fRotationAngle == 0)
{
- int layerDataSize = fImgLayerSize * fImgLayerSize * ((fImage.getFormat() == GL_BGRA || fImage.getFormat() == GL_RGBA) ? 4 : 3);
- imageDataOffset = layerDataSize * int(normValue * float(fImgLayerCount-1));
+ DISTRHO_SAFE_ASSERT_RETURN(fImgLayerCount > 0,);
+ DISTRHO_SAFE_ASSERT_RETURN(normValue >= 0.0f,);
+
+ const uint layerDataSize = fImgLayerSize * fImgLayerSize * ((fImage.getFormat() == GL_BGRA || fImage.getFormat() == GL_RGBA) ? 4 : 3);
+ /* */ imageDataOffset = layerDataSize * uint(normValue * float(fImgLayerCount-1));
}
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWidth(), getHeight(), 0, fImage.getFormat(), fImage.getType(), fImage.getRawData() + imageDataOffset);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ static_cast<GLsizei>(getWidth()), static_cast<GLsizei>(getHeight()), 0,
+ fImage.getFormat(), fImage.getType(), fImage.getRawData() + imageDataOffset);
fIsReady = true;
}
+ const int w = static_cast<int>(getWidth());
+ const int h = static_cast<int>(getHeight());
+
if (fRotationAngle != 0)
{
glPushMatrix();
- const GLint w2 = getWidth()/2;
- const GLint h2 = getHeight()/2;
+ const int w2 = w/2;
+ const int h2 = h/2;
glTranslatef(static_cast<float>(w2), static_cast<float>(h2), 0.0f);
glRotatef(normValue*static_cast<float>(fRotationAngle), 0.0f, 0.0f, 1.0f);
- Rectangle<int>(-w2, -h2, getWidth(), getHeight()).draw();
+ Rectangle<int>(-w2, -h2, w, h).draw();
glPopMatrix();
}
else
{
- Rectangle<int>(0, 0, getWidth(), getHeight()).draw();
+ Rectangle<int>(0, 0, w, h).draw();
}
glBindTexture(GL_TEXTURE_2D, 0);
@@ -403,7 +393,7 @@ bool ImageKnob::onMotion(const MotionEvent& ev)
{
fValueTmp = value = fMaximum;
}
- else if (fStep != 0.0f)
+ else if (d_isNotZero(fStep))
{
fValueTmp = value;
const float rest = std::fmod(value, fStep);
@@ -437,7 +427,7 @@ bool ImageKnob::onScroll(const ScrollEvent& ev)
{
fValueTmp = value = fMaximum;
}
- else if (fStep != 0.0f)
+ else if (d_isNotZero(fStep))
{
fValueTmp = value;
const float rest = std::fmod(value, fStep);
diff --git a/libs/dgl/src/ImageSlider.cpp b/libs/dgl/src/ImageSlider.cpp
index b9ae84e..12f7b37 100644
--- a/libs/dgl/src/ImageSlider.cpp
+++ b/libs/dgl/src/ImageSlider.cpp
@@ -22,10 +22,9 @@ START_NAMESPACE_DGL
// -----------------------------------------------------------------------
-ImageSlider::ImageSlider(Window& parent, const Image& image, int id) noexcept
+ImageSlider::ImageSlider(Window& parent, const Image& image) noexcept
: Widget(parent),
fImage(image),
- fId(id),
fMinimum(0.0f),
fMaximum(1.0f),
fStep(0.0f),
@@ -44,10 +43,9 @@ ImageSlider::ImageSlider(Window& parent, const Image& image, int id) noexcept
Widget::setNeedsFullViewport(true);
}
-ImageSlider::ImageSlider(Widget* widget, const Image& image, int id) noexcept
+ImageSlider::ImageSlider(Widget* widget, const Image& image) noexcept
: Widget(widget->getParentWindow()),
fImage(image),
- fId(id),
fMinimum(0.0f),
fMaximum(1.0f),
fStep(0.0f),
@@ -69,7 +67,6 @@ ImageSlider::ImageSlider(Widget* widget, const Image& image, int id) noexcept
ImageSlider::ImageSlider(const ImageSlider& imageSlider) noexcept
: Widget(imageSlider.getParentWindow()),
fImage(imageSlider.fImage),
- fId(imageSlider.fId),
fMinimum(imageSlider.fMinimum),
fMaximum(imageSlider.fMaximum),
fStep(imageSlider.fStep),
@@ -91,7 +88,6 @@ ImageSlider::ImageSlider(const ImageSlider& imageSlider) noexcept
ImageSlider& ImageSlider::operator=(const ImageSlider& imageSlider) noexcept
{
fImage = imageSlider.fImage;
- fId = imageSlider.fId;
fMinimum = imageSlider.fMinimum;
fMaximum = imageSlider.fMaximum;
fStep = imageSlider.fStep;
@@ -109,16 +105,6 @@ ImageSlider& ImageSlider::operator=(const ImageSlider& imageSlider) noexcept
return *this;
}
-int ImageSlider::getId() const noexcept
-{
- return fId;
-}
-
-void ImageSlider::setId(int id) noexcept
-{
- fId = id;
-}
-
float ImageSlider::getValue() const noexcept
{
return fValue;
@@ -193,12 +179,12 @@ void ImageSlider::setStep(float step) noexcept
void ImageSlider::setValue(float value, bool sendCallback) noexcept
{
- if (fValue == value)
+ if (d_isEqual(fValue, value))
return;
fValue = value;
- if (fStep == 0.0f)
+ if (d_isZero(fStep))
fValueTmp = value;
repaint();
@@ -224,7 +210,7 @@ void ImageSlider::onDisplay()
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
#endif
- float normValue = (fValue - fMinimum) / (fMaximum - fMinimum);
+ const float normValue = (fValue - fMinimum) / (fMaximum - fMinimum);
int x, y;
@@ -292,7 +278,7 @@ bool ImageSlider::onMouse(const MouseEvent& ev)
{
fValueTmp = value = fMaximum;
}
- else if (fStep != 0.0f)
+ else if (d_isNotZero(fStep))
{
fValueTmp = value;
const float rest = std::fmod(value, fStep);
@@ -361,7 +347,7 @@ bool ImageSlider::onMotion(const MotionEvent& ev)
{
fValueTmp = value = fMaximum;
}
- else if (fStep != 0.0f)
+ else if (d_isNotZero(fStep))
{
fValueTmp = value;
const float rest = std::fmod(value, fStep);
@@ -395,16 +381,16 @@ void ImageSlider::_recheckArea() noexcept
// horizontal
fSliderArea = Rectangle<int>(fStartPos.getX(),
fStartPos.getY(),
- fEndPos.getX() + fImage.getWidth() - fStartPos.getX(),
- fImage.getHeight());
+ fEndPos.getX() + static_cast<int>(fImage.getWidth()) - fStartPos.getX(),
+ static_cast<int>(fImage.getHeight()));
}
else
{
// vertical
fSliderArea = Rectangle<int>(fStartPos.getX(),
fStartPos.getY(),
- fImage.getWidth(),
- fEndPos.getY() + fImage.getHeight() - fStartPos.getY());
+ static_cast<int>(fImage.getWidth()),
+ fEndPos.getY() + static_cast<int>(fImage.getHeight()) - fStartPos.getY());
}
}
diff --git a/libs/dgl/src/ImageSwitch.cpp b/libs/dgl/src/ImageSwitch.cpp
index bd99786..37b3e56 100644
--- a/libs/dgl/src/ImageSwitch.cpp
+++ b/libs/dgl/src/ImageSwitch.cpp
@@ -20,12 +20,11 @@ START_NAMESPACE_DGL
// -----------------------------------------------------------------------
-ImageSwitch::ImageSwitch(Window& parent, const Image& imageNormal, const Image& imageDown, int id) noexcept
+ImageSwitch::ImageSwitch(Window& parent, const Image& imageNormal, const Image& imageDown) noexcept
: Widget(parent),
fImageNormal(imageNormal),
fImageDown(imageDown),
fIsDown(false),
- fId(id),
fCallback(nullptr),
leakDetector_ImageSwitch()
{
@@ -34,12 +33,11 @@ ImageSwitch::ImageSwitch(Window& parent, const Image& imageNormal, const Image&
setSize(fImageNormal.getSize());
}
-ImageSwitch::ImageSwitch(Widget* widget, const Image& imageNormal, const Image& imageDown, int id) noexcept
+ImageSwitch::ImageSwitch(Widget* widget, const Image& imageNormal, const Image& imageDown) noexcept
: Widget(widget->getParentWindow()),
fImageNormal(imageNormal),
fImageDown(imageDown),
fIsDown(false),
- fId(id),
fCallback(nullptr),
leakDetector_ImageSwitch()
{
@@ -53,7 +51,6 @@ ImageSwitch::ImageSwitch(const ImageSwitch& imageSwitch) noexcept
fImageNormal(imageSwitch.fImageNormal),
fImageDown(imageSwitch.fImageDown),
fIsDown(imageSwitch.fIsDown),
- fId(imageSwitch.fId),
fCallback(imageSwitch.fCallback),
leakDetector_ImageSwitch()
{
@@ -67,7 +64,6 @@ ImageSwitch& ImageSwitch::operator=(const ImageSwitch& imageSwitch) noexcept
fImageNormal = imageSwitch.fImageNormal;
fImageDown = imageSwitch.fImageDown;
fIsDown = imageSwitch.fIsDown;
- fId = imageSwitch.fId;
fCallback = imageSwitch.fCallback;
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageDown.getSize());
@@ -77,16 +73,6 @@ ImageSwitch& ImageSwitch::operator=(const ImageSwitch& imageSwitch) noexcept
return *this;
}
-int ImageSwitch::getId() const noexcept
-{
- return fId;
-}
-
-void ImageSwitch::setId(int id) noexcept
-{
- fId = id;;
-}
-
bool ImageSwitch::isDown() const noexcept
{
return fIsDown;
diff --git a/libs/dgl/src/NanoVG.cpp b/libs/dgl/src/NanoVG.cpp
index bb7b9f1..a4c357b 100644
--- a/libs/dgl/src/NanoVG.cpp
+++ b/libs/dgl/src/NanoVG.cpp
@@ -18,8 +18,32 @@
#include "../Window.hpp"
// -----------------------------------------------------------------------
+// Ignore some warnings if debugging
+
+#if 0 //def DEBUG
+# define NANOVG_GL3 0
+# define NANOVG_GLES2 0
+# define NANOVG_GLES3 0
+# define NANOVG_GL_USE_UNIFORMBUFFER 0
+# if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Weverything"
+# elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wall"
+# pragma GCC diagnostic ignored "-Wextra"
+# pragma GCC diagnostic ignored "-Wconversion"
+# pragma GCC diagnostic ignored "-Weffc++"
+# pragma GCC diagnostic ignored "-Wsign-conversion"
+# pragma GCC diagnostic ignored "-Wundef"
+# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+# endif
+#endif
+
+// -----------------------------------------------------------------------
+// Include NanoVG OpenGL implementation
-#define NANOVG_GL2_IMPLEMENTATION
+#define NANOVG_GL2_IMPLEMENTATION 1
#include "nanovg/nanovg_gl.h"
#if defined(NANOVG_GL2)
@@ -36,6 +60,19 @@
# define nvgDeleteGL nvgDeleteGLES3
#endif
+// -----------------------------------------------------------------------
+// Restore normal state if debugging
+
+#if 0//def DEBUG
+# if defined(__clang__)
+# pragma clang diagnostic pop
+# elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+# pragma GCC diagnostic pop
+# endif
+#endif
+
+// -----------------------------------------------------------------------
+
START_NAMESPACE_DGL
// -----------------------------------------------------------------------
@@ -75,7 +112,8 @@ NanoVG::Paint::operator NVGpaint() const noexcept
NanoImage::NanoImage(NVGcontext* const context, const int imageId) noexcept
: fContext(context),
fImageId(imageId),
- fSize()
+ fSize(),
+ leakDetector_NanoImage()
{
_updateSize();
}
@@ -114,7 +152,7 @@ void NanoImage::_updateSize()
if (h < 0) h = 0;
}
- fSize.setSize(w, h);
+ fSize.setSize(static_cast<uint>(w), static_cast<uint>(h));
}
// -----------------------------------------------------------------------
@@ -122,14 +160,16 @@ void NanoImage::_updateSize()
NanoVG::NanoVG()
: fContext(nvgCreateGL(512, 512, NVG_ANTIALIAS)),
- fInFrame(false)
+ fInFrame(false),
+ leakDetector_NanoVG()
{
DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,);
}
NanoVG::NanoVG(const int textAtlasWidth, const int textAtlasHeight)
: fContext(nvgCreateGL(textAtlasWidth, textAtlasHeight, NVG_ANTIALIAS)),
- fInFrame(false)
+ fInFrame(false),
+ leakDetector_NanoVG()
{
DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,);
}
@@ -151,7 +191,7 @@ void NanoVG::beginFrame(const uint width, const uint height, const float scaleFa
DISTRHO_SAFE_ASSERT_RETURN(! fInFrame,);
fInFrame = true;
- nvgBeginFrame(fContext, width, height, scaleFactor, static_cast<NVGalpha>(alpha));
+ nvgBeginFrame(fContext, static_cast<int>(width), static_cast<int>(height), scaleFactor, static_cast<NVGalpha>(alpha));
}
void NanoVG::beginFrame(Widget* const widget)
@@ -163,7 +203,7 @@ void NanoVG::beginFrame(Widget* const widget)
Window& window(widget->getParentWindow());
fInFrame = true;
- nvgBeginFrame(fContext, window.getWidth(), window.getHeight(), 1.0f, NVG_PREMULTIPLIED_ALPHA);
+ nvgBeginFrame(fContext, static_cast<int>(window.getWidth()), static_cast<int>(window.getHeight()), 1.0f, NVG_PREMULTIPLIED_ALPHA);
}
void NanoVG::endFrame()
@@ -209,7 +249,17 @@ void NanoVG::strokeColor(const Color& color)
void NanoVG::strokeColor(const int red, const int green, const int blue, const int alpha)
{
if (fContext != nullptr)
- nvgStrokeColor(fContext, nvgRGBA(red, green, blue, alpha));
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(red >= 0 && red <= 255,);
+ DISTRHO_SAFE_ASSERT_RETURN(green >= 0 && green <= 255,);
+ DISTRHO_SAFE_ASSERT_RETURN(blue >= 0 && blue <= 255,);
+ DISTRHO_SAFE_ASSERT_RETURN(alpha >= 0 && alpha <= 255,);
+
+ nvgStrokeColor(fContext, nvgRGBA(static_cast<uchar>(red),
+ static_cast<uchar>(green),
+ static_cast<uchar>(blue),
+ static_cast<uchar>(alpha)));
+ }
}
void NanoVG::strokeColor(const float red, const float green, const float blue, const float alpha)
@@ -233,7 +283,17 @@ void NanoVG::fillColor(const Color& color)
void NanoVG::fillColor(const int red, const int green, const int blue, const int alpha)
{
if (fContext != nullptr)
- nvgFillColor(fContext, nvgRGBA(red, green, blue, alpha));
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(red >= 0 && red <= 255,);
+ DISTRHO_SAFE_ASSERT_RETURN(green >= 0 && green <= 255,);
+ DISTRHO_SAFE_ASSERT_RETURN(blue >= 0 && blue <= 255,);
+ DISTRHO_SAFE_ASSERT_RETURN(alpha >= 0 && alpha <= 255,);
+
+ nvgFillColor(fContext, nvgRGBA(static_cast<uchar>(red),
+ static_cast<uchar>(green),
+ static_cast<uchar>(blue),
+ static_cast<uchar>(alpha)));
+ }
}
void NanoVG::fillColor(const float red, const float green, const float blue, const float alpha)
@@ -427,7 +487,7 @@ NanoImage* NanoVG::createImageRGBA(uint w, uint h, const uchar* data)
if (fContext == nullptr) return nullptr;
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, nullptr);
- if (const int imageId = nvgCreateImageRGBA(fContext, w, h, data))
+ if (const int imageId = nvgCreateImageRGBA(fContext, static_cast<int>(w), static_cast<int>(h), data))
return new NanoImage(fContext, imageId);
return nullptr;
@@ -576,13 +636,13 @@ NanoVG::FontId NanoVG::createFont(const char* name, const char* filename)
return nvgCreateFont(fContext, name, filename);
}
-NanoVG::FontId NanoVG::createFontMem(const char* name, uchar* data, int ndata, bool freeData)
+NanoVG::FontId NanoVG::createFontMem(const char* name, const uchar* data, int ndata, bool freeData)
{
if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1);
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, -1);
- return nvgCreateFontMem(fContext, name, data, ndata, freeData);
+ return nvgCreateFontMem(fContext, name, const_cast<uchar*>(data), ndata, freeData);
}
NanoVG::FontId NanoVG::findFont(const char* name)
diff --git a/libs/dgl/src/Widget.cpp b/libs/dgl/src/Widget.cpp
index 6013ea2..d2898b3 100644
--- a/libs/dgl/src/Widget.cpp
+++ b/libs/dgl/src/Widget.cpp
@@ -27,6 +27,7 @@ Widget::Widget(Window& parent)
fNeedsFullViewport(false),
fNeedsScaling(false),
fVisible(true),
+ fId(0),
fAbsolutePos(0, 0),
fSize(0, 0),
leakDetector_Widget()
@@ -200,6 +201,16 @@ void Widget::repaint() noexcept
fParent.repaint();
}
+uint Widget::getId() const noexcept
+{
+ return fId;
+}
+
+void Widget::setId(uint id) noexcept
+{
+ fId = id;
+}
+
bool Widget::onKeyboard(const KeyboardEvent&)
{
return false;
diff --git a/libs/dgl/src/Window.cpp b/libs/dgl/src/Window.cpp
index e31b75c..c901ff2 100644
--- a/libs/dgl/src/Window.cpp
+++ b/libs/dgl/src/Window.cpp
@@ -15,11 +15,12 @@
*/
// we need this for now
-#define PUGL_GRAB_FOCUS 1
+//#define PUGL_GRAB_FOCUS 1
#include "AppPrivateData.hpp"
#include "../Widget.hpp"
#include "../Window.hpp"
+#include "../../distrho/extra/d_string.hpp"
#include "pugl/pugl.h"
@@ -62,13 +63,15 @@ struct Window::PrivateData {
PrivateData(App& app, Window* const self)
: fApp(app),
fSelf(self),
- fView(puglInit(nullptr, nullptr)),
+ fView(puglInit()),
fFirstInit(true),
fVisible(false),
fResizable(true),
fUsingEmbed(false),
fWidth(1),
fHeight(1),
+ fTitle(nullptr),
+ fWidgets(),
fModal(),
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0),
@@ -89,13 +92,15 @@ struct Window::PrivateData {
PrivateData(App& app, Window* const self, Window& parent)
: fApp(app),
fSelf(self),
- fView(puglInit(nullptr, nullptr)),
+ fView(puglInit()),
fFirstInit(true),
fVisible(false),
fResizable(true),
fUsingEmbed(false),
fWidth(1),
fHeight(1),
+ fTitle(nullptr),
+ fWidgets(),
fModal(parent.pData),
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0),
@@ -112,23 +117,29 @@ struct Window::PrivateData {
DBG("Creating window with parent..."); DBGF;
init();
-#ifdef DISTRHO_OS_LINUX
const PuglInternals* const parentImpl(parent.pData->fView->impl);
-
+#if defined(DISTRHO_OS_LINUX)
XSetTransientForHint(xDisplay, xWindow, parentImpl->win);
+//#elif defined(DISTRHO_OS_MAC)
+// [parentImpl->window orderWindow:NSWindowBelow relativeTo:[[mView window] windowNumber]];
+#else
+ // unused
+ return; (void)parentImpl;
#endif
}
PrivateData(App& app, Window* const self, const intptr_t parentId)
: fApp(app),
fSelf(self),
- fView(puglInit(nullptr, nullptr)),
+ fView(puglInit()),
fFirstInit(true),
fVisible(parentId != 0),
fResizable(parentId == 0),
fUsingEmbed(parentId != 0),
fWidth(1),
fHeight(1),
+ fTitle(nullptr),
+ fWidgets(),
fModal(),
#if defined(DISTRHO_OS_WINDOWS)
hwnd(0),
@@ -136,7 +147,7 @@ struct Window::PrivateData {
xDisplay(nullptr),
xWindow(0),
#elif defined(DISTRHO_OS_MAC)
- fNeedsIdle(false),
+ fNeedsIdle(parentId == 0),
mView(nullptr),
mWindow(nullptr),
#endif
@@ -172,7 +183,7 @@ struct Window::PrivateData {
}
puglInitResizable(fView, fResizable);
- puglInitWindowSize(fView, fWidth, fHeight);
+ puglInitWindowSize(fView, static_cast<int>(fWidth), static_cast<int>(fHeight));
puglSetHandle(fView, this);
puglSetDisplayFunc(fView, onDisplayCallback);
@@ -183,6 +194,7 @@ struct Window::PrivateData {
puglSetSpecialFunc(fView, onSpecialCallback);
puglSetReshapeFunc(fView, onReshapeCallback);
puglSetCloseFunc(fView, onCloseCallback);
+ puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback);
puglCreateWindow(fView, nullptr);
@@ -221,7 +233,12 @@ struct Window::PrivateData {
{
DBG("Destroying window..."); DBGF;
- //fOnModal = false;
+ if (fModal.enabled)
+ {
+ exec_fini();
+ close();
+ }
+
fWidgets.clear();
if (fUsingEmbed)
@@ -444,7 +461,11 @@ struct Window::PrivateData {
fResizable = yesNo;
-#ifdef CARLA_OS_MAC
+#if defined(DISTRHO_OS_WINDOWS)
+ const int winFlags = fResizable ? GetWindowLong(hwnd, GWL_STYLE) | WS_SIZEBOX
+ : GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX;
+ SetWindowLong(hwnd, GWL_STYLE, winFlags);
+#elif defined(DISTRHO_OS_MAC)
// FIXME?
const uint flags(yesNo ? (NSViewWidthSizable|NSViewHeightSizable) : 0x0);
[mView setAutoresizingMask:flags];
@@ -457,7 +478,7 @@ struct Window::PrivateData {
void setSize(uint width, uint height, const bool forced = false)
{
- if (width == 0 || height == 0)
+ if (width <= 1 || height <= 1)
{
DBGp("Window setSize called with invalid value(s) %i %i, ignoring request\n", width, height);
return;
@@ -472,18 +493,15 @@ struct Window::PrivateData {
fWidth = width;
fHeight = height;
- DBGp("Window setSize called %s, size %i %i\n", forced ? "(forced)" : "(not forced)", width, height);
+ DBGp("Window setSize called %s, size %i %i, resizable %s\n", forced ? "(forced)" : "(not forced)", width, height, fResizable?"true":"false");
#if defined(DISTRHO_OS_WINDOWS)
- int winFlags = WS_POPUPWINDOW | WS_CAPTION;
-
- if (fResizable)
- winFlags |= WS_SIZEBOX;
-
+ const int winFlags = WS_POPUPWINDOW | WS_CAPTION | (fResizable ? WS_SIZEBOX : 0x0);
RECT wr = { 0, 0, static_cast<long>(width), static_cast<long>(height) };
- AdjustWindowRectEx(&wr, winFlags, FALSE, WS_EX_TOPMOST);
+ AdjustWindowRectEx(&wr, fUsingEmbed ? WS_CHILD : winFlags, FALSE, WS_EX_TOPMOST);
- SetWindowPos(hwnd, 0, 0, 0, wr.right-wr.left, wr.bottom-wr.top, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER);
+ SetWindowPos(hwnd, 0, 0, 0, wr.right-wr.left, wr.bottom-wr.top,
+ SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER);
if (! forced)
UpdateWindow(hwnd);
@@ -522,10 +540,22 @@ struct Window::PrivateData {
// -------------------------------------------------------------------
+ const char* getTitle() const noexcept
+ {
+ static const char* const kFallback = "";
+
+ return fTitle != nullptr ? fTitle : kFallback;
+ }
+
void setTitle(const char* const title)
{
DBGp("Window setTitle \"%s\"\n", title);
+ if (fTitle != nullptr)
+ std::free(fTitle);
+
+ fTitle = strdup(title);
+
#if defined(DISTRHO_OS_WINDOWS)
SetWindowTextA(hwnd, title);
#elif defined(DISTRHO_OS_MAC)
@@ -543,7 +573,7 @@ struct Window::PrivateData {
#endif
}
- void setTransientWinId(const intptr_t winId)
+ void setTransientWinId(const uintptr_t winId)
{
#if defined(DISTRHO_OS_LINUX)
XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId));
@@ -600,7 +630,7 @@ struct Window::PrivateData {
// -------------------------------------------------------------------
- void onDisplay()
+ void onPuglDisplay()
{
fSelf->onDisplayBefore();
@@ -618,22 +648,35 @@ struct Window::PrivateData {
if (widget->fNeedsFullViewport || (widget->fAbsolutePos.isZero() && widget->fSize == Size<uint>(fWidth, fHeight)))
{
// full viewport size
- glViewport(0, 0, fWidth, fHeight);
+ glViewport(0,
+ 0,
+ static_cast<GLsizei>(fWidth),
+ static_cast<GLsizei>(fHeight));
}
else if (! widget->fNeedsScaling)
{
// only set viewport pos
- glViewport(widget->getAbsoluteX(), /*fView->height - widget->getHeight()*/ - widget->getAbsoluteY(), fWidth, fHeight);
+ glViewport(widget->getAbsoluteX(),
+ /*fView->height - static_cast<int>(widget->getHeight())*/ - widget->getAbsoluteY(),
+ static_cast<GLsizei>(fWidth),
+ static_cast<GLsizei>(fHeight));
// then cut the outer bounds
- glScissor(widget->getAbsoluteX(), fView->height - widget->getHeight() - widget->getAbsoluteY(), widget->getWidth(), widget->getHeight());
+ glScissor(widget->getAbsoluteX(),
+ fView->height - static_cast<int>(widget->getHeight()) - widget->getAbsoluteY(),
+ static_cast<GLsizei>(widget->getWidth()),
+ static_cast<GLsizei>(widget->getHeight()));
+
glEnable(GL_SCISSOR_TEST);
needsDisableScissor = true;
}
else
{
// limit viewport to widget bounds
- glViewport(widget->getAbsoluteX(), fView->height - widget->getHeight() - widget->getAbsoluteY(), widget->getWidth(), widget->getHeight());
+ glViewport(widget->getAbsoluteX(),
+ fView->height - static_cast<int>(widget->getHeight()) - widget->getAbsoluteY(),
+ static_cast<GLsizei>(widget->getWidth()),
+ static_cast<GLsizei>(widget->getHeight()));
}
// display widget
@@ -650,7 +693,7 @@ struct Window::PrivateData {
fSelf->onDisplayAfter();
}
- void onKeyboard(const bool press, const uint key)
+ void onPuglKeyboard(const bool press, const uint key)
{
DBGp("PUGL: onKeyboard : %i %i\n", press, key);
@@ -672,7 +715,7 @@ struct Window::PrivateData {
}
}
- void onSpecial(const bool press, const Key key)
+ void onPuglSpecial(const bool press, const Key key)
{
DBGp("PUGL: onSpecial : %i %i\n", press, key);
@@ -681,9 +724,9 @@ struct Window::PrivateData {
Widget::SpecialEvent ev;
ev.press = press;
- ev.key = key;
- ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
- ev.time = puglGetEventTimestamp(fView);
+ ev.key = key;
+ ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
+ ev.time = puglGetEventTimestamp(fView);
FOR_EACH_WIDGET_INV(rit)
{
@@ -694,18 +737,21 @@ struct Window::PrivateData {
}
}
- void onMouse(const int button, const bool press, const int x, const int y)
+ void onPuglMouse(const int button, const bool press, const int x, const int y)
{
DBGp("PUGL: onMouse : %i %i %i %i\n", button, press, x, y);
+ // FIXME - pugl sends 2 of these for each window on init, don't ask me why. we'll ignore it
+ if (press && button == 0 && x == 0 && y == 0) return;
+
if (fModal.childFocus != nullptr)
return fModal.childFocus->focus();
Widget::MouseEvent ev;
ev.button = button;
- ev.press = press;
- ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
- ev.time = puglGetEventTimestamp(fView);
+ ev.press = press;
+ ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
+ ev.time = puglGetEventTimestamp(fView);
FOR_EACH_WIDGET_INV(rit)
{
@@ -718,7 +764,7 @@ struct Window::PrivateData {
}
}
- void onMotion(const int x, const int y)
+ void onPuglMotion(const int x, const int y)
{
DBGp("PUGL: onMotion : %i %i\n", x, y);
@@ -740,7 +786,7 @@ struct Window::PrivateData {
}
}
- void onScroll(const int x, const int y, const float dx, const float dy)
+ void onPuglScroll(const int x, const int y, const float dx, const float dy)
{
DBGp("PUGL: onScroll : %i %i %f %f\n", x, y, dx, dy);
@@ -763,38 +809,38 @@ struct Window::PrivateData {
}
}
- void onReshape(const int width, const int height)
+ void onPuglReshape(const int width, const int height)
{
DBGp("PUGL: onReshape : %i %i\n", width, height);
- if (width == 1 && height == 1)
+ if (width <= 1 && height <= 1)
return;
- fWidth = width;
- fHeight = height;
+ fWidth = static_cast<uint>(width);
+ fHeight = static_cast<uint>(height);
- fSelf->onReshape(width, height);
+ fSelf->onReshape(fWidth, fHeight);
FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);
if (widget->fNeedsFullViewport)
- widget->setSize(width, height);
+ widget->setSize(fWidth, fHeight);
}
}
- void onClose()
+ void onPuglClose()
{
DBG("PUGL: onClose\n");
- if (fModal.enabled && fModal.parent != nullptr)
+ if (fModal.enabled)
exec_fini();
fSelf->onClose();
if (fModal.childFocus != nullptr)
- fModal.childFocus->onClose();
+ fModal.childFocus->fSelf->onClose();
close();
}
@@ -811,6 +857,7 @@ struct Window::PrivateData {
bool fUsingEmbed;
uint fWidth;
uint fHeight;
+ char* fTitle;
std::list<Widget*> fWidgets;
struct Modal {
@@ -833,6 +880,8 @@ struct Window::PrivateData {
DISTRHO_SAFE_ASSERT(! enabled);
DISTRHO_SAFE_ASSERT(childFocus == nullptr);
}
+
+ DISTRHO_DECLARE_NON_COPY_STRUCT(Modal)
} fModal;
#if defined(DISTRHO_OS_WINDOWS)
@@ -853,42 +902,47 @@ struct Window::PrivateData {
static void onDisplayCallback(PuglView* view)
{
- handlePtr->onDisplay();
+ handlePtr->onPuglDisplay();
}
static void onKeyboardCallback(PuglView* view, bool press, uint32_t key)
{
- handlePtr->onKeyboard(press, key);
+ handlePtr->onPuglKeyboard(press, key);
}
static void onSpecialCallback(PuglView* view, bool press, PuglKey key)
{
- handlePtr->onSpecial(press, static_cast<Key>(key));
+ handlePtr->onPuglSpecial(press, static_cast<Key>(key));
}
static void onMouseCallback(PuglView* view, int button, bool press, int x, int y)
{
- handlePtr->onMouse(button, press, x, y);
+ handlePtr->onPuglMouse(button, press, x, y);
}
static void onMotionCallback(PuglView* view, int x, int y)
{
- handlePtr->onMotion(x, y);
+ handlePtr->onPuglMotion(x, y);
}
static void onScrollCallback(PuglView* view, int x, int y, float dx, float dy)
{
- handlePtr->onScroll(x, y, dx, dy);
+ handlePtr->onPuglScroll(x, y, dx, dy);
}
static void onReshapeCallback(PuglView* view, int width, int height)
{
- handlePtr->onReshape(width, height);
+ handlePtr->onPuglReshape(width, height);
}
static void onCloseCallback(PuglView* view)
{
- handlePtr->onClose();
+ handlePtr->onPuglClose();
+ }
+
+ static void fileBrowserSelectedCallback(PuglView* view, const char* filename)
+ {
+ handlePtr->fSelf->fileBrowserSelected(filename);
}
#undef handlePtr
@@ -900,13 +954,16 @@ struct Window::PrivateData {
// Window
Window::Window(App& app)
- : pData(new PrivateData(app, this)) {}
+ : pData(new PrivateData(app, this)),
+ leakDetector_Window() {}
Window::Window(App& app, Window& parent)
- : pData(new PrivateData(app, this, parent)) {}
+ : pData(new PrivateData(app, this, parent)),
+ leakDetector_Window() {}
Window::Window(App& app, intptr_t parentId)
- : pData(new PrivateData(app, this, parentId)) {}
+ : pData(new PrivateData(app, this, parentId)),
+ leakDetector_Window() {}
Window::~Window()
{
@@ -943,6 +1000,73 @@ void Window::repaint() noexcept
puglPostRedisplay(pData->fView);
}
+// static int fib_filter_filename_filter(const char* const name)
+// {
+// return 1;
+// (void)name;
+// }
+
+bool Window::openFileBrowser(const FileBrowserOptions& options)
+{
+ using DISTRHO_NAMESPACE::d_string;
+
+ // --------------------------------------------------------------------------
+ // configure start dir
+
+ // TODO: get abspath if needed
+ // TODO: cross-platform
+
+ d_string startDir(options.startDir);
+
+ if (startDir.isEmpty())
+ {
+ if (char* const dir_name = get_current_dir_name())
+ {
+ startDir = dir_name;
+ std::free(dir_name);
+ }
+ }
+
+ DISTRHO_SAFE_ASSERT_RETURN(startDir.isNotEmpty(), false);
+
+ if (! startDir.endsWith('/'))
+ startDir += "/";
+
+ DISTRHO_SAFE_ASSERT_RETURN(x_fib_configure(0, startDir) == 0, false);
+
+ // --------------------------------------------------------------------------
+ // configure title
+
+ d_string title(options.title);
+
+ if (title.isEmpty())
+ {
+ title = pData->getTitle();
+
+ if (title.isEmpty())
+ title = "FileBrowser";
+ }
+
+ DISTRHO_SAFE_ASSERT_RETURN(x_fib_configure(1, title) == 0, false);
+
+ // --------------------------------------------------------------------------
+ // configure filters
+
+ x_fib_cfg_filter_callback(nullptr); //fib_filter_filename_filter);
+
+ // --------------------------------------------------------------------------
+ // configure buttons
+
+ x_fib_cfg_buttons(3, options.buttons.listAllFiles-1);
+ x_fib_cfg_buttons(1, options.buttons.showHidden-1);
+ x_fib_cfg_buttons(2, options.buttons.showPlaces-1);
+
+ // --------------------------------------------------------------------------
+ // show
+
+ return (x_fib_show(pData->xDisplay, pData->xWindow, /*options.width*/0, /*options.height*/0) == 0);
+}
+
bool Window::isVisible() const noexcept
{
return pData->fVisible;
@@ -988,12 +1112,17 @@ void Window::setSize(Size<uint> size)
pData->setSize(size.getWidth(), size.getHeight());
}
+const char* Window::getTitle() const noexcept
+{
+ return pData->getTitle();
+}
+
void Window::setTitle(const char* title)
{
pData->setTitle(title);
}
-void Window::setTransientWinId(intptr_t winId)
+void Window::setTransientWinId(uintptr_t winId)
{
pData->setTransientWinId(winId);
}
@@ -1057,8 +1186,8 @@ void Window::onReshape(uint width, uint height)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(0, width, height, 0, 0.0f, 1.0f);
- glViewport(0, 0, width, height);
+ glOrtho(0.0, static_cast<GLdouble>(width), static_cast<GLdouble>(height), 0.0, 0.0, 1.0);
+ glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
@@ -1067,6 +1196,10 @@ void Window::onClose()
{
}
+void Window::fileBrowserSelected(const char*)
+{
+}
+
// -----------------------------------------------------------------------
END_NAMESPACE_DGL
diff --git a/libs/dgl/src/nanovg/fontstash.h b/libs/dgl/src/nanovg/fontstash.h
index 7fb8955..a97ce53 100644
--- a/libs/dgl/src/nanovg/fontstash.h
+++ b/libs/dgl/src/nanovg/fontstash.h
@@ -41,7 +41,7 @@ enum FONSalign {
enum FONSerrorCode {
// Font atlas is full.
FONS_ATLAS_FULL = 1,
- // Scratch memory used to render glyphs is full, requested size reported in 'val', you may need to bump up FONS_SCRATCH_BUF_SIZE.
+ // Scratch memory used to render glyphs is full, requested size reported in 'val', you may need to bump up FONS_SCRATCH_BUF_SIZE.
FONS_SCRATCH_FULL = 2,
// Calls to fonsPushState has craeted too large stack, if you need deep state stack bump up FONS_MAX_STATES.
FONS_STATES_OVERFLOW = 3,
@@ -85,7 +85,7 @@ void fonsDeleteInternal(struct FONScontext* s);
void fonsSetErrorCallback(struct FONScontext* s, void (*callback)(void* uptr, int error, int val), void* uptr);
// Returns current atlas size.
void fonsGetAtlasSize(struct FONScontext* s, int* width, int* height);
-// Expands the atlas size.
+// Expands the atlas size.
int fonsExpandAtlas(struct FONScontext* s, int width, int height);
// Reseta the whole stash.
int fonsResetAtlas(struct FONScontext* stash, int width, int height);
@@ -1388,7 +1388,7 @@ void fonsDrawDebug(struct FONScontext* stash, float x, float y)
}
float fonsTextBounds(struct FONScontext* stash,
- float x, float y,
+ float x, float y,
const char* str, const char* end,
float* bounds)
{
@@ -1576,7 +1576,7 @@ int fonsExpandAtlas(struct FONScontext* stash, int width, int height)
height = fons__maxi(height, stash->params.height);
if (width == stash->params.width && height == stash->params.height)
- return 1;
+ return 1;
// Flush pending glyphs.
fons__flush(stash);
diff --git a/libs/dgl/src/pugl/pugl.h b/libs/dgl/src/pugl/pugl.h
index 360f8e8..7cd8b84 100644
--- a/libs/dgl/src/pugl/pugl.h
+++ b/libs/dgl/src/pugl/pugl.h
@@ -51,7 +51,11 @@
# define PUGL_API PUGL_LIB_IMPORT
# endif
#else
-# define PUGL_API
+# ifdef _WIN32
+# define PUGL_API
+# else
+# define PUGL_API __attribute__((visibility("hidden")))
+# endif
#endif
#ifdef __cplusplus
@@ -196,19 +200,18 @@ typedef void (*PuglReshapeFunc)(PuglView* view, int width, int height);
so programs should handle any value gracefully.
@param view The view being scrolled.
+ @param x The window-relative x coordinate of the pointer.
+ @param y The window-relative y coordinate of the pointer.
@param dx The scroll x distance.
@param dx The scroll y distance.
*/
-typedef void (*PuglScrollFunc)(PuglView* view,
- int x,
- int y,
- float dx,
- float dy);
+typedef void (*PuglScrollFunc)(PuglView* view, int x, int y, float dx, float dy);
/**
A function called when a special key is pressed or released.
This callback allows the use of keys that do not have unicode points.
+ Note that some are non-printable keys.
@param view The view the event occured in.
@param press True if the key was pressed, false if released.
@@ -217,16 +220,21 @@ typedef void (*PuglScrollFunc)(PuglView* view,
typedef void (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key);
/**
+ A function called when a filename is selected via file-browser.
+
+ @param view The view the event occured in.
+ @param filename The selected file name or NULL if the dialog was canceled.
+*/
+typedef void (*PuglFileSelectedFunc)(PuglView* view, const char* filename);
+
+/**
Create a Pugl context.
To create a window, call the various puglInit* functions as necessary, then
call puglCreateWindow().
-
- @param pargc Pointer to argument count (unused, for GLUT compatibility).
- @param argv Arguments (unused, for GLUT compatibility).
*/
PUGL_API PuglView*
-puglInit(int* pargc, char** argv);
+puglInit(void);
/**
Set the parent window before creating a window (for embedding).
@@ -244,7 +252,7 @@ puglInitWindowSize(PuglView* view, int width, int height);
Enable or disable resizing before creating a window.
*/
PUGL_API void
-puglInitResizable(PuglView* view, bool resizable);
+puglInitUserResizable(PuglView* view, bool resizable);
/**
Create a window with the settings given by the various puglInit functions.
@@ -353,6 +361,12 @@ PUGL_API void
puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc);
/**
+ Set the function to call on file-browser selections.
+*/
+PUGL_API void
+puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc);
+
+/**
Return the native window handle.
*/
PUGL_API PuglNativeWindow
diff --git a/libs/dgl/src/pugl/pugl_internal.h b/libs/dgl/src/pugl/pugl_internal.h
index 1f75830..7301091 100644
--- a/libs/dgl/src/pugl/pugl_internal.h
+++ b/libs/dgl/src/pugl/pugl_internal.h
@@ -51,9 +51,9 @@ struct PuglViewImpl {
PuglReshapeFunc reshapeFunc;
PuglScrollFunc scrollFunc;
PuglSpecialFunc specialFunc;
+ PuglFileSelectedFunc fileSelectedFunc;
PuglInternals* impl;
-
PuglNativeWindow parent;
int width;
@@ -66,12 +66,10 @@ struct PuglViewImpl {
uint32_t event_timestamp_ms;
};
-PuglInternals* puglInitInternals();
-
-void puglDefaultReshape(PuglView* view, int width, int height);
+PuglInternals* puglInitInternals(void);
PuglView*
-puglInit(int* pargc, char** argv)
+puglInit(void)
{
PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
if (!view) {
@@ -80,6 +78,7 @@ puglInit(int* pargc, char** argv)
PuglInternals* impl = puglInitInternals();
if (!impl) {
+ free(view);
return NULL;
}
@@ -88,9 +87,6 @@ puglInit(int* pargc, char** argv)
view->height = 480;
return view;
-
- // unused
- (void)pargc; (void)argv;
}
void
@@ -136,7 +132,7 @@ puglGetModifiers(PuglView* view)
return view->mods;
}
-void
+static void
puglDefaultReshape(PuglView* view, int width, int height)
{
glMatrixMode(GL_PROJECTION);
@@ -205,3 +201,9 @@ puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc)
{
view->specialFunc = specialFunc;
}
+
+void
+puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc)
+{
+ view->fileSelectedFunc = fileSelectedFunc;
+}
diff --git a/libs/dgl/src/pugl/pugl_osx.m b/libs/dgl/src/pugl/pugl_osx.m
index 96aa57a..a99d8d0 100644
--- a/libs/dgl/src/pugl/pugl_osx.m
+++ b/libs/dgl/src/pugl/pugl_osx.m
@@ -35,6 +35,7 @@
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag;
- (void) setPuglview:(PuglView*)view;
+- (BOOL) canBecomeKeyWindow;
- (BOOL) windowShouldClose:(id)sender;
@end
@@ -54,7 +55,7 @@
[result setAcceptsMouseMovedEvents:YES];
[result setLevel: CGShieldingWindowLevel() + 1];
- return result;
+ return (PuglWindow*)result;
// unused
(void)aStyle; (void)bufferingType; (void)flag;
@@ -66,6 +67,11 @@
[self setContentSize:NSMakeSize(view->width, view->height)];
}
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
- (BOOL)windowShouldClose:(id)sender
{
if (puglview->closeFunc)
@@ -81,6 +87,7 @@
static void
puglDisplay(PuglView* view)
{
+ view->redisplay = false;
if (view->displayFunc) {
view->displayFunc(view);
}
@@ -88,28 +95,33 @@ puglDisplay(PuglView* view)
@interface PuglOpenGLView : NSOpenGLView
{
- int colorBits;
- int depthBits;
@public
PuglView* puglview;
-
NSTrackingArea* trackingArea;
+ bool doubleBuffered;
}
-- (id) initWithFrame:(NSRect)frame
- colorBits:(int)numColorBits
- depthBits:(int)numDepthBits;
+- (BOOL) acceptsFirstMouse:(NSEvent*)e;
+- (BOOL) acceptsFirstResponder;
+- (BOOL) isFlipped;
+- (BOOL) isOpaque;
+- (BOOL) preservesContentInLiveResize;
+- (id) initWithFrame:(NSRect)frame;
- (void) reshape;
-- (void) drawRect:(NSRect)rect;
-- (void) mouseEntered:(NSEvent*)event;
-- (void) mouseExited:(NSEvent*)event;
+- (void) drawRect:(NSRect)r;
+- (void) cursorUpdate:(NSEvent*)e;
+- (void) updateTrackingAreas;
+- (void) viewWillMoveToWindow:(NSWindow*)newWindow;
- (void) mouseMoved:(NSEvent*)event;
- (void) mouseDragged:(NSEvent*)event;
- (void) rightMouseDragged:(NSEvent*)event;
+- (void) otherMouseDragged:(NSEvent*)event;
- (void) mouseDown:(NSEvent*)event;
-- (void) mouseUp:(NSEvent*)event;
- (void) rightMouseDown:(NSEvent*)event;
+- (void) otherMouseDown:(NSEvent*)event;
+- (void) mouseUp:(NSEvent*)event;
- (void) rightMouseUp:(NSEvent*)event;
+- (void) otherMouseUp:(NSEvent*)event;
- (void) scrollWheel:(NSEvent*)event;
- (void) keyDown:(NSEvent*)event;
- (void) keyUp:(NSEvent*)event;
@@ -119,22 +131,46 @@ puglDisplay(PuglView* view)
@implementation PuglOpenGLView
+- (BOOL) acceptsFirstMouse:(NSEvent*)e
+{
+ return YES;
+
+ // unused
+ (void)e;
+}
+
+- (BOOL) acceptsFirstResponder
+{
+ return YES;
+}
+
+- (BOOL) isFlipped
+{
+ return YES;
+}
+
+- (BOOL) isOpaque
+{
+ return YES;
+}
+
+- (BOOL) preservesContentInLiveResize
+{
+ return NO;
+}
+
- (id) initWithFrame:(NSRect)frame
- colorBits:(int)numColorBits
- depthBits:(int)numDepthBits
{
- colorBits = numColorBits;
- depthBits = numDepthBits;
- puglview = nil;
- trackingArea = nil;
+ puglview = nil;
+ trackingArea = nil;
+ doubleBuffered = true;
- NSOpenGLPixelFormatAttribute pixelAttribs[16] = {
+ NSOpenGLPixelFormatAttribute pixelAttribs[] = {
+ NSOpenGLPFAColorSize, 24,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFADepthSize, 16,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
- NSOpenGLPFAColorSize,
- colorBits,
- NSOpenGLPFADepthSize,
- depthBits,
0
};
@@ -144,12 +180,21 @@ puglDisplay(PuglView* view)
if (pixelFormat) {
self = [super initWithFrame:frame pixelFormat:pixelFormat];
[pixelFormat release];
- if (self) {
- [[self openGLContext] makeCurrentContext];
- [self reshape];
- }
+ printf("Is doubleBuffered? TRUE\n");
} else {
- self = nil;
+ self = [super initWithFrame:frame];
+ doubleBuffered = false;
+ printf("Is doubleBuffered? FALSE\n");
+ }
+
+ if (self) {
+ NSOpenGLContext* context = [self openGLContext];
+ [context makeCurrentContext];
+
+ GLint swapInterval = 1;
+ [context setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+
+ [self reshape];
}
return self;
@@ -159,156 +204,180 @@ puglDisplay(PuglView* view)
{
[[self openGLContext] update];
- NSRect bounds = [self bounds];
- int width = bounds.size.width;
- int height = bounds.size.height;
-
- if (puglview) {
+ if (!puglview) {
/* NOTE: Apparently reshape gets called when the GC gets around to
deleting the view (?), so we must have reset puglview to NULL when
this comes around.
*/
- if (puglview->reshapeFunc) {
- puglview->reshapeFunc(puglview, width, height);
- } else {
- puglDefaultReshape(puglview, width, height);
- }
+ return;
+ }
+
+ NSRect bounds = [self bounds];
+ int width = bounds.size.width;
+ int height = bounds.size.height;
- puglview->width = width;
- puglview->height = height;
+ if (puglview->reshapeFunc) {
+ puglview->reshapeFunc(puglview, width, height);
+ } else {
+ puglDefaultReshape(puglview, width, height);
}
+
+ puglview->width = width;
+ puglview->height = height;
}
-- (void) drawRect:(NSRect)rect
+- (void) drawRect:(NSRect)r
{
puglDisplay(puglview);
- glFlush();
- glSwapAPPLE();
+
+ if (doubleBuffered) {
+ [[self openGLContext] flushBuffer];
+ } else {
+ glFlush();
+ //glSwapAPPLE();
+ }
// unused
- return; (void)rect;
+ return; (void)r;
}
-static unsigned
-getModifiers(PuglView* view, NSEvent* ev)
+- (void) cursorUpdate:(NSEvent*)e
{
- const unsigned modifierFlags = [ev modifierFlags];
+ [[NSCursor arrowCursor] set];
- view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX);
-
- unsigned mods = 0;
- mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0;
- mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0;
- mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0;
- mods |= (modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0;
- return mods;
+ // unused
+ return; (void)e;
}
--(void)updateTrackingAreas
+- (void) updateTrackingAreas
{
+ static const int opts = NSTrackingMouseEnteredAndExited
+ | NSTrackingMouseMoved
+ | NSTrackingEnabledDuringMouseDrag
+ | NSTrackingInVisibleRect
+ | NSTrackingActiveAlways
+ | NSTrackingCursorUpdate;
+
if (trackingArea != nil) {
[self removeTrackingArea:trackingArea];
[trackingArea release];
}
- const int opts = (NSTrackingMouseEnteredAndExited |
- NSTrackingMouseMoved |
- NSTrackingActiveAlways);
- trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
- options:opts
- owner:self
- userInfo:nil];
+ trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
+ options:opts
+ owner:self
+ userInfo:nil];
[self addTrackingArea:trackingArea];
+ [super updateTrackingAreas];
}
-- (void)mouseEntered:(NSEvent*)theEvent
+- (void) viewWillMoveToWindow:(NSWindow*)newWindow
{
- [self updateTrackingAreas];
+ if (newWindow != nil) {
+ [newWindow setAcceptsMouseMovedEvents:YES];
+ [newWindow makeFirstResponder:self];
+ }
- // unused
- return; (void)theEvent;
+ [super viewWillMoveToWindow:newWindow];
}
-- (void)mouseExited:(NSEvent*)theEvent
+static unsigned
+getModifiers(PuglView* view, NSEvent* ev)
{
- // unused
- return; (void)theEvent;
+ const unsigned modifierFlags = [ev modifierFlags];
+
+ view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX);
+
+ unsigned mods = 0;
+ mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0;
+ mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0;
+ mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0;
+ mods |= (modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0;
+ return mods;
+}
+
+static int
+getFixedAppKitButton(NSInteger button)
+{
+ switch (button) {
+ case 0: return 1;
+ case 1: return 3;
+ case 2: return 2;
+ default: return button;
+ }
}
- (void) mouseMoved:(NSEvent*)event
{
if (puglview->motionFunc) {
- NSPoint loc = [event locationInWindow];
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
puglview->mods = getModifiers(puglview, event);
- puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
+ puglview->motionFunc(puglview, loc.x, loc.y);
}
}
- (void) mouseDragged:(NSEvent*)event
{
- if (puglview->motionFunc) {
- NSPoint loc = [event locationInWindow];
- puglview->mods = getModifiers(puglview, event);
- puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
- }
+ [self mouseMoved:event];
}
- (void) rightMouseDragged:(NSEvent*)event
{
- if (puglview->motionFunc) {
- NSPoint loc = [event locationInWindow];
- puglview->mods = getModifiers(puglview, event);
- puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
- }
+ [self mouseDragged:event];
}
-- (void) mouseDown:(NSEvent*)event
+- (void) otherMouseDragged:(NSEvent*)event
{
- if (puglview->mouseFunc) {
- NSPoint loc = [event locationInWindow];
- puglview->mods = getModifiers(puglview, event);
- puglview->mouseFunc(puglview, 1, true, loc.x, puglview->height - loc.y);
- }
+ [self mouseDragged:event];
}
-- (void) mouseUp:(NSEvent*)event
+- (void) mouseDown:(NSEvent*)event
{
if (puglview->mouseFunc) {
- NSPoint loc = [event locationInWindow];
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
puglview->mods = getModifiers(puglview, event);
- puglview->mouseFunc(puglview, 1, false, loc.x, puglview->height - loc.y);
+ puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), true, loc.x, loc.y);
}
- [self updateTrackingAreas];
}
- (void) rightMouseDown:(NSEvent*)event
{
+ [self mouseDown:event];
+}
+
+- (void) otherMouseDown:(NSEvent*)event
+{
+ [self mouseDown:event];
+}
+
+- (void) mouseUp:(NSEvent*)event
+{
if (puglview->mouseFunc) {
- NSPoint loc = [event locationInWindow];
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
puglview->mods = getModifiers(puglview, event);
- puglview->mouseFunc(puglview, 3, true, loc.x, puglview->height - loc.y);
+ puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), false, loc.x, loc.y);
}
}
- (void) rightMouseUp:(NSEvent*)event
{
- if (puglview->mouseFunc) {
- NSPoint loc = [event locationInWindow];
- puglview->mods = getModifiers(puglview, event);
- puglview->mouseFunc(puglview, 3, false, loc.x, puglview->height - loc.y);
- }
+ [self mouseUp:event];
+}
+
+- (void) otherMouseUp:(NSEvent*)event
+{
+ [self mouseUp:event];
}
- (void) scrollWheel:(NSEvent*)event
{
if (puglview->scrollFunc) {
- NSPoint loc = [event locationInWindow];
+ NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
puglview->mods = getModifiers(puglview, event);
puglview->scrollFunc(puglview,
- loc.x, puglview->height - loc.y,
+ loc.x, loc.y,
[event deltaX], [event deltaY]);
}
- [self updateTrackingAreas];
}
- (void) keyDown:(NSEvent*)event
@@ -368,6 +437,11 @@ puglCreateWindow(PuglView* view, const char* title)
[NSApplication sharedApplication];
impl->glview = [PuglOpenGLView new];
+
+ if (!impl->glview) {
+ return 1;
+ }
+
impl->glview->puglview = view;
if (view->resizable) {
@@ -375,6 +449,7 @@ puglCreateWindow(PuglView* view, const char* title)
}
if (view->parent) {
+ [impl->glview retain];
NSView* pview = (NSView*)view->parent;
[pview addSubview:impl->glview];
return 0;
@@ -451,15 +526,17 @@ puglDestroy(PuglView* view)
PuglStatus
puglProcessEvents(PuglView* view)
{
- [view->impl->glview setNeedsDisplay: YES];
-
return PUGL_SUCCESS;
+
+ // unused
+ (void)view;
}
void
puglPostRedisplay(PuglView* view)
{
view->redisplay = true;
+ [view->impl->glview setNeedsDisplay:YES];
}
PuglNativeWindow
diff --git a/libs/dgl/src/pugl/pugl_win.cpp b/libs/dgl/src/pugl/pugl_win.cpp
index 9837671..0837ac1 100644
--- a/libs/dgl/src/pugl/pugl_win.cpp
+++ b/libs/dgl/src/pugl/pugl_win.cpp
@@ -22,6 +22,7 @@
#include <windowsx.h>
#include <GL/gl.h>
+#include <ctime>
#include <stdio.h>
#include <stdlib.h>
@@ -37,7 +38,7 @@
# define WHEEL_DELTA 120
#endif
-#define PUGL_LOCAL_CLOSE_MSG (WM_USER + 50)
+const int LOCAL_CLOSE_MSG = WM_USER + 50;
HINSTANCE hInstance = NULL;
@@ -51,6 +52,7 @@ struct PuglInternalsImpl {
LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+#if 0
extern "C" {
BOOL WINAPI
DllMain(HINSTANCE hInst, DWORD, LPVOID)
@@ -59,6 +61,7 @@ DllMain(HINSTANCE hInst, DWORD, LPVOID)
return 1;
}
} // extern "C"
+#endif
PuglInternals*
puglInitInternals()
@@ -79,7 +82,9 @@ puglCreateWindow(PuglView* view, const char* title)
// Should class be a parameter? Does this make sense on other platforms?
static int wc_count = 0;
char classNameBuf[256];
- _snprintf(classNameBuf, sizeof(classNameBuf), "%s_%d\n", title, wc_count++);
+ std::srand((std::time(NULL)));
+ _snprintf(classNameBuf, sizeof(classNameBuf), "%s_%d-%d", title, std::rand(), ++wc_count);
+ classNameBuf[sizeof(classNameBuf)-1] = '\0';
impl->wc.style = CS_OWNDC;
impl->wc.lpfnWndProc = wndProc;
@@ -90,36 +95,36 @@ puglCreateWindow(PuglView* view, const char* title)
impl->wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
impl->wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
impl->wc.lpszMenuName = NULL;
- impl->wc.lpszClassName = classNameBuf;
- RegisterClass(&impl->wc);
+ impl->wc.lpszClassName = strdup(classNameBuf);
- int winFlags = WS_POPUPWINDOW | WS_CAPTION;
- if (view->resizable) {
- winFlags |= WS_SIZEBOX;
+ if (!RegisterClass(&impl->wc)) {
+ free((void*)impl->wc.lpszClassName);
+ free(impl);
+ free(view);
+ return 1;
}
// Adjust the overall window size to accomodate our requested client size
+ const int winFlags = WS_POPUPWINDOW | WS_CAPTION | (view->resizable ? WS_SIZEBOX : 0x0);
RECT wr = { 0, 0, view->width, view->height };
- AdjustWindowRectEx(&wr, winFlags, FALSE, WS_EX_TOPMOST);
+ AdjustWindowRectEx(&wr, view->parent ? WS_CHILD : winFlags, FALSE, WS_EX_TOPMOST);
impl->hwnd = CreateWindowEx(
WS_EX_TOPMOST,
classNameBuf, title,
- view->parent ? WS_CHILD : winFlags,
+ view->parent ? (WS_CHILD | WS_VISIBLE) : winFlags,
CW_USEDEFAULT, CW_USEDEFAULT, wr.right-wr.left, wr.bottom-wr.top,
(HWND)view->parent, NULL, hInstance, NULL);
if (!impl->hwnd) {
+ UnregisterClass(impl->wc.lpszClassName, NULL);
+ free((void*)impl->wc.lpszClassName);
free(impl);
free(view);
return 1;
}
-#ifdef _WIN64
SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view);
-#else
- SetWindowLongPtr(impl->hwnd, GWL_USERDATA, (LONG)view);
-#endif
impl->hdc = GetDC(impl->hwnd);
@@ -137,6 +142,16 @@ puglCreateWindow(PuglView* view, const char* title)
SetPixelFormat(impl->hdc, format, &pfd);
impl->hglrc = wglCreateContext(impl->hdc);
+ if (!impl->hglrc) {
+ ReleaseDC (impl->hwnd, impl->hdc);
+ DestroyWindow (impl->hwnd);
+ UnregisterClass (impl->wc.lpszClassName, NULL);
+ free((void*)impl->wc.lpszClassName);
+ free(impl);
+ free(view);
+ return 1;
+ }
+
wglMakeCurrent(impl->hdc, impl->hglrc);
return 0;
@@ -166,6 +181,7 @@ puglDestroy(PuglView* view)
ReleaseDC(view->impl->hwnd, view->impl->hdc);
DestroyWindow(view->impl->hwnd);
UnregisterClass(view->impl->wc.lpszClassName, NULL);
+ free((void*)view->impl->wc.lpszClassName);
free(view->impl);
free(view);
}
@@ -190,13 +206,13 @@ puglDisplay(PuglView* view)
{
wglMakeCurrent(view->impl->hdc, view->impl->hglrc);
+ view->redisplay = false;
if (view->displayFunc) {
view->displayFunc(view);
}
glFlush();
SwapBuffers(view->impl->hdc);
- view->redisplay = false;
}
static PuglKey
@@ -309,17 +325,21 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
case WM_MOUSEWHEEL:
if (view->scrollFunc) {
view->event_timestamp_ms = GetMessageTime();
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ ScreenToClient(view->impl->hwnd, &pt);
view->scrollFunc(
- view, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
- 0.0f, (int16_t)HIWORD(wParam) / (float)WHEEL_DELTA);
+ view, pt.x, pt.y,
+ 0, GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA);
}
break;
case WM_MOUSEHWHEEL:
if (view->scrollFunc) {
view->event_timestamp_ms = GetMessageTime();
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ ScreenToClient(view->impl->hwnd, &pt);
view->scrollFunc(
- view, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
- (int16_t)HIWORD(wParam) / float(WHEEL_DELTA), 0.0f);
+ view, pt.x, pt.y,
+ GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0);
}
break;
case WM_KEYDOWN:
@@ -333,11 +353,18 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
view->specialFunc(view, message == WM_KEYDOWN, key);
}
} else if (view->keyboardFunc) {
- view->keyboardFunc(view, message == WM_KEYDOWN, wParam);
+ static BYTE kbs[256];
+ if (GetKeyboardState(kbs) != FALSE) {
+ char lb[2];
+ UINT scanCode = (lParam >> 8) & 0xFFFFFF00;
+ if ( 1 == ToAscii(wParam, scanCode, kbs, (LPWORD)lb, 0)) {
+ view->keyboardFunc(view, message == WM_KEYDOWN, (char)lb[0]);
+ }
+ }
}
break;
case WM_QUIT:
- case PUGL_LOCAL_CLOSE_MSG:
+ case LOCAL_CLOSE_MSG:
if (view->closeFunc) {
view->closeFunc(view);
}
@@ -358,7 +385,6 @@ puglProcessEvents(PuglView* view)
handleMessage(view, msg.message, msg.wParam, msg.lParam);
}
-
if (view->redisplay) {
InvalidateRect(view->impl->hwnd, NULL, FALSE);
}
@@ -369,23 +395,19 @@ puglProcessEvents(PuglView* view)
LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
-#ifdef _WIN64
PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-#else
- PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWL_USERDATA);
-#endif
switch (message) {
case WM_CREATE:
PostMessage(hwnd, WM_SHOWWINDOW, TRUE, 0);
return 0;
case WM_CLOSE:
- PostMessage(hwnd, PUGL_LOCAL_CLOSE_MSG, wParam, lParam);
+ PostMessage(hwnd, LOCAL_CLOSE_MSG, wParam, lParam);
return 0;
case WM_DESTROY:
return 0;
default:
- if (view) {
+ if (view && hwnd == view->impl->hwnd) {
return handleMessage(view, message, wParam, lParam);
} else {
return DefWindowProc(hwnd, message, wParam, lParam);
diff --git a/libs/dgl/src/pugl/pugl_x11.c b/libs/dgl/src/pugl/pugl_x11.c
index fdba1b6..eac570c 100644
--- a/libs/dgl/src/pugl/pugl_x11.c
+++ b/libs/dgl/src/pugl/pugl_x11.c
@@ -1,6 +1,7 @@
/*
Copyright 2012-2014 David Robillard <http://drobilla.net>
Copyright 2011-2012 Ben Loftis, Harrison Consoles
+ Copyright 2013 Robin Gareus <robin@gareus.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -31,6 +32,10 @@
#include "pugl_internal.h"
+#define SOFD_HAVE_X11
+#include "../sofd/libsofd.h"
+#include "../sofd/libsofd.c"
+
struct PuglInternalsImpl {
Display* display;
int screen;
@@ -49,6 +54,7 @@ static int attrListSgl[] = {
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
+ GLX_ARB_multisample, 1,
None
};
@@ -62,11 +68,29 @@ static int attrListDbl[] = {
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
+ GLX_ARB_multisample, 1,
+ None
+};
+
+/**
+ Attributes for double-buffered RGBA with multi-sampling
+ (antialiasing)
+*/
+static int attrListDblMS[] = {
+ GLX_RGBA,
+ GLX_DOUBLEBUFFER , True,
+ GLX_RED_SIZE , 4,
+ GLX_GREEN_SIZE , 4,
+ GLX_BLUE_SIZE , 4,
+ GLX_ALPHA_SIZE , 4,
+ GLX_DEPTH_SIZE , 16,
+ GLX_SAMPLE_BUFFERS , 1,
+ GLX_SAMPLES , 4,
None
};
PuglInternals*
-puglInitInternals()
+puglInitInternals(void)
{
return (PuglInternals*)calloc(1, sizeof(PuglInternals));
}
@@ -76,17 +100,21 @@ puglCreateWindow(PuglView* view, const char* title)
{
PuglInternals* impl = view->impl;
- impl->display = XOpenDisplay(0);
+ impl->display = XOpenDisplay(NULL);
impl->screen = DefaultScreen(impl->display);
+ impl->doubleBuffered = True;
+
+ XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDblMS);
+
+ if (!vi) {
+ vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
+ PUGL_LOG("multisampling (antialiasing) is not available\n");
+ }
- XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
if (!vi) {
vi = glXChooseVisual(impl->display, impl->screen, attrListSgl);
impl->doubleBuffered = False;
- PUGL_LOG("No double buffering available\n");
- } else {
- impl->doubleBuffered = True;
- PUGL_LOG("Double buffered rendering enabled\n");
+ PUGL_LOG("singlebuffered rendering will be used, no doublebuffering available\n");
}
int glxMajor, glxMinor;
@@ -202,16 +230,17 @@ puglDisplay(PuglView* view)
{
glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);
+ view->redisplay = false;
+
if (view->displayFunc) {
view->displayFunc(view);
}
glFlush();
+
if (view->impl->doubleBuffered) {
glXSwapBuffers(view->impl->display, view->impl->win);
}
-
- view->redisplay = false;
}
static PuglKey
@@ -269,9 +298,16 @@ dispatchKey(PuglView* view, XEvent* event, bool press)
KeySym sym;
char str[5];
const int n = XLookupString(&event->xkey, str, 4, &sym, NULL);
+
+ if (sym == XK_Escape && view->closeFunc && !press && !view->parent) {
+ view->closeFunc(view);
+ view->redisplay = false;
+ return;
+ }
if (n == 0) {
return;
- } else if (n > 1) {
+ }
+ if (n > 1) {
fprintf(stderr, "warning: Unsupported multi-byte key %X\n", (int)sym);
return;
}
@@ -290,6 +326,26 @@ puglProcessEvents(PuglView* view)
XEvent event;
while (XPending(view->impl->display) > 0) {
XNextEvent(view->impl->display, &event);
+
+ if (x_fib_handle_events(view->impl->display, &event)) {
+ const int status = x_fib_status();
+
+ if (status > 0) {
+ char* const filename = x_fib_filename();
+ x_fib_close(view->impl->display);
+ if (view->fileSelectedFunc) {
+ view->fileSelectedFunc(view, filename);
+ }
+ free(filename);
+ } else if (status < 0) {
+ x_fib_close(view->impl->display);
+ if (view->fileSelectedFunc) {
+ view->fileSelectedFunc(view, NULL);
+ }
+ }
+ break;
+ }
+
switch (event.type) {
case MapNotify:
puglReshape(view, view->width, view->height);
@@ -325,9 +381,7 @@ puglProcessEvents(PuglView* view)
case 6: dx = -1.0f; break;
case 7: dx = 1.0f; break;
}
- view->scrollFunc(view,
- event.xbutton.x, event.xbutton.y,
- dx, dy);
+ view->scrollFunc(view, event.xbutton.x, event.xbutton.y, dx, dy);
}
break;
}
@@ -345,8 +399,9 @@ puglProcessEvents(PuglView* view)
setModifiers(view, event.xkey.state, event.xkey.time);
dispatchKey(view, &event, true);
break;
- case KeyRelease:
+ case KeyRelease: {
setModifiers(view, event.xkey.state, event.xkey.time);
+ bool repeated = false;
if (view->ignoreKeyRepeat &&
XEventsQueued(view->impl->display, QueuedAfterReading)) {
XEvent next;
@@ -355,27 +410,27 @@ puglProcessEvents(PuglView* view)
next.xkey.time == event.xkey.time &&
next.xkey.keycode == event.xkey.keycode) {
XNextEvent(view->impl->display, &event);
- break;
+ repeated = true;
}
}
- dispatchKey(view, &event, false);
- break;
+ if (!repeated) {
+ dispatchKey(view, &event, false);
+ }
+ } break;
case ClientMessage: {
char* type = XGetAtomName(view->impl->display,
event.xclient.message_type);
if (!strcmp(type, "WM_PROTOCOLS")) {
if (view->closeFunc) {
view->closeFunc(view);
+ view->redisplay = false;
}
}
XFree(type);
- } break;
+ } break;
#ifdef PUGL_GRAB_FOCUS
case EnterNotify:
- XSetInputFocus(view->impl->display,
- view->impl->win,
- RevertToPointerRoot,
- CurrentTime);
+ XSetInputFocus(view->impl->display, view->impl->win, RevertToPointerRoot, CurrentTime);
break;
#endif
default: