Hello again,
I am trying to find a solution to this. I am need of using input style boxes in my game however I cannot seem to locate how to accomplish this. I have used my books and research and I can't do the following:
1) Detect Mouse Coordinates
2) Detect Key Presses
So what do I need to do? The only way I can think of is to somehow set the coordinates of where the boxes are and if they are clicked then have a loop function that displays | flashing and constantly displays keys that are pressed until the mouse leaves the coordinates or until tab is hit.
Is this close to being right?
Have you tried using the Allegro GUI functions?
I have working solution for this at home. If i remember i'll post it for you later today.
Hi all well I found some source code online and did some editing so I could get the caret to flash. The only thing I need to figure out now is how to draw all of it on screen with a background. Double buffering will not work because it has to clear the buffer between flashes so I'm thinking of converting the caret to a bitmap image and just clear the bitmap image instead of the whole buffer. If possible can you make a buffer background transparent? I know a buffer is just a blank bitmap so I have the option of drawing the input box in the buffer image and updating that I suppose.
Your way of thinking about double buffering is severely flawed. In double buffering you have an off screen buffer, in every frame you fill this buffer completely with what you want to be displayed on the screen, and then blit the buffer to screen. If what you want to be displayed on the screen is an input box with a flashing |, then you need to draw the box to the buffer, keep a variable that tracks the status of the caret (on/off) and if it's "on", draw the caret. Every now and then (like twice a second) you toggle the status of the caret flag between on and off.
Cant find the files.. Sorry.
Here let me show you my code to give you an idea of what I was trying:
| 1 | #include <allegro.h> |
| 2 | |
| 3 | #define BUFFERSIZE 128 |
| 4 | #define WHITE makecol(255, 255, 255) |
| 5 | int x = 0; |
| 6 | int main() |
| 7 | { |
| 8 | allegro_init(); |
| 9 | install_keyboard(); |
| 10 | install_mouse(); |
| 11 | set_color_depth(32); |
| 12 | set_gfx_mode(GFX_AUTODETECT, 800, 600, 0, 0); |
| 13 | |
| 14 | BITMAP* bg = NULL; |
| 15 | bg = load_bitmap("mainmenu.bmp", NULL); |
| 16 | BITMAP* buffer = NULL; |
| 17 | BITMAP* buffer2 = NULL; |
| 18 | char edittext[BUFFERSIZE]; |
| 19 | int caret = 0; |
| 20 | |
| 21 | /* typical Allegro initialization */ |
| 22 | |
| 23 | |
| 24 | buffer = create_bitmap(800, 600); |
| 25 | buffer2 = create_bitmap(800, 600); |
| 26 | |
| 27 | |
| 28 | blit(bg, buffer, 0, 0, 0, 0, 800, 600); |
| 29 | |
| 30 | while(!key[KEY_ESC]) { |
| 31 | |
| 32 | if(keypressed()) |
| 33 | { |
| 34 | |
| 35 | int newkey = readkey(); |
| 36 | char ASCII = newkey & 0xff; |
| 37 | char scancode = newkey >> 8; |
| 38 | |
| 39 | /* a character key was pressed; add it to the string */ |
| 40 | if(ASCII >= 32 && ASCII <= 126) |
| 41 | { |
| 42 | if(caret < BUFFERSIZE - 1) |
| 43 | { |
| 44 | edittext[caret] = ASCII; |
| 45 | caret++; |
| 46 | edittext[caret] = '\0'; |
| 47 | } |
| 48 | } |
| 49 | else if(scancode == KEY_BACKSPACE) |
| 50 | { |
| 51 | if (caret > 0) caret--; |
| 52 | edittext[caret] = '\0'; |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | /* all drawing goes here */ |
| 57 | |
| 58 | textout_ex(buffer2, font, edittext, 0, 10, WHITE, -1); |
| 59 | x++; |
| 60 | if(x % 8) |
| 61 | vline(buffer2, caret * 8, 8, 18, WHITE); |
| 62 | else |
| 63 | vline(buffer2, caret * 8, 8, 18, 0); |
| 64 | |
| 65 | blit(buffer2, buffer, 0, 0, 0, 0, 300, 300); |
| 66 | blit(buffer, screen, 0, 0, 0, 0, 800, 600); |
| 67 | clear(buffer2); |
| 68 | |
| 69 | rest(50); |
| 70 | |
| 71 | |
| 72 | |
| 73 | } |
| 74 | |
| 75 | |
| 76 | destroy_bitmap(buffer); |
| 77 | |
| 78 | return 0; |
| 79 | } |
| 80 | END_OF_MAIN() |
EDITED, Thanks for the heads up Thomas
Please use [code] tags, take a look at the "HTML Mockup Code" link thats just above the textarea.
I have one that draws a box with text inside it. There is a blinking cursor and backspace support, no left and right support and no scrolling. I might post it when I get home. The allegro routines are better, but not so user friendly.
Here are your options:
a) Use the Allegro GUI
b) Use a 3rd-party GUI library (browse the depot; there are a few useful ones there)
c) Analyze the original allegro code and copy-past from it to make your own routine
d) Hack something together yourself. It's not that hard.
It's probably no use, but here goes:
| 1 | void textbox(BITMAP *bmp, FONT *thefont, char value[], int maxlen, int id, int x, int y, int w) { |
| 2 | static int time; |
| 3 | static int focus; |
| 4 | static int white, blue, yellow; |
| 5 | int kee = 0; |
| 6 | |
| 7 | if(!white) { //Untested |
| 8 | white = makecol(255, 255, 255); |
| 9 | blue = makecol(0, 0, 255); |
| 10 | yellow = makecol(255, 255, 0); |
| 11 | } |
| 12 | |
| 13 | if(id == -1) {//Remove focus |
| 14 | focus = id; |
| 15 | return; |
| 16 | } |
| 17 | |
| 18 | if(click(x, y, (x+w), (y+text_height(thefont)+8))) focus = id; |
| 19 | |
| 20 | if(focus == id) { |
| 21 | if(keypressed()) kee = readkey(); |
| 22 | switch(kee & 0xFF) { |
| 23 | case 8: |
| 24 | if(strlen(value) != 0) value[strlen(value)-1] = '\0'; |
| 25 | break; |
| 26 | default: |
| 27 | if(strlen(value) != (unsigned int)maxlen) value[strlen(value)] = (char)kee; |
| 28 | break; |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | rectfill(bmp, x, y, w+6, (y+text_height(thefont)+8), white); |
| 33 | rect(bmp, x, y, w+6, (y+text_height(thefont)+8), yellow); |
| 34 | rect(bmp, x+1, y+1, w+5, (y+text_height(thefont)+7), yellow); |
| 35 | rect(bmp, x+2, y+2, w+5, (y+text_height(thefont)+6), yellow); |
| 36 | |
| 37 | textout_ex(bmp, thefont, value, x+4, y+4, blue, -1); |
| 38 | |
| 39 | if(focus == id) { |
| 40 | time++; |
| 41 | if(time >= 50) time = 0; |
| 42 | if(time > 25) vline(bmp, (text_length(thefont, value)+x+5), y+5, (y+text_height(thefont)+3), blue); |
| 43 | } |
| 44 | } |
Call it like:
textbox(canvas, font, my_char, 12, TEXT_BOX_1, 50, 50, 200);
Obviously, you put #define TEXT_BOX_1 1 in a header. The id is so that it knows where to put the text, otherwise if you had two on the screen at the same time, it wouldn't know which was in focus.
EDIT:
You'll want click() as well:
EDIT2:
Pass -1 as the focus parameter to put all textboxes out of focus. You might need a small char array, or use one you already have. It won't get changed. I promise.
EDIT3:
I defined some colours inside the function when I noticed they weren't defined already.