www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - SpinButton Signal Oddness...

reply Ron Tarrant <rontarrant gmail.com> writes:
I posted this over on the gtkD forum, but thought I'd post here, 
too, to get a wider pool of expertise:

 I hooked up some signals to a few SpinButtons and I'm getting 
 double-firings, 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 writeln() in a callback 
 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
 
 ```
Apr 24 2019
parent Ron Tarrant <rontarrant gmail.com> writes:
On Wednesday, 24 April 2019 at 14:18:00 UTC, Ron Tarrant wrote:
 I posted this over on the gtkD forum, but thought I'd post 
 here, too, to get a wider pool of expertise:
This issue has been resolved over here: https://forum.gtkd.org/groups/GtkD/thread/982/
Apr 24 2019