如何制作GUI?

时间:2020-03-05 18:38:53  来源:igfitidea点击:

我为Nintendo DS制作了GUI系统的许多不同部分,例如按钮,文本框和选择框,但是我需要一种将这些类包含在一个Gui类中的方法,以便可以将所有内容绘制到屏幕上。一次,然后立即检查所有按钮以检查是否有任何按钮被按下。我的问题是将所有类(例如按钮和文本框)组织到一个GUI类中的最佳方法是什么?

这是我想到的一种方法,但似乎不正确:

编辑:我正在使用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;
}

这段代码有一些问题,但我只是想让我们了解我想要的东西。

解决方案

回答

要记住的一种有用策略可能是复合模式。从低层次上讲,它可能使我们在构建完所有GUI对象(以及对象集合)后就更加轻松。但是我不知道GUI框架设计涉及什么,因此,可以找到一个通用灵感的地方是现有项目的源代码。 WxWidgets是可提供源代码的跨平台GUI框架。祝项目好运!

回答

我认为,看看其他GUI工具包的完成方式将是一个不错的起点。对于C ++示例,我听到了很多有关Qt的好处。我还没有亲自使用过它。当然还有尼克提到的WxWidgets。

回答

这个问题与我要发布的问题非常相似,只有我的问题适用于Sony PSP编程。

我一直在玩弄一段时间,查阅过一些书籍和VTM,到目前为止,这是一个简单的ui系统的粗略概念。

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();
    ...
}

原则是创建一个窗口并向其添加ui元素,并从相应的主要函数调用draw和update方法。

我还没有任何工作,因为绘图代码有问题。在PC和PSP上使用不同的API时,我正在查看OpenGL和psp gu的一些包装代码。

希望这可以帮助。

的东西

回答

就像我们建议的那样,我编写了一个非常简单的GUI。我可以在Windows,Linux和Macintosh上运行它。它也应该相对容易地移植到任何系统,例如PSP或者DS。

它是开源的LGPL,位于以下位置:

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

回答

对于任何有兴趣的人,这是我为DS提供的BSD许可的开源GUI工具包:

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

something2k的答案是相当不错的,但我强烈建议我们在uiElement基类中包含用于包含子UI元素的代码。这是我在Woopsi中遵循的模式。

如果在基类中不支持此功能,那么当我们尝试实现比文本框和按钮更复杂的内容时,就会遇到主要问题。例如:

  • 标签栏可以建模为将多个按钮组合到一个父UI元素中,以强制选择的互斥性。
  • 单选按钮组(同上);
  • 滚动条可以表示为滑块/装订线元素和上/下按钮;
  • 滚动列表可以表示为一个容器和多个选项UI元素。

另外,值得记住的是,DS具有66MHz的CPU和4MB的RAM,用于存储程序和执行程序(DS ROM在运行前已加载到RAM中)。我们实际上应该将其视为嵌入式系统,这意味着STL已淘汰。我从Woopsi删除了STL,并设法节省了0.5MB。按台式机标准来看,这不是很多,但这只是STL垃圾消耗的DS总可用内存的1/8.

我已经详细说明了在博客上编写UI的整个过程:

http://ant.simianzombie.com/blog

它包括对我提出的用于重画屏幕的两种算法的描述,这是创建GUI时最棘手的部分(一种只是将矩形拆分并记住可见区域;另一种使用BSP树,这种树效率更高且更容易了解),优化技巧等。