0051 – MVC IV – The ComboBox with Text
Today starts a mini-series within our MVC series in which we look at a simple
ComboBox example to reproduce what we’ve already done with the
So… unlike the
ComboBoxText—which you more or less just throw strings at—the
ComboBox needs an actual
Model (ListStore or
TreeStore) to draw text strings from. This is a little more work than it was with the
ComboBoxText, so let’s dig in…
We start with a
Now, there are similarities. We still have a string array, but how we handle it is quite different.
The Model Constructor
ListStore constructor takes an array of
GTypes and these define the data types each column in the
ListStore will hold. The
GType enum, found in
generated/gtkd/gobject/c/types.d, defines all the built-in types we can use here. Later, when we look at more complex examples, we’ll go over how to deal with more complex types, but for now, these will do.
You’ll note that the call to
super() still gets an array for an argument, even though we’re only using one data type. And, of course, because there’s only one element in the array, there will be only one column.
for() loop steps through the array, picks one from the
items array, instantiates a
TreeIter, and then sets the value in the
setValue() arguments are:
treeIter– a pointer to the
ListStorerow where we’ll store the current data,
0– the column number (in this case the only column we have) within the
ListStorewhere the data will end up, and
message– the string data we’re storing.
ComboBox acts as both View and Control. Keep in mind that it’s based on the
CellLayout interface and so it a non-standard implementation of the MVC paradigm. But, no matter. The results are so similar, they make no real difference, so let’s carry on.
Let’s look at the
SignComboBox a bit at a time starting with…
The Initialization Chunk
Here’s what these are:
entryOnwe’ve used before and with it being false, it stops the
ComboBoxfrom including an
_signListStoreis just a convenient (and local) place to keep a pointer to the
ComboBoxthat we’ll be working with and displaying text items,
ListStorecolumn number from which we’ll draw data, and
ListStorerow number (index) that’ll be selected by default.
We’ll talk more about the
visibleColumn variable and
CellRenderers of various types when we look at other examples later in this mini-series.
After the instantiation of the super-class, we have three stages to this constructor:
- setting up and packing the
- initializing the
- hooking up the signal.
Stage 1: CellRendererText
In the introduction to this series, I mentioned that one or more
CellRenderers are packed into a
TreeViewColumn so it knows how to display its contents. With a
ComboBox, we don’t have a
TreeViewColumn. Instead, as I said earlier, the
ComboBox is an implementation of the
CellLayout interface. This interface is also implemented by the
TreeViewColumn which means the
ComboBox acts as its own
TreeViewColumn of a sort. All this means is that you can treat the ComboBox as if it has a TreeViewColumn… more or less. Later on, we’ll see how flexible this can be.
For now, though, this is what happens in the first stage of the constructor:
- its packed into the
- we use
addAttribute()to tell the
- what its single column will display,
CellRendererto use, and
- which column will be visible (in this case, the only column we have).
Stage 2: Initializing the Model
Not a big deal, we just:
- assign a local pointer to the
setModel()to tell the
ComboBoxwhere to look for its data, and
- pre-select one of the items, using
setActive(), so the
ComboBoxshows a default value.
Stage 3: The Callback
And the last line of the constructor hooks up the callback signal, but that’s straightforward, so let’s look at the callback code itself:
Again, we define a
TreeIter which we’ll go over in a moment.
The first action we take is to get the index of the currently-selected item. This is here purely for completeness sake. It really has nothing to do with the next step…
which is where we use the
TreeIter, not to stuff data into the
ListStore, but to retrieve it. The
getActiveIter() function returns a Boolean to indicate success or failure, so we can predicate further action on whether or not the
TreeIter gets initialized here. And yes, it’s one of those D-language situations where the function definition looks like this:
public bool getActiveIter(out TreeIter iter)
And if you don’t yet know, that’s D’s way of asking a function to assign value to an argument. And to make things easy for this worker function, D has the ability to hand it the argument using the
Anyway, if the
TreeIter gets instantiated by
getActiveIter(), we then:
getModel()to grab the
TreeModelso we can
- use its
getValueString()function to grab the data stored in the first (
0th) column of the Model.
It looks and sounds far more complex than it actually is. We could have done the same thing like this:
But, whatever. From there, we can do whatever we want with the fetched data. In this case, we just echo it to the terminal.
Okay, so there we have a reproduction of the
ComboBoxText using a
ComboBox and—who’d-a thunk it—some text. Sure, it’s more work, but as we’ll see in the rest of this mini-series within a series, when we turn to non-string data, we need to know this stuff.
See you next time when we tackle a
ComboBox with integers.
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