How to close a Modal Dialog window by a mouse click outside?

I have a ContainerControl in a project. The container consists of a TextField and a BevelButton. Clicking the Button shows a Modal Dialog Window with a data-picker (e.g. a Calendar). The user can choose to click in it. This will fill the TextField and close the Modal Dialog (Choice-Window / Picker). If the user clicks outside, the Modal Window sould be closed as well.
For that, i’m using a Timer on the Modal Dialog (ModeMultiple, Period: 100):

if System.MouseDown then if (System.MouseX < Self.Left) or (System.MouseX > Self.Left + Self.Width) or _ (System.MouseY < Self.Top) or (System.MouseY > Self.Top + Self.Height) then Close end if end if

This works quite well on all Windows / OS X / Linux. Except for the situation when one is using a TrackPad on OS X configured with “Tap to Click”. The Timer catches pressing a button on a mouse, or doing a ‘real click’ on the Trackpad, but is missing the ‘tap on TrackPad’. Most likely because the “MouseDown” is much shorter in that situation (at least on OS X).

So the question is: How can the ‘Close by clicking outside’ be changed in a way a ‘tap on TrackPad’ is being recognized as well? Is there a better approach than the Timer?
I don’t want to have any code in the main window for that (e.g. in the Mouse-Events), because this ContainerControl is placed on several windows. So it should be self-contained in the TextField/BevelButton (or in the ContainerControl).

Example Project: https://dl.dropboxusercontent.com/u/17104905/DismissOnMouseClickOutside.rbp

Could you do a regular window (instead of modal) and put code in the lost focus event to close it?

Yes and No.
A Window doesn’t have a LostFocus event.

Yes:
In the example project, i could do that with the (Picker)-Canvas Event ‘LostFocus’ instead.

No:
The real project does have a single Plugin-Control there (a Calendar Picker), which does not have a LostFocus-Event.
So there i don’t have any ‘LostFocus’ event in the ‘Choice Picker Window’ on both Control and Window…

My mistake. Try the deactivate event of the window instead.

Thanks. That original code example was created in my first months using REALbasic.
So I guess it’s the effect that it’s hard to think “outside the box” (think of a different approach) when looking at such “old code”, so that one doesn’t even think of the most obvious solutions…
Of course the Deactivate-Event works just fine - even with a modally shown ‘Plain Box’ Window.

Okay, it works well when this is used in the main Document Window.
If this ‘Picker Container Control’ is placed in a Modal Dialog Window, then things look different.

Picker as ‘Plain Box’: On OS X, the picker then shows behind the Modal Dialog Window.
Picker as ‘Modal Dialog’: The Deactivate-Event is not fired if the user clicks on the Dialog-Window below (only if the user clicks e.g. on the Desktop, so that the entire Application is in ‘deactivated’ state).

Should someone want to try this: https://dl.dropboxusercontent.com/u/17104905/DismissOnMouseClickOutside.rbp

[quote=159288:@Jürg Otter]Okay, it works well when this is used in the main Document Window.
If this ‘Picker Container Control’ is placed in a Modal Dialog Window, then things look different.

Picker as ‘Plain Box’: On OS X, the picker then shows behind the Modal Dialog Window.
Picker as ‘Modal Dialog’: The Deactivate-Event is not fired if the user clicks on the Dialog-Window below (only if the user clicks e.g. on the Desktop, so that the entire Application is in ‘deactivated’ state).

Should someone want to try this: https://dl.dropboxusercontent.com/u/17104905/DismissOnMouseClickOutside.rbp[/quote]

I fail to see why you want a modal window and dismiss it with a mouse click outside. By definition, a modal window is explicitly intended to PREVENT what you want to do, so the user cannot click anything outside of the window. Bill Gookin rightfully suggested yesterday to use a regular window. If you only try that, you will stop making it hard on yourself, and obtain the behavior you want.

A regular window will let the user click outside, so it loses z-order and fire deactivate, where you simply close it. No need for convoluted recourse to additional methods. Simple.Elegant.

Took 10 seconds to modify your project which now dismisses the window whenever one clicks outside of it :
https://www.dropbox.com/s/9ubov8emrpt4mhn/DismissOnMouseClickOutside.rbp?dl=0

I don’t want that at all.

But the Application has some Modal Windows (e.g. a ‘Settings Dialog’).
On that ‘Settings Dialog’, there is that kind of ‘Data Picker Container Control’ (which needs to show yet another dialog, modally or not). All i want is that this ‘Picker’ can be dismissed (by clicking somewhere outside in the modally shown ‘Settings Dialog’).

