Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » GUI present in Allegro 5?

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
GUI present in Allegro 5?
Martin Kalbfuß
Member #9,131
October 2007
avatar

For linux there is no standard file dialog, because there is no standard gui.
But 2 gui's are mostly used. qt and gtk. So, for using such a dialog you has to link the libraries.

You could use wx for such a things, because its file dialog looks like a native one on different platforms.

But you cannot integrate them into your game. So better do your own dialog.

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

SiegeLord
Member #7,827
October 2006
avatar

KnightWhoSaysNi, look at this: this thread. But overall, I agree with Martin Kalbfuß.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Steve Terry
Member #1,989
March 2002
avatar

NASGUI has potential, just nobody ever used it :P

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

axilmar
Member #1,204
April 2001

Quote:

See what I mean? You just can't please everyone. AllegroGUI is fine as is for what it does. If you want something more complex, get a 3rd party addon. Am I to stop doing my primitives addon because I can't do all that libcairo does? Should the audio addons be scrapped because they cannot do a full 3D sound refraction and handling like a good sound library would do? Clearly, you people are missing the point of Allegro (at least according to me). Allegro's point is to allow people to provide the basics, basics without which it would be impossible to make games. And GUI is a basic need. Layout is not necessary for a game, I pray you tell me where the layout engine for Quake's GUI system is located. Data events? If they fit in the general event queue method, then fine, but otherwise just use plain member access. Input focus? AllegroGUI of old did that. Data validation? Do it yourself.

A way to proceed would be just to reimplement A4 GUI given that there is a new event method system, but still allow for d1-3, dp1-3 to be used for people who don't want to interact with their GUI via events. Also, fix all of the blocking GUI bugs in A4. Perhaps make it a little more pretty by default. And that should be enough for 90% of games out there. For the 10% that want a Qt equivalent, let them make their own or use some sort of 3rd party lib.

Aha. So we are talking about a game gui, not a tools gui for making game-oriented tools.

So the core issues are:

1) screen update method.

For full screen games, it makes sense that the GUI is redrawn every frame, especially for those games that use triple or double buffering.

For non-full screen games, a clever GUI update method is required that updates only those parts that need to be updated, i.e. a dirty rectangle system or dirty tiling system or something similar.

2) styling functionality. The GUI should be easily adaptable to different styles. This means that the old DIALOG structure is no longer appropriate, because each widget needs extra space to hold all its styling-related properties.

3) Widget hierarchies? being able to move one widget and have all the children move along?

4) adding widgets at run-time to a dialog? this is not possible, currently, because DIALOG structures are put in arrays.

Is there somewhere documentation about the Allegro 5 API? I'd like to study it so as that I have a better view of what is possible with it and what is not, in the context of GUI, of course.

Milan Mimica
Member #3,877
September 2003
avatar

Quote:

1) screen update method.

For full screen games, it makes sense that the GUI is redrawn every frame, especially for those games that use triple or double buffering.

For non-full screen games, a clever GUI update method is required that updates only those parts that need to be updated, i.e. a dirty rectangle system or dirty tiling system or something similar.

Completely missed. With A5, always redraw every frame.

Some API documentation is here: http://wiki.allegro.cc/index.php?title=NewAPI
Not always accurate enough or up to date.

Martin Kalbfuß
Member #9,131
October 2007
avatar

I think styling should be handled separately. I'm working on this at the moment. The standard gui elements call some theme related functions which are reading a theme file and drawing the widget with the present informations. It is working fine. Not all elements are rewritten, to do so.

At the moment:

d_box_proc
d_shadow_box_proc
d_button_proc
d_edit_proc

The theme functions are:

1 
2/*drawing the widgets(border and background)*/
3void draw_box(int x, int y, int w, int h, int border, DATAFILE *data_file, WIDGET_STATE state);
4 
5/*needed for the menu seperator*/
6void draw_line(int x, int y, int w, DATAFILE *data_file);
7 
8/*set drawing area for widget content*/
9CLIPRECT set_clipping_rect(int x, int y, int w, int h, int lb, int rb, int tb, int bb);
10 
11/*restore drawing area to standard settings after drawing*/
12void restore_clipping_rect(void);
13 
14/*For transparent widgets. No good solution. But simple*/
15BITMAP *save_background(int x, int y, int w, int h);
16 
17/* in work */
18 
19/*set clipping rect from theme file information*/
20void set_theme_clipping_rect(DATAFILE *data_file, WIDGET_STATE state);

