Sign in to follow this  

Modal GUI and ongoing events

This topic is 483 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What is the normal way to handle events when a GUI becomes modal, for instance because a modal dialog appears? This can happen while the user is clicking, dragging, resizing or whatever.

 

How should the events be terminated or aborted? For instance, if the user is dragging something when the modal dialog appears, there will be no mouse up event because the GUI has gone modal. Only the modal dialog receives events. So his cursor will show a resizing sprite forever.

Edited by captain_crunch

Share this post


Link to post
Share on other sites

IMHO: From an UX point of view, your GUI has a design flaw when it regularly causes such a break. Why should a modal dialog appear without a causing user interaction? You should definitely avoid that. It can be accepted in seriously problematic situations, but then the pointer's shape should be your least problem. That said, what are the specific use cases you have in mind?

Share this post


Link to post
Share on other sites

In the past I've deal with this like a 'focus lost' type situation. I'd send an internal event saying the focus was lost (I can't recall the exact wording) and anything that found that useful could listen for it do something with it. The system that is handling whatever the mouse is dragging could listen for the event and deal with it (drop the item for example).

Share this post


Link to post
Share on other sites
The modal dialog appears when an event happens in the game that the player has to decide on. The game is a realtime simulation strategy game.

An often seen strategy here is to make it clear to the user that a message or a decision is waiting for him, and wait for the user to finish whatever he is doing, and click on the "let me see the message" button.

 

In a realtime game, there are moments of intense activity, and users generally don't like getting unexpected popups in the middle of that.

Edited by Alberth

Share this post


Link to post
Share on other sites

The normal way for a GUI to handle this is that the GUI knows that there is a modal window, routes all events to that, and doesn't propagate them to anything else.

 

If the user was dragging something when the modal dialog box appears, then the eventual mouse-up event will be swallowed by the modal dialog and nothing happens.

 

It should not be the responsibility of the dialogs to change your mouse cursor, so there's no reason why the swallowing of that event should mean a broken mouse cursor. The GUI system as a whole should be watching for these operations and knows that a drag operation ends on mouse-up regardless of where that occurs. Dialogs can advise the GUI that a drag operation is valid in the beginning, but they don't get to decide when the operation ends.

Share this post


Link to post
Share on other sites
I have a component class called ResizableArea that can be placed on a form. Currently it has these event methods:
 
 
 /// <summary>
        /// Change to resize cursor.
        /// </summary>
        /// <param name="args">Mouse event arguments.</param>
        protected override void OnMouseOver(UIComponent sender, MouseEventArgs args)
        {
            base.OnMouseOver(sender, args);
            ShowResizeCursor();
        }


        /// <summary>
        /// Put cursor back to normal.
        /// </summary>
        /// <param name="args">Mouse event arguments.</param>
        protected override void OnMouseOut(UIComponent sender, MouseEventArgs args)
        {
            base.OnMouseOut(sender, args);


            // Set back mouse cursor
            GUIManager.SetMouseCursor(MouseSprites.Normal);
        }


        /// <summary>
        /// Starts dragging, and invokes the StartResizing event.
        /// </summary>
        /// <param name="args">Mouse event arguments.</param>
        protected override void OnMouseDown(MouseEventArgs args)
        {
            if (args.Button == MouseButtons.Left)
            {
                this.dragging = true;
                this.lastLocation = args.Position;


                if (StartResizing != null)
                    StartResizing.Invoke(this);
            }
        }


        /// <summary>
        /// Finishes dragging, and invokes the EndResizing event.
        /// </summary>
        /// <param name="args">Mouse event arguments.</param>
        protected override void OnMouseUp(MouseEventArgs args)
        {
            if (args.Button == MouseButtons.Left)
            {
                this.dragging = false;


                if (EndResizing != null)
                    EndResizing.Invoke(this);
            }
        }

Should this kind of code be moved to the GUIManager class (how), or should I change the logic globally so all event methods can handle a situation where an expected event never occurs?

 

Looking at it again, it would probably be better if the component handled a "focus lost" event that could place it back in a normal state.

Edited by captain_crunch

Share this post


Link to post
Share on other sites

Your component should not be telling the GUIManager what to do, ever. Usually it should be the other way around. The only bit of code you really need to remove is where the component tells the GUIManager when to change cursor styles. However the main problem is that you also do that based on assumptions made about events arriving in a certain order, which you can't guarantee. You might want to have the GUIManager send OnDragStart and OnDragStop messages to the component instead.

Share this post


Link to post
Share on other sites

This topic is 483 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this