// Generated by gmmproc 2.86.0 -- DO NOT MODIFY!
#ifndef _GDKMM_GRAPHENE_RECT_H
#define _GDKMM_GRAPHENE_RECT_H

#include <gdkmmconfig.h>


#include <glibmm/ustring.h>
#include <sigc++/sigc++.h>

/* Copyright (C) 2023 The gtkmm Development Team
 *
 * 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */
 
#include <gdkmm/graphene_point.h>
#include <gdkmm/graphene_size.h>
#include <gdkmm/graphene_vec2.h>
#include <array>
#include <optional>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
extern "C"
{
struct _graphene_rect_t;
using graphene_rect_t = _graphene_rect_t;
}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

namespace Gdk
{
/** Types for graphic libraries.
 *
 * Namespace %Gdk::Graphene contains C++ bindings of part of the
 * [Graphene](https://github.com/ebassi/graphene) library.
 * It contains classes and class members that are useful in Gtkmm.
 * It does not aim at being a complete C++ binding of %Graphene.
 */
namespace Graphene
{
//TODO: When we can break ABI, _CLASS_OPAQUE_COPYABLE -> _CLASS_GENERIC.
// graphene_rect_t gobject_; //Not a pointer.
// https://gitlab.gnome.org/GNOME/gtkmm/-/issues/155

/** The location and size of a rectangle region.
 *
 * The width and height of a %Gdk::Graphene::Rect can be negative; for instance,
 * a %Gdk::Graphene::Rect with an origin of [ 0, 0 ] and a size of [ 10, 10 ] is
 * equivalent to a %Gdk::Graphene::Rect with an origin of [ 10, 10 ] and a size
 * of [ -10, -10 ].
 *
 * Application code can normalize rectangles using normalize();
 * this function will ensure that the width and height of a rectangle are
 * positive values. All functions taking a %Gdk::Graphene::Rect as an argument
 * will internally operate on a normalized copy; all functions returning a
 * %Gdk::Graphene::Rect will always return a normalized rectangle.
 *
 * @newin{4,12}
 */
class GDKMM_API Rect
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  using CppObjectType = Rect;
  using BaseObjectType = graphene_rect_t;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  /** Constructs an invalid object.
   * E.g. for output arguments to methods. There is not much you can do with
   * the object before it has been assigned a valid value.
   */
  Rect();

  // Use make_a_copy=true when getting it directly from a struct.
  explicit Rect(graphene_rect_t* castitem, bool make_a_copy = false);

  Rect(const Rect& src);
  Rect& operator=(const Rect& src);

  Rect(Rect&& other) noexcept;
  Rect& operator=(Rect&& other) noexcept;

  ~Rect() noexcept;

  void swap(Rect& other) noexcept;

  graphene_rect_t*       gobj()       { return gobject_; }
  const graphene_rect_t* gobj() const { return gobject_; }

  ///Provides access to the underlying C instance. The caller is responsible for freeing it. Use when directly setting fields in structs.
  graphene_rect_t* gobj_copy() const;

protected:
  graphene_rect_t* gobject_;

private:

  
public:
  Rect(float x, float y, float width, float height);

  /** Checks if this instance is valid.
   * It is valid if and only if it contains a value.
   * For instance,
   * @code
   * if (rect)
   *   do_something()
   * @endcode
   */
  explicit operator bool() const;

 
  Point get_origin() const;
  void set_origin(const Point& value);
  Size get_size() const;
  void set_size(const Size& value);

  /** Retrieves the coordinates of the center of the given rectangle.
   */
  Point get_center() const;
  

  /** Retrieves the coordinates of the top-left corner of the given rectangle.
   */
  Point get_top_left() const;
  

  /** Retrieves the coordinates of the top-right corner of the given rectangle.
   */
  Point get_top_right() const;
  

  /** Retrieves the coordinates of the bottom-right corner of the given rectangle.
   */
  Point get_bottom_right() const;
  

  /** Retrieves the coordinates of the bottom-left corner of the given rectangle.
   */
  Point get_bottom_left() const;
  

  /** Computes the four vertices of this %Rect.
   *
   * @newin{4,24}
   *
   * @return Array of the 4 vertices.
   */
  std::array<Vec2,4> get_vertices() const;
  

  /** Checks whether the two given rectangle are equal.
   * 
   * @newin{4,12}
   * 
   * @param b A #graphene_rect_t.
   * @return `true` if the rectangles are equal.
   */
  bool equal(const Rect& b) const;
  
  /** Normalizes the passed rectangle.
   * 
   * This function ensures that the size of the rectangle is made of
   * positive values, and that the origin is the top-left corner of
   * the rectangle.
   * 
   * @newin{4,12}
   */
  void normalize();
  
  
  /** Retrieves the normalized X coordinate of the origin of the given
   * rectangle.
   * 
   * @newin{4,12}
   * 
   * @return The normalized X coordinate of the rectangle.
   */
  float get_x() const;
  
  /** Retrieves the normalized Y coordinate of the origin of the given
   * rectangle.
   * 
   * @newin{4,12}
   * 
   * @return The normalized Y coordinate of the rectangle.
   */
  float get_y() const;
  
  /** Retrieves the normalized width of the given rectangle.
   * 
   * @newin{4,12}
   * 
   * @return The normalized width of the rectangle.
   */
  float get_width() const;
  