I think dirty rectangles should be banned. They are not really needed. With buffering transparency and animation support could be easily integrated

The d_button_proc as an example:

1 
2int d_my_button_proc(int msg, DIALOG *d, int c)
3{
4 switch(msg)
5 {
6 case MSG_DRAW:
7 
8 if (d->flags & D_SELECTED)
9 draw_box(d->x, d->y, d->w, d->h, 0, gui_theme, SELECTED);
10 
11 else if(d->flags & D_GOTFOCUS)
12 draw_box(d->x, d->y, d->w, d->h, 0, gui_theme, FOCUSED);
13 
14 else if(d->flags & D_DISABLED)
15 draw_box(d->x, d->y, d->w, d->h, 0, gui_theme, DISABLED);
16
17 else
18 draw_box(d->x, d->y, d->w, d->h, 0, gui_theme, NORMAL);
19 
20 /*this should be replaced py set_theme_clipping_rect, because drawing area should be part of the theme*/
21 set_clipping_rect(d->x, d->y, d->w, d->h, 2, 2, 2, 2);
22 
23 gui_textout_ex(gui_get_screen(), d->dp, (d->x + d->w/2.0) + 0.5,(d->y + d->h/2.0 - text_height(font) / 2.0) + 0.5, makecol(0,0,0), -1, TRUE);
24 
25 restore_clipping_rect();
26
27 
28 return D_O_K;
29 
30
31 default:
32 
33 return d_button_proc(msg, d, c);
34 }
35}

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

SiegeLord
Member #7,827
October 2006
avatar

Quote:

2) styling functionality

I was thinking of storing that in the AL_GUI_MANAGER struct, it would hold basically the functions that Martin Kalbfuß suggested (draw rectangle of various varieties: raised, sunken, etc), font to use, current colours etc. By default it'd just use primitivies for those, but a dedicated user would be able to overwrite those vtable entries to some other, theme enhanced buttons. My understanding is that people use d_icon_proc anyway (a bitmap button), so that shouldn't be too much of a problem.

Quote:

3) Widget hierarchies

This is a common request, and I think it would be an easy and very useful addition.

Quote:

4) adding widgets at run-time to a dialog?

My understanding is that allegro5 has a public resizeable array API? And even it is isn't public, my suggestion of having specific add_widget function blend right into that.

In my opinion, A5's gui, if any, should be tiny and extremely simple to use, at the cost of flexibility and features. There should be some basic customizeability, but just taking a survey of most games most GUI's they use are restricted to either a static bitmap, or naked text.

Martin Kalbfuß, what are the clipping functions for? And there is no problem rewriting much of the allegro GUI anyway, it's broken in many places as is.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Martin Kalbfuß
Member #9,131
October 2007
avatar

The clipping functions set the rectangle area, the content will be shown in. Content, overlapping the rectangle isn't drawn. This is used for button text for example, when the button is to small for the whole text.

And it returnes a CLIPTRECT struct, containing, x1, x2, y1 and y2. These values can be used to position the content.

typedef struct
{
  int x1, y1,
      x2, y2;
}  
CLIPRECT;

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

SiegeLord
Member #7,827
October 2006
avatar

I'd just draw the text so it would just go outside of bounds, it's the darn user's fault that his text is too long :P

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Martin Kalbfuß
Member #9,131
October 2007
avatar

This function isn't very usefull at the moment. It is a low level function, that will be used by the set_theme_clipping_rect function. This function is reading the needed values for the borders out of the theme file, and then calls the set_clipping_rect function, to set the wanted behaviour.

The final function, that will be used, is:

CLIPRECT set_theme_clipping_rect(int x, int y, int w, int h, DATAFILE *themeobject, WIDGET_STATE state);

I forgot the x,y,w and h values. They are still needed.

The button wasn't a good example. Imagine a popup menu with some kind of popup effect. By using set_clipping_rect or set_theme_clipping_rect the content of the menu will never overflow the given area when resizing for realizing the popup effect.

