X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fwindow_manager.cc;h=b4767879266b40fe84a0583866f0fff086b93653;hb=4f5ca7ecb5b7230f54e123339f7bc05e752bbc96;hp=f50fe444a8337123c612947c535183ad41ad8faf;hpb=e1b0f1bd0b03c071d2b5987e4ab75ef059e32111;p=ardour.git diff --git a/gtk2_ardour/window_manager.cc b/gtk2_ardour/window_manager.cc index f50fe444a8..b476787926 100644 --- a/gtk2_ardour/window_manager.cc +++ b/gtk2_ardour/window_manager.cc @@ -25,29 +25,39 @@ #include "gtkmm2ext/visibility_tracker.h" #include "actions.h" +#include "ardour_dialog.h" +#include "ardour_window.h" #include "window_manager.h" +#include "processor_box.h" #include "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); @@ -58,13 +68,13 @@ WindowManager::register_window (ProxyBase* info) ActionManager::add_action_group (window_actions); } - 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 (ActionManager::register_action (window_actions, info->action_name().c_str(), info->menu_name().c_str(), + 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) { @@ -75,7 +85,7 @@ WindowManager::remove (const ProxyBase* info) } void -WindowManager::toggle_window (ProxyBase* proxy) +Manager::toggle_window (ProxyBase* proxy) { if (proxy) { proxy->toggle (); @@ -83,10 +93,16 @@ 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()) { + if (! (*i)->get (true)) { + /* the window may be a plugin GUI for a plugin which + * is disabled or longer present. + */ + continue; + } (*i)->show_all (); (*i)->present (); } @@ -94,27 +110,67 @@ 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) { - root.add_child_nocopy ((*i)->get_state()); + /* don't save state for temporary proxy windows + */ + if (dynamic_cast (*i)) { + continue; + } + if (dynamic_cast (*i)) { + ProcessorWindowProxy *pi = dynamic_cast (*i); + root.add_child_nocopy (pi->get_state()); + } else { + 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 +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(); + if (win) { + win->set_transient_for (*parent); + } + } + } else { + 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); + } } } + + current_transient_parent = parent; +#endif } -/*-----------------------*/ +/*-------------------------*/ -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) @@ -122,12 +178,12 @@ WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu , _x_off (-1) , _y_off (-1) , _width (-1) - , _height (-1) + , _height (-1) , vistracker (0) { } -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) @@ -135,19 +191,20 @@ WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu , _x_off (-1) , _y_off (-1) , _width (-1) - , _height (-1) + , _height (-1) , vistracker (0) { set_state (node); } -WindowManager::ProxyBase::~ProxyBase () +ProxyBase::~ProxyBase () { delete vistracker; + delete _window; } void -WindowManager::ProxyBase::set_state (const XMLNode& node) +ProxyBase::set_state (const XMLNode& node) { XMLNodeList children = node.children (); @@ -171,16 +228,16 @@ WindowManager::ProxyBase::set_state (const XMLNode& node) } if ((prop = (*i)->property (X_("x-off"))) != 0) { - _x_off = atoi (prop->value().c_str()); + _x_off = atoi (prop->value()); } if ((prop = (*i)->property (X_("y-off"))) != 0) { - _y_off = atoi (prop->value().c_str()); + _y_off = atoi (prop->value()); } if ((prop = (*i)->property (X_("x-size"))) != 0) { - _width = atoi (prop->value().c_str()); + _width = atoi (prop->value()); } if ((prop = (*i)->property (X_("y-size"))) != 0) { - _height = atoi (prop->value().c_str()); + _height = atoi (prop->value()); } } @@ -192,19 +249,19 @@ WindowManager::ProxyBase::set_state (const XMLNode& node) } void -WindowManager::ProxyBase::set_action (Glib::RefPtr act) +ProxyBase::set_action (Glib::RefPtr 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); @@ -215,30 +272,51 @@ WindowManager::ProxyBase::toggle() _window->show_all(); /* we'd like to just call this and nothing else */ _window->present (); + + if (_width != -1 && _height != -1) { + _window->set_default_size (_width, _height); + } + if (_x_off != -1 && _y_off != -1) { + _window->move (_x_off, _y_off); + } + } else { + if (_window->is_mapped()) { + save_pos_and_size(); + } vistracker->cycle_visibility (); + if (_window->is_mapped()) { + if (_width != -1 && _height != -1) { + _window->set_default_size (_width, _height); + } + if (_x_off != -1 && _y_off != -1) { + _window->move (_x_off, _y_off); + } + } } } XMLNode& -WindowManager::ProxyBase::get_state () const +ProxyBase::get_state () const { XMLNode* node = new XMLNode (X_("Window")); - char buf[32]; + 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); + if (_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); @@ -252,7 +330,7 @@ WindowManager::ProxyBase::get_state () const } void -WindowManager::ProxyBase::drop_window () +ProxyBase::drop_window () { if (_window) { _window->hide (); @@ -264,7 +342,7 @@ WindowManager::ProxyBase::drop_window () } void -WindowManager::ProxyBase::use_window (Gtk::Window& win) +ProxyBase::use_window (Gtk::Window& win) { drop_window (); _window = &win; @@ -272,11 +350,17 @@ WindowManager::ProxyBase::use_window (Gtk::Window& win) } void -WindowManager::ProxyBase::setup () +ProxyBase::setup () { assert (_window); vistracker = new Gtkmm2ext::VisibilityTracker (*_window); + _window->signal_delete_event().connect (sigc::mem_fun (*this, &ProxyBase::delete_event_handler)); + + 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); @@ -285,17 +369,19 @@ WindowManager::ProxyBase::setup () if (_x_off != -1 && _y_off != -1) { _window->move (_x_off, _y_off); } + set_session(_session); } - + void -WindowManager::ProxyBase::show () +ProxyBase::show () { - Gtk::Window* win = get (true); - win->show (); + get (true); + assert (_window); + _window->show (); } void -WindowManager::ProxyBase::maybe_show () +ProxyBase::maybe_show () { if (_visible) { show (); @@ -303,27 +389,70 @@ WindowManager::ProxyBase::maybe_show () } void -WindowManager::ProxyBase::show_all () +ProxyBase::show_all () { - Gtk::Window* win = get (true); - win->show_all (); + get (true); + assert (_window); + _window->show_all (); } +void +ProxyBase::present () +{ + get (true); + assert (_window); + + _window->show_all (); + _window->present (); + + /* turn off any mouse-based positioning */ + _window->set_position (Gtk::WIN_POS_NONE); +} void -WindowManager::ProxyBase::present () +ProxyBase::hide () +{ + if (_window) { + save_pos_and_size(); + _window->hide (); + } +} + +bool +ProxyBase::delete_event_handler (GdkEventAny* /*ev*/) { - Gtk::Window* win = get (true); - win->show_all (); - win->present (); + hide(); + return true; } void -WindowManager::ProxyBase::hide () +ProxyBase::save_pos_and_size () { - Gtk::Window* win = get (false); - if (win) { - win->hide (); + if (_window) { + _window->get_position (_x_off, _y_off); + _window->get_size (_width, _height); } } +/*-----------------------*/ + +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 (_window); + if (aw) { return aw; } + ArdourDialog* ad = dynamic_cast (_window); + if (ad) { return ad; } + return 0; +}