Re: [gtkmm] filter or validate
- From: Roger Leigh <roger whinlatter uklinux net>
- To: gtkmm-list gnome org
- Subject: Re: [gtkmm] filter or validate
- Date: Sat, 22 May 2004 12:06:48 +0100
Eduardo Andrés Mizerit <eamlinux yahoo com ar> writes:
> I would setup a Gtk::Entry widget such that it only accepts numerical
> characters and drops any other characters.
> I need an example about it.
Easy ;-)
Here's one I prepared earlier. I'm sure you could adapt it to your
needs.
Validation is immediate, but if you use on_activated() and
on_focus_out_event() rather than on_changed() this could be deferred.
It's a template, so can be used with any numeric type. For example:
// integer entry for numbers between 0 and 10, defaulting to 1
NumericEntry<int> int_entry(1,0,10);
// double precision floating point entry, with the whole range of
// double
NumericEntry<double> double_entry(0.0);
It can also be used with Glade/libglade and get_widget_derived():
Glib::RefPtr<Gnome::Glade::Xml> xml = ...
NumericEntry<long> *entry;
xml->get_widget_derived("entry_name", *entry);
// numeric entry widget -*- C++ -*-
// $Id: numericentry.h,v 1.2 2003/12/14 16:14:54 roger Exp $
//
// Copyright (C) 2003 Roger Leigh.
//
// Authors: Roger Leigh <rleigh debian org>
//
//
// 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////
#ifndef GTKMM_RLEXTRA_NUMERICENTRY_H
#define GTKMM_RLEXTRA_NUMERICENTRY_H
#include <limits>
#include <sstream>
#include <gtkmm/entry.h>
#include <libglademm/xml.h>
namespace Gtkmm
{
/**
* Entry widget for numeric values.
*
* This widget may be used for entering numberic values. Unlike
* Gtk::SpinButton, this widget does not have spinbuttons. Being a
* template class, it may be used to enter values for any numeric
* data type, for example int, long, double or any numeric classes
* that behave like numbers (they must be Assignable and
* comparable).
*
* This widget requires that minumum and maximum limits are set, so
* that values outside these bounds can not be entered. If
* unspecified, these values default to those obtainable through
* std::numeric_limits<>.
*
* Future enhancements will include validation through regular
* expressions, and specifying the range of precision allowed.
*/
template<typename _Number>
class NumericEntry : public Gtk::Entry
{
public:
/**
* The constructor.
* @param value the initial value of the number displayed.
* @param min the minimum value allowed.
* @param max the maxumum value allowed.
*/
NumericEntry(_Number value,
_Number min = std::numeric_limits<_Number>::min(),
_Number max = std::numeric_limits<_Number>::max()):
m_error(false),
m_min(min),
m_max(max)
{
set_value(value);
}
/**
* Constructor for initialisation from a Glade interface description.
* @param cobject the GTK+ C object.
* @param xml_interface the Glade XML interface.
*/
explicit NumericEntry(BaseObjectType* cobject,
const Glib::RefPtr<Gnome::Glade::Xml>& xml_interface):
Gtk::Entry(cobject),
m_error(false),
m_min(std::numeric_limits<_Number>::min()),
m_max(std::numeric_limits<_Number>::max())
{}
/// The destructor.
virtual ~NumericEntry()
{}
/**
* Check if an error has occured.
* An error occurs when an invalid number has been entered (for
* example, out of bounds). In this situation, get_value() may
* not return an accurate or meaningful result.
* @returns true if in an error state, or false if no error.
*/
bool error() const
{
return m_error;
}
/**
* Get the value of the number in the entry.
* Make sure to check the error status with error() before calling
* this method.
* @returns the current value of the entry.
*/
_Number get_value() const
{
std::istringstream input(get_text());
_Number ret;
input >> ret;
return ret;
}
private:
/**
* Check if the number is within the specified bounds. If outside
* the bounds, clip to the appropriate limit.
*/
void check_bounds(_Number& value)
{
if (value < m_min)
value = m_min;
if (value > m_max)
value = m_max;
}
public:
/**
* Set the value of the number in the entry.
* The value will be clipped to the specified bounds, if necessary.
* @param value the value to set.
*/
void set_value(_Number value)
{
check_bounds(value);
std::ostringstream output;
output << value;
set_text(output.str());
}
/**
* Get the maximum value allowed.
* @returns the maximum value.
*/
_Number get_max() const
{
return m_max;
}
/**
* Set the maximum value allowed.
* The minimum and current value will be clipped if necessary.
* @param value the maximum value.
*/
void set_max(_Number value)
{
if (value < m_min)
m_min = value;
m_max = value;
_Number num = get_value();
check_bounds(num);
set_value(num);
}
/**
* Get the minimum value allowed.
* @returns the minimum value.
*/
_Number get_min() const
{
return m_min;
}
/**
* Set the minimum value allowed.
* The maximum and current value will be clipped if necessary.
* @param value the minimum value.
*/
void set_min(_Number value)
{
if (value > m_max)
m_max = value;
m_min = value;
_Number num = get_value();
check_bounds(num);
set_value(num);
}
/// Signal hander run when the entry has changed.
virtual void on_changed()
{
m_error = false;
// Filter out all characters except +-.,0123456789
Glib::ustring orig = get_text();
Glib::ustring stripped;
Glib::ustring::iterator cur;
for (cur = orig.begin();
cur != orig.end();
++cur)
{
if ((*cur >= '0' && *cur <= '9') ||
*cur == '+' || *cur == '-' ||
*cur == '.' || *cur == ',')
stripped += *cur;
}
if (orig.compare(stripped) != 0)
set_text(stripped);
std::istringstream input(get_text());
_Number number;
input >> number;
if (input.fail())
m_error = true;
else
if (number < m_min || number > m_max)
m_error = true;
if (m_error == true)
modify_base(Gtk::STATE_NORMAL, Gdk::Color("red"));
else
modify_base(Gtk::STATE_NORMAL, Gdk::Color(NULL));
}
protected:
/// Error status.
bool m_error;
/// Minimum value.
_Number m_min;
/// Maximum value.
_Number m_max;
}; // class NumericEntry
}; // namespace Gtkmm
#endif // GTKMM_RLEXTRA_NUMERICENTRY_H
--
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]