[ XF9 ]

Buttons in MonoGame

Posted on in C#, Code.

Buttons aren’t a part of the MonoGames feature list, but they are quite easy to build. Learn how to do so here!

This is just an abstract button implementation, providing the basics for a button. It covers the following features:

  • toggle/click mode
  • color settings for the states default / hover / active (if toggle)
  • an eventhandler for broadcasting click events

If the button is in toggle mode it will stay active after clicking till it is clicked again – like an on/off switch. Otherwise it will just emit the click event and return to normal mode. According to the current state it will have color information on how to render it. Last but not least it has an eventhandler like described here so you can react to button clicks ;)

Now lets get going and have a look at the different parts of it. The full sourcecode is available from my GitHub.

First of we will need two rectangles which we will be using as boundingboxes. One for the button itself, one for the current mouseposition to check for the mouse hover event:

        /// <summary>
        /// the bounding box of the button
        /// </summary>
        protected Rectangle buttonBoundingbox;

        /// <summary>
        /// the bounding box of the mouse
        /// </summary>
        protected Rectangle mouseBoundingbox;

Next are the settings for the toggle mode:

        /// <summary>
        /// whether the button is a toggle button or a push button
        /// </summary>
        private Boolean toggle;

        private Boolean isActive;
        /// <summary>
        /// used for toggle buttons -> true = active
        /// </summary>
        public Boolean IsActive
        {
            get { return isActive; }
            set { isActive = value; }
        }

The clickhandler itself is pretty straight forward:

        /// <summary>
        /// clickhandler for click events
        /// </summary>
        public event EventHandler onClick;

The color settings – change to your desired colors. Color is the attribute you should check if you want to draw the button since it will store the current color value.

        /// <summary>
        /// the button color to draw with
        /// </summary>
        protected Color color;

        /// <summary>
        /// default color for the button
        /// </summary>
        private Color defaultColor = new Color(140, 140, 140);

        /// <summary>
        /// default color for the button if hovered
        /// </summary>
        private Color defaultHover = new Color(0, 133, 188);

        /// <summary>
        /// default color for the button if active
        /// </summary>
        private Color defaultActive = Microsoft.Xna.Framework.Color.LightBlue;

Constructor. Sets values and stuff.

        /// <summary>
        /// a basic button.
        /// </summary>
        /// <param name="toggle">should the button be a toggle button?</param>
        public Button(Boolean toggle)
        {
            this.buttonBoundingbox= new Rectangle();
            this.mouseBoundingbox = new Rectangle(0, 0, 10, 10);
            this.toggle = toggle;
            this.isActive = false;
            this.color = Color.White;
        }

This function have to be called every time the boundingbox of the button changes: on translation and scaling operations.

        /// <summary>
        /// updates the bounding box of the button
        /// </summary>
        /// <param name="buttonBoundingbox">the new bounding box</param>
        protected void UpdateBoundingbox(Rectangle buttonBoundingbox)
        {
            this.buttonBoundingbox = buttonBoundingbox;
        }

This is the update function for the button. It will take the current mouse state, move the mouse boundingbox the current cursor location, set the button state according the the mouse position and fires the onClick event if needed:

        /// <summary>
        /// button update
        /// </summary>
        /// <param name="mouseState">the current MouseState</param>
        public void Update(Microsoft.Xna.Framework.Input.MouseState mouseState){

            // if there are click listener check if the mouse is over the button
            if (this.onClick != null && this.onClick.GetInvocationList().Length > 0)
            {
                this.mouseBoundingbox.X = mouseState.X;
                this.mouseBoundingbox.Y = mouseState.Y;

                if (this.buttonBoundingbox.Intersects(this.mouseBoundingbox))
                {
                    this.color = defaultHover;

                    if (FenrirGame.Instance.Properties.Input.LeftClick)
                        this.OnClick(new EventArgs());
                }
                else
                {
                    if (this.isActive)
                        this.color = defaultActive;
                    else
                        this.color = defaultColor;
                }
            }
        }

The onClick handler. Will switch the current active state if toggle is active and emit the onClick event to all registered receivers.

        /// <summary>
        /// on click handle thing
        /// </summary>
        /// <param name="e">the click event</param>
        protected virtual void OnClick(EventArgs e)
        {
            if (this.toggle && !this.isActive)
                this.isActive = true;
            else if (this.toggle && this.isActive)
                this.isActive = false;

            EventHandler handler = onClick;
            if (handler != null)
                handler(this, e);
        }

The draw functionm .. depends on your button so you need to do that yourself ;)

        /// <summary>
        /// basic draw method .. does nothing - implement it! ;)
        /// </summary>
        public virtual void Draw() { }

Thats it folks! Happy coding :)


Write a reply or comment

Your email address will not be published.