Hello Guest

Author Topic: Adding a textbox to a scene?  (Read 2896 times)

0 Members and 1 Guest are viewing this topic.

Zyrex

  • Member
  • Posts: 4
    • View Profile
Adding a textbox to a scene?
« on: February 16, 2015, 09:11:32 PM »
As the title says, I'm not sure how I would add user input to a scene. As far as I know the otter2d.UI is not fully implemented and I can't figure out if adding a textbox to a scene is possible.
Apologies if this is a dumb question, I want to work login into my application which is why I would like basic user controls such as a textbox, password box and submit button.

Kyle

  • Administrator
  • Member
  • Posts: 259
    • View Profile
Re: Adding a textbox to a scene?
« Reply #1 on: February 17, 2015, 04:32:51 PM »
A text box is possible but it might not work exactly how you think.  There is no real support for GUI stuff right now and anything involving text input you'd have to make yourself.  You have access to Input.KeyString (or Input.Instance.KeyString) which is a string composed of all the characters that have been pressed on the keyboard.

A very simple way to do this would be having an Entity with a Text graphic.  When the user clicks on it, the Entity would go into some sort of "focused" state.  When you enter the focused state, you can set the Input.KeyString to the string in the Text graphic.  Then while the Entity has focus set the Text's string to the Input.KeyString every update.  If you actually follow a Flashpunk tutorial on this you should be able to spot the similarities: http://firner.com/weblog/article/user-editable-text-boxes-in-flashpunk

Kyle

  • Administrator
  • Member
  • Posts: 259
    • View Profile
Re: Adding a textbox to a scene?
« Reply #2 on: February 17, 2015, 09:28:15 PM »
Here's a quick example of text boxes in otter:

Code: [Select]
using Otter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TextEditBox {
    class Program {
        static void Main(string[] args) {
            // Create an Otter game with default parameters.
            var game = new Game();
            // Set the background color.
            game.Color = new Color(0.2f, 0.2f, 0.5f);
            // Want to show the mouse for this example.
            game.MouseVisible = true;

            // Create a new scene.
            var scene = new Scene();

            // Add some text edit boxes to the scene at various positions.
            scene.Add(new TextEditBox(100, 100));
            scene.Add(new TextEditBox(100, 200));
            scene.Add(new TextEditBox(100, 300));

            // Start up the game using the scene we just made.
            game.Start(scene);
        }
    }

    class TextEditBox : Entity {

        // The text graphic to display.
        public Text Text = new Text();
        // The background image to display the text on.
        public Image ImageBox = Image.CreateRectangle(400, 20);

        // Wether or not the entity has focus or not.
        public bool HasFocus;

        // The size limit of the string.
        public int CharacterLimit = 44;

        // The string inputted into the box.
        public string InputString = "";

        public TextEditBox(float x, float y) : base(x, y) {
            // Configure the box for the text.
            ImageBox.OutlineColor = Color.Black;
            ImageBox.OutlineThickness = 3;

            // Set the color of the text to black.
            Text.Color = Color.Black;

            // Add the graphics.
            AddGraphic(ImageBox);
            AddGraphic(Text);
        }

        public override void Update() {
            base.Update();

            // If the text box currently has focus then set the Text's string to the Input KeyString.
            if (HasFocus) {
                InputString = Input.KeyString;
                // If we exceed the character limit...
                if (InputString.Length > CharacterLimit) {
                    // Only keep the characters from under the limit.
                    InputString = InputString.Substring(0, CharacterLimit);
                    // Then set the KeyString to get rid of characters beyond the limit.
                    Input.KeyString = InputString;
                }

                // If the character limit isn't reached...
                if (InputString.Length < CharacterLimit) {
                    // Display a blinking pipe character.
                    if (Timer % 30 >= 15) {
                        Text.String = InputString + "|";
                    }
                    else {
                        Text.String = InputString;
                    }
                }
                else {
                    // If we're at the limit just show the string
                    Text.String = InputString;
                }
            }
            else {
                // If no focus then just display the string normally.
                Text.String = InputString;
            }

            // If the mouse button left is pressed check if I was clicked on.
            if (Input.MouseButtonPressed(MouseButton.Left)) {
                if (Util.InRect(Scene.MouseX, Scene.MouseY, X, Y, 400, 50)) {
                    if (!HasFocus) {
                        // If I was clicked on, and I didn't have focus, then I now have focus.
                        Focus();
                    }
                }
                else {
                    if (HasFocus) {
                        // If I wasn't clicked on, and I had focus, then I don't have focus.
                        Unfocus();
                    }
                }
            }

            if (HasFocus) {
                // If we have focus check for the return key.
                if (Input.KeyPressed(Key.Return)) {
                    // If pressed then unfocus.
                    Unfocus();
                }
            }
        }

        public void Focus() {
            // Set focus to true.
            HasFocus = true;
            // When this object first gets focus set the Input.KeyString to the current string of the text.
            Input.KeyString = InputString;
            // Also make the outline color fancy yay.
            ImageBox.OutlineColor = Color.Yellow;
        }

        public void Unfocus() {
            // Set focus to false.
            HasFocus = false;
            // Trim the string (in case we added a \n from the return.)
            InputString = InputString.Trim();
            // Restore the outline color to black.
            ImageBox.OutlineColor = Color.Black;
        }

    }
}