I try to find a way which allows that ‘Picker Container Control’ to be placed on both a main Document Window, or in a Modal Dialog.
To test both situations, there is the PushButton [Show Modal Dialog].

In the current state of the example, the Picker Container Control works fine on the main Document Window, but not on the Modal Window.

[quote=159293:@Jürg Otter]I don’t want that at all.

But the Application has some Modal Windows (e.g. a ‘Settings Dialog’).
On that ‘Settings Dialog’, there is that kind of ‘Data Picker Container Control’ (which needs to show yet another dialog, modally or not). All i want is that this ‘Picker’ can be dismissed (by clicking somewhere outside in the modally shown ‘Settings Dialog’).

I try to find a way which allows that ‘Picker Container Control’ to be placed on both a main Document Window, or in a Modal Dialog.
To test both situations, there is the PushButton [Show Modal Dialog].

In the current state of the example, the Picker Container Control works fine on the main Document Window, but not on the Modal Window.[/quote]

Have you only tried not to use a modal dialog ? Look at the project I posted. Click on “show modal dialog” and click outside.

Michel - he wants to pop up a window FROM a modal dialog that will disappear if you click back on the modal dialog itself. But the modal dialog is making his popup window immediately deactivate so it never really shows up.

I’m not sure what I’d do here…if I think of something I’ll post it though.

[quote=159313:@Bill Gookin]Michel - he wants to pop up a window FROM a modal dialog that will disappear if you click back on the modal dialog itself. But the modal dialog is making his popup window immediately deactivate so it never really shows up.

I’m not sure what I’d do here…if I think of something I’ll post it though.[/quote]

If you talk about dlgChoice, deactivate works fine here and the close it contains does close the box if clicked outside.

2014R3.1 Cocoa.

Yet, I still believe there is absolutely no reason to display it modal, if he wants to be able to dismiss it with a click out of the box area. dlgChoice.ShowWithin(oWithinWindow) works quite fine, apparently.

Modal is modal is modal. Displaying a window modal and then going to extraordinary steps to make it behave like an ordinary window makes no sense at all…

When you run his app, click the “Show Modal Dialog” button. Then click the “…” button to bring up dlgChoice. THAT’S what he’s having trouble with now. He wants to show the popup window on top of a modal dialog but the modal dialog (correctly) keeps deactivating the popup.

All it took was to change Window2.ShowModalWithin to ShowWithin. Now the choice box appears correctly on top of Window2, which is still movable modal.

https://www.dropbox.com/s/9ubov8emrpt4mhn/DismissOnMouseClickOutside.rbp?dl=0

Unless there is something else…

Well yeah, the choice box works, but Window2 is no longer behaving modally as it can now be behind Window1.

I think the issue is to use a window for dlgChoice in the first place. It should not be window, since it is in fact used as sort of a drop down menu to the TextField. A Container Control would work a lot better in this instance.

At one point, using a hammer to drive screws is bound to create accidents :wink:

If container controls worked perfectly, I totally agree. But if a container control is shown over other controls, there can be bleed through and other ugliness, right? :frowning:

Also, I was hoping to edit out my line about how the window was defined before anybody saw it. That’s what I get for typing without thinking. LOL

I have not observed such uglinesses, but it does not mean they do not manifest, in particular in Windows.

For the moment, I simply copied the controls in dlgChoice over a containercontrol, placed an instance over Window2, and it works just as well without the pesky windows problems. Using the visible property false instead of close makes it disappear just as well.

Alternatively, the canvas he places as window background could stand on its own as well, as canvases can serve as controls containers.

The point is, why use a window to display a drop down menu ?

@Bill, thanks - you’re seeing the “issue” i have…

The Modal Window(s) are a fact I can’t change, and which make sense in a lot of places.
The question remains how to show such a “Data Picker” within that… If i don’t use “ShowModal” for the Picker, it gets displayed below, which makes no sense at all. Showing it modally works fine, but there’s no way to dismiss it by a “click outside” (which is what people tend to do, being used to “popovers”). Well, only by a click “outside the application” (that’s the only way to get the Deactivate-event), but people click “ouside of the picker”, somewhere else on the Modal Window, and not “outside of the Application”.

So I still haven’t found a way to achive this “dismissing by click outside” for a “Container Control (Data Picker)”, which can be used anywhere in an Application (in the main window, or a Modal Window).

At the moment, the only way is still the original idea: The timer checks for System.MouseDown (in an Area ouside).
This works almost perfect - except for a “tap on the Touchpad”, which is not being recognized by the timer. A “click” on the Touchpad works as expected.