Quoting Bryce Harrington <bryce@...260...>:
A good technique for providing this capability is to implement Factory methods (see a Design Patterns book for detail).
This probably means we will need to have each dialog include a create() function that returns a new'd Dialog* of its class, and then build a hash of GQuarks to create() function pointers. We would then also need a registration function to add new create() functions to the hash.
And this is where I think it veers a bit off course.
I'll have to get up to speed on the overal state of things, but requiring a create() function on the dialog classes might be restrictive. Instead we might want to have a collection of Factories there, and let them have a create() method. Then the DialogManager would be a Facade in front of the Factories (and maybe even multiple inheritance could be used to have create() on some dialog classes themselves).
However... the big picture is what we might need to look at here. In this case, we're getting tripped up by tricky implementation details, but if it's for something we don't need to be doing in the first place, then we can avoid a lot of the complexity and trickiness.
The thing that trips my radar is the getDialog() method. Instead of jumping straight down into "how can we code this method", let's back up and say "*why* are we coding this method?" That in general, and in this case specifically, can lead to clarity and reduction of problems.
:-)
So... one question is "why do other parts of the code *need* to get a dialog?" Do they really care that much about the details of how some UI is being presented? If not, then I say we should get rid of that method altogether.
This is where adding a "PanelManager" or some such might come in. If the code that's making that other call really only needs to be able to present a given 'control panel' thingie, and doesn't need to know if it's in a dialog or embedded in the UI elsewhere, then don't ask for a 'dialog'. Is the end goal more like "Show the user the thing so that he can align and distribute"? If so, then we can have
FooManager::showPanel(GQuark q) {...}
Then the using code would no longer need to duplicate the functionality of asking for a given dialog and then showing it. So duplicate code would be refactored out to a common function. Additionally, in the cases where no Dialog itself were involved, the using code would neither know or care, and things would just work. And... if using dialogs or not were to be changed in any given cases, changes would be limited and kept away from the other parts of the code that were calling it.
In essence, I'm not suggesting trashing the existing stuff as much as A) adding a layer of abstraction and B) shifting our focus away from presentation and onto information.
BTW, once I had this stuff worked out in general conceptually, I went and checked what the latest GIMP does. And it turns out that functionally it lines up to be presenting the same concpets, including just flashing the title bar of an embedded panel if the requested "dialog" is docked.