I hooked up some signals to a few SpinButtons (one with double increments, the other two with float) and I'm getting some double-firings on the two float buttons, but not all the time.

The buttons are as follows:

  • double,
  • float with no extra precision, and
  • float with precision down to 1000ths.

The results when they're hooked up to the onValueChanged signal:

  • the double never double-fires (how's that for irony?),
  • the float with no extra precision always double-fires, and
  • the 1000ths float only double-fires as it's crossing a boundary of 3/1000ths in either direction.

With the onOutput signal:

  • double always double-fires,
  • float with no extra precision always double-fires except for the first time it's clicked, and
  • 1000ths float always double-fires.

When I say "double-fires" I mean that it reports the value before and after the value changes, so something like:

click:

  • 0.1
  • 0.2
    click:
  • 0.2
  • 0.3
    click:
  • 0.3
  • 0.4

Here's the code:

// SpinButton madness

import std.stdio;

import gtk.MainWindow;
import gtk.Main;
import gtk.Box;
import gtk.Widget;
import gtk.SpinButton;
import gtk.Adjustment;
import gtk.c.types;

void main(string[] args)
{
	Main.init(args);

	TestRigWindow myTestRig = new TestRigWindow("Test Rig with SpinButton");
	
	Main.run();
	
} // main()


class TestRigWindow : MainWindow
{
	AppBox appBox;
	
	this(string title)
	{
		super(title);
		addOnDestroy(&quitApp);
		
		appBox = new AppBox();
		add(appBox);
		
		showAll();

	} // this() CONSTRUCTOR
	
		
	void quitApp(Widget widget)
	{
		writeln("Bye.");
		Main.quit();
		
	} // quitApp()

} // class myAppWindow


class AppBox : Box
{
	DoubleSpinButton doubleSpinButton;
	FloatSpinButton floatSpinButton;
	PrecisionSpinButton precisionSpinButton;
		
	this()
	{
		super(Orientation.VERTICAL, 10);
		
		doubleSpinButton = new DoubleSpinButton();
		packStart(doubleSpinButton, false, false, 0);

		floatSpinButton = new FloatSpinButton();
		packStart(floatSpinButton, false, false, 0);

		precisionSpinButton = new PrecisionSpinButton();
		packStart(precisionSpinButton, false, false, 0);

	} // this()

} // class AppBox


class DoubleSpinButton : SpinButton
{
	double minimum = -48;
	double maximum = 48;
	double step = 2;

	Adjustment adjustment;
	double initialValue = 0;
	double pageIncrement = 8;
	double pageSize = 0;
	
	this()
	{
		super(minimum, maximum, step);

		adjustment = new Adjustment(initialValue, minimum, maximum, step, pageIncrement, pageSize);
		setAdjustment(adjustment);
//		addOnValueChanged(&valueChanged);
		addOnOutput(&outputValue);
		
	} // this()

	void valueChanged(SpinButton sb)
	{
		writeln("Double", getValue());
		
	} // valueChanged()

	
	bool outputValue(SpinButton sb)
	{
		writeln("Double: ", getValue());
		
		return(false);
		
	} // outputValue()
	
} // class DoubleSpinButton


class FloatSpinButton : SpinButton
{
	float minimum = -1.0;
	float maximum = 1.0;
	float step = .1;

	Adjustment adjustment;
	float initialValue = 0.0;
	float pageIncrement = 0.5;
	float pageSize = 0.0;
	
	this()
	{
		super(minimum, maximum, step);
		adjustment = new Adjustment(initialValue, minimum, maximum, step, pageIncrement, pageSize);
		setAdjustment(adjustment);
		setWrap(true);
		
		// WHY do these trigger twice?
		addOnValueChanged(&valueChanged);
//		addOnOutput(&outputValue);
		
	} // this()

	void valueChanged(SpinButton sb)
	{
		writeln("Float Standard", getValue());
		
	} // valueChanged()

	
	bool outputValue(SpinButton sb)
	{
		writeln("Float Standard: ", getValue());
		
		return(false);
		
	} // outputValue()
	
} // class FloatSpinButton


class PrecisionSpinButton : SpinButton
{
	float minimum = -1.0;
	float maximum = 1.0;
	float step = .001;
	uint precision = 3;

	Adjustment adjustment;
	float initialValue = 0.0;
	float pageIncrement = 0.01;
	float pageSize = 0.0;
	
	this()
	{
		super(minimum, maximum, step);
		adjustment = new Adjustment(initialValue, minimum, maximum, step, pageIncrement, pageSize);
		setAdjustment(adjustment);
		setDigits(precision);

//		addOnValueChanged(&valueChanged);
		addOnOutput(&outputValue);
		
	} // this()

	void valueChanged(SpinButton sb)
	{
		writeln("Float Precision", getValue());
		
	} // valueChanged()

	
	bool outputValue(SpinButton sb)
	{
		writeln("Float Precision: ", getValue());
		
		return(false);
		
	} // outputValue()
	
} // class PrecisionSpinButton