X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fwindow_manager.cc;h=b3960b0b50e19f2a08523b3396b61fbfad2e5651;hb=b64dcac17ec6ab503198d933ef893760fb02ae22;hp=627e9a1744e401aad42aa3cd5167e2ec3f4dc7bd;hpb=a902737db97e6bdd55493a1536242a26e26a0014;p=ardour.git diff --git a/gtk2_ardour/window_manager.cc b/gtk2_ardour/window_manager.cc index 627e9a1744..b3960b0b50 100644 --- a/gtk2_ardour/window_manager.cc +++ b/gtk2_ardour/window_manager.cc @@ -22,49 +22,95 @@ #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->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))); + info->set_action (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 +Manager::window_proxy_was_mapped (ProxyBase* proxy) +{ + 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 +Manager::window_proxy_was_unmapped (ProxyBase* proxy) +{ + 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::remove (const ProxyBase* info) +Manager::remove (const ProxyBase* info) { for (Windows::iterator i = _windows.begin(); i != _windows.end(); ++i) { if ((*i) == info) { @@ -75,18 +121,50 @@ WindowManager::remove (const ProxyBase* info) } void -WindowManager::toggle_window (ProxyBase* proxy) +Manager::toggle_window (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; + } + + if (tact->get_active()) { + proxy->present (); + } else { + proxy->hide (); } } void -WindowManager::show_visible() const +Manager::show_visible() const { for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { 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 (); } @@ -94,27 +172,41 @@ 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 (*i)) { + continue; + } + root.add_child_nocopy ((*i)->get_state()); } } void -WindowManager::set_session (ARDOUR::Session* s) +Manager::set_session (ARDOUR::Session* s) { + SessionHandlePtr::set_session (s); for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { - ARDOUR::SessionHandlePtr* sp = (*i)->session_handle (); - if (sp) { - sp->set_session (s); - } + (*i)->set_session(s); } } void -WindowManager::set_transient_for (Gtk::Window* parent) +Manager::set_transient_for (Gtk::Window* parent) { + /* 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(); @@ -130,228 +222,51 @@ WindowManager::set_transient_for (Gtk::Window* parent) } } } -} - -/*-----------------------*/ - -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) -{ - 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 ()); - } - - 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 ((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 (); - } -} - -void -WindowManager::ProxyBase::set_action (Glib::RefPtr act) -{ - _action = act; + current_transient_parent = parent; +#endif } -std::string -WindowManager::ProxyBase::action_name() const -{ - return string_compose (X_("toggle-%1"), _name); -} +/*-------------------------*/ -void -WindowManager::ProxyBase::toggle() +ProxyBase::ProxyBase (const std::string& name, const std::string& menu_name) + : WindowProxy (name, menu_name) { - 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 (); - } else { - vistracker->cycle_visibility (); - } } -XMLNode& -WindowManager::ProxyBase::get_state () const +ProxyBase::ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode& node) + : WindowProxy (name, menu_name, node) { - XMLNode* node = new XMLNode (X_("Window")); - char buf[32]; - - node->add_property (X_("name"), _name); - - if (_window && vistracker) { - - /* we have a window, so use current state */ - - _visible = vistracker->partially_visible (); - _window->get_position (_x_off, _y_off); - _window->get_size (_width, _height); - } - - node->add_property (X_("visible"), _visible? X_("yes") : X_("no")); - - 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::drop_window () +ProxyBase::setup () { - if (_window) { - _window->hide (); - delete _window; - _window = 0; - delete vistracker; - vistracker = 0; - } -} + WindowProxy::setup (); + set_session(_session); -void -WindowManager::ProxyBase::use_window (Gtk::Window& win) -{ - drop_window (); - _window = &win; - setup (); } -void -WindowManager::ProxyBase::setup () -{ - assert (_window); - - vistracker = new Gtkmm2ext::VisibilityTracker (*_window); - - if (_width != -1 || _height != -1 || _x_off != -1 || _y_off != -1) { - /* cancel any mouse-based positioning */ - _window->set_position (Gtk::WIN_POS_NONE); - } - - if (_width != -1 && _height != -1) { - _window->set_default_size (_width, _height); - } - - 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 () +ProxyTemporary::ProxyTemporary (const string& name, Gtk::Window* win) + : ProxyBase (name, string()) { - if (_visible) { - show (); - } + _window = win; } -void -WindowManager::ProxyBase::show_all () +ProxyTemporary::~ProxyTemporary () { - Gtk::Window* win = get (true); - win->show_all (); } -void -WindowManager::ProxyBase::present () +ARDOUR::SessionHandlePtr* +ProxyTemporary::session_handle() { - Gtk::Window* win = get (true); - win->show_all (); - win->present (); - - /* turn off any mouse-based positioning */ - _window->set_position (Gtk::WIN_POS_NONE); + /* may return null */ + ArdourWindow* aw = dynamic_cast (_window); + if (aw) { return aw; } + ArdourDialog* ad = dynamic_cast (_window); + if (ad) { return ad; } + return 0; } - -void -WindowManager::ProxyBase::hide () -{ - Gtk::Window* win = get (false); - if (win) { - win->hide (); - } -} -