0010: Observing CheckButtons
Today’s mission is to have a button exhibit different behaviour depending on the state of another widget, a CheckButton
.
Another Import
Right at the top, as usual, we have to add an import statement:
import gtk.CheckButton;
The Observer
Now, skip to the end of the file to look at the ObserverButton
class:
class ObserverButton : Button
{
string label = "Take Action";
string standardMessage = "Droids? We don't need no stinking droids!";
string switchMessage = "These aren't the droids you're looking for.";
CheckButton checkButton;
this(CheckButton extCheckButton)
{
super(label);
addOnClicked(&doSomething);
checkButton = extCheckButton;
} // this()
void doSomething(Button b)
{
if(checkButton.getActive() == true)
{
writeln(switchMessage);
}
else
{
writeln(standardMessage);
}
} // doSomething()
} // class ObserverButton
This is the observer half of the observer/observed class objects that make up the observer pattern. Our other button (which we’ll look at in a moment, as dull as it is) is watched so the ObserverButton
knows which of two actions to take.
You’ll notice, below the label and other strings representing actions we can take with this button, there’s a pointer to a CheckButton
. It’s passed in through the ObserverButton
’s constructor and assigned to a local variable so we can call its getActive()
function which reads the state of the CheckButton
.
The Callback: doSomething()
If you look at the callback (so aptly named: doSomething
) you’ll see the simple logic used to decide which of the two messages to spit out to the command shell.
Everything else here is off-the-shelf, so let’s look at…
The ObservationBox
Not that there’s anything really new here. All we do is establish the box as parent to both buttons. If we’d built them outside the box, we’d have to drag them in here anyway, so why not?
And Now for Something Completely… Toggled
Imports
Here, the CheckButton
is replaced by the ToggleButton
. The statement:
import gtk.CheckButton;
has been replaced by:
import gtk.ToggleButton;
ObservationBox
Take a look at the ObservationBox
class:
class ObservationBox : Box
{
this()
{
super(Orientation.VERTICAL, 5);
ObservedToggleButton observedToggle = new ObservedToggleButton();
ObserverButton myObserverButton = new ObserverButton(observedToggle);
add(myObserverButton);
add(observedToggle);
} // this()
} // class ObservationBox
We’re still adding two buttons, but the ObservedToggleButton
is more elaborate than the simple CheckButton
used in the first example. So, let’s go look at that:
class ObservedToggleButton : ToggleButton
{
string onText = "Toggle is on.";
string offText = "Toggle is off.";
string onLabel = "Toggle: ON";
string offLabel = "Toggle: OFF";
this()
{
super(onLabel);
addOnClicked(&toggleMode);
setMode(true);
writeln(onText);
} // this()
void toggleMode(Button b)
{
if(getMode() == true)
{
setMode(false);
writeln(offText);
setLabel(offLabel);
}
else
{
setMode(true);
writeln(onText);
setLabel(onLabel);
}
} // toggleMode()
} // class MyToggleButton
This is what can happen if we want to hook something up to one of the ToggleButton
’s signals, giving it something else to do besides sitting there looking oh-so pretty. All those strings are there to tell us the state of things, not just in the command shell, but on the ToggleButton
’s label, too.
And in the constructor, we’re using a new signal, the onToggle
signal, which we hook up with addOnToggled()
.
A little side note: if we’d wanted to add a callback to the CheckButton
, instead of using the onClicked
signal (inherited from Button
) we could have used onToggle
there, too. But because CheckButton
inherits the signal from ToggleButton
, we’d have to add an extra import statement:
import gtk.ToggleButton;
import gtk.CheckButton;
in order to get access to the signal and the all-important hook-up function, addOnToggled()
.
And that’s pretty much it. The ObserverButton
is almost identical to the one in the CheckButton
example. The only significant difference being that it calls the ObservedToggleButton
’s getMode()
to find its state rather than the getActive()
function used with the first example.
And that is a day’s work, two examples that do very much the same thing, a CheckButton
and a ToggleButton
. You might think there’s so little difference that only one is actually needed and maybe that’s the case. But when you think about it, the CheckButton
’s state is visually obvious the moment you glance at it. With a ToggleButton
, we’ve got to go the extra mile and make changes to the label. We could also have changed the colour of the button if we really wanted it to stand out. Either way, though, in the end it comes down to which is more appealing for the GUI design you’re working on.
And that’s it. Until next time, may your wookies eat cookies and don’t stare into any novas.
Comments? Questions? Observations?
Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.
- come on over to the D Language Forum and look for one of the gtkDcoding announcement posts,
- drop by the GtkD Forum,
- follow the link below to email me, or
- go to the gtkDcoding Facebook page.
You can also subscribe via RSS so you won't miss anything. Thank you very much for dropping by.
© Copyright 2024 Ron Tarrant