commit c9cd0b1a1f70354f4e7dcc22cdf8da4e1d60758d
parent 73641904f7e63ad46f5d936b40631234de84f2ed
Author: falkTX <falktx@gmail.com>
Date: Sun, 17 Aug 2014 21:54:59 +0100
NTK UIs seem to be working
Diffstat:
6 files changed, 327 insertions(+), 33 deletions(-)
diff --git a/dgl/ntk/NtkApp.hpp b/dgl/ntk/NtkApp.hpp
@@ -42,7 +42,7 @@ public:
Constructor.
*/
NtkApp()
- : fIsRunning(false),
+ : fIsRunning(true),
fWindows()
{
static bool initialized = false;
@@ -51,7 +51,9 @@ public:
{
initialized = true;
fl_register_images();
+#ifdef DISTRHO_OS_LINUX
fl_open_display();
+#endif
}
}
@@ -67,7 +69,7 @@ public:
/**
Idle function.
- This calls the NTK event-loop once.
+ This calls the NTK event-loop once (and all idle callbacks).
*/
void idle()
{
@@ -115,6 +117,28 @@ private:
friend class NtkWindow;
+ /** @internal used by NtkWindow. */
+ void addWindow(Fl_Double_Window* const window)
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,);
+
+ if (fWindows.size() == 0)
+ fIsRunning = true;
+
+ fWindows.push_back(window);
+ }
+
+ /** @internal used by NtkWindow. */
+ void removeWindow(Fl_Double_Window* const window)
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,);
+
+ fWindows.remove(window);
+
+ if (fWindows.size() == 0)
+ fIsRunning = false;
+ }
+
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NtkApp)
};
diff --git a/dgl/ntk/NtkWidget.hpp b/dgl/ntk/NtkWidget.hpp
@@ -19,8 +19,6 @@
#include "NtkWindow.hpp"
-#include "../Geometry.hpp"
-
START_NAMESPACE_DGL
// -----------------------------------------------------------------------
@@ -29,16 +27,18 @@ START_NAMESPACE_DGL
DGL compatible Widget class that uses NTK instead of OpenGL.
@see Widget
*/
-class NtkWidget : public Fl_Group
+class NtkWidget : public Fl_Double_Window
{
public:
/**
Constructor.
*/
explicit NtkWidget(NtkWindow& parent)
- : Fl_Group(0, 0, 0, 0),
+ : Fl_Double_Window(100, 100),
fParent(parent)
{
+ fParent.add(this);
+ show();
}
/**
@@ -46,6 +46,181 @@ public:
*/
~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();
+ }
+
+ /**
+ Get size.
+ */
+ Size<int> getSize() const
+ {
+ return Size<int>(w(), 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);
+ }
+
+ /**
+ Set size.
+ */
+ void setSize(const Size<int>& size)
+ {
+ resize(x(), y(), size.getWidth(), size.getHeight());
+ }
+
+ /**
+ Get absolute X.
+ */
+ int getAbsoluteX() const
+ {
+ return x();
+ }
+
+ /**
+ Get absolute Y.
+ */
+ int getAbsoluteY() const
+ {
+ return y();
+ }
+
+ /**
+ Get absolute position.
+ */
+ Point<int> getAbsolutePos() const
+ {
+ return Point<int>(x(), 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());
+ }
+
+ /**
+ Set absolute position.
+ */
+ void setAbsolutePos(const Point<int>& pos)
+ {
+ resize(pos.getX(), pos.getY(), 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());
+ }
+
+ /**
+ Check if this widget contains the point @a pos.
+ */
+ bool contains(const Point<int>& pos) const
+ {
+ return contains(pos.getX(), pos.getY());
+ }
+
+ /**
+ Tell this widget's window to repaint itself.
+ */
+ void repaint()
+ {
+ redraw();
}
protected:
diff --git a/dgl/ntk/NtkWindow.hpp b/dgl/ntk/NtkWindow.hpp
@@ -19,6 +19,8 @@
#include "NtkApp.hpp"
+#include "../Geometry.hpp"
+
START_NAMESPACE_DGL
class NtkWidget;
@@ -31,59 +33,147 @@ public:
explicit NtkWindow(NtkApp& app)
: Fl_Double_Window(100, 100),
fApp(app),
+ fIsVisible(false),
fUsingEmbed(false),
- fParent(nullptr),
- fWidgets() {}
+ fParent(nullptr) {}
explicit NtkWindow(NtkApp& app, NtkWindow& parent)
: Fl_Double_Window(100, 100),
fApp(app),
+ fIsVisible(false),
fUsingEmbed(false),
- fParent(&parent),
- fWidgets() {}
+ fParent(&parent) {}
explicit NtkWindow(NtkApp& app, intptr_t parentId)
: Fl_Double_Window(100, 100),
fApp(app),
+ fIsVisible(parentId != 0),
fUsingEmbed(parentId != 0),
- fParent(nullptr),
- fWidgets()
+ fParent(nullptr)
{
if (fUsingEmbed)
{
fl_embed(this, (Window)parentId);
Fl_Double_Window::show();
+ fApp.addWindow(this);
}
}
~NtkWindow() override
{
- fWidgets.clear();
-
if (fUsingEmbed)
+ {
+ fApp.removeWindow(this);
Fl_Double_Window::hide();
+ }
}
- void show()
+ void show() override
{
+ if (fUsingEmbed || fIsVisible)
+ return;
+
Fl_Double_Window::show();
+ fApp.addWindow(this);
+ fIsVisible = true;
-#ifdef DISTRHO_OS_LINUX
- if (fParent == nullptr)
+ 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();
+ }
+
+ Size<uint> getSize() const noexcept
+ {
+ return Size<uint>(w(), h());
+ }
+
+ void setSize(uint width, uint height)
+ {
+ resize(x(), y(), width, height);
+ }
+
+ void setSize(Size<uint> size)
+ {
+ resize(x(), y(), size.getWidth(), size.getHeight());
+ }
+
+ 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));
+ const ::Window ourWindow(fl_xid(this));
DISTRHO_SAFE_ASSERT_RETURN(ourWindow != 0,);
- const ::Window parentWindow(fl_xid_(fParent));
- DISTRHO_SAFE_ASSERT_RETURN(parentWindow != 0,);
-
- XSetTransientForHint(fl_display, ourWindow, parentWindow);
+ 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,);
@@ -106,12 +196,12 @@ public:
private:
NtkApp& fApp;
+ bool fIsVisible;
bool fUsingEmbed;
// transient parent, may be null
NtkWindow* const fParent;
- std::list<Fl_Group*> fWidgets;
std::list<IdleCallback*> fIdleCallbacks;
friend class NtkWidget;
diff --git a/distrho/DistrhoUI.hpp b/distrho/DistrhoUI.hpp
@@ -95,7 +95,11 @@ protected:
// UI Callbacks (optional)
virtual void d_uiIdle() {}
+
+#if ! DISTRHO_UI_USE_NTK
+ // updates window openGL state
virtual void d_uiReshape(int width, int height);
+#endif
// -------------------------------------------------------------------
@@ -106,6 +110,7 @@ private:
friend class UIExporterWindow;
// these should not be used
+ void position(int, int) noexcept {}
void setAbsoluteX(int) const noexcept {}
void setAbsoluteY(int) const noexcept {}
void setAbsolutePos(int, int) const noexcept {}
diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp
@@ -98,9 +98,9 @@ void UI::d_sampleRateChanged(double) {}
// -----------------------------------------------------------------------
// UI Callbacks (optional)
+#if ! DISTRHO_UI_USE_NTK
void UI::d_uiReshape(int width, int height)
{
-#if ! DISTRHO_UI_USE_NTK
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
@@ -109,10 +109,8 @@ void UI::d_uiReshape(int width, int height)
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
-#else
- (void)width; (void)height;
-#endif
}
+#endif
// -----------------------------------------------------------------------
diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp
@@ -157,17 +157,15 @@ public:
{
DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
-#if ! DISTRHO_UI_USE_NTK
const int width = fUI->d_getWidth();
const int height = fUI->d_getHeight();
// set widget size
fUI->setSize(width, height);
- // set this window size
+ // set window size
setResizable(false);
setSize(width, height);
-#endif
}
~UIExporterWindow()
@@ -185,8 +183,14 @@ public:
return fIsReady;
}
-#if ! DISTRHO_UI_USE_NTK
protected:
+#if DISTRHO_UI_USE_NTK
+ void resize(int x, int y, int width, int height) override
+ {
+ UIWindow::resize(x, y, width, height);
+ fIsReady = true;
+ }
+#else
void onReshape(int width, int height) override
{
DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
@@ -292,7 +296,6 @@ public:
}
#endif
-#if ! DISTRHO_UI_USE_NTK
// -------------------------------------------------------------------
void exec(IdleCallback* const cb)
@@ -355,7 +358,6 @@ public:
return ! glApp.isQuiting();
}
-#endif
void setSampleRate(const double sampleRate, const bool doCallback = false)
{