I'm designing a GUI system where I use a Widget class to represent everything. A widget can have child widgets (buttons in a panel, label in a button) and my game feeds the root widget input events from SFML or whatever. When given an event the widget does an action in response then (optionally) hands the event down to its children.

In addition to mouseDown, widgets will respond to mouse drag and mouse up events. I'm going to ignore mouse move events so that I don't have to worry about enter and leave actions, and because touchscreens are teh futures.

I'm thinking about good ways to handle keyboard and mouse focus. A widget gets keyboard focus either programatically or by being clicked, and has all keyboard events forwarded to it. Mouse focus is something I'm thinking of in terms of widgets like scrollbars responding to mouse drag events even when the mouse is outside of them. I figure that would be like one widget receiving all mouse drag events, so the widget would have mouse focus in the same way a widget can have keyboard focus until the next mouse-up. Plus I want the ancestors of the focused widget (either keyboard or mouse) to see the relevant event first like with the mouseDown event.

One idea I came up with is representing focus state with four variables: hasKeyFocus, hasMouseFocus, keyFocusedChildIndex, and mouseFocusedChildIndex. A widget responds to a key if its hasKeyFocus is true or its keyFocusedChildIndex is greater than -1, and the widget passes the event along to its child at children[keyFocusedChildIndex]. A widget uses its hasMouseFocus and mouseFocusedChildIndex variables in the same way for mouse drag and mouse up events.

I said I want all ancestors of the focused widget to see the events directed at it. Suppose we have a widget tree like this:

Main Panel

Panel A

Button A

Button B

Panel B

If Button A had the focus, I'd want the event processing to go Main Panel > Panel A > Button A, in that order, instead of the event going straight to Button A.

As for keeping the information in a centralized location, I want as little overhead as possible. I don't want to wrap my widgets in a "gui manager" class. The application just needs to keep a reference to one or more root widgets, where a widget can be anything from a single button to a large control panel.

As for keeping the information in a centralized location, I want as little overhead as possible. I don't want to wrap my widgets in a "gui manager" class. The application just needs to keep a reference to one or more root widgets, where a widget can be anything from a single button to a large control panel.

If anything, I think a central location would actually reduce overhead. If you don't want a manager or globals, you could go for a static members.

I'd still like the ancestors of the focused widget to see the event before the widget itself sees it though.

One example I had in mind for my project is a panel with a draggable row of pictures. I can either click on a picture to "select" it and have some data show up somewhere, or I can grab and drag anywhere in the whole row panel to scroll it.

That is, I'd want to be able to click-and-drag anywhere inside the panel - including inside a picture - and drag the row of pictures around. Clicking and not moving the mouse while over a picture would be interpreted as selecting the picture.

I figured I could make this work by letting pictures under the mouse (if any) get the focus but let the parent panel see the events sent to them. That way if the mouse is dragged beyond a certain threshold I can have the panel do its scrolling action even when it's a picture that has the actual focus.

I'd still like the ancestors of the focused widget to see the event before the widget itself sees it though.

One example I had in mind for my project is a panel with a draggable row of pictures. I can either click on a picture to "select" it and have some data show up somewhere, or I can grab and drag anywhere in the whole row panel to scroll it.[...]

Hi. I'd like to 1-up ApochPiQ's recommendation on following the design of a single focus widget at a time. Using a hierarchical focus approach can complicate things. Consider: you have a text box in a scrollable window. The user clicks on the text box and presses the right arrow key to move the caret in the text box, but the parent window sees this and scrolls to the right. Chaos.

The 1-or-zero focus window/widget approach, which happens to be what all GUI libraries I've come across use, has proven to be functional and versatile enough to implement whatever functionality you can think of.

Regarding your picture panel, the functionality of scrolling when the user clicks and drags and selecting when the user clicks but does not drag can be implemented using the single focus widget approach in a number of ways. The first obvious way is to not use widgets for the pictures in the panel and instead have the panel draw the pictures itself, as well as perform the required mouse hit-testing. This approach is used a lot. For example, tabs in a tab control are not individual widgets. There is no set criteria, but in general, if it's "a component in a list" kind of thing and doesn't require complex internal user interactions, it's not a widget, but an internal component of the parent widget.

So, the picture panel detects when the user clicks, and waits for the user to release the mouse button. If during this wait the user moves the mouse a certain number of pixels away from the original click location, it initiates a scroll operation. Otherwise, the picture is selected when the mouse button is released.

So rather than pass events to the root widget, where a widget first processes the event then decides which child to pass the event to, I'd pass events to the focused widget, where a widget first sends the even to its parent then processes the event.

Regarding your picture panel, the functionality of scrolling when the user clicks and drags and selecting when the user clicks but does not drag can be implemented using the single focus widget approach in a number of ways. The first obvious way is to not use widgets for the pictures in the panel and instead have the panel draw the pictures itself, as well as perform the required mouse hit-testing. This approach is used a lot. For example, tabs in a tab control are not individual widgets. There is no set criteria, but in general, if it's "a component in a list" kind of thing and doesn't require complex internal user interactions, it's not a widget, but an internal component of the parent widget.

Hm. My example of the scrollable row of pictures would have been implemented with a panel that contains a row layout widget, with the row layout widget containing a bunch of image widgets, If the panel becomes a single widget without focusable sub-widgets then would it still be possible for me to reuse the image and row layout widgets? I want to leverage composition as much as possible throughout my GUI system, e.g. buttons contain text labels.

A button contains a text label. It also contains an icon, a background, an optional drop-down arrow, various states (hot, disabled), and so on. These are visual "widgets". To be reusable, they don't have to be real widgets (meaning fully interactive widgets that process mouse and keyboard input, have their own message queues or whatever functionality you have for what you call a widget). They can be "visual elements". I assume your "raw layout widget" is a widget that arranges other widgets in rows? If so, wouldn't it be more reusable if it were a simple class which takes as input a rectangle, spacing parameters, and a list of sized items, and outputs a list of arranged rectangles? It could do hit-testing and even animations.

But that's not the point. The point is that for input processing, a single input processor (widget) at a time is more intuitive, predictable, and less bug-prone. But then again, using a hierarchical focus approach is not necessarily WRONG. As long as you understand what's going on in your system and have a clear understanding of how input messages are being passed around and processed, and if you feel it's more intuitive for you, then go ahead and use it. Just with all design choices, if you later find that you are doing a lot of shortcuts and hacks in your code, it's an indication that the design may be flawed. So pick something, work with that, and see how it works for you.