BitteWenden

  • Member
  • Posts: 13
    • View Profile
Re: Adding a textbox to a scene?
« Reply #3 on: April 07, 2015, 01:59:15 AM »
A little late but changed this example a little bit because it has some problems with more than one textbox. I think this should work better.

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Otter;

namespace SpaceBuild.GUI
{
    class TextBox : Entity
    {

        // The text graphic to display.
        public Text Text = new Text("", Assets.FONT_RODUS, Global.SPACEBUILD.Width / 30);
        // The background image to display the text on.
        public Image ImageBox;
       
        // Wether or not the entity has focus or not.
        public bool HasFocus;

        // The size limit of the string.
        public int CharacterLimit;

        // The string inputted into the box.
        public string InputString = "";

        public TextBox(float x, float y, int width, int height, int limit)
            : base(x, y)
        {
            ImageBox = Image.CreateRectangle(width, height);
            // Configure the box for the text.
            ImageBox.OutlineColor = Color.Black;
            ImageBox.OutlineThickness = 2;
            CharacterLimit = limit;
            // Set the color of the text to black.
            Text.Color = Color.Black;
            Text.Y = Text.Y - 8;
            // Add the graphics.
            AddGraphic(ImageBox);
            AddGraphic(this.Text);
        }

        public override void Update()
        {
            base.Update();

            // If the text box currently has focus then set the Text's string to the Input KeyString.
            if (HasFocus)
            {
                InputString = InputString + Input.KeyString;
                Input.ClearKeystring();
                // If we exceed the character limit...
                if (InputString.Length > CharacterLimit)
                {
                    // Only keep the characters from under the limit.
                    InputString = InputString.Substring(0, CharacterLimit);
                    // Then set the KeyString to get rid of characters beyond the limit.
                    Input.KeyString = InputString;
                }

                // If the character limit isn't reached...
                if (InputString.Length < CharacterLimit)
                {
                    // Display a blinking pipe character.
                    if (Timer % 30 >= 15)
                    {
                        Text.String = InputString + "|";
                    }
                    else
                    {
                        Text.String = InputString;
                    }
                }
                else
                {
                    // If we're at the limit just show the string
                    Text.String = InputString;
                }
            }
            else
            {         
                // If no focus then just display the string normally.
                Text.String = InputString;
               
            }

            // If the mouse backButton left is pressed check if I was clicked on.
            if (Input.MouseButtonPressed(MouseButton.Left))
            {
                if (Util.InRect(Scene.MouseX, Scene.MouseY, X, Y, ImageBox.Width, ImageBox.Height))
                {
                    if (!HasFocus)
                    {
                        // If I was clicked on, and I didn't have focus, then I now have focus.
                        Focus();
                    }
                }
                else
                {
                    if (HasFocus)
                    {
                        // If I wasn't clicked on, and I had focus, then I don't have focus.
                        Unfocus();
                    }
                }
            }

            if (HasFocus)
            {
                // If we have focus check for the return key.
                if (Input.KeyPressed(Key.Return))
                {
                    // If pressed then unfocus.
                    Unfocus();
                }
            }
        }

        public void Focus()
        {
            // Set focus to true.
            HasFocus = true;
            // When this object first gets focus set the Input.KeyString to the current string of the text.
            /*Input.KeyString = InputString;*/
            Input.ClearKeystring();
            // Also make the outline color fancy yay.
            ImageBox.OutlineColor = Color.Bytes(25, 25, 112, 255);
        }

        public void Unfocus()
        {     
            // Set focus to false.
            HasFocus = false;
            // Trim the string (in case we added a \n from the return.)
            InputString = InputString.Trim();
            // Restore the outline color to black.
            ImageBox.OutlineColor = Color.Black;
        }

    }
}

Instead of setting the InputString equal to the currently entered KeyString I'm adding the entered String to the current string of the textbox and then clear the InputKeyString so it doesn't write the entered letter endless. When the textbox gets focused I also don't set the InputKeyString to the current Textbox String because this isn't necessary anymore. Instead I again clear the currentKeyString.