allegro gui
julian_boolean

Can anyone tell me if this is even near right?

1int button::logic(int msg)
2{
3 if(is_mouse_over)
4 {
5 switch(msg)
6 {
7 case MSG_LPRESS:
8 {
9 
10 if(mouse_b & 1 && mouse_status != NOT_ON_FOCUS)
11 {
12 mouse_status = MOUSE_STATUS_DOWN;
13 draw_frame = DRAW_FRAME_DOWN;
14 play_sound = PLAY_SOUND_DOWN;
15 }
16 }break;
17
18 case MSG_LRELEASE:
19 {
20 if(!(mouse_b & 1) && mouse_status == MOUSE_STATUS_DOWN)
21 {
22 mouse_status = MOUSE_STATUS_UP;
23 draw_frame = DRAW_FRAME_ON;
24 play_sound = PLAY_SOUND_ON;
25
26 return TRUE;
27 }
28 }break;
29 }
30 }
31}

Edit:

I'm guessing I'll also need to throw MSG_IDLE in there, somewhere.

CGamesPlay

Yeah, for the most part. You don't need to check mouse_b in MSG_LRELEASE, because you wouldn't have gotten the message otherwise.

Also, make sure you get both a MSG_LPRESS and a MSG_LRELEASE. Otherwise, I can hold down the mouse button over nothing, drag to over the button, and release the mouse button, and the button would feel it had been pressed.

[append]
I am too tired. I see that you already do that ::)

julian_boolean

How about this:

1int button::logic(int msg)
2{
3 switch(msg)
4 {
5 if(is_mouse_over)
6 {
7 case MSG_LPRESS:
8 {
9 if(mouse_b & 1 && mouse_status != NOT_ON_FOCUS)
10 {
11 mouse_status = MOUSE_STATUS_DOWN;
12 draw_frame = DRAW_FRAME_DOWN;
13 play_sound = PLAY_SOUND_DOWN;
14 }
15 }break;
16
17 case MSG_LRELEASE:
18 {
19 if(mouse_status == NOT_ON_FOCUS)
20 {
21 mouse_status = MOUSE_STATUS_UP;
22 draw_frame = DRAW_FRAME_ON;
23 play_sound = PLAY_SOUND_ON;
24 }
25
26 else if(mouse_status == MOUSE_STATUS_DOWN)
27 {
28 mouse_status = MOUSE_STATUS_UP;
29 draw_frame = DRAW_FRAME_ON;
30 play_sound = PLAY_SOUND_ON;
31
32 return TRUE;
33 }
34 }break;
35 }
36
37 case MSG_IDLE:
38 {
39 mouse_status = NOT_ON_FOCUS;
40 draw_frame = DRAW_FRAME_OFF;
41 }
42 }
43}

And what did you mean by "Also, make sure you get both a MSG_LPRESS and a MSG_LRELEASE"?.. I still don't understand how I'm suppose to use this function, like this (exit->logic(MSG_LPRESS))?

CGamesPlay
Quote:

How about this:

Good, do the same for the MSG_LPRESS... and remove that crazy, invalid if statement.

Quote:

I still don't understand how I'm suppose to use this function, like this (exit->logic(MSG_LPRESS))?

Err, you pass it to an Allegro dialog in the proc field.
DIALOG

julian_boolean

Proc field eh. And which crazy invalid if statement? ;)

Thomas Fjellstrom
Quote:

and remove that crazy, invalid if statement.

If you mean the one I think you mean, its not invalid. It is crazy though ;) just move it outside the switch...

You can mix statements in with a switch iirc. its used with loop unrolling lots.

edit, maybe I'm wrong, since Duff's Device seems to start after the first label.. Meh.

julian_boolean

The if(is_mouse_over) you mean?

CGamesPlay

Yes. Besides, you won't get a MSG_LPRESS if the mouse is over a different control.

julian_boolean

If I move it outside the switch how can I draw the button graphics when the user isn't touching it?

CGamesPlay

I think you should remove the if statement entirely. Why would you get a MSG_LPRESS if the mouse wasn't over the object?

julian_boolean

Well I just don't understand how it knows. So more need of the "mouse_status" stuff?

CGamesPlay

