Article View: comp.windows.interviews
Article #1448Re: MOdal Dialogs/ G++
From: John Vlissides
Date: Fri, 07 Jun 1991 17:50
Date: Fri, 07 Jun 1991 17:50
107 lines
4031 bytes
4031 bytes
> Here at MCC one of our programmers created
> a new kind of dialog that does not allow any
> other interactors to receive events while it
> is "popped up". We call this a Modal Dialog.
>
> What we had to do was to take over the run
> operation during display of the MD and refuse
> to pass on any events occurring outside the
> bounds of the local scene to their targets.
>
> I had the same problem. In fact, with the non modal dialogs, it was
> easy to invoke the same dialog box twice, leaving internal variables
> in a bad state. I came up with the same solution as you: checking the
> bounding box of the Dialog and only passing on events inside.
>
> However, there is a fatal flaw with that approach as well. If the
> window manager buries the dialog window (e.g. if you click on the boundary
> of an overlapping window initially behind the dialog), the dialog box
> will be partly or completely obscured, potentially by another window of the
> same application. Now an event read in the Dialog::Run for this other window
> may be within the Dialog bounding box, but not destined for a subwindow
> of the Dialog. Same problem occurrs, and it is not as unlikely as it sounds!
>
> My solution - actually check the target interactor for having the dialog
> as an ancestor:
The BasicDialog class in Unidraw (3.0) addresses this problem in a
similar manner by defining Forward and IsAChild members:
void BasicDialog::Forward (Event& e) {
if (IsAChild(e.target)) {
e.target->Handle(e);
} else {
Handle(e);
}
}
boolean BasicDialog::IsAChild (Interactor* i) {
Scene* parent = i->Parent();
while (parent != nil) {
if (parent == this) {
return true;
}
parent = parent->Parent();
}
return false;
}
Subclasses use Forward instead of Handle to forward events only to
interactors inside the dialog. AcknowledgeDialog, for example, simply
posts a message that the user can dismiss:
class AcknowledgeDialog : public BasicDialog {
public:
AcknowledgeDialog(const char* title, const char* subtitle = "");
virtual void Acknowledge();
private:
Interactor* Interior();
};
AcknowledgeDialog::AcknowledgeDialog (
const char* title, const char* subtitle
) : BasicDialog(new ButtonState, title, subtitle) {
Insert(Interior());
input = new Sensor(noEvents);
input->Catch(KeyEvent);
}
void AcknowledgeDialog::Acknowledge () {
Event e;
int v = 0;
state->SetValue(v);
do {
Read(e);
if (e.eventType == KeyEvent) {
state->SetValue(e.keystring[0]);
} else {
Forward(e);
}
state->GetValue(v);
} while (v == 0);
}
Interactor* AcknowledgeDialog::Interior () {
const int space = round(.5*cm);
return new MarginFrame(
new VBox(
new HBox(_title, new HGlue),
new HBox(_subtitle, new HGlue),
new VGlue(space),
new HBox(
new HGlue,
new PushButton(" OK ", state, 1),
new HGlue
)
), space, space/2, 0
);
}
--
John Vlissides
Computer Systems Lab
Stanford University
vlis@interviews.stanford.edu
Technical Details
Message-ID:
<VLIS.91Jun7105037@lurch.stanford.edu>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ucbvax!agate!stanford.edu!leland.Stanford.EDU!portia!vlisReferences:
<1991Jun5.141228@Pkg.Mcc.COM> <9106061529.AA29233@shelby.Stanford.EDU>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ucbvax!agate!stanford.edu!leland.Stanford.EDU!portia!vlis From: vlis@lurch.stanford.edu (John Vlissides) Newsgroups: comp.windows.interviews Subject: Re: MOdal Dialogs/ G++ Message-ID: <VLIS.91Jun7105037@lurch.stanford.edu> Date: 7 Jun 91 17:50:37 GMT References: <1991Jun5.141228@Pkg.Mcc.COM> <9106061529.AA29233@shelby.Stanford.EDU> Sender: news@leland.Stanford.EDU (Mr News) Organization: stanford university Lines: 107 In-Reply-To: neil@AKBAR.TELEOS.COM's message of Thu, 6 Jun 1991 15:29:18 GMT