Logo Search packages:      
Sourcecode: passepartout version File versions  Download package

spinner.cc

///
// Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING
///
#include "spinner.h"
#include <gtkmm/adjustment.h>

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
    menu = manage(new Gtk::Menu());
    using namespace Gtk::Menu_Helpers;
    MenuList& menu_list = menu->items();
    FUUnits::UnitList list = units->list_units();

    Glib::ustring top_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));
      top_unit = default_unit;  // after get_factor(), in case it
                          // throws unknown_unit_error
      }
      catch(const unknown_unit_error&) {
      }
    }

    // putting the top unit first makes it the default
    menu_list.push_back(MenuElem(top_unit)); 
    for(FUUnits::UnitList::const_iterator 
        i = list.begin(); i != list.end(); i++) {
      if(*i != top_unit)  // don't add top unit twice
      menu_list.push_back(MenuElem(*i));
    }

    optionmenu = manage(new Gtk::OptionMenu());
    optionmenu->set_menu(*menu);
    menu->signal_selection_done().connect
      (slot(*this, &Spinner::on_unit_select));

    optionmenu->set_size_request(-1, spinbutton->get_height());
    pack_start(*optionmenu);
  } // if(units)

  show_all();
}

Spinner::~Spinner() { delete value; }

void Spinner::limits(float low, float high) {
  value->set_lower(low);
  value->set_upper(high);
}

void Spinner::set_unit(const Glib::ustring &unit) {
  Gtk::Menu_Helpers::MenuList::const_iterator i = menu->items().begin();
  while (i != menu->items().end()) {
    const Gtk::Label *label = dynamic_cast<const Gtk::Label*>(i->get_child());
    if(label && (label->get_text() == unit))
      i->select();
  }
}

void Spinner::set(float _value) { 
  value->set_value(_value);
}

float Spinner::get() const {
  return value->get_real_value();
}

Glib::SignalProxy0<void> Spinner::signal_value_changed() {
  return value->signal_value_changed();
}

00123 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() {
  const Gtk::Label *label = 
    dynamic_cast<const Gtk::Label*>(optionmenu->get_child());
  if(!label)
    return;
  if(units) {
    try {
      value->set_factor(units->get_factor(label->get_text()));
    } catch(const unknown_unit_error&) {}
  }
}



Generated by  Doxygen 1.6.0   Back to index