From a29f76c1c45e112279d9cb0a002f41d0fb9155ab Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 3 Jul 2015 15:06:29 -0400 Subject: [PATCH] initial versions of Tabbable object --- libs/gtkmm2ext/gtkmm2ext/tabbable.h | 68 ++++++++++++ libs/gtkmm2ext/tabbable.cc | 165 ++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 libs/gtkmm2ext/gtkmm2ext/tabbable.h create mode 100644 libs/gtkmm2ext/tabbable.cc diff --git a/libs/gtkmm2ext/gtkmm2ext/tabbable.h b/libs/gtkmm2ext/gtkmm2ext/tabbable.h new file mode 100644 index 0000000000..418602477e --- /dev/null +++ b/libs/gtkmm2ext/gtkmm2ext/tabbable.h @@ -0,0 +1,68 @@ +/* + 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_tabbable_h__ +#define __gtkmm2ext_tabbable_h__ + +#include + +#include "gtkmm2ext/window_proxy.h" +#include "gtkmm2ext/visibility.h" + +namespace Gtk { + class Window; + class Notebook; +} + +namespace Gtkmm2ext { + +class VisibilityTracker; + +class LIBGTKMM2EXT_API Tabbable : public WindowProxy { + public: + Tabbable (Gtk::Widget&); + ~Tabbable (); + + void add_to_notebook (Gtk::Notebook& notebook, const std::string& tab_title, int position); + + Gtk::Window* get (bool create = false); + Gtk::Window* own_window () { return get (false); } + Gtk::Notebook* tabbed_parent (); + virtual Gtk::Window* use_own_window (); + + bool has_own_window () const; + bool is_tabbed () const; + + virtual void show_window (); + + bool window_visible (); + + protected: + bool delete_event_handler (GdkEventAny *ev); + + private: + Gtk::Widget& _contents; + Gtk::Notebook* _parent_notebook; + std::string _tab_title; + int _notebook_position; +}; + +} + +#endif diff --git a/libs/gtkmm2ext/tabbable.cc b/libs/gtkmm2ext/tabbable.cc new file mode 100644 index 0000000000..123649036a --- /dev/null +++ b/libs/gtkmm2ext/tabbable.cc @@ -0,0 +1,165 @@ +/* + 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 +#include +#include + +#include "gtkmm2ext/tabbable.h" +#include "gtkmm2ext/visibility_tracker.h" + +using namespace Gtkmm2ext; +using namespace Gtk; +using std::string; + +Tabbable::Tabbable (Widget& w) + : _contents (w) +{ +} + +Tabbable::~Tabbable () +{ + if (_window) { + delete _window; + _window = 0; + } +} + +void +Tabbable::add_to_notebook (Notebook& notebook, const string& tab_title, int position) +{ + notebook.insert_page (_contents, tab_title, position, false); + notebook.set_tab_detachable (_contents); + + _parent_notebook = ¬ebook; + _tab_title = tab_title; + _notebook_position = position; +} + +Window* +Tabbable::use_own_window () +{ + return get (true); +} + +bool +Tabbable::window_visible () +{ + if (!own_window()) { + return false; + } + + return visible(); +} + +Window* +Tabbable::get (bool create) +{ + if (_window) { + return _window; + } + + if (!create) { + return 0; + } + + if ((_window = new Window (WINDOW_TOPLEVEL)) == 0) { + return 0; + } + + /* allow parent window to become the key focus window */ + _window->set_flags (CAN_FOCUS); + + return _window; +} + +void +Tabbable::show_window () +{ + Window* toplevel = dynamic_cast (_contents.get_toplevel()); + + if (toplevel == _window) { + _window->present (); + } + + if (!_visible) { /* was hidden, update status */ + set_pos_and_size (); + } + + if (toplevel != _window) { + /* not in its own window, just switch parent notebook to show + this Tabbable. + */ + if (_parent_notebook) { + _parent_notebook->set_current_page (_notebook_position); + } + } +} + +bool +Tabbable::delete_event_handler (GdkEventAny *ev) +{ + Window* toplevel = dynamic_cast (_contents.get_toplevel()); + + if (_window == toplevel) { + + /* unpack Tabbable from parent, put it back in the main tabbed + * notebook + */ + + save_pos_and_size (); + + _contents.get_parent()->remove (_contents); + + /* leave the window around */ + + _window->hide (); + + if (_parent_notebook) { + + _parent_notebook->insert_page (_contents, _tab_title, _notebook_position); + _parent_notebook->set_tab_detachable (_contents); + } + + show_all (); + + /* don't let anything else handle this */ + + return true; + } + + /* nothing to do */ + return false; +} + +bool +Tabbable::is_tabbed () const +{ + Window* toplevel = (Window*) _contents.get_toplevel(); + + if (_window && (toplevel == _window)) { + return false; + } + + if (_parent_notebook) { + return true; + } + + return false; +}