Hello again.
So I am creating an app that would let users to select time in seconds, and display a gtk.Spinner
for the given time period. The button that triggers the spinner (in the code, trigger
) is also supposed to show a countdown in the button label.
Problem is, the timeout is way too inaccurate. What's causing this inaccuracy and how can I fix it?
import gio.Application : GioApp = Application;
import gtk.Application : Application;
import gtkc.giotypes : GApplicationFlags;
auto app = new Application("org.gitlab.radagast.spinner", GApplicationFlags.FLAGS_NONE);
app.addOnActivate(delegate void(GioApp _) {
import gtk.ApplicationWindow : ApplicationWindow;
auto aw = new ApplicationWindow(app);
scope (success)
aw.showAll();
aw.setDefaultSize(320, 200);
aw.setBorderWidth(40);
aw.setTitle("Spinner Demo");
import gtk.Box : Box;
import gtkc.gtktypes : GtkOrientation;
auto vbox = new Box(GtkOrientation.VERTICAL, 10);
scope (success)
aw.add(vbox);
import gtk.Spinner : Spinner;
auto spinner = new Spinner();
vbox.packStart(spinner, true, true, 0);
auto hbox = new Box(GtkOrientation.HORIZONTAL, 10);
scope (success)
vbox.packStart(hbox, false, true, 0);
import gtk.SpinButton : SpinButton;
import gtkc.gtktypes : SpinButtonUpdatePolicy;
auto spinButton = new SpinButton(0, 50, 1);
spinButton.setNumeric(true);
spinButton.setUpdatePolicy(SpinButtonUpdatePolicy.IF_VALID);
hbox.packStart(spinButton, true, true, 0);
import gtk.Button : Button;
auto trigger = new Button("Start");
trigger.addOnClicked(delegate void(Button _) {
// retrieve the time
auto time = spinButton.getValueAsInt();
// set the button and the spinbutton insensitive
spinButton.setSensitive(false);
trigger.setSensitive(false);
// start the spinner
spinner.start();
// stop the spinner after the given time
import glib.Timeout : Timeout;
import gtkc.gtktypes : GPriority;
//Timeout(bool delegate() dlg, uint seconds, bool fireNow = false)
auto timeout = new Timeout(delegate bool() {
static int s;
s++;
if (s >= time) {
s = 0;
// stop the spinner
spinner.stop();
// hide the spinner
//spinner.setVisible(false);
// make the button and the spinbutton sensitive again
spinButton.setSensitive(true);
trigger.setLabel("Start");
trigger.setSensitive(true);
return false;
}
else {
import std.format : format;
trigger.setLabel(format("Start (%s)", time - s));
return true;
}
}, time, GPriority.HIGH);
});
hbox.packStart(trigger, true, true, 0);
});
return app.run(args);
}