DownUnder UI, a MonoGame based UI framework

I’ve been working on this daily for the past year or so now and I have absolutely no idea how to present it. Here it is.

What’s going on here is a bit more complicated than it seems, each rectangle is a Widget. I’m currently working on a WidgetBehavior system that adds additional behaviors to Widgets.

The goal of this project is ultimately to combine MonoGame/XNA with the workflow of a UI framework such as Qt, Windows Forms, or UWP, and to build past those platforms with more visually appealing graphical effects. But there is still a lot of work to be done, and I plan on heavily integrating this with MonoGame from the top down relying on the framework for cross-platform capabilities.

Setup and usage guide here.

4 Likes

Progress post, because why not? I like working in my own little hobbit hole, but I might as well share more.

Still working on this. It will be developing alongside my other project, and probably with every project I work on from here on out. My current one happens to be a website front end. Every scenario I run into I see what still needs to be done in my library.

The various misalignments will be fixed with a little more polish! I’ve already got some ideas on how to automate that. OCD pays off in UI design. There will also be a couple of nice shaders once I’m done with this specific widget, though I’m am a fan of the simplistic black with white lines. I imagine modern design to be most importantly “things that don’t hurt your eyes at 3:00 AM because no one sleeps anymore”

The code for this UI is as follows if anyone is interested in seeing how the workflow is. I was working on a visual designer, but serialization is very annoying and I’d rather not deal with it right now. Like windows forms/Qt it can easily be done in code.

using DownUnder.UI.Widgets;
using DownUnder.UI.Widgets.Behaviors.Functional;
using DownUnder.UI.Widgets.Behaviors.Visual;
using DownUnder.UI.Widgets.Behaviors.Visual.DrawTextBehaviors;
using DownUnder.UI.Widgets.DataTypes;
using MonoGame.Extended;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PRTCommonWidgets
{
    public static class CommonWidgets
    {
        public static Widget LoginLayout()
        {
            Widget layout = new Widget { ChangeColorOnMouseOver = false };
            Widget inner = new Widget { Size = new Point2(370, 270) };
            inner.Behaviors.Add(new PinPosition { Pin = InnerWidgetLocation.Centered });
            inner.ChangeColorOnMouseOver = false;

            Widget username_entry = new Widget { Position = new Point2(160, 70), Width = 150, Height = 40 };
            Widget password_entry = new Widget { Position = new Point2(160, 130), Width = 150, Height = 40 };
            Widget username_label = new Widget { Position = new Point2(50, 70), Width = 60, Height = 40, DrawBackground = false, DrawOutline = false };
            Widget password_label = new Widget { Position = new Point2(50, 130), Width = 60, Height = 40, DrawBackground = false, DrawOutline = false };
            Widget login_button = new Widget { Area = new RectangleF(160, 190, 150, 40) };

            username_label.Behaviors.Add(new DrawText { Text = "Username: " });
            password_label.Behaviors.Add(new DrawText { Text = "Password: " });
            login_button.Behaviors.Add(new DrawText { Text = "Login", TextPositioning = DrawText.TextPositioningPolicy.center });

            username_entry.Behaviors.Add(new DrawEditableText());
            password_entry.Behaviors.Add(new DrawEditableText());

            username_entry.Behaviors.GetFirst<DrawText>().ConstrainAreaToText = false;
            password_entry.Behaviors.GetFirst<DrawText>().ConstrainAreaToText = false;

            inner.Add(username_label);
            inner.Add(password_label);
            inner.Add(username_entry);
            inner.Add(password_entry);
            inner.Add(login_button);

            layout.Add(inner);

            return layout;
        }
    }
}

That’s a fancier login screen. I added a behavior that automatically centers widget contents, which is why the contents of the login box are centered exactly in the middle. Still a bit of asymmetry going on with the text though (and obviously you can see the password field, which is no good).

Effects are now working correctly thanks to MonoGame 3.8’s shared content template. This probably means I’ll switch from nuget to Azure DevOps to distribute the package, but its amazing at the same time, since I’ll be able to use the ContentManager in my project again without worrying about runtime compilation.

Can’t wait to get this running in the browser! :slight_smile: Great stuff MonoGame devs, I’m loving working with this framework.

2 Likes