Allegro only calls your update function with MSG_LPRESS when the current control receives a click.

julian_boolean

Yes but how does it know what the user is clicking on, is there some kinda bounds checking already made?

CGamesPlay

Yes, the Allegro GUI automatically handles that. It wouldn't be very useful if it didn't lessen your work load, would it? ;)

julian_boolean

That's sweet :D so then it SHOULD look something like this?

1int button::logic(int msg)
2{
3 switch(msg)
4 {
5 case MSG_LPRESS:
6 draw_frame = DRAW_FRAME_DOWN;
7 play_sound = PLAY_SOUND_DOWN;
8 break;
9
10 case MSG_LRELEASE:
11 draw_frame = DRAW_FRAME_ON;
12 play_sound = PLAY_SOUND_ON;
13 break;
14
15 case MSG_IDLE:
16 draw_frame = DRAW_FRAME_OFF;
17 break;
18 }
19}

Why does this look too simple/good to be true?

CGamesPlay

Not quite. MSG_IDLE will happen regardless of the mouse button's state. So that means that for 1 frame your button will have the DRAW_FRAME_DOWN image, then it will switch back to DRAW_FRAME_OFF. You need to check that !(mouse_b & 1) in the MSG_IDLE handler :)

Steve Terry

coding doesn't have to be complicated, most great programs are written elegantly such that it is coherent and easy to understand even if you didn't code it. One step further would be to register a callback in your button so that when you click you set your variables. This makes it more flexible and not hard coded to your sound player. Then you can reuse your button for anything you need. It's really very simple as:

(*(button_callback))(params);

julian_boolean

That's not so bad. Will I have to make different messange handlers for different objects or can I just have one.. To rule them all.

Not really sure what you mean about the callback thing..

Dustin Dettmer
1class Foo {
2public:
3 typedef (*ButtonCallback)();
4 
5 ButtonCallback callback;
6 
7 void foo() { callback(); }
8}
9 
10bool shit = false;
11 
12void awShit()
13{
14 shit = true;
15}
16 
17main()
18{
19 Foo f;
20 f.callback = awShit;
21 f.foo();
22 shit == true
23}

julian_boolean

Thanks :D hmm.. Could someone whip up a quick example of how this should look using the dialog handler? I get the impression I'm probably not going to need as many classes.

Steve Terry

Another way to handle callbacks with C++ is to have a virtual method inside your main button widget that is called on button press. This can be overloaded in a new button class which is derived from the main button widget. Then inside the overloaded method you do what you need to do.

Quote:

bool shit;

;D that's funny man.

nonnus29
julian_boolean

I was actually reading that awhile ago. So I'll need something like this?

// Copied from a random example

DIALOG the_dialog[] =
{
   /* (dialog proc)     (x)   (y)   (w)   (h) (fg)(bg) (key) (flags)     (d1) (d2)    (dp)                   (dp2) (dp3) */
   { d_clear_proc,        0,   0,    0,    0,   0,  0,    0,      0,       0,   0,    NULL,                   NULL, NULL  },
   { d_text_proc,         0,  10,    0,    0,   0,  0,    0,      0,       0,   0,    (void*)"enter number",  NULL, NULL  },
   { d_edit_proc,       160,  10,  160,    8,   0,  0,    0, D_EXIT,      64,   0,    (void*)the_string,      NULL, NULL  },
   { d_button_proc,     328,   6,  160,   16,   0,  0,    0, D_EXIT,       0,   0,    (void*)"OK",            NULL, NULL  },
   { d_yield_proc,        0,   0,    0,    0,   0,  0,    0,      0,       0,   0,    NULL,                   NULL, NULL  },
   { NULL,                0,   0,    0,    0,   0,  0,    0,      0,       0,   0,    NULL,                   NULL, NULL  }
};

I still don't understand how this works exactly, and how it will work with the graphics I want to use..

Dustin Dettmer

You'll have to make your own widgets if you want to use custom graphics. This is a lot of work. If you're looking to take the next step and use custom graphics I would recommend the agup library. While we're at I might as well throw in a plug for the unfinished XUI gui scripting project.

julian_boolean

I already have my own widget classes made. I just wanted to find a cleaner way to handle them without using someone elses library. Is there any way to handle my classes with the Allegro gui or do I HAVE to scrap it and use their ugly buttons?

