Keyboard Input Listener what is the correct way to determine which textbox the input comes from?

Have a column of textboxes. Each can receive input from the keyboard.

In my keyboard event handler I have no location parameter to determine which textbox the input is for.
So, I implemented a mouse listener to get the location. But, when the user inputs text into the first textbox without first clicking in that box the input goes into all the textboxes. Not very nice.

Am I missing something in the design to correctly identify which textbox the input is for?

You probably should use the TextChanged-Event and write a function for each textbox

Is this your own textbox code or are you using a library from extended?

If its your own you can use something like this .

 public class TextBox
    {
        /// the text of the textbox
        string text;

        //the input listoner
        Func<char> Input;

        //the main update
        public void Update()
        {
            if (Input != null) //check we have listioner
            {
                //read input
                char ca = Input();
            }
        }

        private static char StringInput()
        {
            ///her is your keyboard input code and returns a value
            return 'c'; 
        }

        //when the texbox is selected
        public void OnSelect()
        {
            Input = StringInput; //set the listoner
        }

        //when the textbox is deselected
        public void OnDeSelect()
        {
            Input = null; //remove the listoner
        }
    }

Thanks for the reply.

I am writing a custom generic “level” editor for my suite of solitaire games. There are 2 textbox classes, Textbox that handles a string and a multiline block of text and Textbox4 that has up to 4 subfields to handle 9 types; string, Color, Vector3, Vector2, float, Point, int, byte, bool. Textbox4 includes basic editing of the types. The editor is structured in a hierarchy, Screens, Forms and Controls. Currently, I have set up a focus system to identify which control is selected. If the user clicks on a control then the screen, form and control has focus. I am having trouble with the initial conditions hence my question. If the user selects with the mouse or pointer that item has focus but if he selects with the keyboard it is not clear what should happen. By hitting the tab key he can move to the next field.

What I am having trouble with is how to uniquely identify which sprites/controls.are selected.
Hope this clarifies my situation.

It might be useful if you posted some code.

It’s not really clear what code you’re referring too?

Due to the lack of response to this question tells me that few people run into this problem.

Textboxes are rarely found in games and usually only as a single textbox.

In a textbox there are 2 cursors, a screen cursor that is pixel based and a character cursor that is character based. The challenge is to co-ordinate the 2 cursors as well as the pointer and the keyboard. When the user clicks in the textbox on the screen, the pointer location must be converted to a character cursor position. When receiving character input from the keyboard at the character cursor, the position of the character must be converted to pixel position to be displayed on the screen. Using an input listener to receive the keyboard character in an event handler works very well.

If only one textbox is present this works well. For multiple textboxes the sender needs to be checked to see if the screen cursor is in the textbox before accepting the input. If this is not done then the input character is displayed in all the textboxes. Not a desired result.

If there is interest I can work up a code sample of how I solved this. Textbox code is rather detailed.

Happy coding.

I’m starting to understand what you were asking. But posting it in Extended really was confusing, because I think this is about the Monogame.Extended Framework which also contains a UI-Framework.

Another simple solution in general for UIs is to check the mouse for every element. If the mouse is inside an UIElement(or once clicked, depending on usecase) this UIElement will be set to ‘active’, otherwise ‘deactive’. Then there’s always only a single active UIElement and therefore only a single element accepting input.

Sorry for posting this in the wrong place. .But my original question asked if there were problems in my design. I was using a mouse listener rather than polling for input.

In my case, I have found that this is not so simple. I have a hierarchy of elements, screens, forms and controls. To determine which element is active it is required to traverse the hierarchy and determine which element is in front of others. What I would really like is to have a game design that makes this easy. Searching for how to detect overlapping sprites does not give me any pointers for the correct design, Replies like “you need to implement a z value” are not very helpful. How does one do that?

For the moment I have implemented a focus system and it seems to work. But it is quite cumbersome. It would be nice to have a design that makes this easy.
Hope this sheds some light on my challenges.
Thanks.

Oh actually it really is quite simple.
Just do:

void UIElement.Update()
{
    //first update children of this UIElement
    var childHandledInput = false;
    foreach(child in children)
    {
        child.Update()
        if(child._handledInput)
            childHandledInput = true;
    }
    
    this._handledInput = false;
    //Only handle input if none of the children have handled the input 
    //and the mouse clicked inside the bounds
    if(!childHandledInput && Mouse.Intersects(this.Bounds) && Mouse.Clicked)
    {
        print "Only I was clicked!"
        _handledInput = true;
    }
}

Weird pseudo-code but I think you get the point

Thanks for the pointers. As always this gets quite complicated. I have implemented this approach for one level of my control hierarchy but am having trouble with the various levels. It is not clear to me how I detect if a complex element is active. For example, my Form element is composed of a border, buttons and other elements which can be complex like a textbox or a list. All the controls are based on Control. However, in some cases I have added functionality to the derived class that handles input. I would like to tidy up all the elements but I am unsure of the design. I keep running into design problems such as resizing, animating and dragging elements.

It would be nice to have a design that helps to implement features rather than cobbling them together and constantly reworking things.

Are there game design patterns that could be followed?

Well I can only tell you how I’m trying to handle it.
Basically I have my base class UIElement:

public abstract class UIElement
{
    public Vector2 Size;
    public Rectangle Bounds;

    public Texture2D Texture;

    public UIElement Parent;
    public List<UIElement> Children;

    public bool Focused;

    protected bool _handledInput;

    public virtual void AddChild(UIElement child)
    {
        Children.Add(child);
    }

    public virtual void Update(GameTime gameTime) 
    {
        //first update children of this UIElement
    var childHandledInput = false;
    foreach(child in children)
    {
        child.Update()
        if(child._handledInput)
            childHandledInput = true;
    }
    
    this._handledInput = false;
    //Only handle input if none of the children have handled the input 
    //and the mouse clicked inside the bounds
    if(!childHandledInput && Mouse.Intersects(this.Bounds) && Mouse.Clicked)
    {
        Focused = true;
        _handledInput = true;
    }
    if(!Mouse.Intersects(this.Bounds) && Mouse.Clicked)
        Focused = false;
    }

    public virtual void Draw(SpriteBatch batch) 
    {
        //Draw self
        batch.Draw(Texture, Bounds.Location, Color.White);

        foreach(var child in Children)
            child.Draw(batch);
    }
}

(You have to add some more logic to the focused stuff for parent, but you get the idea)

And then for a textbox you would do something like this:

public class Textbox : UIElement
{
    public string Text;

    public override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
        
        if(Focused)
        {
            //Handle input for changing the text
        }
    }
}

Now to use alls this you just start with an Element, e.g. a Window.

var window = new Window();
var textbox = new Textbox();

window.Add(textbox);

//...

window.Update(gameTime);

//...

window.Draw(spriteBatch);

This way all children will be drawn and updated and only one element is Focused at a time.

I find this to be a quite simple approach and it works pretty well for me :slight_smile:
Of course this is really a stripped down and incomplete example. For the UIElement you’ll need to handle stuff like parent == null. Also adding events is really nice and handling resizing etc.

This works well except for the elements that change state. For example a button that when clicked raises an event to change the screen disappears before it can be checked to see if it is active. I think what is required is to find some way of saving the action state or deferring the changing of the state until after the action takes place. Hope this makes sense.

Yeah well that’s true. But why do you need the button to be focused if you’re changing screen anyway?