Input box using Allegro
makeshift_theory

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?

Rampage

Have you tried using the Allegro GUI functions?

Eradicor

I have working solution for this at home. If i remember i'll post it for you later today.

makeshift_theory

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.

miran

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.

Eradicor

Cant find the files.. Sorry.

makeshift_theory

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)
5int x = 0;
6int 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}
80END_OF_MAIN()

EDITED, Thanks for the heads up Thomas

Thomas Fjellstrom

Please use [code] tags, take a look at the "HTML Mockup Code" link thats just above the textarea.

James Stanley

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.

Tobias Dammers

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.

James Stanley

It's probably no use, but here goes:

1void 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:

int click(int x1, int y1, int x2, int y2) {
  if((mouse_x >= x1) && (mouse_x <= x2) && (mouse_y >= y1) && (mouse_y <= y2) && (mouse_b & 1)) return 1; else return 0;
}

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.

Thread #587830. Printed from Allegro.cc