summaryrefslogtreecommitdiff
path: root/libs/gtkmm2ext/window_proxy.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-07-01 17:26:14 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2016-02-22 15:31:21 -0500
commitdf05e97288b48f10d9133d0dd9e56a156a5c3287 (patch)
tree7d7145a07fa9ae945fd06dc9e6aa5524e1556646 /libs/gtkmm2ext/window_proxy.cc
parent1a00e323e391b413e4b3da487ea4cf2d24b0576d (diff)
first version of Gtkmm2ext::WindowProxy
Diffstat (limited to 'libs/gtkmm2ext/window_proxy.cc')
-rw-r--r--libs/gtkmm2ext/window_proxy.cc303
1 files changed, 303 insertions, 0 deletions
diff --git a/libs/gtkmm2ext/window_proxy.cc b/libs/gtkmm2ext/window_proxy.cc
new file mode 100644
index 0000000000..b01fc6c628
--- /dev/null
+++ b/libs/gtkmm2ext/window_proxy.cc
@@ -0,0 +1,303 @@
+/*
+ Copyright (C) 2015 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <gtkmm/action.h>
+#include <gtkmm/window.h>
+
+#include "pbd/convert.h"
+#include "pbd/xml++.h"
+
+#include "gtkmm2ext/window_proxy.h"
+#include "gtkmm2ext/visibility_tracker.h"
+
+#include "i18n.h"
+
+using namespace Gtk;
+using namespace Gtkmm2ext;
+using namespace PBD;
+
+WindowProxy::WindowProxy (const std::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)
+{
+}
+
+WindowProxy::WindowProxy (const std::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);
+}
+
+WindowProxy::~WindowProxy ()
+{
+ delete vistracker;
+ delete _window;
+}
+
+void
+WindowProxy::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());
+ }
+ if ((prop = (*i)->property (X_("y-off"))) != 0) {
+ _y_off = atoi (prop->value());
+ }
+ if ((prop = (*i)->property (X_("x-size"))) != 0) {
+ _width = atoi (prop->value());
+ }
+ if ((prop = (*i)->property (X_("y-size"))) != 0) {
+ _height = atoi (prop->value());
+ }
+ }
+
+ /* if the window is marked visible but doesn't yet exist, create it */
+
+ if (_visible) {
+ if (!_window) {
+ _window = get (true);
+ }
+ }
+
+ if (_window) {
+ setup ();
+ }
+}
+
+void
+WindowProxy::set_action (Glib::RefPtr<Gtk::Action> act)
+{
+ _action = act;
+}
+
+std::string
+WindowProxy::action_name() const
+{
+ return string_compose (X_("toggle-%1"), _name);
+}
+
+void
+WindowProxy::toggle()
+{
+ 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 {
+ 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&
+WindowProxy::get_state () const
+{
+ 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
+WindowProxy::drop_window ()
+{
+ if (_window) {
+ _window->hide ();
+ delete _window;
+ _window = 0;
+ delete vistracker;
+ vistracker = 0;
+ }
+}
+
+void
+WindowProxy::use_window (Gtk::Window& win)
+{
+ drop_window ();
+ _window = &win;
+ setup ();
+}
+
+void
+WindowProxy::setup ()
+{
+ assert (_window);
+
+ vistracker = new Gtkmm2ext::VisibilityTracker (*_window);
+ _window->signal_delete_event().connect (sigc::mem_fun (*this, &WindowProxy::delete_event_handler));
+
+ set_pos_and_size ();
+}
+
+void
+WindowProxy::show ()
+{
+ get (true);
+ assert (_window);
+ _window->show ();
+}
+
+void
+WindowProxy::maybe_show ()
+{
+ if (_visible) {
+ show ();
+ }
+}
+
+void
+WindowProxy::show_all ()
+{
+ get (true);
+ assert (_window);
+ _window->show_all ();
+}
+
+void
+WindowProxy::present ()
+{
+ get (true);
+ assert (_window);
+
+ _window->show_all ();
+ _window->present ();
+
+ /* turn off any mouse-based positioning */
+ _window->set_position (Gtk::WIN_POS_NONE);
+}
+
+void
+WindowProxy::hide ()
+{
+ if (_window) {
+ save_pos_and_size();
+ _window->hide ();
+ }
+}
+
+bool
+WindowProxy::delete_event_handler (GdkEventAny* /*ev*/)
+{
+ hide();
+ return true;
+}
+
+void
+WindowProxy::save_pos_and_size ()
+{
+ if (_window) {
+ _window->get_position (_x_off, _y_off);
+ _window->get_size (_width, _height);
+ }
+}
+
+void
+WindowProxy::set_pos_and_size ()
+{
+ if (!_window) {
+ 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 (_width != -1 && _height != -1) {
+ _window->set_default_size (_width, _height);
+ }
+
+ if (_x_off != -1 && _y_off != -1) {
+ _window->move (_x_off, _y_off);
+ }
+}
+