0044: Dialogs X - Customizing (3 of 3)
- Fancy Content Area
This collection of topics is split up like this:
- Part I (the time before last) deals with how to create an aesthetically-pleasing widget layout for a custom
- Part II (last time) covers user interaction, and
- Part III (this time) brings it all together.
As promised, this time around we talk about the
Dialog’s Content Area and wrap up by rolling our own Action Area and Content Area together into a fully-fledged custom
Dialog. However, since we went over Action Area stuff last time and this example is only different in a few small way, I’m not going to discuss it here except to say:
The Action Area used in this example uses an array of roll-yer-own
Label text strings. ‘Nuff said. And now…
The Content Area
The first thing to know about the Content Area is that it’s just an ordinary
Box jammed into the top section of the
Dialog. Knowing that, we just isolate the
Content Area so we can address it directly, then treat it like any other
Box. It takes a couple of steps to get there, but it works, so why not?
In the constructor, we instantiate the
Dialog, then call a function named
farmOutContent() to do the dirty work:
And here’s that farming function which really just gives us a convenient handle to grab our
Box and hand it around:
It may seem redundant to have variables for both
contentArea, but keep in mind that one’s a
Box and the other is a customized
ContentArea object which contains that
Box we grabbed from the the
Dialog. The fact that we’re passing
contentArea to the
AreaContent class’s constructor is a dead giveaway. It’s the same technique we used for defining Part I’s
HPadBox. And the
AreaContent object wraps the handle.
And here’s where it all gets wrapped up in a nice, neat… um… object:
_contentArea property is defined as a
Box (note that we don’t need to call
cast() for this to work) and it gets assigned to the
Box pointer passed into the constructor. The constructor goes on to create our padded
PadGrid class) and stuffs that into the Content Area.
And this is important: We have to call
_contentArea.showAll() for the
Dialog just as we do with a
MainWindow. If we don’t, the
Dialog will appear without its Content Area.
PadGrid (see Part I of this series if you haven’t already) has morphed into the
NewImageDataGrid class (but only to support the paradigm present in the example) and contains all the bits and bobs for gathering data from the user. In this case, we’re gathering a file name, x and y dimensions, and the resolution of a new image to create. For the sake of brevity, I won’t reproduce the entire
NewImageDataGrid here, but these are the properties it contains:
Entry, and placeholder text for the file name, and
- a name
Entry, placeholder text, and units
Labelfor each of these:
- height, and
And all that stuff is stored in these variables:
Naturally, the constructor takes all these properties, instantiates all the
Entrys, then stuffs them into the super-class
Grid while also using values from our
enum to make things look nice.
Note: When using the
attach() function, the arguments are:
- child = the widget to add,
- left = the column number to attach the left side of @child to,
- top = the row number to attach the top side of @child to,
- width = the number of columns that @child will span, and
- height = the number of rows that @child will span.
And like when we were dealing with menus, it’s always a good idea to draw a diagram of your
Grid layout to more easily keep track of what’s going on.
And one function in the
NewImageDataGrid will be of interest. It looks like this:
What you’re looking at is some D-specific coolness. To get the user-supplied data out of the
Entrys, we’re dealing with two kinds of data, a string and a handful of integers. We use D’s
Tuple(S, I, I, I) construct to declare a mixed return value and
tuple() to put it together before handing it to the
Note: You can also return a mixed bag of variables using a
struct. Here’s a short bit of example code showing all three: tuple, Variant, and struct.
Using this as a model, you can grab any combination of mixed data from the user, package it up, and get it back to whatever caller needs it.
Now, let’s skip back to the
NewImageDialog’s callback function… well, part of it, anyway…
Retrieving the User-supplied Data
To handle the
Buttons in the action area, I set up a
switch() statement inside the
doSomething() callback. Here’s one relevant bit of that
case code. And for convenience, here’s the entire file again if you don’t wanna scroll back up to the link):
If the user clicked on the OK button in the Action Area, we step through each item in the
tuple returned by
getData() and print it to the terminal. Naturally, you’d wanna do this differently in an application, perhaps more like this:
writeln("filename: ", areaContent.getNewImageDataGrid.getData()); writeln("width: ", areaContent.getNewImageDataGrid.getData()); writeln("height: ", areaContent.getNewImageDataGrid.getData()); writeln("resolution: ", areaContent.getNewImageDataGrid.getData());
So you can work with the variables independently of each other.
And that is it! You now have all the information you need to:
- build a custom
- populate it with
- make everything look pretty, and
- retrieve user-supplied data for use in your application.
May you have as much fun creating your own custom
Dialogs as I did coming up with these examples and writing this mini-series around them.
And remember: semper ubi sub-ubi.
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