Dustin Dettmer

Yes, there are many ways.

CGamesPlay
Quote:

Is there any way to handle my classes with the Allegro gui or do I HAVE to scrap it and use their ugly buttons?

Of course you can do it with Allegro. What's the problem?

julian_boolean

The problem is I don't know how. :P Well I have a vague idea..

CGamesPlay

Well try, fail, and post your code when you get stuck! :)

Dustin Dettmer

The trick is to look at the extra parameter the callback gets. In that parameter pass a pointer to your class object.

julian_boolean

I did post code, and when am I not stuck? :P

How is this to work with the switch(msg)?

Dustin Dettmer

You skipped the first two steps:

Ryan said:

Well try, fail, ...

julian_boolean

Very well ;) thanks for the help everyone and you'll be sure to hear back from me very shortly :P

Johan Halmén
Quote:

or do I HAVE to scrap it and use their ugly buttons?

Well, Allegro has some ugly buttons, but you can always use d_icon_proc() which is a button with three bitmaps, one for each state of the button (up, down, inactive). If that is still ugly, you suck with graphics.

I once made a class that created these three buttons on the fly. It took a string, a pattern bitmap and a font as parameters. Very simple. Every button looked a bit different. The pattern was seamless and the tiling started at a random point on each button.

Steve Terry

MASkinG and NAS both use themed buttons using 9 bitmaps per button like so:

+---+-------------+---+
|   |             |   |
+---+-------------+---+
|   |I'M A BUTTON!|   |
+---+-------------+---+
|   |             |   |
+---+-------------+---+

You have four corners, a top, bottom, left, right, and middle image. Text goes in the middle, and you can stretch or tile the other bitmaps to make the button any size. This is a much better way than a single bitmap. You can write your own Allegro Button widget by overloading the MSG draw portion of the allegro button with your own widget proc. It's not hard to do and the other messages are left alone so you won't have to recode that.

julian_boolean
Quote:

You can write your own Allegro Button widget by overloading the MSG draw portion of the allegro button with your own widget proc. It's not hard to do and the other messages are left alone so you won't have to recode that.

Yes! This is what I want to do ;) but how? (example?)

Steve Terry
int my_button_proc(int msg, DIALOG *d, int c)
{
   if(msg == MSG_DRAW)
   {
      // Draw the button
   }
   else
      return d_button_proc(msg, d, c);
}

:P

julian_boolean

I sorta understand that.. But I don't understand how it's suppose to work with the switch statement, or how I'm suppose to use the function in a game state, like is_clicked().

BAF

What switch statement?

julian_boolean

It was on the previous page:

1int button::logic(int msg)
2{
3 switch(msg)
4 {
5 case MSG_LPRESS:
6 draw_frame = DRAW_FRAME_DOWN;
7 play_sound = PLAY_SOUND_DOWN;
8 break;
9
10 case MSG_LRELEASE:
11 draw_frame = DRAW_FRAME_ON;
12 play_sound = PLAY_SOUND_ON;
13 break;
14
15 case MSG_IDLE:
16 draw_frame = DRAW_FRAME_OFF;
17 break;
18 }
19}

Something like that anyway.

BAF

Uhm, you don't need that to overload MSG_DRAW because you aren't checking for all those messages.

julian_boolean

I wish I could understand. What's the point of using this MSG_DRAW when I could use this instead? I need to draw different frames of the button if it's down, up, or whatever.

Er wait a sec, how about this?

case MSG_DRAW
{
  if(MSG_LPRESS)
  {
    draw_frame = DRAW_FRAME_DOWN;
  }
}break;

Steve Terry

The DIALOG object has a flags field. You can get the state of the button through the flags and draw accordingly. Here is code from NAS that does just that:

