13
0

change namespace/naming of WindowManager classes; register all ArdourDialog and ArdourWindow classes as ProxyTemporary windows so that transient-for can be set for all such windows

This commit is contained in:
Paul Davis 2013-05-07 22:09:16 -04:00
parent 87d502c15b
commit bedc7b170e
12 changed files with 277 additions and 206 deletions

View File

@ -27,6 +27,7 @@
#include "keyboard.h"
#include "splash.h"
#include "utils.h"
#include "window_manager.h"
using namespace std;
using namespace Gtk;
@ -34,6 +35,7 @@ using namespace Gtkmm2ext;
ArdourDialog::ArdourDialog (string title, bool modal, bool use_seperator)
: Dialog (title, modal, use_seperator)
, proxy (0)
, _splash_pushed (false)
{
init ();
@ -57,6 +59,7 @@ ArdourDialog::~ArdourDialog ()
spl->pop_front();
}
}
WM::Manager::instance().remove (proxy);
}
bool
@ -115,11 +118,14 @@ ArdourDialog::init ()
set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG);
Gtk::Window* parent = WindowManager::instance().transient_parent();
Gtk::Window* parent = WM::Manager::instance().transient_parent();
if (parent) {
set_transient_for (*parent);
}
ARDOUR_UI::CloseAllDialogs.connect (sigc::bind (sigc::mem_fun (*this, &ArdourDialog::response), RESPONSE_CANCEL));
proxy = new WM::ProxyTemporary (get_title(), this);
WM::Manager::instance().register_window (proxy);
}

View File

@ -25,6 +25,10 @@
#include "ardour/session_handle.h"
namespace WM {
class ProxyTemporary;
}
/*
* This virtual parent class is so that each dialog box uses the
* same mechanism to declare its closing. It shares a common
@ -46,6 +50,7 @@ class ArdourDialog : public Gtk::Dialog, public ARDOUR::SessionHandlePtr
void on_show ();
private:
WM::ProxyTemporary* proxy;
bool _splash_pushed;
void init ();

View File

@ -344,20 +344,20 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
midi_port_matrix.set_state (*ui_xml);
}
WindowManager::instance().register_window (&theme_manager);
WindowManager::instance().register_window (&key_editor);
WindowManager::instance().register_window (&rc_option_editor);
WindowManager::instance().register_window (&session_option_editor);
WindowManager::instance().register_window (&speaker_config_window);
WindowManager::instance().register_window (&about);
WindowManager::instance().register_window (&add_route_dialog);
WindowManager::instance().register_window (&add_video_dialog);
WindowManager::instance().register_window (&route_params);
WindowManager::instance().register_window (&bundle_manager);
WindowManager::instance().register_window (&location_ui);
WindowManager::instance().register_window (&big_clock_window);
WindowManager::instance().register_window (&audio_port_matrix);
WindowManager::instance().register_window (&midi_port_matrix);
WM::Manager::instance().register_window (&theme_manager);
WM::Manager::instance().register_window (&key_editor);
WM::Manager::instance().register_window (&rc_option_editor);
WM::Manager::instance().register_window (&session_option_editor);
WM::Manager::instance().register_window (&speaker_config_window);
WM::Manager::instance().register_window (&about);
WM::Manager::instance().register_window (&add_route_dialog);
WM::Manager::instance().register_window (&add_video_dialog);
WM::Manager::instance().register_window (&route_params);
WM::Manager::instance().register_window (&bundle_manager);
WM::Manager::instance().register_window (&location_ui);
WM::Manager::instance().register_window (&big_clock_window);
WM::Manager::instance().register_window (&audio_port_matrix);
WM::Manager::instance().register_window (&midi_port_matrix);
/* We need to instantiate the theme manager because it loads our
theme files. This should really change so that its window
@ -753,7 +753,7 @@ ARDOUR_UI::startup ()
goto_editor_window ();
WindowManager::instance().show_visible ();
WM::Manager::instance().show_visible ();
/* We have to do this here since goto_editor_window() ends up calling show_all() on the
* editor window, and we may want stuff to be hidden.
@ -2336,7 +2336,7 @@ ARDOUR_UI::save_state (const string & name, bool switch_to_it)
{
XMLNode* node = new XMLNode (X_("UI"));
WindowManager::instance().add_state (*node);
WM::Manager::instance().add_state (*node);
node->add_child_nocopy (gui_object_state->get_state());

View File

@ -572,23 +572,23 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
/* Dialogs that can be created via new<T> */
WindowManager::Proxy<SpeakerDialog> speaker_config_window;
WindowManager::Proxy<ThemeManager> theme_manager;
WindowManager::Proxy<KeyEditor> key_editor;
WindowManager::Proxy<RCOptionEditor> rc_option_editor;
WindowManager::Proxy<AddRouteDialog> add_route_dialog;
WindowManager::Proxy<About> about;
WindowManager::Proxy<LocationUIWindow> location_ui;
WindowManager::Proxy<RouteParams_UI> route_params;
WM::Proxy<SpeakerDialog> speaker_config_window;
WM::Proxy<ThemeManager> theme_manager;
WM::Proxy<KeyEditor> key_editor;
WM::Proxy<RCOptionEditor> rc_option_editor;
WM::Proxy<AddRouteDialog> add_route_dialog;
WM::Proxy<About> about;
WM::Proxy<LocationUIWindow> location_ui;
WM::Proxy<RouteParams_UI> route_params;
/* Windows/Dialogs that require a creator method */
WindowManager::ProxyWithConstructor<SessionOptionEditor> session_option_editor;
WindowManager::ProxyWithConstructor<AddVideoDialog> add_video_dialog;
WindowManager::ProxyWithConstructor<BundleManager> bundle_manager;
WindowManager::ProxyWithConstructor<BigClockWindow> big_clock_window;
WindowManager::ProxyWithConstructor<GlobalPortMatrixWindow> audio_port_matrix;
WindowManager::ProxyWithConstructor<GlobalPortMatrixWindow> midi_port_matrix;
WM::ProxyWithConstructor<SessionOptionEditor> session_option_editor;
WM::ProxyWithConstructor<AddVideoDialog> add_video_dialog;
WM::ProxyWithConstructor<BundleManager> bundle_manager;
WM::ProxyWithConstructor<BigClockWindow> big_clock_window;
WM::ProxyWithConstructor<GlobalPortMatrixWindow> audio_port_matrix;
WM::ProxyWithConstructor<GlobalPortMatrixWindow> midi_port_matrix;
/* creator methods */

View File

@ -95,7 +95,7 @@ ARDOUR_UI::set_session (Session *s)
}
AutomationWatch::instance().set_session (s);
WindowManager::instance().set_session (s);
WM::Manager::instance().set_session (s);
if (shuttle_box) {
shuttle_box->set_session (s);
@ -269,7 +269,7 @@ ARDOUR_UI::goto_editor_window ()
editor->show_window ();
editor->present ();
/* mixer should now be on top */
WindowManager::instance().set_transient_for (editor);
WM::Manager::instance().set_transient_for (editor);
_mixer_on_top = false;
}
@ -298,7 +298,7 @@ ARDOUR_UI::goto_mixer_window ()
mixer->show_window ();
mixer->present ();
/* mixer should now be on top */
WindowManager::instance().set_transient_for (mixer);
WM::Manager::instance().set_transient_for (mixer);
_mixer_on_top = true;
}

View File

@ -612,7 +612,7 @@ ARDOUR_UI::save_ardour_state ()
/* Windows */
WindowManager::instance().add_state (*window_node);
WM::Manager::instance().add_state (*window_node);
/* tearoffs */

View File

@ -51,6 +51,7 @@ ArdourWindow::ArdourWindow (Gtk::Window& parent, string /*title*/)
ArdourWindow::~ArdourWindow ()
{
WM::Manager::instance().remove (proxy);
}
bool
@ -103,20 +104,20 @@ ArdourWindow::init ()
*/
if (ARDOUR_UI::instance()->config()->all_floating_windows_are_dialogs.get()) {
cerr << "AW " << get_title() << " => dialog\n";
set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG);
} else {
cerr << "AW " << get_title() << " => utility\n";
set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY);
}
Gtk::Window* parent = WindowManager::instance().transient_parent();
Gtk::Window* parent = WM::Manager::instance().transient_parent();
if (parent) {
cerr << "\tmarked as transient for " << parent->get_title() << endl;
set_transient_for (*parent);
}
ARDOUR_UI::CloseAllDialogs.connect (sigc::mem_fun (*this, &ArdourWindow::hide));
proxy = new WM::ProxyTemporary (get_title(), this);
WM::Manager::instance().register_window (proxy);
}

View File

@ -27,6 +27,10 @@
#include "ardour/session_handle.h"
namespace WM {
class ProxyTemporary;
}
/**
* This virtual parent class is so that each window uses the
* same mechanism to declare its closing. It shares a common
@ -47,7 +51,8 @@ class ArdourWindow : public Gtk::Window, public ARDOUR::SessionHandlePtr, public
void on_unmap ();
private:
void init ();
WM::ProxyTemporary* proxy;
void init ();
};
#endif // __ardour_window_h__

View File

@ -1378,7 +1378,7 @@ ProcessorBox::redisplay_processors ()
++j;
if (!(*i)->marked) {
WindowManager::instance().remove (*i);
WM::Manager::instance().remove (*i);
delete *i;
_processor_window_info.erase (i);
}
@ -1451,7 +1451,7 @@ ProcessorBox::maybe_add_processor_to_ui_list (boost::weak_ptr<Processor> w)
}
_processor_window_info.push_back (wp);
WindowManager::instance().register_window (wp);
WM::Manager::instance().register_window (wp);
}
void
@ -2624,7 +2624,7 @@ ProcessorBox::update_gui_object_state (ProcessorEntry* entry)
}
ProcessorWindowProxy::ProcessorWindowProxy (string const & name, ProcessorBox* box, boost::weak_ptr<Processor> processor)
: WindowManager::ProxyBase (name, string())
: WM::ProxyBase (name, string())
, marked (false)
, _processor_box (box)
, _processor (processor)
@ -2678,5 +2678,5 @@ ProcessorWindowProxy::toggle ()
drop_window ();
}
WindowManager::ProxyBase::toggle ();
WM::ProxyBase::toggle ();
}

View File

@ -75,7 +75,7 @@ namespace ARDOUR {
class ProcessorBox;
class ProcessorWindowProxy : public WindowManager::ProxyBase
class ProcessorWindowProxy : public WM::ProxyBase
{
public:
ProcessorWindowProxy (std::string const &, ProcessorBox *, boost::weak_ptr<ARDOUR::Processor>);

View File

@ -25,30 +25,33 @@
#include "gtkmm2ext/visibility_tracker.h"
#include "actions.h"
#include "ardour_dialog.h"
#include "ardour_window.h"
#include "window_manager.h"
#include "i18n.h"
using std::string;
using namespace WM;
WindowManager* WindowManager::_instance = 0;
Manager* Manager::_instance = 0;
WindowManager&
WindowManager::instance ()
Manager&
Manager::instance ()
{
if (!_instance) {
_instance = new WindowManager;
_instance = new Manager;
}
return *_instance;
}
WindowManager::WindowManager ()
Manager::Manager ()
: current_transient_parent (0)
{
}
void
WindowManager::register_window (ProxyBase* info)
Manager::register_window (ProxyBase* info)
{
_windows.push_back (info);
@ -60,12 +63,12 @@ WindowManager::register_window (ProxyBase* info)
}
info->set_action (ActionManager::register_action (window_actions, info->action_name().c_str(), info->menu_name().c_str(),
sigc::bind (sigc::mem_fun (*this, &WindowManager::toggle_window), info)));
sigc::bind (sigc::mem_fun (*this, &Manager::toggle_window), info)));
}
}
void
WindowManager::remove (const ProxyBase* info)
Manager::remove (const ProxyBase* info)
{
for (Windows::iterator i = _windows.begin(); i != _windows.end(); ++i) {
if ((*i) == info) {
@ -76,7 +79,7 @@ WindowManager::remove (const ProxyBase* info)
}
void
WindowManager::toggle_window (ProxyBase* proxy)
Manager::toggle_window (ProxyBase* proxy)
{
if (proxy) {
proxy->toggle ();
@ -84,7 +87,7 @@ WindowManager::toggle_window (ProxyBase* proxy)
}
void
WindowManager::show_visible() const
Manager::show_visible() const
{
for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) {
if ((*i)->visible()) {
@ -95,15 +98,20 @@ WindowManager::show_visible() const
}
void
WindowManager::add_state (XMLNode& root) const
Manager::add_state (XMLNode& root) const
{
for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) {
/* don't save state for temporary proxy windows
*/
if (dynamic_cast<ProxyTemporary*> (*i)) {
continue;
}
root.add_child_nocopy ((*i)->get_state());
}
}
void
WindowManager::set_session (ARDOUR::Session* s)
Manager::set_session (ARDOUR::Session* s)
{
for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) {
ARDOUR::SessionHandlePtr* sp = (*i)->session_handle ();
@ -114,12 +122,13 @@ WindowManager::set_session (ARDOUR::Session* s)
}
void
WindowManager::set_transient_for (Gtk::Window* parent)
Manager::set_transient_for (Gtk::Window* parent)
{
if (parent) {
for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) {
Gtk::Window* win = (*i)->get();
if (win) {
std::cerr << "marked " << win->get_title() << " as transient of " << parent->get_title() << std::endl;
win->set_transient_for (*parent);
}
}
@ -131,13 +140,13 @@ WindowManager::set_transient_for (Gtk::Window* parent)
}
}
}
current_transient_parent = parent;
}
/*-----------------------*/
/*-------------------------*/
WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu_name)
ProxyBase::ProxyBase (const string& name, const std::string& menu_name)
: _name (name)
, _menu_name (menu_name)
, _window (0)
@ -150,7 +159,7 @@ WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu
{
}
WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu_name, const XMLNode& node)
ProxyBase::ProxyBase (const string& name, const std::string& menu_name, const XMLNode& node)
: _name (name)
, _menu_name (menu_name)
, _window (0)
@ -164,13 +173,13 @@ WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu
set_state (node);
}
WindowManager::ProxyBase::~ProxyBase ()
ProxyBase::~ProxyBase ()
{
delete vistracker;
}
void
WindowManager::ProxyBase::set_state (const XMLNode& node)
ProxyBase::set_state (const XMLNode& node)
{
XMLNodeList children = node.children ();
@ -215,19 +224,19 @@ WindowManager::ProxyBase::set_state (const XMLNode& node)
}
void
WindowManager::ProxyBase::set_action (Glib::RefPtr<Gtk::Action> act)
ProxyBase::set_action (Glib::RefPtr<Gtk::Action> act)
{
_action = act;
}
std::string
WindowManager::ProxyBase::action_name() const
ProxyBase::action_name() const
{
return string_compose (X_("toggle-%1"), _name);
}
void
WindowManager::ProxyBase::toggle()
ProxyBase::toggle()
{
if (!_window) {
(void) get (true);
@ -244,7 +253,7 @@ WindowManager::ProxyBase::toggle()
}
XMLNode&
WindowManager::ProxyBase::get_state () const
ProxyBase::get_state () const
{
XMLNode* node = new XMLNode (X_("Window"));
char buf[32];
@ -275,7 +284,7 @@ WindowManager::ProxyBase::get_state () const
}
void
WindowManager::ProxyBase::drop_window ()
ProxyBase::drop_window ()
{
if (_window) {
_window->hide ();
@ -287,7 +296,7 @@ WindowManager::ProxyBase::drop_window ()
}
void
WindowManager::ProxyBase::use_window (Gtk::Window& win)
ProxyBase::use_window (Gtk::Window& win)
{
drop_window ();
_window = &win;
@ -295,7 +304,7 @@ WindowManager::ProxyBase::use_window (Gtk::Window& win)
}
void
WindowManager::ProxyBase::setup ()
ProxyBase::setup ()
{
assert (_window);
@ -316,14 +325,14 @@ WindowManager::ProxyBase::setup ()
}
void
WindowManager::ProxyBase::show ()
ProxyBase::show ()
{
Gtk::Window* win = get (true);
win->show ();
}
void
WindowManager::ProxyBase::maybe_show ()
ProxyBase::maybe_show ()
{
if (_visible) {
show ();
@ -331,7 +340,7 @@ WindowManager::ProxyBase::maybe_show ()
}
void
WindowManager::ProxyBase::show_all ()
ProxyBase::show_all ()
{
Gtk::Window* win = get (true);
win->show_all ();
@ -339,7 +348,7 @@ WindowManager::ProxyBase::show_all ()
void
WindowManager::ProxyBase::present ()
ProxyBase::present ()
{
Gtk::Window* win = get (true);
win->show_all ();
@ -350,7 +359,7 @@ WindowManager::ProxyBase::present ()
}
void
WindowManager::ProxyBase::hide ()
ProxyBase::hide ()
{
Gtk::Window* win = get (false);
if (win) {
@ -358,3 +367,25 @@ WindowManager::ProxyBase::hide ()
}
}
/*-----------------------*/
ProxyTemporary::ProxyTemporary (const string& name, Gtk::Window* win)
: ProxyBase (name, string())
{
_window = win;
}
ProxyTemporary::~ProxyTemporary ()
{
}
ARDOUR::SessionHandlePtr*
ProxyTemporary::session_handle()
{
/* may return null */
ArdourWindow* aw = dynamic_cast<ArdourWindow*> (_window);
if (aw) { return aw; }
ArdourDialog* ad = dynamic_cast<ArdourDialog*> (_window);
if (ad) { return ad; }
return 0;
}

View File

@ -43,136 +43,15 @@ namespace ARDOUR {
class SessionHandlePtr;
}
class WindowManager
namespace WM {
class ProxyBase;
class Manager
{
public:
static WindowManager& instance();
static Manager& instance();
class ProxyBase : public sigc::trackable {
public:
ProxyBase (const std::string& name, const std::string& menu_name);
ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&);
virtual ~ProxyBase();
void show ();
void show_all ();
void hide ();
void present ();
void maybe_show ();
bool visible() const { return _visible; }
const std::string& name() const { return _name; }
const std::string& menu_name() const { return _menu_name; }
std::string action_name() const;
void set_action (Glib::RefPtr<Gtk::Action>);
Glib::RefPtr<Gtk::Action> action() const { return _action; };
void drop_window ();
void use_window (Gtk::Window&);
virtual Gtk::Window* get (bool create = false) = 0;
virtual void toggle ();
void set_state (const XMLNode&);
XMLNode& get_state () const;
virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
operator bool() const { return _window != 0; }
protected:
std::string _name;
std::string _menu_name;
Glib::RefPtr<Gtk::Action> _action;
Gtk::Window* _window;
mutable bool _visible; ///< true if the window should be visible on startup
mutable int _x_off; ///< x position
mutable int _y_off; ///< y position
mutable int _width; ///< width
mutable int _height; ///< height
Gtkmm2ext::VisibilityTracker* vistracker;
void setup ();
};
template<typename T>
class ProxyWithConstructor: public ProxyBase {
public:
ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
: ProxyBase (name, menu_name) , creator (c) {}
ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node)
: ProxyBase (name, menu_name, node) , creator (c) {}
Gtk::Window* get (bool create = false) {
if (!_window) {
if (!create) {
return 0;
}
_window = creator ();
if (_window) {
setup ();
}
}
return _window;
}
T* operator->() {
return dynamic_cast<T*> (get (true));
}
ARDOUR::SessionHandlePtr* session_handle () {
/* may return null */
return dynamic_cast<T*> (_window);
}
private:
boost::function<T*()> creator;
};
template<typename T>
class Proxy : public ProxyBase {
public:
Proxy (const std::string& name, const std::string& menu_name)
: ProxyBase (name, menu_name) {}
Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node)
: ProxyBase (name, menu_name, node) {}
Gtk::Window* get (bool create = false) {
if (!_window) {
if (!create) {
return 0;
}
_window = new T ();
if (_window) {
setup ();
}
}
return _window;
}
T* operator->() {
return dynamic_cast<T*> (get(true));
}
ARDOUR::SessionHandlePtr* session_handle () {
/* may return null */
return dynamic_cast<T*> (_window);
}
private:
boost::function<T*()> creator;
};
void register_window (ProxyBase*);
void remove (const ProxyBase*);
void toggle_window (ProxyBase*);
@ -190,10 +69,154 @@ class WindowManager
Glib::RefPtr<Gtk::ActionGroup> window_actions;
Gtk::Window* current_transient_parent;
WindowManager();
~WindowManager();
Manager();
~Manager();
static WindowManager* _instance;
static Manager* _instance;
};
class ProxyBase : public sigc::trackable {
public:
ProxyBase (const std::string& name, const std::string& menu_name);
ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&);
virtual ~ProxyBase();
void show ();
void show_all ();
void hide ();
void present ();
void maybe_show ();
bool visible() const { return _visible; }
const std::string& name() const { return _name; }
const std::string& menu_name() const { return _menu_name; }
std::string action_name() const;
void set_action (Glib::RefPtr<Gtk::Action>);
Glib::RefPtr<Gtk::Action> action() const { return _action; };
void drop_window ();
void use_window (Gtk::Window&);
virtual Gtk::Window* get (bool create = false) = 0;
virtual void toggle ();
void set_state (const XMLNode&);
XMLNode& get_state () const;
virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
operator bool() const { return _window != 0; }
protected:
std::string _name;
std::string _menu_name;
Glib::RefPtr<Gtk::Action> _action;
Gtk::Window* _window;
mutable bool _visible; ///< true if the window should be visible on startup
mutable int _x_off; ///< x position
mutable int _y_off; ///< y position
mutable int _width; ///< width
mutable int _height; ///< height
Gtkmm2ext::VisibilityTracker* vistracker;
void setup ();
};
class ProxyTemporary: public ProxyBase {
public:
ProxyTemporary (const std::string& name, Gtk::Window* win);
~ProxyTemporary();
Gtk::Window* get (bool create = false) {
(void) create;
return _window;
}
Gtk::Window* operator->() {
return _window;
}
ARDOUR::SessionHandlePtr* session_handle ();
};
template<typename T>
class ProxyWithConstructor: public ProxyBase {
public:
ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
: ProxyBase (name, menu_name) , creator (c) {}
ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node)
: ProxyBase (name, menu_name, node) , creator (c) {}
Gtk::Window* get (bool create = false) {
if (!_window) {
if (!create) {
return 0;
}
_window = creator ();
if (_window) {
setup ();
}
}
return _window;
}
T* operator->() {
return dynamic_cast<T*> (get (true));
}
ARDOUR::SessionHandlePtr* session_handle () {
/* may return null */
return dynamic_cast<T*> (_window);
}
private:
boost::function<T*()> creator;
};
template<typename T>
class Proxy : public ProxyBase {
public:
Proxy (const std::string& name, const std::string& menu_name)
: ProxyBase (name, menu_name) {}
Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node)
: ProxyBase (name, menu_name, node) {}
Gtk::Window* get (bool create = false) {
if (!_window) {
if (!create) {
return 0;
}
_window = new T ();
if (_window) {
setup ();
}
}
return _window;
}
T* operator->() {
return dynamic_cast<T*> (get(true));
}
ARDOUR::SessionHandlePtr* session_handle () {
/* may return null */
return dynamic_cast<T*> (_window);
}
private:
boost::function<T*()> creator;
};
} /* namespace */
#endif /* __gtk2_ardour_window_manager_h__ */