tags:

views:

901

answers:

7

I've made many different seperate parts of a GUI system for the Nintendo DS, like buttons and textboxes and select boxes, but I need a way of containing these classes in one Gui class, so that I can draw everything to the screen all at once, and check all the buttons at once to check if any are being pressed. My question is what is the best way organize all the classes (such as buttons and textboxes) into one GUI class?

Here's one way I thought of but it doesn't seem right:

Edit: I'm using C++.

 class Gui {
      public:
           void update_all();
           void draw_all() const;
           int add_button(Button *button); // Returns button id
           void remove_button(int button_id);
      private:
           Button *buttons[10];
           int num_buttons;
 }

This code has a few problems, but I just wanted to give you an idea of what I want.

A: 

Perhaps re-title this to get a bit more attention? (mention that its for the DS specifically)

Michael Neale
A: 

One useful strategy to keep in mind might be the composite pattern. At a low level, it might allow you to treat all GUI objects (and collections of objects) more easily once built. But I have no idea what's involved in GUI framework design, so one place to find general inspiration is in the source code of an existing project. WxWidgets is a cross-platform GUI framework with source available. Good luck with your project!

A: 

I think looking at the way other GUI toolkits have done it would be an excellent place to start. For C++ examples, I hear lots of good things about Qt. I haven't used it personally though. And of course WxWidgets as Nick mentioned.

Bernard
+2  A: 

This question is very similar to one I was going to post, only mine is for Sony PSP programming.

I've been toying with something for a while, I've consulted some books and VTMs, and so far this is a rough idea of a simple ui systems.

class uiElement()
{
    ...
    virtual void Update() = 0;
    virtual void Draw() = 0;
    ...
}

class uiButton() public : uiElement
{
    ...
    virtual void Update();
    virtual void Draw();
    ...
}

class uiTextbox() public : uiElement
{
    ...
    virtual void Update();
    virtual void Draw();
    ...
}

... // Other ui Elements

class uiWindow()
{
    ...
    void Update();
    void Draw();

    void AddElement(uiElement *Element);
    void RemoveElement(uiElement *Element);

    std::list <uiElement*> Elements;

    ...
}

void uiWindow::Update()
{
    ...
    for (list <uiElement*>::iterator it = Elements.begin(); it != Elements.end(); it++ )
        it->Update();
    ...
}

void uiWindow::Draw()
{
    ...
    for (list <uiElement*>::iterator it = Elements.begin(); it != Elements.end(); it++ )
        it->Draw();
    ...
}

The princple is to create a window and attact ui Elements to it, and call the draw and update methods from the respective main functions.

I don't have anything working yet, as I have issues with drawing code. With different APIs on the PC and PSP, I'm looking at some wrapper code for OpenGL and psp gu.

Hope this helps.

thing2k

thing2k
A: 

You may want to consider an immediate mode GUI technique for that particular platform.

Judge Maygarden
A: 

I've written a very simple GUI just like you propose. I have it running on Windows, Linux and Macintosh. It should port relatively easily to any system like the PSP or DS too.

It's open-source, LGPL and is here:

http://code.google.com/p/kgui/

KPexEA
+3  A: 

For anyone who's interested, here's my open source, BSD-licenced GUI toolkit for the DS:

http://www.sourceforge.net/projects/woopsi

thing2k's answer is pretty good, but I'd seriously recommend having code to contain child UI elements in the base uiElement class. This is the pattern I've followed in Woopsi.

If you don't support this in the base class, you'll run into major problems when you try to implement anything more complex than a textbox and a button. For example:

  • Tab bars can be modelled as multiple buttons grouped together into a single parent UI element that enforces mutual exclusiveness of selection;
  • Radio button groups (ditto);
  • Scroll bars can be represented as a slider/gutter element and up/down buttons;
  • Scrolling lists can be represented as a container and multiple option UI elements.

Also, it's worth remembering that the DS has a 66MHz CPU and 4MB of RAM, which is used both to store your program and execute it (DS ROMs are loaded into RAM before they are run). You should really be treating it as an embedded system, which means the STL is out. I removed the STL from Woopsi and managed to save 0.5MB. Not a lot by desktop standards, but that's 1/8th of the DS' total available memory consumed by STL junk.

I've detailed the entire process of writing the UI on my blog:

http://ant.simianzombie.com/blog

It includes descriptions of the two algorithms I came up with for redrawing the screen, which is the trickiest part of creating a GUI (one just splits rectangles up and remembers visible regions; the other uses BSP trees, which is much more efficient and easier to understand), tips for optimisation, etc.

Ant
Yeah I've heard of Woopsi, I'll take a closer look at it. Also thanks for the link to your blog, it looks interesting :)
yjerem