1if(d->flags & D_DISABLED)
2{
3 box = NAS_BUTTON_DISABLED;
4 col = NAS_TEXT_DISABLED;
5}
6else if(d->flags & D_SELECTED)
7{
8 box = NAS_BUTTON_PRESSED;
9 col = NAS_TEXT_PRESSED;
10}
11else if(d->flags & D_GOTMOUSE)
12{
13 box = NAS_BUTTON_HIGHLIGHTED;
14 col = NAS_TEXT_HIGHLIGHTED;
15}
16else if(d->flags & D_GOTFOCUS)
17{
18 box = NAS_BUTTON_FOCUSED;
19 col = NAS_TEXT_FOCUSED;
20}
21else
22{
23 box = NAS_BUTTON_UNSELECTED;
24 col = NAS_TEXT_UNSELECTED;
25}
26drawskinnedrect(wnd, &buttons.rect[box], d->x, d->y, d->x + d->w, d->y + d->h);

[edit]
DON'T mix MSG_DRAW with other messages ...
[/edit]

BAF

Uhm, a switch/case setup is the same as a whole bunch of nested if/else ifs. There is no reason to use a switch, case, or anything else in your case. What Steve posted here will work fine for you. :P

julian_boolean

Hmm.. I'll try it out, but what is NAS_BUTTON/NAS_TEXT?.. And box and col?

Steve Terry

Those are NAS GUI defines but you can use whatever you want... they are just indexes into an array of button images so that when I pass in buttons.rect into draw_skinned_rect I get the proper image to display. col IIRC is the color index of the text to display since each state of the button can have different text color.

julian_boolean

Ohh okay, so I could just use my draw_frame instead? (my text is already on the graphics)

Steve Terry

Right-o

julian_boolean

Awesome :D Thanks a ton.. One last thing, what is d?

Steve Terry
DIALOG struct said:

int (*proc)(int, DIALOG *, int); - dialog procedure
(message handler)
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

d is a pointer to this structure, you have flags... which you can use to get the state of the widget. Positional and size values are x, y, w, h. dpX are pointers to any kind of data you wish (can include a callback function for your button).

julian_boolean

How's this! And will I be able to use the same function for any kinda widget, like radio buttons or text fields?

1int button::is_clicked(void)
2{
3 if(d->flags & D_DISABLED)
4 {
5 draw_frame = DRAW_FRAME_DISABLED
6 }
7 
8 else if(d->flags & D_SELECTED)
9 {
10 draw_frame = DRAW_FRAME_DOWN;
11 play_sound = PLAY_SOUND_DOWN;
12 
13 return TRUE;
14 }
15 
16 else if(d->flags & D_GOTMOUSE)
17 {
18 draw_frame = DRAW_FRAME_ON;
19 play_sound = PLAY_SOUND_ON;
20 }
21 
22 else if(d->flags & D_GOTFOCUS)
23 {
24 // ??
25 }
26 
27 else
28 {
29 draw_frame = DRAW_FRAME_OFF;
30 }
31 
32 return FALSE;
33 
34 // what the hell is this
35 drawskinnedrect(wnd, &buttons.rect[box], d->x, d->y, d->x + d->w, d->y + d->h);
36}

Steve Terry

... is that valid code???

julian_boolean

/bawl.. What am I doing wrong?

Steve Terry

Ok what the hell is your button class? It keeps changing but it still makes no sense. You basically copied my code I gave you and pasted it into your is_clicked method but the code I gave you was for my GUI as a demonstration on how you should handle things. It was not to be taken literally. Your button has an is_clicked method but the code you have inside it has nothing to do with it being clicked.. it's more of a draw method and yet you still use play_sound inside of it which also makes no sense. You keep hanging onto your class, we're just trying to show you how you can make pretty buttons using the Allegro built in GUI. You can pretty much take the Allegro GUI and extend the procs to make pretty nice looking GUI elements. NAS does pretty much that and it extends all the procs to have more functionality. It's up to you how you want to your buttons but the thread is labeled Allegro GUI so I assumed you wanted to use the Allegro GUI in which case your class is irrelevant and your code will need to be rewritten.

julian_boolean

This is just getting depressing.. All I wanted was something to handle the different states for my widgets so I wouldn't have to keep rewriting the (near) same logic in each widget class, while keeping my own graphics and not using libraries other then Allegro to do it. I thought the Allegro GUI could do that, well it seems like it could. My class hasn't changed yet, I just copied the code given to me and rewrote it to the way I thought it works, then reposted it to see if I was even on the right track. :P

This is what I'm using now:

