initial versions of Tabbable object
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 3 Jul 2015 19:06:29 +0000 (15:06 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 22 Feb 2016 20:31:21 +0000 (15:31 -0500)
libs/gtkmm2ext/gtkmm2ext/tabbable.h [new file with mode: 0644]
libs/gtkmm2ext/tabbable.cc [new file with mode: 0644]

diff --git a/libs/gtkmm2ext/gtkmm2ext/tabbable.h b/libs/gtkmm2ext/gtkmm2ext/tabbable.h
new file mode 100644 (file)
index 0000000..4186024
--- /dev/null
@@ -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 <gtkmm/bin.h>
+
+#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 (file)
index 0000000..1236490
--- /dev/null
@@ -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 <gtkmm/action.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/window.h>
+
+#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 = &notebook;
+       _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<Window*> (_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<Window*> (_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;
+}