0030 – Menus V - A More Practical RadioMenuItem
Today let’s look at an example that can perhaps be adapted for everyday use.
Herein we set a bit of data with our
RadioMenuItems and track it with an observed object. And when the application terminates, it spits out a report about the state of all options in the set. This example is patterned after the second CheckMenuItem example from two posts ago, so a lot of this ground was covered there.
Just a quick reminder (if you aren’t flipping back to the previous post) that we created an observed object in
TestRigWindow which got handed down through the hierarchy. We do the same here, but because we’re dealing with
RadioMenuItems and not
CheckMenuItems, there will be a different approach.
The differences are in:
- how the
- where features are turned on or off during signal-handling/callback, and
- (of course) we have mutual exclusivity here which we didn’t in the
Let’s go through them…
A Busier FileMenu Class
Most of the differences (compared to the
CheckMenuItem example) are in the constructor. But there are differences throughout, so let’s look at this thing in chunks:
- Instead of giving each item it’s own name here, we’re creating an array (naming is deferred and we’ll see that in a moment),
featureItemstring will serve as a temporary name within the
foreachloop used to create the items, and
groupis declared here, but will be defined during creation of the first item.
This is the first part of the constructor and includes the
foreach loop used to create the
RadioMenuItems. We step through the
featureNames string array (a part of the
ObservedFeatureList object) to get label text for each item. The strings in
featureNames decide the item names, and the number of strings decides how many items will be in the set.
ifstatement takes care of the first item, the one that also defines the
- note that even though we pass the group variable to the RadioMenuItem constructor, it comes back as
nulland only takes on a value when
group = featureItem.getGroup()is executed,
elsestatement passes the now-defined
groupalong to all other items as they’re created so they become a set, and
- at the end of the
foreach, we concatenate the item into our array of items before appending it to the
This part is where we set the default item and make sure the states of all items in
ObservedFeaturesList agree with the
Since these things take place in the
ObservedFeaturesList class, we’ll cover them when we get there.
Finally, we drop the
ExitItem onto the end of the menu and bail:
Now let’s look at…
Mutual Exclusion in the ObservedFeaturesList Class
Again, we’ll look at this in chunks…
These variables are:
features: an associative array with Boolean flags for tracking which item is active; text strings used as item names double as keys in the key/value pairs,
featureNames: an array of strings used to name the
RadioMenuItems; they do double duty when building the
featuresassociative array, and
defaultFeatureName: this string needs to match one of those in
featureNamesand is used to set the default item on startup.
Earlier I mentioned that the naming of
RadioMenuItems is deferred. Well, this is where it’s done. All we do in the constructor is define which item will be the default and then fill in the array naming all the
RadioMenuItems in the set. This list can be extended or truncated to change the number of items in the set.
Note: Don’t forget to double-check that
defaultFeatureName appears verbatim in the
This is the function called from
FileMenu’s constructor, the one that—as the name implies—sorts out which
RadioMenuItem will be turned on by default.
When an item in the set is selected by the user, this function is called by the callback to keep the
ObservedFeaturesList in sync with the state of the
These functions do the following:
getDefaultFeature()is called from the second half of
FileMenu’s constructor to sync up the flags in the
featuresassociative array with the state of the
getFeatureState()is unused in this example, but is here as a placeholder. It returns the Boolean value of the named feature. It can be tested like this (perhaps from somewhere near the end of the
And Finally: the FeatureRadioMenuItem Class
This is a lot of stuff we’ve seen before, but one thing I’d like to point out is this: The callback is triggered whether the
RadioMenuItem is going into an on state or an off state. That’s why there’s also an
if statement in there to test the state of the
RadioMenuItem. I would assume you could also have an
else for doing some type of clean-up or what-have-you when an item is deselected.
We could also have used the
onActivate signal instead of
onToggled, but the results are pretty much the same either way.
Now, since this looks to be the longest blog post I’ve done to date, pay no attention while I beat a hasty exit, stage right.
If you'd like to leave a comment...
Until I get time to research and install a commenting system, I ask that you try one of these options:
- 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.
© Copyright 2019 Ron Tarrant