[gtkmm] ScrolledWindow: Add remove_with_viewport().



commit 70b5d4545e61e078ead7e0a7bf582293e7f85e3d
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Tue Nov 13 19:20:36 2012 +0100

    ScrolledWindow: Add remove_with_viewport().
    
    * gtk/src/scrolledwindow.[hg|ccg]: Add remove_with_viewport(). Bug #685739.

 ChangeLog                  |    6 ++++++
 gtk/src/scrolledwindow.ccg |   39 +++++++++++++++++++++++++++++++++++++--
 gtk/src/scrolledwindow.hg  |   29 +++++++++++++++++++++++++++--
 3 files changed, 70 insertions(+), 4 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b73dd01..5a03e8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2012-11-13  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
+	ScrolledWindow: Add remove_with_viewport().
+
+	* gtk/src/scrolledwindow.[hg|ccg]: Add remove_with_viewport(). Bug #685739.
+
+2012-11-13  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
 	Bin, Container::remove(): Restore the floating ref of a managed widget.
 
 	* gtk/src/bin.ccg:
diff --git a/gtk/src/scrolledwindow.ccg b/gtk/src/scrolledwindow.ccg
index d9b560a..24be794 100644
--- a/gtk/src/scrolledwindow.ccg
+++ b/gtk/src/scrolledwindow.ccg
@@ -41,9 +41,44 @@ void ScrolledWindow::add(Gtk::Widget& widget)
   }
 }
 
-} //namespace Gtk
-
+void ScrolledWindow::remove_with_viewport()
+{
+  GtkWidget* child = gtk_bin_get_child(Bin::gobj());
+  if (child)
+  {
+    if (GTK_IS_VIEWPORT(child))
+    {
+      // Remove the Viewport's child, if any, from the Viewport.
+      GtkWidget* grandchild = gtk_bin_get_child(GTK_BIN(child)); // A GtkViewport is a GtkBin
+      if (grandchild)
+      {
+        Gtk::Widget* cppGrandchild = Glib::wrap(grandchild);
 
+        //If the grandchild is a managed widget, then do an extra ref so that it will not be
+        //destroyed when it is removed, and restore the floating state of the ref.
+        //This should leave it in the same state as when it was instantiated,
+        //before being added to the first container.
+        if (cppGrandchild->is_managed_())
+        {
+          cppGrandchild->reference();
+          g_object_force_floating(static_cast<Glib::Object*>(cppGrandchild)->gobj());
+        }
 
+        gtk_container_remove(GTK_CONTAINER(child), grandchild);
+      }
 
+      // Remove the Viewport.
+      // Don't do an extra ref on the child (the Viewport). If it's added
+      // by ScrolledWindow::add() or created as a managed widget,
+      // let it be deleted, when it's removed and the ref count reaches 0.
+      gtk_container_remove(Container::gobj(), child);
+    }
+    else
+    {
+      // The child is not a Viewport. Just remove it.
+      Bin::remove();
+    }
+  }
+}
 
+} //namespace Gtk
diff --git a/gtk/src/scrolledwindow.hg b/gtk/src/scrolledwindow.hg
index 75a56c7..a998477 100644
--- a/gtk/src/scrolledwindow.hg
+++ b/gtk/src/scrolledwindow.hg
@@ -30,8 +30,10 @@ class Scrollbar;
  *
  * This container accepts a single child widget. It adds scrollbars to the child widget and optionally draws a beveled frame around the child widget.
  * The scrolled window can work in two ways:
- * 1) Some widgets have native scrolling support; these widgets handle certain Gtk::Adjustment signals. Widgets with native scroll support include Gtk::TreeView, Gtk::TextView, and Gtk::Layout.
- * 2) For widgets that lack native scrolling support, such as Gtk::Table, Gtk::Box, and so on, the widget will be placed inside a Gtk::Viewport.
+ * <OL>
+ * <LI>Some widgets have native scrolling support; these widgets handle certain Gtk::Adjustment signals. Widgets with native scroll support include Gtk::TreeView, Gtk::TextView, and Gtk::Layout.</LI>
+ * <LI>For widgets that lack native scrolling support, such as Gtk::Table, Gtk::Box, and so on, the widget will be placed inside a Gtk::Viewport.</LI>
+ * </OL>
  *
  * The position of the scrollbars is controlled by the scroll adjustments. See Gtk::Adjustment for the fields in an adjustment - for Gtk::Scrollbar, used by Gtk::ScrolledWindow,
  * the "value" field represents the position of the scrollbar, which must be between the "lower" field and "upper - page_size."
@@ -74,6 +76,29 @@ public:
   virtual void add(Gtk::Widget& widget);
   _IGNORE(gtk_scrolled_window_add_with_viewport)
 
+  //TODO: When we can break ABI/API, make Bin::remove() virtual and delete remove_with_viewport().
+  //      Add a ScrolledWindow::remove() override, and let it do approximately
+  //      what remove_with_viewport() does. https://bugzilla.gnome.org/show_bug.cgi?id=685739#c2
+  /** Remove the contained object, possibly also a Gtk::Viewport.
+   * Since this can only hold one object it is not necessary to specify which
+   * object to remove, like containers that don't derive from Gtk::Bin.
+   *
+   * This method is useful if you have added a widget without native scrolling
+   * capability, and ScrolledWindow::add() has created a Gtk::Viewport.
+   *
+   * If the child of the ScrolledWindow is a Gtk::Viewport, remove_with_viewport()
+   * removes the Viewport's child from the Viewport, and removes the Viewport from the
+   * ScrolledWindow. The Viewport is destroyed in two cases.
+   * <OL>
+   * <LI>If it was created by ScrolledWindow::add().</LI>
+   * <LI>If it was created as a managed widget
+   *     (<code>Gtk::Viewport* vp = Gtk::manage(new Gtk::Viewport(hadj, vadj));</code>).</LI>
+   * </OL>
+   *
+   * @newin{3,8}
+   */
+  void remove_with_viewport();
+
 #m4 _CONVERSION(`GtkWidget*',`Scrollbar*',`Glib::wrap((GtkScrollbar*)$3)')
 #m4 _CONVERSION(`GtkWidget*',`const Scrollbar*',`Glib::wrap((GtkScrollbar*)$3)')
   _WRAP_METHOD(Scrollbar* get_vscrollbar(), gtk_scrolled_window_get_vscrollbar)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]