Another use could be for dynamic resizeable widgets.

The edit_proc needs it, too.

http://remote-lisp.spdns.de -- my server side lisp interpreter
http://www.nongnu.org/gm2/ -- Modula-2 alias Pascal++

Timorg
Member #2,028
March 2002

axilmar said:

4) adding widgets at run-time to a dialog? this is not possible, currently, because DIALOG structures are put in arrays.

There is absolutely nothing stopping you adding widgets into the array on the fly, as long as you are careful and have enough room to store them in. I have done it with one of my projects before. You either add your items, making sure that when you overwrite the original NULL, the new one has to be at the end is ready to mark where to stop. Or you have a dummy proc you can overwrite later. ie...

int d_dummy_proc(int msg, DIALOG *d, int c)
{
  return D_O_K;
}

You have a heap of them in a row, estimating how many you actually need, and you know they start at index whatever. You just setup the data variables and the flags before you set the proc for it. When you are changing it back to the dummy one, make sure you set the proc, before you change the variables. I guess this could crash if that index of the dialog is active that you are changing. I have never tried this method to take out things from a dialog. You would have to have a blocking dialog proc, that would alert whatever code is updating the array. That will cause the dialog to unblock. (aka Semaphores)

I have also hacked allegro so that it works out of a stl vector. (It was a dodgy hack that still looked for the NULL at the end.)

DLG v0.43 - a DIALOG editor
Creates dialogs on the fly, so its more than possible to setup a system where you can add and remove objects.

I don't know if its easier to do freaky things in C, or because of the feature set of C++ its generally not required. But you can pretty much do anything as long as no one else or you, have to look at the code later, or parts of your brain will melt. I can't find the example, but this is going back quite a few years, but using pipes with gcc, to compile c code on the fly, then loading the code into memory then running it. I guess it is forcing Reflective-ness into a language that really doesn't support it.

tldr;
Being in an array actually means that its quite simple to add new objects, it just means that you have to be careful. If they were stored in some internal array, it would make it (without hacking) hard to add anything. Being open like it is, makes it quite simple to add more, but with great power comes great responsibility, etc, etc.

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Johan Halmén
Member #1,550
September 2001

The d_dummy_proc() is very handy at coding time, too. I have it there in most projects with dialogs. If I decide to delete one control in the middle or beginning of a dialog struct, I just replace it with the dummy. All indices remain ok. The index thing is the only big disadvantage of Allegro gui. I mean the do_dialog() returning the index number of the control exiting the dialog. The do_dialog() could instead return one int stored in the control:

   int x, y, w, h;       - position and size of the object
   int fg, bg;           - foreground and background colors
   int key;              - ASCII keyboard shortcut
   int flags;            - flags about the status of the object
   int d1, d2;           - whatever you want to use them for
   void *dp, *dp2, *dp3; - pointers to more object-specific data
   int id                - user defined id for the entry, returned by do_dialog() if
                           the dialog was closed with this widget

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

axilmar
Member #1,204
April 2001

Milan Mimica said:

Completely missed. With A5, always redraw every frame.

So there is no need for a dirty rectangle system or an update mechanism, right? I guess all the dialogs will be refreshed at each frame then. Good, this simplifies things a lot.

Martin Kalbfuß said:

I think styling should be handled separately. I'm working on this at the moment. The standard gui elements call some theme related functions which are reading a theme file and drawing the widget with the present informations.

When you say 'reading a theme file' I hope you don't mean at every frame, do you? That would be disastrous.

So the theme file should be loadable and then passed around to the widgets.

SiegeLord said:

I was thinking of storing that in the AL_GUI_MANAGER struct, it would hold basically the functions that Martin Kalbfuß suggested (draw rectangle of various varieties: raised, sunken, etc), font to use, current colours etc. By default it'd just use primitivies for those, but a dedicated user would be able to overwrite those vtable entries to some other, theme enhanced buttons. My understanding is that people use d_icon_proc anyway (a bitmap button), so that shouldn't be too much of a problem.

Not a bad idea. Perhaps each widget should have a pointer to a style manager, and the style manager contains a vtable of methods used for drawing the widgets. Changing the style manager will automatically change the widgets.

SiegeLord said:

This is a common request, and I think it would be an easy and very useful addition.