1 int button::is_clicked(void)
2 {
3 if(!is_active)
4 {
5 return FALSE;
6 }
7
8 if(is_mouse_over())
9 {
10 if(!(mouse_b & 1) && mouse_status == NOT_ON_FOCUS)
11 {
12 mouse_status = MOUSE_STATUS_UP;
13 draw_frame = DRAW_FRAME_ON;
14 play_sound = PLAY_SOUND_ON;
15 }
16 
17 else if(mouse_b & 1 && mouse_status != NOT_ON_FOCUS)
18 {
19 mouse_status = MOUSE_STATUS_DOWN;
20 draw_frame = DRAW_FRAME_DOWN;
21 play_sound = PLAY_SOUND_DOWN;
22 }
23
24 else if(!(mouse_b & 1) && mouse_status == MOUSE_STATUS_DOWN)
25 {
26 mouse_status = MOUSE_STATUS_UP;
27 draw_frame = DRAW_FRAME_ON;
28 play_sound = PLAY_SOUND_ON;
29
30 return TRUE;
31 }
32 }
33 
34 else if(!(mouse_b & 1))
35 {
36 mouse_status = NOT_ON_FOCUS;
37 draw_frame = DRAW_FRAME_OFF;
38 }
39 
40 else
41 {
42 draw_frame = DRAW_FRAME_OFF;
43 }
44
45 return FALSE;
46 }

Steve Terry

Ok you can use your button class but it's not that flexible, I mean you can't use your button for anything else than playing a sound because that's the variable it's setting. You couldn't, for example, use your button to change the color of a box or something. You could also use the Allegro GUI which has the functionality you need but it's a bit ugly but I showed you ways to make it less ugly. Unfortunately to use the Allegro GUI you would have to rewrite your code. That said I would stick with what you have at the moment, you just need to break out your methods a bit and possibly use callbacks or overloaded methods to drive your play_sound variable.

julian_boolean

That's all I want it to do, just draw and play a sound, or return TRUE if I want to use the function outside the class for other things. Before, everyone kept saying that I needed some kinda event handler for all my widgets and since then I've been trying to do that without much luck.

I suppose I could just try to write things like WIDGET_FOCUSED, WIDGET_PRESSED, etc myself.

Dustin Dettmer

A GUI is a pretty advanced and complicated project. Maybe make your user interface a bit simpler this time around and improve with your next game?

julian_boolean

Because I'd just rather start learning it now while I'm at it since I already know how the code I'm using works throughout.

And yeah it can be complicated, depending on how versatile you want it to be. I want it to be pretty specific though, for the most part.

Steve Terry

Hang on I'll whip up a simple widget and button class... I was doing so but accidentally hit the wrong keyboard button and lost my friggin post >:E

julian_boolean

:) Thanks a bunch, hehe I've done that a lot before, which is why I started just writing it in a text file instead of the actual post, then just copy and paste it over.

