first version of Gtkmm2ext::WindowProxy
This commit is contained in:
parent
1a00e323e3
commit
df05e97288
95
libs/gtkmm2ext/gtkmm2ext/window_proxy.h
Normal file
95
libs/gtkmm2ext/gtkmm2ext/window_proxy.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __gtkmm2ext_window_proxy_h__
|
||||
|
||||
#include <string>
|
||||
#include <gdkmm/event.h>
|
||||
#include <glibmm/refptr.h>
|
||||
#include <sigc++/trackable.h>
|
||||
|
||||
class XMLNode;
|
||||
|
||||
#include "gtkmm2ext/visibility.h"
|
||||
|
||||
namespace Gtk {
|
||||
class Window;
|
||||
class Action;
|
||||
}
|
||||
|
||||
namespace Gtkmm2ext {
|
||||
|
||||
class VisibilityTracker;
|
||||
|
||||
class LIBGTKMM2EXT_API WindowProxy : public virtual sigc::trackable
|
||||
{
|
||||
public:
|
||||
WindowProxy (const std::string& name, const std::string& menu_name);
|
||||
WindowProxy (const std::string& name, const std::string& menu_name, const XMLNode&);
|
||||
virtual ~WindowProxy();
|
||||
|
||||
void show ();
|
||||
void show_all ();
|
||||
void hide ();
|
||||
void present ();
|
||||
void maybe_show ();
|
||||
|
||||
bool visible() const { return _visible; }
|
||||
const std::string& name() const { return _name; }
|
||||
const std::string& menu_name() const { return _menu_name; }
|
||||
|
||||
std::string action_name() const;
|
||||
void set_action (Glib::RefPtr<Gtk::Action>);
|
||||
Glib::RefPtr<Gtk::Action> action() const { return _action; };
|
||||
|
||||
void drop_window ();
|
||||
void use_window (Gtk::Window&);
|
||||
|
||||
virtual Gtk::Window* get (bool create = false) = 0;
|
||||
|
||||
virtual void toggle ();
|
||||
|
||||
virtual void set_state (const XMLNode&);
|
||||
virtual XMLNode& get_state () const;
|
||||
|
||||
operator bool() const { return _window != 0; }
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
std::string _menu_name;
|
||||
Glib::RefPtr<Gtk::Action> _action;
|
||||
Gtk::Window* _window;
|
||||
mutable bool _visible; ///< true if the window should be visible on startup
|
||||
mutable int _x_off; ///< x position
|
||||
mutable int _y_off; ///< y position
|
||||
mutable int _width; ///< width
|
||||
mutable int _height; ///< height
|
||||
Gtkmm2ext::VisibilityTracker* vistracker;
|
||||
|
||||
void save_pos_and_size ();
|
||||
void set_pos_and_size ();
|
||||
|
||||
virtual bool delete_event_handler (GdkEventAny *ev);
|
||||
|
||||
virtual void setup ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __gtkmm2ext_window_proxy_h__ */
|
303
libs/gtkmm2ext/window_proxy.cc
Normal file
303
libs/gtkmm2ext/window_proxy.cc
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user