/// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "spinner.h" #include class UnitAdjustment: public Gtk::Adjustment { public: UnitAdjustment(double value, double lower, double upper, double step_increment = 1, double page_increment = 10, double page_size = 0) : Adjustment(value, lower, upper, step_increment, page_increment, page_size), factor(1), low(lower), upp(upper) {} void set_factor(double _factor = 1) { double val = get_real_value(); factor = _factor; set_lower(low); set_upper(upp); set_value(val); } void set_value(double value) { Adjustment::set_value(value / factor); } double get_real_value() const {return get_value() * factor;} void set_lower(double lower) { low = lower; Adjustment::set_lower(lower / factor); } double get_real_lower() const {return low;} void set_upper(double upper) { upp = upper; Adjustment::set_upper(upper / factor); } double get_real_upper() const {return upp;} private: double factor, low, upp; }; Spinner::Spinner(const float _value, bool allow_float, const FUUnits *_units, const Glib::ustring &default_unit, const float _lo_value, const float _hi_value) : value(new UnitAdjustment(_value, _lo_value, _hi_value)), units(_units) { spinbutton = manage(new Gtk::SpinButton(*value, 0, allow_float ? 2 : 0)); spinbutton->set_numeric(false); spinbutton->set_activates_default(); if(!allow_float) spinbutton->set_snap_to_ticks(true); pack_start(*spinbutton); if(units) { // only add menu if we have units for it unitmenu = manage(new Gtk::ComboBoxText()); FUUnits::UnitList list = units->list_units(); Glib::ustring selected_unit = units->get_base_unit(); // use default unit, if given if(!default_unit.empty()) { try { // if the default unit is not the base unit, then the conversion // factor needs to be changed from 1 value->set_factor(units->get_factor(default_unit)); selected_unit = default_unit; // after get_factor(), in case it // throws unknown_unit_error } catch(const unknown_unit_error&) { } } int i = 0; for(FUUnits::UnitList::const_iterator unit = list.begin(); unit != list.end(); unit++, i++) { unitmenu->append_text(*unit); if(*unit == selected_unit) unitmenu->set_active(i); } unitmenu->signal_changed().connect (sigc::mem_fun(*this, &Spinner::on_unit_select)); // unitmenu->set_size_request(-1, spinbutton->get_height()); pack_start(*unitmenu); } // if(units) show_all(); } Spinner::~Spinner() {} void Spinner::limits(float low, float high) { value->set_lower(low); value->set_upper(high); } void Spinner::set(float _value) { value->set_value(_value); } float Spinner::get() const { return value->get_real_value(); } Glib::SignalProxy0 Spinner::signal_value_changed() { return value->signal_value_changed(); } bool Spinner::on_mnemonic_activate(bool group_cycling) { // Not much documented in gtkmm, but it seems this metod gets called when // this widget is activated (by a mnemonic e.g. from a label) so I can put // focus on the proper part of the widget. spinbutton->grab_focus(); return true; } void Spinner::on_unit_select() { value->set_factor(units->get_factor(unitmenu->get_active_text())); }