[gtkmm/wip/dboles/make_managed-4] object: Add Gtk::make_managed<T>(args...) helper



commit 5b8682050febab1724794ea8768f83921be63f51
Author: Daniel Boles <dboles src gmail com>
Date:   Sun Oct 7 13:09:49 2018 +0100

    object: Add Gtk::make_managed<T>(args...) helper
    
    To avoid the discouraged pattern of manually writing `new` and get
    tidier syntax, follow the example of std::make_(unique|shared)() by
    adding a new helper function that both constructs and manages a widget
    in one call. The user will not need to `new` and can user fewer parens.
    
      auto button = Gtk::manage(new Gtk::Button("_Hi", true));
    
    becomes
    
      auto button = Gtk::make_managed<Gtk::Button>("_Hi", true);
    
    Switch to make_managed() in tests and demo, albeit nowhere else (yet?).
    
    https://gitlab.gnome.org/GNOME/gtkmm/issues/33

 demos/gtk-demo/demowindow.cc                      |  2 +-
 demos/gtk-demo/example_appwindow.cc               | 10 +++++-----
 demos/gtk-demo/example_buttonbox.cc               | 12 ++++++------
 demos/gtk-demo/example_change_display.cc          |  4 ++--
 demos/gtk-demo/example_dialog.cc                  |  2 +-
 demos/gtk-demo/example_flowbox.cc                 |  4 ++--
 demos/gtk-demo/example_iconbrowser.cc             |  2 +-
 demos/gtk-demo/example_images.cc                  | 16 ++++++++--------
 demos/gtk-demo/example_menus.cc                   | 20 ++++++++++----------
 demos/gtk-demo/example_panes.cc                   | 10 +++++-----
 demos/gtk-demo/example_sizegroup.cc               |  4 ++--
 demos/gtk-demo/example_stacksidebar.cc            |  4 ++--
 demos/gtk-demo/example_textview.cc                | 18 +++++++++---------
 demos/gtk-demo/example_treeview_editable_cells.cc |  4 ++--
 gtk/gtkmm/object.h                                | 21 +++++++++++++++++++++
 tests/child_widget_managed/main.cc                |  2 +-
 tests/delete_cpp_child/main.cc                    |  8 +++-----
 tests/dialog_deletethis/main.cc                   |  2 +-
 18 files changed, 82 insertions(+), 63 deletions(-)
---
diff --git a/demos/gtk-demo/demowindow.cc b/demos/gtk-demo/demowindow.cc
index 3c02f36d..ce3e5f69 100644
--- a/demos/gtk-demo/demowindow.cc
+++ b/demos/gtk-demo/demowindow.cc
@@ -154,7 +154,7 @@ void DemoWindow::fill_tree()
     }
   }
 
-  auto pCell = Gtk::manage(new Gtk::CellRendererText());
+  auto pCell = Gtk::make_managed<Gtk::CellRendererText>();
   pCell->property_style() = Pango::Style::ITALIC;
 
   auto pColumn = new Gtk::TreeViewColumn("Widget (double click for demo)", *pCell);
diff --git a/demos/gtk-demo/example_appwindow.cc b/demos/gtk-demo/example_appwindow.cc
index 0899d210..d998eeec 100644
--- a/demos/gtk-demo/example_appwindow.cc
+++ b/demos/gtk-demo/example_appwindow.cc
@@ -46,7 +46,7 @@ Example_AppWindow::Example_AppWindow()
     using namespace Gtk::Menu_Helpers;
 
     //File menu:
-    auto pMenuFile = Gtk::manage( new Gtk::Menu() );
+    auto pMenuFile = Gtk::make_managed<Gtk::Menu>();
     MenuList& list_file = pMenuFile->items();
     list_file.push_back( MenuElem("_New", "<control>N", sigc::mem_fun(*this, 
&Example_AppWindow::on_menu_item)) );
     list_file.push_back( MenuElem("_Open", "<control>O", sigc::mem_fun(*this, 
&Example_AppWindow::on_menu_item)) );
@@ -56,11 +56,11 @@ Example_AppWindow::Example_AppWindow()
     list_file.push_back( MenuElem("_Quit", "<control>Q", sigc::mem_fun(*this, 
&Example_AppWindow::on_menu_item)) );
 
     //Preferences menu:
-    auto pMenuPreferences = Gtk::manage( new Gtk::Menu() );
+    auto pMenuPreferences = Gtk::make_managed<Gtk::Menu>();
     MenuList& list_preferences = pMenuPreferences->items();
 
     // Create a submenu
-    auto pMenuSub_Color = Gtk::manage( new Gtk::Menu());
+    auto pMenuSub_Color = Gtk::make_managed<Gtk::Menu>();
     MenuList& list_sub = pMenuSub_Color->items();
     list_sub.push_back( MenuElem("_Red", sigc::mem_fun(*this, &Example_AppWindow::on_menu_item)) );
     list_sub.push_back( MenuElem("_Green", sigc::mem_fun(*this, &Example_AppWindow::on_menu_item)) );
@@ -69,7 +69,7 @@ Example_AppWindow::Example_AppWindow()
     list_preferences.push_back( MenuElem("_Color", *pMenuSub_Color) );
 
     // Create a submenu
-    auto pMenuSub_Shape = Gtk::manage( new Gtk::Menu());
+    auto pMenuSub_Shape = Gtk::make_managed<Gtk::Menu>();
     list_sub = pMenuSub_Shape->items();
     list_sub.push_back( MenuElem("_Square", sigc::mem_fun(*this, &Example_AppWindow::on_menu_item)) );
     list_sub.push_back( MenuElem("_Rectangle", sigc::mem_fun(*this, &Example_AppWindow::on_menu_item)) );
@@ -78,7 +78,7 @@ Example_AppWindow::Example_AppWindow()
     list_preferences.push_back( MenuElem("_Shape", *pMenuSub_Shape) );
 
     //Help menu:
-    auto pMenuHelp = Gtk::manage( new Gtk::Menu() );
+    auto pMenuHelp = Gtk::make_managed<Gtk::Menu>();
     MenuList& list_help = pMenuHelp->items();
     list_help.push_back( MenuElem("_About", sigc::mem_fun(*this, &Example_AppWindow::on_menu_item)) );
 
diff --git a/demos/gtk-demo/example_buttonbox.cc b/demos/gtk-demo/example_buttonbox.cc
index d1c7dc1f..0d2b288c 100644
--- a/demos/gtk-demo/example_buttonbox.cc
+++ b/demos/gtk-demo/example_buttonbox.cc
@@ -71,14 +71,14 @@ Example_ButtonBox::~Example_ButtonBox()
 
 Gtk::Frame* Example_ButtonBox::create_button_box(bool horizontal, const Glib::ustring& title, gint  spacing, 
Gtk::ButtonBoxStyle layout)
 {
-  auto pFrame = Gtk::manage(new Gtk::Frame(title));
+  auto pFrame = Gtk::make_managed<Gtk::Frame>(title);
 
   Gtk::ButtonBox* pButtonBox = nullptr;
   if (horizontal)
-    pButtonBox = Gtk::manage(new Gtk::ButtonBox(Gtk::Orientation::HORIZONTAL));
+    pButtonBox = Gtk::make_managed<Gtk::ButtonBox>(Gtk::Orientation::HORIZONTAL);
   else
   {
-    pButtonBox = Gtk::manage(new Gtk::ButtonBox(Gtk::Orientation::VERTICAL));
+    pButtonBox = Gtk::make_managed<Gtk::ButtonBox>(Gtk::Orientation::VERTICAL);
     pFrame->set_margin_start(5);
     pFrame->set_margin_end(5);
   }
@@ -89,13 +89,13 @@ Gtk::Frame* Example_ButtonBox::create_button_box(bool horizontal, const Glib::us
   pButtonBox->set_layout(layout);
   pButtonBox->set_spacing(spacing);
 
-  auto pButton = Gtk::manage(new Gtk::Button("_OK", true));
+  auto pButton = Gtk::make_managed<Gtk::Button>("_OK", true);
   pButtonBox->add(*pButton);
 
-  pButton = Gtk::manage(new Gtk::Button("_Cancel", true));
+  pButton = Gtk::make_managed<Gtk::Button>("_Cancel", true);
   pButtonBox->add(*pButton);
 
-  pButton = Gtk::manage(new Gtk::Button());
+  pButton = Gtk::make_managed<Gtk::Button>();
   pButton->set_icon_name("help-browser");
   pButtonBox->add(*pButton);
 
diff --git a/demos/gtk-demo/example_change_display.cc b/demos/gtk-demo/example_change_display.cc
index 5e94355d..f3e2d807 100644
--- a/demos/gtk-demo/example_change_display.cc
+++ b/demos/gtk-demo/example_change_display.cc
@@ -144,11 +144,11 @@ Example_ChangeDisplay::~Example_ChangeDisplay()
 
 void Example_ChangeDisplay::setup_frame(Gtk::Frame& frame, Gtk::TreeView& treeview, Gtk::Box& buttonbox)
 {
-  auto pHBox = Gtk::manage( new Gtk::Box(Gtk::Orientation::HORIZONTAL, 8) );
+  auto pHBox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
   pHBox->property_margin() = 8;
   frame.add(*pHBox);
 
-  auto pScrolledWindow = Gtk::manage( new Gtk::ScrolledWindow() );
+  auto pScrolledWindow = Gtk::make_managed<Gtk::ScrolledWindow>();
   pScrolledWindow->set_policy(Gtk::PolicyType::NEVER, Gtk::PolicyType::AUTOMATIC);
   pScrolledWindow->set_shadow_type(Gtk::ShadowType::IN);
   pHBox->pack_start(*pScrolledWindow, Gtk::PackOptions::EXPAND_WIDGET);
diff --git a/demos/gtk-demo/example_dialog.cc b/demos/gtk-demo/example_dialog.cc
index 57f71de8..55e56fdd 100644
--- a/demos/gtk-demo/example_dialog.cc
+++ b/demos/gtk-demo/example_dialog.cc
@@ -81,7 +81,7 @@ Example_Dialog::Example_Dialog()
   m_VBox.pack_start(m_HBox, Gtk::PackOptions::SHRINK);
   m_Button_Message.signal_clicked().connect(sigc::mem_fun(*this, &Example_Dialog::on_button_message));
   m_HBox.pack_start(m_Button_Message, Gtk::PackOptions::SHRINK);
-  m_VBox.pack_start(*(Gtk::manage(new Gtk::Separator(Gtk::Orientation::HORIZONTAL))), 
Gtk::PackOptions::SHRINK);
+  m_VBox.pack_start(*Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::HORIZONTAL), 
Gtk::PackOptions::SHRINK);
 
 
   /* Interactive dialog*/
diff --git a/demos/gtk-demo/example_flowbox.cc b/demos/gtk-demo/example_flowbox.cc
index 507d0ac9..fe005810 100644
--- a/demos/gtk-demo/example_flowbox.cc
+++ b/demos/gtk-demo/example_flowbox.cc
@@ -70,8 +70,8 @@ Example_FlowBox::~Example_FlowBox()
 
 Gtk::Button* Example_FlowBox::create_color_swatch(int swatch_i)
 {
-  auto drawing_area = Gtk::manage(new Gtk::DrawingArea());
-  auto color_swatch = Gtk::manage(new Gtk::Button());
+  auto drawing_area = Gtk::make_managed<Gtk::DrawingArea>();
+  auto color_swatch = Gtk::make_managed<Gtk::Button>();
 
   drawing_area->set_content_width(24);
   drawing_area->set_content_height(24);
diff --git a/demos/gtk-demo/example_iconbrowser.cc b/demos/gtk-demo/example_iconbrowser.cc
index 3ca9f10b..bf656315 100644
--- a/demos/gtk-demo/example_iconbrowser.cc
+++ b/demos/gtk-demo/example_iconbrowser.cc
@@ -834,7 +834,7 @@ void Example_IconBrowser::populate()
 void Example_IconBrowser::add_context(const Glib::ustring& id,
   const Glib::ustring& name, const Glib::ustring& description)
 {
-  IconContextLabel* row = Gtk::manage(new IconContextLabel(id, name));
+  IconContextLabel* row = Gtk::make_managed<IconContextLabel>(id, name);
   row->show();
   row->property_margin() = 10;
   m_context_list.append(*row);
diff --git a/demos/gtk-demo/example_images.cc b/demos/gtk-demo/example_images.cc
index c60ceea8..f9fbb0d2 100644
--- a/demos/gtk-demo/example_images.cc
+++ b/demos/gtk-demo/example_images.cc
@@ -77,7 +77,7 @@ Example_Images::Example_Images()
 
   /* Image */
 
-  auto pVBox = Gtk::manage(new Gtk::Box(Gtk::Orientation::VERTICAL, 8));
+  auto pVBox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 8);
   m_HBox.pack_start(*pVBox, Gtk::PackOptions::SHRINK);
 
   m_Label_Image.set_markup("<u>Image loaded from a file</u>");
@@ -88,7 +88,7 @@ Example_Images::Example_Images()
   m_Frame_Image.set_valign(Gtk::Align::CENTER);
   pVBox->pack_start(m_Frame_Image, Gtk::PackOptions::SHRINK);
 
-  auto pImage = Gtk::manage(new Gtk::Image());
+  auto pImage = Gtk::make_managed<Gtk::Image>();
   pImage->set_from_icon_name("gtk3-demo");
   pImage->set_icon_size(Gtk::IconSize::LARGE);
   m_Frame_Image.add(*pImage);
@@ -103,7 +103,7 @@ Example_Images::Example_Images()
   m_Frame_Animation.set_valign(Gtk::Align::CENTER);
   pVBox->pack_start(m_Frame_Animation, Gtk::PackOptions::SHRINK);
 
-  auto pPicture = Gtk::manage(new Gtk::Picture());
+  auto pPicture = Gtk::make_managed<Gtk::Picture>();
   pPicture->set_resource("/images/floppybuddy.gif");
   m_Frame_Animation.add(*pPicture);
 
@@ -118,13 +118,13 @@ Example_Images::Example_Images()
   pVBox->pack_start(m_Frame_ThemedIcon, Gtk::PackOptions::SHRINK);
 
   auto icon = Gio::ThemedIcon::create("battery-caution-charging-symbolic", true);
-  pImage = Gtk::manage(new Gtk::Image(icon));
+  pImage = Gtk::make_managed<Gtk::Image>(icon);
   pImage->set_icon_size(Gtk::IconSize::LARGE);
   m_Frame_ThemedIcon.add(*pImage);
 
   /* Progressive */
 
-  pVBox = Gtk::manage(new Gtk::Box(Gtk::Orientation::VERTICAL, 8));
+  pVBox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 8);
   m_HBox.pack_start(*pVBox, Gtk::PackOptions::SHRINK);
 
   m_Label_Progressive.set_markup("<u>Progressive image loading</u>");
@@ -152,20 +152,20 @@ Example_Images::Example_Images()
   m_Frame_Video.set_valign(Gtk::Align::CENTER);
   pVBox->pack_start(m_Frame_Video, Gtk::PackOptions::SHRINK);
 
-  auto video = Gtk::manage(new Gtk::Video());
+  auto video = Gtk::make_managed<Gtk::Video>();
   video->set_resource("/images/gtk-logo.webm");
   video->get_media_stream()->set_loop();
   m_Frame_Video.add(*video);
 
   /* Widget paintable */
 
-  pVBox = Gtk::manage(new Gtk::Box(Gtk::Orientation::VERTICAL, 8));
+  pVBox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 8);
   m_HBox.pack_start(*pVBox, Gtk::PackOptions::SHRINK);
 
   m_Label_Paintable.set_markup("<u>Gtk::WidgetPaintable</u>");
   pVBox->pack_start(m_Label_Paintable, Gtk::PackOptions::SHRINK);
 
-  pPicture = Gtk::manage(new Gtk::Picture());
+  pPicture = Gtk::make_managed<Gtk::Picture>();
   auto demo_window = DemoWindow::get_demo_window();
   if (demo_window)
   {
diff --git a/demos/gtk-demo/example_menus.cc b/demos/gtk-demo/example_menus.cc
index e2c757fe..9524fbea 100644
--- a/demos/gtk-demo/example_menus.cc
+++ b/demos/gtk-demo/example_menus.cc
@@ -66,17 +66,17 @@ Example_Menus::Example_Menus()
 
   {
     //Note:: It's generally easier to use the Gtk::Builder API.
-    auto pMenuItem = Gtk::manage(new Gtk::MenuItem("test\nline2"));
+    auto pMenuItem = Gtk::make_managed<Gtk::MenuItem>("test\nline2");
     pMenuItem->set_submenu( *(create_menu(2)) );
     m_MenuBar.append(*pMenuItem);
     pMenuItem->show();
 
-    pMenuItem = Gtk::manage(new Gtk::MenuItem("foo"));
+    pMenuItem = Gtk::make_managed<Gtk::MenuItem>("foo");
     pMenuItem->set_submenu( *(create_menu(3)) );
     m_MenuBar.append(*pMenuItem);
     pMenuItem->show();
 
-    pMenuItem = Gtk::manage(new Gtk::MenuItem("bar"));
+    pMenuItem = Gtk::make_managed<Gtk::MenuItem>("bar");
     pMenuItem->set_submenu( *(create_menu(4)) );
     m_MenuBar.append(*pMenuItem);
     pMenuItem->show();
@@ -92,16 +92,16 @@ Example_Menus::Example_Menus()
     auto pMenu = create_menu(1);
     pMenu->set_accel_group(accel_group);
 
-    Gtk::MenuItem* pMenuItem = Gtk::manage(new Gtk::SeparatorMenuItem());
+    Gtk::MenuItem* pMenuItem = Gtk::make_managed<Gtk::SeparatorMenuItem>();
     pMenu->append(*pMenuItem);
     pMenuItem->show();
 
-    pMenuItem = Gtk::manage(new Gtk::MenuItem("accel"));
+    pMenuItem = Gtk::make_managed<Gtk::MenuItem>("accel");
     pMenuItem->set_submenu(*pMenu);
     m_MenuBar.append(*pMenuItem);
     pMenuItem->show();
 
-    pMenuItem = Gtk::manage(new Gtk::CheckMenuItem("Accelerate Me"));
+    pMenuItem = Gtk::make_managed<Gtk::CheckMenuItem>("Accelerate Me");
     pMenuItem->add_accelerator("activate", accel_group, GDK_KEY_F1,
       Gdk::ModifierType(0), Gtk::AccelFlags::VISIBLE);
     pMenu->append(*pMenuItem);
@@ -109,7 +109,7 @@ Example_Menus::Example_Menus()
     pMenuItem->signal_activate().connect(
       sigc::bind(sigc::mem_fun(*this, &Example_Menus::on_item_activated), "F1"));
 
-    pMenuItem = Gtk::manage(new Gtk::CheckMenuItem("Accelerator Locked"));
+    pMenuItem = Gtk::make_managed<Gtk::CheckMenuItem>("Accelerator Locked");
     pMenu->append(*pMenuItem);
     pMenuItem->add_accelerator("activate", accel_group, GDK_KEY_F2,
       Gdk::ModifierType(0), Gtk::AccelFlags::VISIBLE | Gtk::AccelFlags::LOCKED);
@@ -117,7 +117,7 @@ Example_Menus::Example_Menus()
     pMenuItem->signal_activate().connect(
       sigc::bind(sigc::mem_fun(*this, &Example_Menus::on_item_activated), "F2"));
 
-    pMenuItem = Gtk::manage(new Gtk::CheckMenuItem("Accelerator Frozen"));
+    pMenuItem = Gtk::make_managed<Gtk::CheckMenuItem>("Accelerator Frozen");
     pMenu->append(*pMenuItem);
     pMenuItem->add_accelerator("activate", accel_group, GDK_KEY_F3,
       Gdk::ModifierType(0), Gtk::AccelFlags::VISIBLE);
@@ -149,7 +149,7 @@ Gtk::Menu* Example_Menus::create_menu(gint depth)
   if (depth < 1)
     return nullptr;
 
-  auto pMenu = Gtk::manage(new Gtk::Menu());
+  auto pMenu = Gtk::make_managed<Gtk::Menu>();
 
   {
     Gtk::RadioMenuItem::Group radiogroup;
@@ -159,7 +159,7 @@ Gtk::Menu* Example_Menus::create_menu(gint depth)
       char buf[32];
       sprintf(buf, "item %2d - %d", depth, j);
 
-      auto pMenuItem = Gtk::manage(new Gtk::RadioMenuItem(radiogroup, buf));
+      auto pMenuItem = Gtk::make_managed<Gtk::RadioMenuItem>(radiogroup, buf);
       pMenu->append(*pMenuItem);
       pMenuItem->show();
 
diff --git a/demos/gtk-demo/example_panes.cc b/demos/gtk-demo/example_panes.cc
index c38c41c8..ffdf2f12 100644
--- a/demos/gtk-demo/example_panes.cc
+++ b/demos/gtk-demo/example_panes.cc
@@ -62,7 +62,7 @@ Example_Panes::Example_Panes()
   pHPaned->add1(*Gtk::manage(pFrame1));
   pFrame1->set_shadow_type(Gtk::ShadowType::IN);
   pFrame1->set_size_request(60, 60);
-  pFrame1->add(*Gtk::manage(new Gtk::Button("_Hi there", true)));
+  pFrame1->add(*Gtk::make_managed<Gtk::Button>("_Hi there", true));
 
   Gtk::Frame *const pFrame2 = new Gtk::Frame();
   pHPaned->add2(*Gtk::manage(pFrame2));
@@ -75,8 +75,8 @@ Example_Panes::Example_Panes()
   pFrame3->set_size_request(60, 80);
 
   // Now create check buttons to control sizing
-  pVBox->pack_start(*Gtk::manage(new PaneOptions(*pHPaned, "Horizontal", "Left", "Right")), 
Gtk::PackOptions::SHRINK);
-  pVBox->pack_start(*Gtk::manage(new PaneOptions(*pVPaned, "Vertical", "Top", "Bottom")),   
Gtk::PackOptions::SHRINK);
+  pVBox->pack_start(*Gtk::make_managed<PaneOptions>(*pHPaned, "Horizontal", "Left", "Right"), 
Gtk::PackOptions::SHRINK);
+  pVBox->pack_start(*Gtk::make_managed<PaneOptions>(*pVPaned, "Vertical", "Top", "Bottom"),   
Gtk::PackOptions::SHRINK);
 }
 
 Example_Panes::~Example_Panes()
@@ -97,8 +97,8 @@ PaneOptions::PaneOptions(Gtk::Paned& paned, const Glib::ustring& frame_label,
   pGrid->property_margin() = 4;
   add(*Gtk::manage(pGrid));
 
-  pGrid->attach(*Gtk::manage(new Gtk::Label(label1)), 0, 0, 1, 1);
-  pGrid->attach(*Gtk::manage(new Gtk::Label(label2)), 1, 0, 1, 1);
+  pGrid->attach(*Gtk::make_managed<Gtk::Label>(label1), 0, 0, 1, 1);
+  pGrid->attach(*Gtk::make_managed<Gtk::Label>(label2), 1, 0, 1, 1);
 
   pGrid->attach(m_CheckButton_resize1, 0, 1, 1, 1);
   pGrid->attach(m_CheckButton_shrink1, 0, 2, 1, 1);
diff --git a/demos/gtk-demo/example_sizegroup.cc b/demos/gtk-demo/example_sizegroup.cc
index 6254304e..1802115f 100644
--- a/demos/gtk-demo/example_sizegroup.cc
+++ b/demos/gtk-demo/example_sizegroup.cc
@@ -131,7 +131,7 @@ void Example_SizeGroup::add_row(Gtk::Grid& grid, int row,
                                 const Glib::ustring& label_text,
                                 const std::list<Glib::ustring>& options)
 {
-  auto pLabel = Gtk::manage(new Gtk::Label(label_text, Gtk::Align::START, Gtk::Align::END, true));
+  auto pLabel = Gtk::make_managed<Gtk::Label>(label_text, Gtk::Align::START, Gtk::Align::END, true);
 
   grid.attach(*pLabel, 0, row, 1, 1);
   pLabel->set_hexpand();
@@ -147,7 +147,7 @@ void Example_SizeGroup::add_row(Gtk::Grid& grid, int row,
  */
 Gtk::ComboBoxText* Example_SizeGroup::create_combobox(const std::list<Glib::ustring>& strings)
 {
-  auto pCombo = Gtk::manage( new Gtk::ComboBoxText() );
+  auto pCombo = Gtk::make_managed<Gtk::ComboBoxText>();
 
   for(const auto& str : strings)
   {
diff --git a/demos/gtk-demo/example_stacksidebar.cc b/demos/gtk-demo/example_stacksidebar.cc
index 6a05c1cb..4322dcef 100644
--- a/demos/gtk-demo/example_stacksidebar.cc
+++ b/demos/gtk-demo/example_stacksidebar.cc
@@ -64,14 +64,14 @@ Example_StackSidebar::Example_StackSidebar()
     Gtk::Widget* widget = nullptr;
     if (i == 0)
     {
-      auto image = Gtk::manage(new Gtk::Image());
+      auto image = Gtk::make_managed<Gtk::Image>();
       image->set_from_icon_name("help-about");
       image->set_pixel_size(256);
       widget = image;
     }
     else
     {
-      widget = Gtk::manage(new Gtk::Label(m_page_names[i]));
+      widget = Gtk::make_managed<Gtk::Label>(m_page_names[i]);
     }
     m_Stack.add(*widget, m_page_names[i], m_page_names[i]);
   }
diff --git a/demos/gtk-demo/example_textview.cc b/demos/gtk-demo/example_textview.cc
index 1ef7585d..268e3477 100644
--- a/demos/gtk-demo/example_textview.cc
+++ b/demos/gtk-demo/example_textview.cc
@@ -76,7 +76,7 @@ Example_TextView::Example_TextView()
    * a view widget.
    */
   auto refBuffer = m_View1.get_buffer();
-  m_pView2 = Gtk::manage( new Gtk::TextView(refBuffer) );
+  m_pView2 = Gtk::make_managed<Gtk::TextView>(refBuffer);
 
   m_ScrolledWindow1.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
   m_VPaned.add1(m_ScrolledWindow1);
@@ -385,13 +385,13 @@ void Example_TextView::attach_widgets(Gtk::TextView& text_view)
     Gtk::Widget* pWidget = nullptr;
     if (i == 0)
     {
-      auto pButton = Gtk::manage( new Gtk::Button("Click Me") );
+      auto pButton = Gtk::make_managed<Gtk::Button>("Click Me");
       pButton->signal_clicked().connect(sigc::mem_fun(*this, &Example_TextView::on_button_clicked));
       pWidget = pButton;
     }
     else if (i == 1)
     {
-      auto pCombo = Gtk::manage( new Gtk::ComboBoxText() );
+      auto pCombo = Gtk::make_managed<Gtk::ComboBoxText>();
       pCombo->append("Option 1");
       pCombo->append("Option 2");
       pCombo->append("Option 3");
@@ -400,7 +400,7 @@ void Example_TextView::attach_widgets(Gtk::TextView& text_view)
     }
     else if (i == 2)
     {
-      auto pHScale = Gtk::manage( new Gtk::Scale(Gtk::Orientation::HORIZONTAL) );
+      auto pHScale = Gtk::make_managed<Gtk::Scale>(Gtk::Orientation::HORIZONTAL);
       pHScale->set_range(0, 100);
       pHScale->set_size_request(70, -1);
 
@@ -408,13 +408,13 @@ void Example_TextView::attach_widgets(Gtk::TextView& text_view)
     }
     else if (i == 3)
       {
-        auto pImage = Gtk::manage( new Gtk::Image() );
+        auto pImage = Gtk::make_managed<Gtk::Image>();
         pImage->set_from_resource("/textview/floppybuddy.gif");
         pWidget = pImage;
       }
     else if (i == 4)
     {
-      pWidget = Gtk::manage( new Gtk::Entry() );
+      pWidget = Gtk::make_managed<Gtk::Entry>();
     }
     else
     {
@@ -447,7 +447,7 @@ Window_EasterEgg::Window_EasterEgg()
   auto refAnchor = refBuffer->create_child_anchor(iter);
   refBuffer->insert(refBuffer->end(), "\nDon't do this in real applications, please.\n");
 
-  m_pTextView = Gtk::manage( new Gtk::TextView(refBuffer) );
+  m_pTextView = Gtk::make_managed<Gtk::TextView>(refBuffer);
 
   recursive_attach_view(0, *m_pTextView, refAnchor);
 
@@ -467,10 +467,10 @@ void Window_EasterEgg::recursive_attach_view(int depth, Gtk::TextView& view, Gli
   if (depth > 4)
     return;
 
-  auto pChildView = Gtk::manage( new Gtk::TextView(view.get_buffer()));
+  auto pChildView = Gtk::make_managed<Gtk::TextView(view.get_buffer>());
 
   /* Frame is to add a black border around each child view */
-  auto pFrame = Gtk::manage( new Gtk::Frame());
+  auto pFrame = Gtk::make_managed<Gtk::Frame>();
 
   pFrame->add(*pChildView);
 
diff --git a/demos/gtk-demo/example_treeview_editable_cells.cc 
b/demos/gtk-demo/example_treeview_editable_cells.cc
index 90b0294b..c6a4a7d5 100644
--- a/demos/gtk-demo/example_treeview_editable_cells.cc
+++ b/demos/gtk-demo/example_treeview_editable_cells.cc
@@ -249,7 +249,7 @@ void Example_TreeView_EditableCells::add_columns()
 
   //And this is the way that works with the IRIX MipsPro compiler too:
   {
-    auto pViewColumn = Gtk::manage(new Gtk::TreeView::Column("Number", m_columns.number));
+    auto pViewColumn = Gtk::make_managed<Gtk::TreeView::Column>("Number", m_columns.number);
 
     //connect signal handlers for auto-storing of edited cell data
     auto pCellRenderer = pViewColumn->get_first_cell();
@@ -267,7 +267,7 @@ void Example_TreeView_EditableCells::add_columns()
   }
 
   {
-    auto pViewColumn = Gtk::manage(new Gtk::TreeView::Column("Product", m_columns.product));
+    auto pViewColumn = Gtk::make_managed<Gtk::TreeView::Column>("Product", m_columns.product);
 
     //connect signal handlers for auto-storing of edited cell data
     auto pCellRenderer = pViewColumn->get_first_cell();
diff --git a/gtk/gtkmm/object.h b/gtk/gtkmm/object.h
index a818d407..8ef4788f 100644
--- a/gtk/gtkmm/object.h
+++ b/gtk/gtkmm/object.h
@@ -22,6 +22,8 @@
 #include <gtkmm/base.h>
 #include <gtkmmconfig.h>
 
+#include <utility>
+
 namespace Gtk
 {
 
@@ -44,6 +46,25 @@ T* manage(T* obj)
   return obj;
 }
 
+/** Create a Gtk::Object such as a widget and Gtk::manage() it in a single step.
+ * This matches standard functions like std::make_unique<T>(args) and avoids you
+ * manually invoking the new operator, which is discouraged in modern C++ style.
+ *
+ * For instance,
+ * @code
+ * auto button = Gtk::make_managed<Gtk::Button>("Hello");
+ * vbox.pack_start(*button); //vbox will delete button when vbox is deleted.
+ * @endcode
+ *
+ * @param args Arguments to pass to the constructor of the given template type.
+ * @result A new, managed object of that type, constructed with those arguments.
+ */
+template<class T, class... T_Args>
+auto make_managed(T_Args&&... args)
+{
+  return manage(new T(std::forward<T_Args>(args)...));
+}
+
 /** %Gtk::Object is the base class for all widgets, and for a few non-widget objects
  * such as Gtk::CellRenderer.
  *
diff --git a/tests/child_widget_managed/main.cc b/tests/child_widget_managed/main.cc
index bd81aca6..ae795d63 100644
--- a/tests/child_widget_managed/main.cc
+++ b/tests/child_widget_managed/main.cc
@@ -31,7 +31,7 @@ ExampleWindow::ExampleWindow()
 {
     set_default_size(150, 150);
 
-    m_button = manage(new MyButton);
+    m_button = Gtk::make_managed<MyButton>();
     add(*m_button);
 }
 
diff --git a/tests/delete_cpp_child/main.cc b/tests/delete_cpp_child/main.cc
index 199c75cd..3a665124 100644
--- a/tests/delete_cpp_child/main.cc
+++ b/tests/delete_cpp_child/main.cc
@@ -19,15 +19,13 @@ private:
 AppWindow::AppWindow()
     : m_label (nullptr)
 {
-    Gtk::Box* vbox = Gtk::manage(new Gtk::Box (Gtk::Orientation::VERTICAL, 5));
+    auto vbox = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, 5);
     add(*vbox);
 
-    Gtk::Button* button = Gtk::manage(new Gtk::Button("Delete Label"));
-
+    auto button = Gtk::make_managed<Gtk::Button>("Delete Label");
     vbox->pack_start(*button, Gtk::PackOptions::SHRINK);
 
-
-    //m_label = manage (new Gtk::Label ("test"));
+    //m_label = Gtk::make_managed<Gtk::Label>("test");
     m_label = new Gtk::Label("test");
     g_warning("m_label -> ref_count: %d\n", G_OBJECT(m_label->gobj())->ref_count);
     vbox->pack_start(*m_label, Gtk::PackOptions::SHRINK);
diff --git a/tests/dialog_deletethis/main.cc b/tests/dialog_deletethis/main.cc
index 7e542b7e..41e66b3a 100644
--- a/tests/dialog_deletethis/main.cc
+++ b/tests/dialog_deletethis/main.cc
@@ -10,7 +10,7 @@ class Dlg : public sigc::trackable
     Dlg()
     {
       dlg_ = new Gtk::Dialog("Test Dialog");
-      Gtk::Button *btn = manage(new Gtk::Button("ClickMe"));
+      auto btn = Gtk::make_managed<Gtk::Button>("ClickMe");
       btn->signal_clicked().connect(sigc::mem_fun(*this, &Dlg::on_button_clicked));
       dlg_->get_content_area()->pack_start(*btn, Gtk::PackOptions::EXPAND_WIDGET);
       dlg_->add_button("_OK", Gtk::ResponseType::OK);


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