  /** Retrieves the normalized height of the given rectangle.
   * 
   * @newin{4,12}
   * 
   * @return The normalized height of the rectangle.
   */
  float get_height() const;
  
  /** Compute the area of given normalized rectangle.
   * 
   * @newin{4,12}
   * 
   * @return The area of the normalized rectangle.
   */
  float get_area() const;

  // 'union' is a C and C++ keyword. Can't be a method name. (see also Gdk::Rectangle)
  /** Computes the union of the two rectangles.
   *
   * @newin{4,24}
   *
   * @param b A %Gdk::Graphene::Rect.
   * @return The union of this rectangle and @a b.
   */
  Rect join(const Rect& b) const;
  

  /** Computes the intersection of the two given rectangles.
   *
   * If the two rectangles do not intersect, no value is returned.
   *
   * @newin{4,24}
   *
   * @param b A %Gdk::Graphene::Rect.
   * @return The intersection of this rectangle and @a b, if any.
   */
  std::optional<Rect> intersection(const Rect& b) const;
  

  /** Checks whether a #graphene_rect_t contains the given coordinates.
   * 
   * @newin{4,12}
   * 
   * @param p A #graphene_point_t.
   * @return `true` if the rectangle contains the point.
   */
  bool contains_point(const Point& p) const;
  
  /** Checks whether a #graphene_rect_t fully contains the given
   * rectangle.
   * 
   * @newin{4,12}
   * 
   * @param b A #graphene_rect_t.
   * @return `true` if the rectangle @a a fully contains @a b.
   */
  bool contains_rect(const Rect& b) const;
  
  /** Offsets the origin by @a d_x and @a d_y.
   * 
   * The size of the rectangle is unchanged.
   * 
   * @newin{4,24}
   * 
   * @param d_x The horizontal offset.
   * @param d_y The vertical offset.
   */
  void offset(float d_x, float d_y);
  
  
  /** Changes the given rectangle to be smaller, or larger depending on the
   * given inset parameters.
   * 
   * To create an inset rectangle, use positive @a d_x or @a d_y values; to
   * create a larger, encompassing rectangle, use negative @a d_x or @a d_y
   * values.
   * 
   * The origin of the rectangle is offset by @a d_x and @a d_y, while the size
   * is adjusted by `(2 * @a d_x, 2 * @a d_y)`. If @a d_x and @a d_y are positive
   * values, the size of the rectangle is decreased; if @a d_x and @a d_y are
   * negative values, the size of the rectangle is increased.
   * 
   * If the size of the resulting inset rectangle has a negative width or
   * height then the size will be set to zero.
   * 
   * @newin{4,24}
   * 
   * @param d_x The horizontal inset.
   * @param d_y The vertical inset.
   */
  void inset(float d_x, float d_y);
  
  
  /** Rounds the origin of this rectangle to its nearest
   * integer value and recomputes the size so that the
   * rectangle is large enough to contain all the corners
   * of the original rectangle.
   *
   * This function is the equivalent of calling `floor` on
   * the coordinates of the origin, and recomputing the size
   * calling `ceil` on the bottom-right coordinates.
   *
   * If you want to be sure that the rounded rectangle
   * completely covers the area that was covered by the
   * original rectangle — i.e. you want to cover the area
   * including all its corners — this function will make sure
   * that the size is recomputed taking into account the ceiling
   * of the coordinates of the bottom-right corner.
   * If the difference between the original coordinates and the
   * coordinates of the rounded rectangle is greater than the
   * difference between the original size and the rounded
   * size, then the move of the origin would not be compensated
   * by a move in the anti-origin, leaving the corners of the
   * original rectangle outside the rounded one.
   *
   * @newin{4,24}
   *
   * @return The rectangle with rounded extents.
   */
  Rect round_extents() const;
  

  /** Linearly interpolates the origin and size of this rectangle and rectangle @a b.
   *
   * @newin{4,24}
   *
   * @param b A %Gdk::Graphene::Rect.
   * @param factor The linear interpolation factor.
   * @return The interpolated rectangle.
   */
  Rect interpolate(const Rect& b, double factor) const;
  

  /** Expands this rectangle to contain the given point.
   *
   * @newin{4,24}
   *
   * @param p A Gdk::Graphene::Point.
   * @return The expanded rectangle.
   */
  Rect expand(const Point& p) const;
  

  /** Scales the size and origin of this rectangle horizontally by @a s_h,
   * and vertically by @a s_v.
   *
   * @newin{4,24}
   *
   * @param s_h Horizontal scale factor.
   * @param s_v Vertical scale factor.
   * @return The scaled and normalized rectangle.
   */
  Rect scale(float s_h, float s_v) const;
  

};
} // namespace Graphene
} // namespace Gdk


namespace Gdk
{

namespace Graphene
{

/** @relates Gdk::Graphene::Rect
 * @param lhs The left-hand side
 * @param rhs The right-hand side
 */
inline void swap(Rect& lhs, Rect& rhs) noexcept
  { lhs.swap(rhs); }

} // namespace Graphene

} // namespace Gdk

namespace Glib
{

  /** A Glib::wrap() method for this object.
   *
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gdk::Graphene::Rect
   */
  GDKMM_API
  Gdk::Graphene::Rect wrap(graphene_rect_t* object, bool take_copy = false);

} // namespace Glib


#endif /* _GDKMM_GRAPHENE_RECT_H */

