Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Real-Time Text Input

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Real-Time Text Input
Gatleos
Member #12,534
January 2011

Since I've been having trouble with it and there doesn't seem to be any examples using the Allegro 5 API, I thought I would ask here: is there a tidy way to implement a function that alters a character string in real-time?

Allegro timing is a pain, and I'm trying to display a character string on the screen in real-time as it's being edited through keyboard input. Any help would be appreciated.

Peter Wang
Member #23
April 2000

How about ex_font_justify?

Gatleos
Member #12,534
January 2011

What exactly does ex_font_justify do? It couldn't possibly do all of what I'm asking by itself.

Peter Wang
Member #23
April 2000

See TextEntry class in nihgui.cpp

Tobias Dammers
Member #2,604
August 2002
avatar

You can either use one of the GUI libraries on the Depot (I'm not sure if any of them supports A5 yet though), or you can whip up your own text entry function. A simple one would, in pseudocode, look something like this:

string read_user_input(string initial = "") {
	// Set the current string buffer to the initial value
	string str = initial;

	// Loop until the user presses Esc or Enter
	do {
		int k = readkey();
		switch (k) {
			// a few special keys:
			// Esc cancels
			case Escape: return initial;
			
			// Return commits
			case Return: return str;

			// Backspace deletes last character
			case Backspace:
				if (str.length > 0)
					str.remove_last_char();
				break;

			// Any other key gets appended to the buffer...
			default:
				// but only if it's a regular key
				if (!is_special_key(k))
					str += key_to_ascii(k);
				break;
		}
		// After each keypress, update the display
		display_the_string(str);
	} while (1);
}

This is a very simple example, you'll need to flesh it out a lot more to get the functionality of a typical textbox, but you get the idea. One of the first steps after getting this one working, you might want to add a cursor position, and instead of manipulating the end of the string only, you'd insert and delete at the cursor position, and display a cursor in the textbox.
>:(

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Jonatan Hedborg
Member #4,886
July 2004
avatar

Tobis: That would not really be real-time text input though. It would halt execution and wait for the function to return.

-------
Sweden: Free from the shackles of Democracy since 2008-06-18!

Gatleos
Member #12,534
January 2011

Is there a version of keycode_to_ascii in Allegro 5? If not, this will get messy fast. Anyway, I can't seem to shorten the string with backspace. The closest I can get is inserting a space in the string, but then I get a bunch of spaces tacked onto the end. Is there a simpler way to implement a backspace feature?

#SelectExpand
1else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 2{ 3switch(ev.keyboard.keycode) 4{ 5 case (ALLEGRO_KEY_BACKSPACE): 6 { 7 if (strlen(gamename)>0 && menu==0) 8 { 9 --num; 10 gamename[num]=' '; 11 } 12 break; 13 } 14 case (ALLEGRO_KEY_DOWN): 15 { 16 if(menu<6) 17 menu++; 18 else 19 menu=0; 20 break; 21 } 22 case (ALLEGRO_KEY_UP): 23 { 24 if(menu>0) 25 menu--; 26 else 27 menu=6; 28 break; 29 } 30 case (ALLEGRO_KEY_ENTER): 31 { 32 if(menu==0) 33 { 34 35 } 36 else if(menu==1) 37 { 38 39 } 40 else if(menu==2) 41 { 42 43 } 44 else if(menu==3) 45 { 46 47 } 48 else if(menu==4) 49 { 50 51 } 52 else if(menu==5) 53 { 54 55 } 56 else if(menu==6) 57 { 58 start_game=true; 59 settings=false; 60 } 61 break; 62 } 63 case (ALLEGRO_KEY_ESCAPE): 64 { 65 settings=false; 66 break; 67 } 68 default: 69 { 70 if (strlen(gamename) < 25 && menu==0 && ev.keyboard.keycode<27) 71 { 72 gamename[num]=ev.keyboard.keycode+96; 73 num++; 74 } 75 break; 76 } 77} 78}

SiegeLord
Member #7,827
October 2006
avatar

Did you not look at TextEntry in nihgui.cpp? It shows how to do it all quite clearly.

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

Gatleos
Member #12,534
January 2011

Oh, I forgot to mention: I have no idea what nihgui.cpp is and can't find it anywhere. So yeah.

Matthew Leverton
Supreme Loser
January 1999
avatar

The examples and that file are in the source code package.

SiegeLord
Member #7,827
October 2006
avatar

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

Mark Oates
Member #1,146
March 2001
avatar

I was working on a comprehensive typeable textarea some time ago. I've attached the program.

{"name":"603392","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/1\/71eff6d499bf8da1ea16356015e10ae1.png","w":1053,"h":627,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/1\/71eff6d499bf8da1ea16356015e10ae1"}603392

I put this on hold because I'm waiting on the clipboard stuff ( 8-) ) to come in. But as of now it does one line of text and you can hilight, delete hilighted text, ctrl-jump across words, ctrl-shift-jump across words, etc. Ideally, it should support multiple lines and copy/paste/undo operations.

Though it's not finished, perhaps you can get some help by looking at it.

Gatleos
Member #12,534
January 2011

The thing is, I need to draw the text to the screen in a very specific way. I just need a function that returns a string, nothing more.

Thomas Fjellstrom
Member #476
June 2000
avatar

Gatleos said:

The thing is, I need to draw the text to the screen in a very specific way. I just need a function that returns a string, nothing more.

How would that work? all you get from The OS or Allegro is a sequence of events from the keyboard. Not any kind of string. So handling the actual input is far more complex than I think you think it is.

Now you can always just make a function that returns a string of the current contents of the text entry, but the code that actually handles the keyboard events is going to be a bit more complex.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

AMCerasoli
Member #11,955
May 2010
avatar

Gatleos said:

The thing is, I need to draw the text to the screen in a very specific way. I just need a function that returns a string, nothing more.

You can also do something like this:

I'm using Unicode but you can change that.

It's very simple.

BTW can you download the example .exe (attached) and check if the beeps sounds on your machine?

#SelectExpand
1 2#include <iostream> 3 4#define ALLEGRO_STATICLINK 5#include <allegro5/allegro.h> 6#include "allegro5/allegro_font.h" 7#include "allegro5/allegro_ttf.h" 8 9const float FPS = 60; 10ALLEGRO_USTR *string; 11ALLEGRO_FONT *font; 12ALLEGRO_FONT *font2; 13 14int main(int argc, char **argv) 15{ 16 ALLEGRO_DISPLAY *display = NULL; 17 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 18 ALLEGRO_TIMER *timer = NULL; 19 bool redraw = true; 20 21 22 al_init(); 23 al_init_font_addon(); 24 al_init_ttf_addon(); 25 timer = al_create_timer(1.0 / FPS); 26 al_install_keyboard(); 27 display = al_create_display(800, 600); 28 29 string = al_ustr_new(""); 30 31 32 event_queue = al_create_event_queue(); 33 34 font = al_load_ttf_font("consola.ttf", 60,0); 35 font2 = al_load_ttf_font("consola.ttf", 30,0); 36 37 al_register_event_source(event_queue, al_get_display_event_source(display)); 38 39 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 40 41 al_register_event_source(event_queue, al_get_keyboard_event_source()); 42 43 al_clear_to_color(al_map_rgb(0,0,0)); 44 45 al_flip_display(); 46 47 al_start_timer(timer); 48 49 while(1) 50 { 51 ALLEGRO_EVENT ev; 52 al_wait_for_event(event_queue, &ev); 53 54 if(ev.type == ALLEGRO_EVENT_TIMER) { 55 redraw = true; 56 } 57 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 58 break; 59 } 60 else if(ev.type == ALLEGRO_EVENT_KEY_CHAR) 61 switch(ev.keyboard.unichar) { //you can change that by ev.keyboard.keycode 62 case 0X0071: 63 al_ustr_append_cstr(string, "q"); 64 Beep(rand()%200+500,20); 65 break; 66 67 case 0X0077: // and change also this by its corresponding key codes (ALLERGO_KEY_Q etc...) 68 al_ustr_append_cstr(string, "w"); 69 Beep(rand()%200+500,20); 70 break; 71 72 case 0X0065: 73 al_ustr_append_cstr(string, "e"); 74 Beep(rand()%200+500,20); 75 break; 76 77 case 0X072: 78 al_ustr_append_cstr(string, "r"); 79 Beep(rand()%200+500,20); 80 break; 81 82 case 0X0074: 83 al_ustr_append_cstr(string, "t"); 84 Beep(rand()%200+500,20); 85 break; 86 87 case 0X0079: 88 al_ustr_append_cstr(string, "y"); 89 Beep(rand()%200+500,20); 90 break; 91 92 case 0X0075: 93 al_ustr_append_cstr(string, "u"); 94 Beep(500,20); 95 break; 96 97 case 0X00f1: 98 al_ustr_append_cstr(string, "ñ"); 99 Beep(500,20); 100 break; 101 102 case 0X0008: 103 al_ustr_remove_chr(string, al_ustr_offset(string, -1)); 104 Beep(500,20); 105 break; 106 107 //Etc... 108 } 109 110 111 112 113 114 if(redraw && al_is_event_queue_empty(event_queue)) { 115 redraw = false; 116 al_clear_to_color(al_map_rgb(0,0,0)); 117 118 al_draw_ustr(font,al_map_rgb(250, 250, 250), 0, 100, 0,string); 119 120 al_draw_text(font2,al_map_rgb(250, 250, 250), 0, 0, 0,"Only works the letters: q,w,e,r,t,y,u,ñ."); 121 al_draw_text(font2,al_map_rgb(250, 250, 250), 0, 50, 0,"And don't press CAPS LOCK"); 122 123 al_flip_display(); 124 } 125 } 126 127 al_destroy_timer(timer); 128 al_destroy_display(display); 129 al_destroy_event_queue(event_queue); 130 131 return 0; 132}

Gatleos
Member #12,534
January 2011

That would be perfect if not for the fact that I'm using cstrings and not using fonts. ALLEGRO_USTR won't convert to cstrings, and I'm using my own functions to draw strings, not the font plugin. No beeps either.

I think the only thing I really need now is a reliable way to... er... un-append the string. Shorten it by one character.

LennyLen
Member #5,313
December 2004
avatar

Gatleos said:

I think the only thing I really need now is a reliable way to... er... un-append the string. Shorten it by one character.

Set the currently last character to '\0'

Thomas Fjellstrom
Member #476
June 2000
avatar

Gatleos said:

ALLEGRO_USTR won't convert to cstrings

Yes it will. What makes you think it didn't?

Quote:

I think the only thing I really need now is a reliable way to... er... un-append the string. Shorten it by one character.

With C strings, just write a 0 at the last character. No need to reallocate or anything, just write a 0. Might want to keep track of the length though. Thats where the USTR stuff would help out, it does dynamic allocation for you, and can handle UTF8 so you don't have to think about it. But you're free to use c strings if you wish. Its just harder.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Mark Oates
Member #1,146
March 2001
avatar

Gatleos said:

That would be perfect if not for the fact that I'm using cstrings and not using fonts. ALLEGRO_USTR won't convert to cstrings, and I'm using my own functions to draw strings, not the font plugin. No beeps either.

::)

Quote:

un-append the string

You can always write a 0 at the end. There's a bunch of good stuff here:
http://www.cplusplus.com/reference/clibrary/cstring/

Gatleos
Member #12,534
January 2011

Yes it will. What makes you think it didn't?

My compiler telling me that there is no conversion to char * from ALLEGRO_USTR.

You can always write a 0 at the end. There's a bunch of good stuff here:
http://www.cplusplus.com/reference/clibrary/cstring/

Tried it.

LennyLen said:

Set the currently last character to '\0'

Tried it. Look, if I had a question about basic c++ operations, I wouldn't be asking here. I just assumed it might have something to do with Allegro. If you can alter the code I posted above to work with any of those suggestions, I'd be grateful and happily use it. But it won't work for me.

Mark Oates said:

::)

Too late to go back now. :P

LennyLen
Member #5,313
December 2004
avatar

Gatleos said:

My compiler telling me that there is no conversion to char * from ALLEGRO_USTR.

Of course there's no implicit conversion. It's the same as trying to use a C++ string when a C string is expected. That doesn't mean there isn't a way to convert from one form to the other. Use this.

Quote:

Tried it. Look, if I had a question about basic c++ operations, I wouldn't be asking here. I just assumed it might have something to do with Allegro.

It has nothing to do with Allegro. The only way to reduce the length of C strings is to move the position of the terminator. Perhaps you should ask questions about the basics since it appears you don't know them.

edit: Here's a working example

#include <stdio.h>
#include <string.h>

int main() {

    char example[] = "Hello World!";
    example[strlen(example) - 1] = '\0';

    printf("%s\n", example);

    return 0;
}

It prints "Hello World". Note the removal of the !.

Mark Oates
Member #1,146
March 2001
avatar

Gatleos said:

Tried it.

Quote:

Tried it.

Quote:

If you can alter the code I posted above to work with any of those suggestions, I'd be grateful and happily use it. But it won't work for me.

You gotta be responsible for your own code, man. We can't do it for you.

video

Gatleos
Member #12,534
January 2011

You gotta be responsible for your own code, man. We can't do it for you.

No, I wasn't asking you to write my code for me. You gave suggestions, they didn't work. I accept that I may have misunderstood what you were suggesting, so I wanted to see your implementation in case you meant something different than I thought you did.

Never assume someone's just asking you to write their code for them. Most people want help with their code, not a codesitter.

My original question was whether there was an efficient way to do this with Allegro timing, but I guess there isn't. I can figure it out on my own from here, I think. Unless someone has another suggestion.

Thomas Fjellstrom
Member #476
June 2000
avatar

Gatleos said:

Most people want help with their code, not a codesitter.

You'd be surprised.

Quote:

My original question was whether there was an efficient way to do this with Allegro timing, but I guess there isn't.

The question itself doesn't make much sense to me. Timing has nothing to do with keyboard input for the most part. Or an editable text entry.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

AMCerasoli
Member #11,955
May 2010
avatar

I think the same... I can't understand you. "an efficient way to do this with Allegro timing" ??? .

You're talking about separating the Keyboard inputs from the drawing?

 1   2 


Go to: