X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fwindow_manager.cc;h=1d63751c5ec369e9f1fe1eee4c768274206b02e0;hb=abf1f286d49482ade939da7e49863a3d63048b42;hp=5732e21a2533b83ea91c34321a1afb6490ebc74f;hpb=9267648e5dd8d8db5fa39ae2a264b261d6c75dbe;p=ardour.git diff --git a/gtk2_ardour/window_manager.cc b/gtk2_ardour/window_manager.cc index 5732e21a25..1d63751c5e 100644 --- a/gtk2_ardour/window_manager.cc +++ b/gtk2_ardour/window_manager.cc @@ -22,312 +22,251 @@ #include "ardour/session_handle.h" +#include "gtkmm2ext/bindings.h" #include "gtkmm2ext/visibility_tracker.h" #include "actions.h" +#include "ardour_dialog.h" +#include "ardour_ui.h" +#include "ardour_window.h" #include "window_manager.h" +#include "processor_box.h" -#include "i18n.h" +#include "pbd/i18n.h" using std::string; +using namespace WM; +using namespace PBD; -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) +{ +} + +Manager::~Manager () { } void -WindowManager::register_window (ProxyBase* info) +Manager::register_window (ProxyBase* info) { _windows.push_back (info); - if (info->rc_configured() && !info->menu_name().empty()) { + if (!info->menu_name().empty()) { if (!window_actions) { - window_actions = Gtk::ActionGroup::create (X_("Window")); - ActionManager::add_action_group (window_actions); + window_actions = ARDOUR_UI::instance()->global_actions.create_action_group (X_("Window")); } - 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))); + ARDOUR_UI::instance()->global_actions.register_toggle_action (window_actions, + info->action_name().c_str(), info->menu_name().c_str(), + sigc::bind (sigc::mem_fun (*this, &Manager::toggle_window), info)); + + info->signal_map.connect (sigc::bind (sigc::mem_fun (*this, &Manager::window_proxy_was_mapped), info)); + info->signal_unmap.connect (sigc::bind (sigc::mem_fun (*this, &Manager::window_proxy_was_unmapped), info)); + } } void -WindowManager::remove (const ProxyBase* info) +Manager::window_proxy_was_mapped (ProxyBase* proxy) { - for (Windows::iterator i = _windows.begin(); i != _windows.end(); ++i) { - if ((*i) == info) { - _windows.erase (i); - return; - } + Glib::RefPtr act = ARDOUR_UI::instance()->global_actions.find_action (string_compose ("%1/%2", window_actions->get_name(), proxy->action_name())); + if (!act) { + return; + } + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); + if (!tact) { + return; } + + tact->set_active (true); } void -WindowManager::toggle_window (ProxyBase* proxy) +Manager::window_proxy_was_unmapped (ProxyBase* proxy) { - if (proxy) { - proxy->toggle (); + Glib::RefPtr act = ARDOUR_UI::instance()->global_actions.find_action (string_compose ("%1/%2", window_actions->get_name(), proxy->action_name())); + if (!act) { + return; } + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); + if (!tact) { + return; + } + + tact->set_active (false); } void -WindowManager::show_visible() const +Manager::remove (const ProxyBase* info) { - for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { - if ((*i)->visible()) { - (*i)->show_all (); - (*i)->present (); + for (Windows::iterator i = _windows.begin(); i != _windows.end(); ++i) { + if ((*i) == info) { + _windows.erase (i); + return; } } } void -WindowManager::add_state (XMLNode& root) const +Manager::toggle_window (ProxyBase* proxy) { - for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { - root.add_child_nocopy ((*i)->get_state()); + Glib::RefPtr act = ARDOUR_UI::instance()->global_actions.find_action (string_compose ("%1/%2", window_actions->get_name(), proxy->action_name())); + if (!act) { + return; + } + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); + if (!tact) { + return; + } + + if (tact->get_active()) { + proxy->present (); + } else { + proxy->hide (); } } void -WindowManager::set_session (ARDOUR::Session* s) +Manager::show_visible() const { for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { - ARDOUR::SessionHandlePtr* sp = (*i)->session_handle (); - if (sp) { - sp->set_session (s); + if ((*i)->visible()) { + Gtk::Window* win = (*i)->get (true); + if (!win) { + /* the window may be a plugin GUI for a plugin which + * is disabled or longer present. + */ + continue; + } + if (dynamic_cast (win)) { + /* do not show dialogs at startup. Most + * dialogs require some signal connection work + * because we are trying to avoid recursive + * event loops (connecting instead to + * ::signal_response(). This means we need to + * destroy the window as well, so that the code + * which checks if it should be created will + * find that it is missing and will create it + * and connect to any necessary signals. + */ + (*i)->drop_window (); + continue; + } + (*i)->show_all (); + (*i)->present (); } } } -/*-----------------------*/ - -WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu_name) - : _name (name) - , _menu_name (menu_name) - , _window (0) - , _visible (false) - , _x_off (-1) - , _y_off (-1) - , _width (-1) - , _height (-1) - , vistracker (0) -{ -} - -WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu_name, const XMLNode& node) - : _name (name) - , _menu_name (menu_name) - , _window (0) - , _visible (false) - , _x_off (-1) - , _y_off (-1) - , _width (-1) - , _height (-1) - , vistracker (0) -{ - set_state (node); -} - -WindowManager::ProxyBase::~ProxyBase () -{ - delete vistracker; -} - void -WindowManager::ProxyBase::set_state (const XMLNode& node) +Manager::add_state (XMLNode& root) const { - XMLNodeList children = node.children (); - - XMLNodeList::const_iterator i = children.begin (); - - while (i != children.end()) { - XMLProperty* prop = (*i)->property (X_("name")); - if ((*i)->name() == X_("Window") && prop && prop->value() == _name) { - break; - } - - ++i; - } - - if (i != children.end()) { - - XMLProperty* prop; - - if ((prop = (*i)->property (X_("visible"))) != 0) { - _visible = PBD::string_is_affirmative (prop->value ()); - } + for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { + /* don't save state for temporary proxy windows + */ - if ((prop = (*i)->property (X_("x-off"))) != 0) { - _x_off = atoi (prop->value().c_str()); - } - if ((prop = (*i)->property (X_("y-off"))) != 0) { - _y_off = atoi (prop->value().c_str()); + if (dynamic_cast (*i)) { + continue; } - if ((prop = (*i)->property (X_("x-size"))) != 0) { - _width = atoi (prop->value().c_str()); - } - if ((prop = (*i)->property (X_("y-size"))) != 0) { - _height = atoi (prop->value().c_str()); - } - } - /* if we have a window already, reset its properties */ - - if (_window) { - setup (); + root.add_child_nocopy ((*i)->get_state()); } } void -WindowManager::ProxyBase::set_action (Glib::RefPtr act) +Manager::set_session (ARDOUR::Session* s) { - _action = act; -} - -std::string -WindowManager::ProxyBase::action_name() const -{ - return string_compose (X_("toggle-%1"), _name); + SessionHandlePtr::set_session (s); + for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { + (*i)->set_session(s); + } } void -WindowManager::ProxyBase::toggle() +Manager::set_transient_for (Gtk::Window* parent) { - if (!_window) { - (void) get (true); - assert (_window); - /* XXX this is a hack - the window object should really - ensure its components are all visible. sigh. - */ - _window->show_all(); - /* we'd like to just call this and nothing else */ - _window->present (); + /* OS X has a richer concept of window layering than X does (or + * certainly, than any accepted conventions on X), and so the use of + * Manager::set_transient_for() is not necessary on that platform. + * + * On OS X this is mostly taken care of by using the window type rather + * than explicit 1:1 transient-for relationships. + */ + +#ifndef __APPLE__ + if (parent) { + for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { + Gtk::Window* win = (*i)->get(); + if (win) { + win->set_transient_for (*parent); + } + } } else { - vistracker->cycle_visibility (); + for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { + Gtk::Window* win = (*i)->get(); + if (win) { + gtk_window_set_transient_for (win->gobj(), 0); + } + } } -} - -bool -WindowManager::ProxyBase::configured (GdkEventConfigure* ev) -{ - _visible = true; - _x_off = ev->x; - _y_off = ev->y; - _height = ev->height; - _width = ev->width; - return false; + current_transient_parent = parent; +#endif } -XMLNode& -WindowManager::ProxyBase::get_state () const -{ - XMLNode* node = new XMLNode (X_("Window")); - node->add_property (X_("name"), _name); - node->add_property (X_("visible"), _visible ? X_("yes") : X_("no")); - - char buf[32]; - snprintf (buf, sizeof (buf), "%d", _x_off); - node->add_property (X_("x-off"), buf); - snprintf (buf, sizeof (buf), "%d", _y_off); - node->add_property (X_("y-off"), buf); - snprintf (buf, sizeof (buf), "%d", _width); - node->add_property (X_("x-size"), buf); - snprintf (buf, sizeof (buf), "%d", _height); - node->add_property (X_("y-size"), buf); - - return *node; -} +/*-------------------------*/ -void -WindowManager::ProxyBase::clear () +ProxyBase::ProxyBase (const std::string& name, const std::string& menu_name) + : WindowProxy (name, menu_name) { - if (_window) { - _window->hide (); - delete _window; - _window = 0; - configure_connection.disconnect (); - delete vistracker; - vistracker = 0; - } } -void -WindowManager::ProxyBase::use_window (Gtk::Window& win) +ProxyBase::ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode& node) + : WindowProxy (name, menu_name, node) { - clear (); - _window = &win; - setup (); } void -WindowManager::ProxyBase::setup () +ProxyBase::setup () { - assert (_window); - - configure_connection = _window->signal_configure_event().connect (sigc::mem_fun (*this, &ProxyBase::configured), false); - - vistracker = new Gtkmm2ext::VisibilityTracker (*_window); - - if (_width != -1 && _height != -1) { - _window->set_default_size (_width, _height); - } + WindowProxy::setup (); + set_session(_session); - if (_x_off != -1 && _y_off != -1) { - _window->move (_x_off, _y_off); - } -} - -void -WindowManager::ProxyBase::show () -{ - Gtk::Window* win = get (true); - win->show (); } -void -WindowManager::ProxyBase::maybe_show () -{ - if (_visible) { - show (); - } -} +/*-----------------------*/ -void -WindowManager::ProxyBase::show_all () +ProxyTemporary::ProxyTemporary (const string& name, Gtk::Window* win) + : ProxyBase (name, string()) { - Gtk::Window* win = get (true); - win->show_all (); + _window = win; } - -void -WindowManager::ProxyBase::present () +ProxyTemporary::~ProxyTemporary () { - Gtk::Window* win = get (true); - win->show_all (); - win->present (); } -void -WindowManager::ProxyBase::hide () + +ARDOUR::SessionHandlePtr* +ProxyTemporary::session_handle() { - Gtk::Window* win = get (false); - if (win) { - win->hide (); - } + /* may return null */ + ArdourWindow* aw = dynamic_cast (_window); + if (aw) { return aw; } + ArdourDialog* ad = dynamic_cast (_window); + if (ad) { return ad; } + return 0; } -