@@ -0,0 +1,125 @@ | |||||
/* | |||||
* 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 <list> | |||||
#include <FL/Fl.H> | |||||
#include <FL/Fl_Double_Window.H> | |||||
#include <FL/Fl_Shared_Image.H> | |||||
#include <FL/x.H> | |||||
START_NAMESPACE_DGL | |||||
class NtkWindow; | |||||
// ----------------------------------------------------------------------- | |||||
/** | |||||
DGL compatible App class that uses NTK instead of OpenGL. | |||||
@see App | |||||
*/ | |||||
class NtkApp | |||||
{ | |||||
public: | |||||
/** | |||||
Constructor. | |||||
*/ | |||||
NtkApp() | |||||
: fIsRunning(false), | |||||
fWindows() | |||||
{ | |||||
static bool initialized = false; | |||||
if (! initialized) | |||||
{ | |||||
initialized = true; | |||||
fl_register_images(); | |||||
fl_open_display(); | |||||
} | |||||
} | |||||
/** | |||||
Destructor. | |||||
*/ | |||||
~NtkApp() | |||||
{ | |||||
DISTRHO_SAFE_ASSERT(! fIsRunning); | |||||
fWindows.clear(); | |||||
} | |||||
/** | |||||
Idle function. | |||||
This calls the NTK event-loop once. | |||||
*/ | |||||
void idle() | |||||
{ | |||||
Fl::check(); | |||||
} | |||||
/** | |||||
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() | |||||
{ | |||||
fIsRunning = true; | |||||
Fl::run(); | |||||
fIsRunning = false; | |||||
} | |||||
/** | |||||
Quit the application. | |||||
This stops the event-loop and closes all Windows. | |||||
*/ | |||||
void quit() | |||||
{ | |||||
fIsRunning = false; | |||||
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(); | |||||
} | |||||
} | |||||
/** | |||||
Check if the application is about to quit. | |||||
Returning true means there's no event-loop running at the moment. | |||||
*/ | |||||
bool isQuiting() const noexcept | |||||
{ | |||||
return !fIsRunning; | |||||
} | |||||
private: | |||||
bool fIsRunning; | |||||
std::list<Fl_Double_Window*> fWindows; | |||||
friend class NtkWindow; | |||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NtkApp) | |||||
}; | |||||
// ----------------------------------------------------------------------- | |||||
END_NAMESPACE_DGL | |||||
#endif // DGL_NTK_APP_HPP_INCLUDED |
@@ -0,0 +1,67 @@ | |||||
/* | |||||
* 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" | |||||
#include "../Geometry.hpp" | |||||
START_NAMESPACE_DGL | |||||
// ----------------------------------------------------------------------- | |||||
/** | |||||
DGL compatible Widget class that uses NTK instead of OpenGL. | |||||
@see Widget | |||||
*/ | |||||
class NtkWidget : public Fl_Group | |||||
{ | |||||
public: | |||||
/** | |||||
Constructor. | |||||
*/ | |||||
explicit NtkWidget(NtkWindow& parent) | |||||
: Fl_Group(0, 0, 0, 0), | |||||
fParent(parent) | |||||
{ | |||||
} | |||||
/** | |||||
Destructor. | |||||
*/ | |||||
~NtkWidget() override | |||||
{ | |||||
} | |||||
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 |
@@ -0,0 +1,137 @@ | |||||
/* | |||||
* 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), | |||||
fUsingEmbed(false), | |||||
fParent(nullptr), | |||||
fWidgets() {} | |||||
explicit NtkWindow(NtkApp& app, NtkWindow& parent) | |||||
: Fl_Double_Window(100, 100), | |||||
fApp(app), | |||||
fUsingEmbed(false), | |||||
fParent(&parent), | |||||
fWidgets() {} | |||||
explicit NtkWindow(NtkApp& app, intptr_t parentId) | |||||
: Fl_Double_Window(100, 100), | |||||
fApp(app), | |||||
fUsingEmbed(parentId != 0), | |||||
fParent(nullptr), | |||||
fWidgets() | |||||
{ | |||||
if (fUsingEmbed) | |||||
{ | |||||
fl_embed(this, (Window)parentId); | |||||
Fl_Double_Window::show(); | |||||
} | |||||
} | |||||
~NtkWindow() override | |||||
{ | |||||
fWidgets.clear(); | |||||
if (fUsingEmbed) | |||||
Fl_Double_Window::hide(); | |||||
} | |||||
void show() | |||||
{ | |||||
Fl_Double_Window::show(); | |||||
#ifdef DISTRHO_OS_LINUX | |||||
if (fParent == nullptr) | |||||
return; | |||||
DISTRHO_SAFE_ASSERT_RETURN(fl_display != nullptr,); | |||||
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); | |||||
#endif | |||||
} | |||||
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 fUsingEmbed; | |||||
// transient parent, may be null | |||||
NtkWindow* const fParent; | |||||
std::list<Fl_Group*> fWidgets; | |||||
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 |