enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / libs / gtkmm2ext / window_proxy.cc
index d7670cb89e8726c7ff0397c2fb49cc682354cd5b..1f2fa54112d55b097c325af8fbedbbdfde98d0d8 100644 (file)
@@ -27,7 +27,7 @@
 #include "gtkmm2ext/window_proxy.h"
 #include "gtkmm2ext/visibility_tracker.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace Gtk;
 using namespace Gtkmm2ext;
@@ -40,8 +40,9 @@ WindowProxy::WindowProxy (const std::string& name)
        , _x_off (-1)
        , _y_off (-1)
        , _width (-1)
-       , _height (-1) 
+       , _height (-1)
        , vistracker (0)
+       , _state_mask (StateMask (Position|Size))
 {
 }
 
@@ -53,8 +54,9 @@ WindowProxy::WindowProxy (const std::string& name, const std::string& menu_name)
        , _x_off (-1)
        , _y_off (-1)
        , _width (-1)
-       , _height (-1) 
+       , _height (-1)
        , vistracker (0)
+       , _state_mask (StateMask (Position|Size))
 {
 }
 
@@ -66,7 +68,7 @@ WindowProxy::WindowProxy (const std::string& name, const std::string& menu_name,
        , _x_off (-1)
        , _y_off (-1)
        , _width (-1)
-       , _height (-1) 
+       , _height (-1)
        , vistracker (0)
 {
        set_state (node, 0);
@@ -82,12 +84,13 @@ int
 WindowProxy::set_state (const XMLNode& node, int /* version */)
 {
        XMLNodeList children = node.children ();
-
+       XMLNode const * child;
        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) {
+               child = *i;
+               XMLProperty const * prop = child->property (X_("name"));
+               if (child->name() == X_("Window") && prop && prop->value() == _name) {
                        break;
                }
 
@@ -96,22 +99,23 @@ WindowProxy::set_state (const XMLNode& node, int /* version */)
 
        if (i != children.end()) {
 
-               XMLProperty* prop;
+               XMLProperty const * prop;
+               child = *i;
 
-               if ((prop = (*i)->property (X_("visible"))) != 0) {
+               if ((prop = child->property (X_("visible"))) != 0) {
                        _visible = PBD::string_is_affirmative (prop->value ());
                }
 
-               if ((prop = (*i)->property (X_("x-off"))) != 0) {
+               if ((prop = child->property (X_("x-off"))) != 0) {
                        _x_off = atoi (prop->value());
                }
-               if ((prop = (*i)->property (X_("y-off"))) != 0) {
+               if ((prop = child->property (X_("y-off"))) != 0) {
                        _y_off = atoi (prop->value());
                }
-               if ((prop = (*i)->property (X_("x-size"))) != 0) {
+               if ((prop = child->property (X_("x-size"))) != 0) {
                        _width = atoi (prop->value());
                }
-               if ((prop = (*i)->property (X_("y-size"))) != 0) {
+               if ((prop = child->property (X_("y-size"))) != 0) {
                        _height = atoi (prop->value());
                }
        }
@@ -130,13 +134,13 @@ WindowProxy::set_action (Glib::RefPtr<Gtk::Action> act)
 }
 
 std::string
-WindowProxy::action_name() const 
+WindowProxy::action_name() const
 {
        return string_compose (X_("toggle-%1"), _name);
 }
 
 void
-WindowProxy::toggle() 
+WindowProxy::toggle()
 {
        if (!_window) {
                (void) get (true);
@@ -176,12 +180,12 @@ XMLNode&
 WindowProxy::get_state ()
 {
        XMLNode* node = new XMLNode (xml_node_name());
-       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 ();
@@ -189,14 +193,32 @@ WindowProxy::get_state ()
                _window->get_size (_width, _height);
        }
 
+       int x, y, w, h;
+
+       if (_state_mask & Position) {
+               x = _x_off;
+               y = _y_off;
+       } else {
+               x = -1;
+               y = -1;
+       }
+
+       if (_state_mask & Size) {
+               w = _width;
+               h = _height;
+       } else {
+               w = -1;
+               h = -1;
+       }
+
        node->add_property (X_("visible"), _visible? X_("yes") : X_("no"));
-       snprintf (buf, sizeof (buf), "%d", _x_off);
+       snprintf (buf, sizeof (buf), "%d", x);
        node->add_property (X_("x-off"), buf);
-       snprintf (buf, sizeof (buf), "%d", _y_off);
+       snprintf (buf, sizeof (buf), "%d", y);
        node->add_property (X_("y-off"), buf);
-       snprintf (buf, sizeof (buf), "%d", _width);
+       snprintf (buf, sizeof (buf), "%d", w);
        node->add_property (X_("x-size"), buf);
-       snprintf (buf, sizeof (buf), "%d", _height);
+       snprintf (buf, sizeof (buf), "%d", h);
        node->add_property (X_("y-size"), buf);
 
        return *node;
@@ -206,6 +228,10 @@ void
 WindowProxy::drop_window ()
 {
        if (_window) {
+               delete_connection.disconnect ();
+               configure_connection.disconnect ();
+               map_connection.disconnect ();
+               unmap_connection.disconnect ();
                _window->hide ();
                delete _window;
                _window = 0;
@@ -228,11 +254,63 @@ WindowProxy::setup ()
        assert (_window);
 
        vistracker = new Gtkmm2ext::VisibilityTracker (*_window);
-       _window->signal_delete_event().connect (sigc::mem_fun (*this, &WindowProxy::delete_event_handler));
+
+       delete_connection = _window->signal_delete_event().connect (sigc::mem_fun (*this, &WindowProxy::delete_event_handler));
+       configure_connection = _window->signal_configure_event().connect (sigc::mem_fun (*this, &WindowProxy::configure_handler), false);
+       map_connection = _window->signal_map().connect (sigc::mem_fun (*this, &WindowProxy::map_handler), false);
+       unmap_connection = _window->signal_unmap().connect (sigc::mem_fun (*this, &WindowProxy::unmap_handler), false);
 
        set_pos_and_size ();
 }
-       
+
+void
+WindowProxy::map_handler ()
+{
+       /* emit our own signal */
+       signal_map ();
+}
+
+void
+WindowProxy::unmap_handler ()
+{
+       /* emit out own signal */
+       signal_unmap ();
+}
+
+bool
+WindowProxy::configure_handler (GdkEventConfigure* ev)
+{
+       /* stupidly, the geometry data in the event isn't the same as we get
+          from the window geometry APIs.so we have to actively interrogate
+          them to get the new information.
+
+          the difference is generally down to window manager framing.
+       */
+       save_pos_and_size ();
+       return false;
+}
+
+
+bool
+WindowProxy::visible() const
+{
+       if (vistracker) {
+               /* update with current state */
+               _visible = vistracker->partially_visible();
+       }
+       return _visible;
+}
+
+bool
+WindowProxy::fully_visible () const
+{
+       if (!vistracker) {
+               /* no vistracker .. no window .. cannot be fully visible */
+               return false;
+       }
+       return vistracker->fully_visible();
+}
+
 void
 WindowProxy::show ()
 {
@@ -307,13 +385,34 @@ WindowProxy::set_pos_and_size ()
                return;
        }
 
-       if (_width != -1 || _height != -1 || _x_off != -1 || _y_off != -1) {
+       if ((_state_mask & Position) && (_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 ((_state_mask & Size) && _width != -1 && _height != -1) {
+               _window->resize (_width, _height);
+       }
+
+       if ((_state_mask & Position) && _x_off != -1 && _y_off != -1) {
+               _window->move (_x_off, _y_off);
+       }
+}
+
+void
+WindowProxy::set_pos ()
+{
+       if (!_window) {
+               return;
+       }
+
+       if (!(_state_mask & Position)) {
+               return;
+       }
+
+       if (_width != -1 || _height != -1 || _x_off != -1 || _y_off != -1) {
+               /* cancel any mouse-based positioning */
+               _window->set_position (Gtk::WIN_POS_NONE);
        }
 
        if (_x_off != -1 && _y_off != -1) {
@@ -321,3 +420,8 @@ WindowProxy::set_pos_and_size ()
        }
 }
 
+void
+WindowProxy::set_state_mask (StateMask sm)
+{
+       _state_mask = sm;
+}