Steve Terry
1#define W_SELECTED 1
2#define W_DISABLED 2
3#define W_GOTMOUSE 4
4 
5class widget
6{
7 public:
8 int x, y, w, h; // dimensions
9 unsigned int flags; // flags
10 void widget(int x, int y, int w, int h); // default constructor
11 virtual void ~widget(); // virtual destructor
12 bool mouse_over(); // true if mouse_over
13 void enable(); // enables a widget
14 void disable(); // disables a widget
15 virtual void init(); // method to do some initialization
16 virtual void draw(BITMAP *b); // method to draw
17 virtual void idle(); // method to do stuff during idle
18 virutal bool onKeyPressed(int key); // method to react to a key pressed (returns true if accepted key press)
19};
20 
21void widget::widget(int x, int y, int w, int h)
22{
23 this->x = x;
24 thix->y = y;
25 this->w = w;
26 this->h = h;
27 this->flags = 0;
28 init();
29}
30 
31bool widget::mouse_over()
32{
33 return flags & W_GOTMOUSE;
34}
35 
36void widget::idle()
37{
38 if(mouse_x >= x && mouse_x <= x + w && mouse_y >= y && mouse_y <= y + h)
39 flags |= W_GOTMOUSE;
40 else
41 flags &= ~W_GOTMOUSE;
42}
43 
44void widget::enable()
45{
46 flags &= ~W_DISABLED;
47}
48 
49void widget::disable()
50{
51 flags |= W_DISABLED;
52}
53 
54class button : public widget
55{
56 public:
57 void button(int x, int y, int w, int h); // default constructor
58 bool clicked(); // clicked method
59 virtual void ~button(); // virtual destructor
60 virtual void onButtonClickedCallback(); // clicked callback
61};
62 
63void button::button(int x, int y, int w, int h)
64{
65 widget::widget(x, y, w, h);
66}
67 
68void button::idle()
69{
70 // Do some idle stuff
71}
72 
73void button::draw(BITMAP *b)
74{
75 int draw_frame;
76 if(flags & W_DISABLED)
77 {
78 draw_frame = DRAW_FRAME_DISABLED;
79 }
80 else
81 {
82 if(widget::mouse_over())
83 {
84 if(!mouse_b & 1)
85 draw_frame = DRAW_FRAME_HIGHLIGHTED;
86 else if(mouse_b & 1)
87 draw_frame = DRAW_FRAME_PRESSED;
88 }
89 else
90 draw_frame = DRAW_FRAME_OFF;
91 }
92 // draw the button using draw_frame
93}
94 
95bool button::clicked()
96{
97 if(flags & D_DISABLED)
98 return false;
99 if(widget::mouse_over())
100 {
101 if(mouse_b & 1)
102 {
103 onButtonClickedCallback();
104 return true;
105 }
106 }
107 return false;
108}
109 
110class mySoundButton : button
111{
112 private:
113 SOUND *my_sound;
114 public:
115 void mySoundButton(int x, int y, int w, int h);
116 virtual void ~mySoundButton();
117}
118 
119void mySoundButton::mySoundButton()
120{
121 widget::widget(x, y, w, h);
122 my_sound = Load_Sound("my_sound.wav");
123}
124 
125void mySoundButton::~mySoundButton()
126{
127 if(my_sound != NULL)
128 {
129 Unload_Sound(my_sound);
130 my_sound = NULL;
131 }
132}
133 
134void mySoundButton::onButtonClickedCallback()
135{
136 ASSERT(my_sound);
137 Play_Sound(my_sound);
138}

I made three classes, one is the base widget class. The widget class is what every other GUI object is derived from. The next class is a base button class, all it is concerned about is doing a few methods essential to a button. The third class is a class derived from button which overloads a few methods and utilizes the callback to play a sound when the button is pressed. Please use this code only as a template, I have not compiled it and it probably won't work correctly but it should give you a direction. If you notice all methods do what their names imply and nothing more. They each do a small part. This code is not optimized either but as I said it's just to give a general idea.

[edit]
Also note that this widget class doesn't use messages but instead virtual methods to do the drawing, idling, and whatnot. You can have a message handler as part of the base widget I just did it the lazy way :P
[/edit]

julian_boolean

Looks very promising to me, going to look it over before bed (stupid work in the morning) :P

Thanks a million for all your help, and everyone elses help (again) hehe tomorrow whenever I get home I'll try to fool around with it for awhile and will certainly give a heads up if I run into any problems, but I understand this a lot more then the Allergo gui stuff. ;)

Steve Terry

Why would you do that? You are making confusing methods again. set_enabled sets a variable wheras enable acts on that variable? Why not just have a method called set_enable(bool enable) that takes true or false and enables or disables the widget there. No need for an extra method that is seemingly pointless.

[edit]
aww you erased your post :P
[/edit]

julian_boolean

Sorry hehe erased it after looking it over for a couple seconds. Thanks again though. ;)

Steve Terry

Sorry I made some minor tweaks to the widget and button classes because I could ;D

julian_boolean

Hmm.. The button is being displayed properly, but it doesn't seem to be doing the "clicked" logic. Also, what does |= and &= mean?

Johan Halmén

I've tried to read this thread some times, but can't figure out what you want to do. Do you want to create your own gui system? Or do you just want to have a button in your game? If the former, I guess it's a bit hard, if you still learn about &= and |=. If the latter, Allegro gui should do the job.

a = a & b;
is same as
a &= b;

julian_boolean

I just wanted an event/message handler using only Allegro. What is the difference between & and && anyway?

Steve Terry