I think it's useful as well, but this means that widgets will be stored trees, with pointers to parent and children and siblings, not stored in arrays.

By the way, here is another question: since widgets can be are hierarchical, will parent widgets clip their children?

And yet another question: how to handle the focus, when widgets are hierarchical?

SiegeLord said:

My understanding is that allegro5 has a public resizeable array API? And even it is isn't public, my suggestion of having specific add_widget function blend right into that.

The tree functions can cover that.

SiegeLord said:

In my opinion, A5's gui, if any, should be tiny and extremely simple to use, at the cost of flexibility and features.

Agreed, but the gui should also be designed in such a way that it is easily extensible. There is no reason to reimplement parts of it in other libraries just in order to add something useful to it.

Timorg said:

There is absolutely nothing stopping you adding widgets into the array on the fly, as long as you are careful and have enough room to store them in. I have done it with one of my projects before. You either add your items, making sure that when you overwrite the original NULL, the new one has to be at the end is ready to mark where to stop. Or you have a dummy proc you can overwrite later. ie...

I am sorry, it's an ugly hack not good for writing quality code.

For example:

Johan Halmén said:

The d_dummy_proc() is very handy at coding time, too. I have it there in most projects with dialogs. If I decide to delete one control in the middle or beginning of a dialog struct, I just replace it with the dummy. All indices remain ok. The index thing is the only big disadvantage of Allegro gui.

SiegeLord
Member #7,827
October 2006
avatar

I agree that a tree structure is best, I for some reason was thinking of storing the individual children in an array... a list is probably better.

Quote:

By the way, here is another question: since widgets can be are hierarchical, will parent widgets clip their children?

And yet another question: how to handle the focus, when widgets are hierarchical?

I don't like clipping in general, unless it's a flag or something. But, I can't really think of a good need for widgets that are not clipped by their parents, so I think either way is fine with me.

For hierarchical focus, I was thinking for the focus to be on a level-per-level basis. I.e. the root widget would have one of its children have focus. The child that has focus, has one of its children also have focus and so on and on. For input things, the input event will get passed down the tree until someone can handle it. So, say you have a dialog with an edit box. Normal key input will be handled by the edit box, that has focus. The ESC key, however, would be intercepted by the dialog before it reaches the edit box, and close the dialog. Usually, the top level widgets wouldn't be able to handle any events, but by keeping each level in the widget hierarchy with a separate focus flag will allow for easy keeping track of which widgets actually have focus I think.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Timorg
Member #2,028
March 2002

axilmar said:

For example:
[quote Johan Halmén]
The d_dummy_proc() is very handy at coding time, too. I have it there in most projects with dialogs. If I decide to delete one control in the middle or beginning of a dialog struct, I just replace it with the dummy. All indices remain ok. The index thing is the only big disadvantage of Allegro gui.

</quote>

Personally I don't use the index method, because of its flaws, to share information between widgets, I use the message system and send user messages to them. At most only one is going to be refereed to by index, and that is the one that updates variables external to the dialog. By either changing global variables, or by changing a struct stored in one of its data pointers.

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

axilmar
Member #1,204
April 2001

Quote:

For hierarchical focus, I was thinking for the focus to be on a level-per-level basis. I.e. the root widget would have one of its children have focus. The child that has focus, has one of its children also have focus and so on and on. For input things, the input event will get passed down the tree until someone can handle it. So, say you have a dialog with an edit box. Normal key input will be handled by the edit box, that has focus. The ESC key, however, would be intercepted by the dialog before it reaches the edit box, and close the dialog. Usually, the top level widgets wouldn't be able to handle any events, but by keeping each level in the widget hierarchy with a separate focus flag will allow for easy keeping track of which widgets actually have focus I think.

Excellent, truly excellent idea!!!!

Matt Smith
Member #783
November 2000

It's nice to have add_button() style funcs. adime provided this for Allegro many years ago.

Part of the charm and simplicity of Allegro GUI has been the ability to statically define DIALOG arrays, but for anything except the simplest menus this becomes thorughly evil, because you need to adjust so many things at runtime anyway. I started this post to defend static arrays but now I find I can't :) Burn them, plant a nice tree.

 1   2   3 


Go to: