/* Copyright (C) 2005 to 2011 and 2013 Chris Vine

The library comprised in this file or of which this file is part is
distributed by Chris Vine under the GNU Lesser General Public
License as follows:

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   as published by the Free Software Foundation; either version 2.1 of
   the License, or (at your option) any later version.

   This library 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
   Lesser General Public License, version 2.1, for more details.

   You should have received a copy of the GNU Lesser General Public
   License, version 2.1, along with this library (see the file LGPL.TXT
   which came with this source code package in the c++-gtk-utils
   sub-directory); if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*/

#ifndef CGU_WIDGET_H
#define CGU_WIDGET_H

#include <c++-gtk-utils/cgu_config.h>

#ifdef CGU_USE_GTK
#include <gtk/gtk.h>
#endif

namespace Cgu {

#if defined(DOXYGEN_PARSING) || defined(CGU_USE_GTK)

/**
 * @class MainWidgetBase widget.h c++-gtk-utils/widget.h
 * @brief This is a class to manage the lifetime of widgets which are
 * not top-level widgets (ie which are not derived from GtkWindow).
 * @sa WinBase GobjHandle
 *
 * Normally you will not need this class, because the GObject
 * reference counting system coupled with the WinBase class will
 * provide for lifetime management and exception safety, provided that
 * widgets are placed in their containers on a "top-down" basis and
 * the top-level window is managed by a WinBase object.
 *
 * However, sometimes it is convenient for a class to encapsulate only
 * part of the implementation of a top level window, and for there to
 * be automatic lifetime management of a widget before it is placed in
 * a GTK+ container.
 *
 * The MainWidgetBase class is intended to achieve this, by managing
 * references with g_object_ref_sink() such that the widget managed by
 * the class and its children are correctly destroyed when the
 * MainWidgetBase class goes out of scope or is deleted even if they
 * are not subsequently placed in another GTK+ container object which
 * calls g_object_ref_sink() on the widget.
 *
 * This class therefore represents a safety feature which can be used
 * simply by inheriting from it.  It also enables a widget to be
 * placed in and removed from a GTK+ container without it being
 * destroyed by the removal, since it is owned by the MainWidgetBase
 * class object.
 *
 * A similar effect could be achieved by managing a widget with
 * GobjHandle, but MainWidgetBase enables, by inheritance,
 * encapsulation of supplementary operations on the contained widget.
 *
 * See @ref Threading for particulars about GTK+ thread safety (and so
 * MainWidgetBase thread safety).
 *
 * MainWidgetBase objects can be used with widget heirarchies created
 * using GtkBuilder.  See @ref GtkBuilder for particulars about that.
 *
 * This class is not compiled into the library if the library is built
 * with the \--without-gtk configuration option.
 */

class MainWidgetBase {
  // main widget object
  GtkWidget* g_widget_p;

public:
  /**
   * Returns the GtkWidget object managed by this class.  This method
   * will not throw.
   * @return The managed GtkWidget object.
   */
  GtkWidget* get_main_widget() const {return g_widget_p;}

  /**
   * The constructor will not throw.  It calls g_object_ref_sink() to
   * take ownership of the object to be managed.
   * @param widget The GtkWidget object to be managed by this class.
   */
  MainWidgetBase(GtkWidget* widget);

/**
 * This class cannot be copied.  The copy constructor is deleted.
 */
  MainWidgetBase(const MainWidgetBase&) = delete;

/**
 * This class cannot be copied.  The copy assignment operator is
 * deleted.
 */
  MainWidgetBase& operator=(const MainWidgetBase&) = delete;

/**
 * The default constructor is deleted.  This class requires
 * initialisation with a GtkWidget object or to be moved to - it is
 * intended that a MainWidgetBase object will always be managing a
 * valid GtkWidget object unless it has been moved from and is
 * therefore awaiting destruction.
 */
  MainWidgetBase() = delete;

/**
 * The move constructor will not throw.
 *
 * @param obj The MainWidgetBase object to be moved.
 *
 * Since 2.0.19/2.2.2
 */
  MainWidgetBase(MainWidgetBase&& obj);

/**
 * The move assignment operator will not throw.  It will call
 * g_object_unref() on the previously managed GtkWidget object, if
 * any.
 *
 * @param obj The MainWidgetBase object to be moved.
 *
 * Since 2.0.19/2.2.2
 */
  MainWidgetBase& operator=(MainWidgetBase&& obj);

  /**
   * The destructor will not throw.  It calls g_object_unref() to
   * relinquish ownership of the managed object.
   */
  virtual ~MainWidgetBase();

/* Only has effect if --with-glib-memory-slices-compat or
 * --with-glib-memory-slices-no-compat option picked */
  CGU_GLIB_MEMORY_SLICES_FUNCS
};

#endif // CGU_USE_GTK

} // namespace Cgu

#endif // CGU_WIDGET_H