&& is an AND comparison operator whereas & is a binary AND operator. For instance you would say if(someval == 2 && someotherval > 0) to only trigger the if statement only if both statements are true. Binary operations are completely different:

1#define THIS 1
2#define THAT 2
3#define OTHER 4
4char someval = 0;
5someval |= THIS; // someval = 0x01 - sets bit 1
6someval |= THAT; // someval = 0x03 - sets bit 2
7someval |= OTHER; // someval = 0x07 - sets bit 3
8someval &= ~THAT; // someval = 0x05 - unsets bit 2
9someval ^= THAT; // someval = 0x07 - toggles bit 2
10if(someval & THAT) // true if bit 2 is set
11{
12 // do something
13}
14if(someval & (THIS | THAT)) // true if bit 1 and bit 2 are set
15{
16 // do something
17}

I'm using the operations to toggle bits in the flags variable. Which by posting this I realize a flaw in my W_* enumeration. You need each state to be a power of two. The changes would be:

#define W_DISABLED   1
#define W_GOTMOUSE   2
#define W_SELECTED   4

julian_boolean

Still no luck. :/ No idea why it's not working for me, doesn't seem to like those W_'s.

Steve Terry

Allegro's defines are the same to mine, no reason it wouldn't work. Again I never said the code would work right off the bat, it's just there as an example so you can understand how things work. How are you using the class? Just stating it doesn't work doesn't tell me you are doing something wrong elsewhere.

julian_boolean

I just took functions from the code you did and stuck it in my own classes, modifying them slightly.

1 void widget::logic()
2 {
3 if(flag &W_DISABLED)
4 {
5 draw_frame = DRAW_FRAME_DISABLED
6 }
7 
8 else
9 {
10 if(flag &W_GOTMOUSE)
11 {
12 if(!mouse_b & 1)
13 {
14 draw_frame = DRAW_FRAME_ON;
15 }
16 
17 else if(mouse_b & 1)
18 {
19 play(); // plays a sound when widget is pressed
20 draw_frame = DRAW_FRAME_DOWN;
21 }
22 }
23 
24 else
25 {
26 draw_frame = DRAW_FRAME_OFF;
27 }
28 }
29 }
30 
31 void widget::draw(BITMAP *dbuff)
32 {
33 if(draw_frame == DRAW_FRAME_ON)
34 {
35 if(on_bitmap != NULL)
36 {
37 acquire_screen();
38 stretch_sprite(dbuff, on_bitmap, x_pos, y_pos, w_pos, h_pos);
39 release_screen();
40 }
41 }
42
43 if(draw_frame == DRAW_FRAME_OFF)
44 {
45 if(off_bitmap != NULL)
46 {
47 acquire_screen();
48 stretch_sprite(dbuff, off_bitmap, x_pos, y_pos, w_pos, h_pos);
49 release_screen();
50 }
51 }
52
53 if(draw_frame == DRAW_FRAME_DOWN)
54 {
55 if(down_bitmap != NULL)
56 {
57 acquire_screen();
58 stretch_sprite(dbuff, down_bitmap, x_pos, y_pos, w_pos, h_pos);
59 release_screen();
60 }
61 }
62 
63 if(draw_frame == DRAW_FRAME_DISABLED)
64 {
65 if(disable_bitmap != NULL)
66 {
67 acquire_screen();
68 stretch_sprite(dbuff, disabled_bitmap, x_pos, y_pos, w_pos, h_pos);
69 release_screen();
70 }
71 }
72 }
73 
74//=================================================================
75 
76 bool button::is_clicked()
77 {
78 if(flag &W_DISABLED)
79 {
80 return false;
81 }
82 
83 if(flag &W_GOTMOUSE)
84 {
85 if(mouse_over()) // i want this to be if(flag &W_PRESSED)
86 {
87 return true;
88 }
89 }
90 
91 return false;
92 }

Steve Terry

I don't know... you just aren't getting the picture here. I'm not sure if I can even help you. Take a closer look at my code instead of copying and pasting and get a good grasp of the concepts first. I give up.

julian_boolean

Will do.. I'm sorry for bugging so much, going to just work with what you did until it works for me! Thank you. :)

Thread #590091. Printed from Allegro.cc