/*
 * Copyright (C) 1998-2002 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <gtkmm/range.h>
_DEFS(gtkmm,gtk)

_PINCLUDE(gtkmm/private/range_p.h)

namespace Gtk
{

/** A slider widget for selecting a value from a range.
 *
 * A Gtk::Scale is a slider control used to select a numeric value. To use it,
 * you'll probably want to investigate the methods on its base class,
 * Gtk::Range, in addition to the methods for Gtk::Scale itself. To set the
 * value of a scale, you would normally use set_value(). To detect
 * changes to the value, you would normally use signal_value_changed().
 *
 * Note that using the same upper and lower bounds for the Scale (through
 * the Range methods) will hide the slider itself. This is useful for
 * applications that want to show an undeterminate value on the scale, without
 * changing the layout of the application (such as movie or music players).
 *
 * @ingroup Widgets
 */
class Scale : public Range
{
  _CLASS_GTKOBJECT(Scale,GtkScale,GTK_SCALE,Gtk::Range,GtkRange)
public:

  _CTOR_DEFAULT()

  /**
   * @newin{3,2}
   */
  explicit Scale(Orientation orientation);

  //Note that we try to use the same default parameter value as the default property value.
  explicit Scale(const Glib::RefPtr<Adjustment>& adjustment, Orientation orientation = ORIENTATION_HORIZONTAL);
  _IGNORE(gtk_scale_new)

  /** Set the number of decimal digits.
   *
   * This also causes the adjustment to be rounded off so the retrieved value
   * matches the value the user sees. Setting digits to 1 gives for example
   * 1.0, 2 gives 1.00, etc.
   */
  _WRAP_METHOD(void set_digits(int digits), gtk_scale_set_digits)

  /** Get the number of decimal digits.
   */
  _WRAP_METHOD(int get_digits() const, gtk_scale_get_digits)

  /** Set whether the current value is displayed as a string next to the slider.
   */
  _WRAP_METHOD(void set_draw_value(bool draw_value = true), gtk_scale_set_draw_value)

  /** Get whether the current value is displayed as a string next to the slider.
   */
  _WRAP_METHOD(bool get_draw_value() const, gtk_scale_get_draw_value)


  /** Set the position in which the value is displayed.
   */
  _WRAP_METHOD(void set_value_pos(PositionType pos), gtk_scale_set_value_pos)

  /** Get the position in which the value is displayed.
   */
  _WRAP_METHOD(PositionType get_value_pos() const, gtk_scale_get_value_pos)


  _WRAP_METHOD(void set_has_origin(bool has_origin = true), gtk_scale_set_has_origin)
  _WRAP_METHOD(bool get_has_origin() const, gtk_scale_get_has_origin)

  _WRAP_METHOD(Glib::RefPtr<Pango::Layout> get_layout(), gtk_scale_get_layout, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Pango::Layout> get_layout() const, gtk_scale_get_layout, refreturn, constversion)
  _WRAP_METHOD(void get_layout_offsets(int& x, int& y) const, gtk_scale_get_layout_offsets)

  _WRAP_METHOD(void add_mark(double value, PositionType position, const Glib::ustring& markup), gtk_scale_add_mark)
  _WRAP_METHOD(void clear_marks(), gtk_scale_clear_marks)

#m4 dnl// The ::format_value signal handler should return a newly allocated string.
#m4 dnl// (which is obviously not a const gchar*)
#m4 dnl// Also, ensure that format_value never returns an empty char[],
#m4 dnl// because that could be caused by an intermediate empty ustring from an initial null char*,
#m4 dnl//See bug http://bugzilla.gnome.org/show_bug.cgi?id=168747.
#m4 _CONVERSION(`Glib::ustring',`gchar*',`(strlen($3.c_str()) ? g_strdup($3.c_str()) : nullptr)')

  _WRAP_SIGNAL(Glib::ustring format_value(double value), "format_value")
  // TODO: When we can break ABI, this signal needs to be
  // Glib::ustring format_value(double value, bool& use_default_formatting),
  // where use_default_formatting specifies whether the return value will actually be a null char*.

  /** Number of displayed decimal digits.
   */
  _WRAP_PROPERTY("digits", int)

  /** Whether to draw the value as a string next to slider.
   */
  _WRAP_PROPERTY("draw-value", bool)

  /** The position in which the value is displayed.
   */
  _WRAP_PROPERTY("value-pos", PositionType)

  _WRAP_PROPERTY("has-origin", bool)

protected:

  _WRAP_VFUNC(void draw_value(), draw_value)

  virtual int calc_digits_(double step) const;
};

} //namespace Gtk
