Sign in to follow this  
Fire Lancer

UI in direct3D

Recommended Posts

What is the best way to create a UI in direct3D? Idealy Id like to break it down into a number of classes with Update, Render, and On* events but I'm not sure of the best implementation :(. I also would like a way to have tool tips but buttons etc. eg I would like these classes, so I can have a list of Base* to iterate through for update/render... For example, should individel buttons be derived from the Button class, or should there be just one Button class, with a pointer to the OnClick() function? And I'm at a real loss for the texbox, I want t0 allow copy/paste, numeric only, being able to select the text, etc....Also while the textbox is "active" all other key events should be "blocked" For dropdown boxes I need a way to stop the mouse regestering on what evers "under" the list as well, while still alloing things "outside" to work, as well as closeing the box...
namespace ui
{
    class Base
    {
        float x,y;
        virtual void Update()=0;
        virtual void Render()=0;
    };
    class Image : public Base
    {
        IDirect3DTexture9 *Image;
    };
    class Label : public Base
    {
        std::string Text;
    };
    class Button : public Base
    {
        IDirect3DTexture9 *ImageHover, ImagePressed, *ImageHover;
        std::string Text, ToolTip;
    };
    class ToggleButton : public Base
    {
        int State;
        IDirect3DTexture9 *ImageUp, *ImageDown, *ImageUpHover, ImageDownHover;
        std::string Text, ToolTip;
    };
    class TextBox : public Base
    {
        IDirect3DTexture9 *Background;
        std::string Text, ToolTip;
    };
    class DropDownBox : public Base
    {
        int CurrentChoice;
        std::vector<std::string>Options;
    };
}

Share this post


Link to post
Share on other sites
I would come at it a little more like this:

Have a base class Control, which has virtual event-handling functions, onClick(), onKeyDown(), onFocus() etc, and a uniform interface for getting the information(getString, getNumber, getBool). There needs to be some mechanism for switching which control has focus. This is probably just the current game state's event-capturing system. There would have to be a Control* focusedControl; or something that contains the currently focused control. It would capture clicks, iterate through the list of controls, and check if the click collided with any of them. If it did, put that control into focusedControl, and give it an onClick event. Any key-press events are routed straight into the control pointed at by focusedControl.

Buttons: Only subclass Buttons for different types, not for each one.

Textbox: it's not really a matter of "blocking" events, but just of re-directing them.

Drop-Down: Hmm. Just expand the collision rect to prevent de-focusing. You might want each menu element to be a control itself, of a special DropDownMenuElement type. The menu has it's own DropDownMenuElement* focusedControl, and uses the onClick events given it by the main event loop to update it. You probably get the idea. An onUnfocus event would tell the menu to collapse and shrink it's collision box back down.

Tool-Tips: MouseOver events? each control would be responsible for it's own tool-tip probably, if any. Or you might try some system where each element just supplies a tool-tip string, and lets someone else handle. I don't have any ideas on how to implement that cleanly, though.

Sorry for the slightly incoherent post, I made half of this up as I went!

Share this post


Link to post
Share on other sites
Ok, I still can't really think of an implmentation design, like how am I meant to "redirect" input which is held in a buffer?

I searched around but could not find any articles on how most games do there UI's...

Share this post


Link to post
Share on other sites
I'm not sure what you mean by a buffer. I'm talking about taking raw-board events and passing them straight to the textbox

psuedo-python, in your main loop

for event in events:
if event.type == MOUSE_DOWN:## if there's a click
for control in listOfControls:
if collide(control.rect, event.x, event.y):
focusedControl = control
focusedControl.onFocus()
focusedControl.onClick(event.x, event.y)
if event.type == KEY_DOWN:
if focusedControl:##there might not be a focused control yet, if user hasn't clicked
focusedControl.onKeyDown(event.key)##you might choose to translate this to an actual character now, or leave it to the control, if it cares
if event.type == MOUSE_MOVE:
##you may want to pass these, too, but they might be tricky
##it would be a nice effect for a control to light up with a mouseover.



The text box would be responsible for maintaining its own buffer, if that's what you mean.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this