Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: DrewCCU on Wed 04/08/2010 04:41:37

Title: Text Box question [solved]
Post by: DrewCCU on Wed 04/08/2010 04:41:37
I realize there may be several ways to do what i'm about to ask but seeing as how i've never used the text box option before i wanted to ask around for what may be the best solution so i don't end up with any bugs.  So let me go ahead and ask the question so you get the idea:

I have a GUI text box on a gui (obviously) and what i would like to be able to do is something like this:

I want the player to type in a number (from 1-100) and then i want that number to be converted to an integer so that AGS can use it in a mathematical equation in the script.
i.e. something like:  

int VAR = txtUserInput.Text;


Now the problems i'm foreseeing are things like what if the player types in numbers that are above 100 or below 1?  Or even worst, what if they type in letters?  My ideal situation is that if they type in something that is not 1-100 i want to display a message that says something like "Input only a value between 1 & 100." or something like that.

Any suggestions?  
Title: Re: Text Box question
Post by: Gilbert on Wed 04/08/2010 05:02:04
First,

int VAR = txtUserInput.Text;

doesn't work, as this will cause a type-mismatch error.

You need to convert the String to an integer with functions like say, String.AsInt (http://www.adventuregamestudio.co.uk/manual/String.AsInt.htm).

To check whether there are "illegal" characters just check each character of the string. So you may make some function like (untested):


function CheckConvertText(String tempstr){
 int ii=0;
 while (ii<tempstr.Length){
   if (tempstr.Chars[ii]<'0'||tempstr.Chars[ii]>'9') return -1;  //"illegal" character
   ii++;
 }
 int value=tempstr.AsInt;
 if (value>=1||value<=100) return value;
 else return -1;
}


Then when you want to check for the validity of the textbox just do womething like:

int VAR=CheckConvertText(txtUserInput.Text);
if (VAR==-1) Display("Input only a value between 1 & 100.");
Title: Re: Text Box question
Post by: DrewCCU on Wed 04/08/2010 05:43:39
Thanks. I'll try that out.

Another question I have:

Is there a way to set a maximum character length for a text box?

EDIT:

Okay, I put the custom function into the global script then in the global.ash i used the import function code so the room could access it.  I put the

int VAR=CheckConvertText(txtUserInput.Text);
if (VAR==-1) Display("Input only a value between 1 & 100.");


in the room script (in rep exec).

I got a parse error in the global script.asc on the line:

if (tempstr.Chars[ii])<'0'||tempstr.Chars[ii])>'9') return -1;  //"illegal" character

PE04: Parse error at '<'

Another thing - i read the String.AsInt file but i'm having a little trouble interpreting how to convert txtUserInput.Text into an int with it.
Title: Re: Text Box question
Post by: Gilbert on Wed 04/08/2010 06:14:58
Quote from: DrewCCU on Wed 04/08/2010 05:43:39
Thanks. I'll try that out.
PE04: Parse error at '<'
There're some obvious typos in that line, that I put two extra )'s in it. Supposed to be fixed now.

Quote
Another thing - i read the String.AsInt file but i'm having a little trouble interpreting how to convert txtUserInput.Text into an int with it.
The AsInt property works just like how the examples show. The problem is that it seems that you cannot use something like txtUserInput.Text.AsInt or (txtUserInput.Text).AsInt in AGS (this is one reason why OOP sucks IMO as normally StringToInt(txtUserInput.Text) is much more readable and makes more sense, I don't know whether this is possible for programming languages in general, but I think it's possibly more doable on dialects that support the -> syntax), so you probably need to use another String to hold its content first, like this:

String blah=txtUserInput.Text;
int VAL=blah.AsInt;
Title: Re: Text Box question
Post by: DrewCCU on Wed 04/08/2010 06:17:29
ah i see. it makes sense now.  thank you very much.  tomorrow i will try out this new information and let you know what happens.  thanks again.
Title: Re: Text Box question
Post by: monkey0506 on Wed 04/08/2010 07:08:05
Quote from: Gilbet V7000a on Wed 04/08/2010 06:14:58The problem is that it seems that you cannot use something like txtUserInput.Text.AsInt or (txtUserInput.Text).AsInt in AGS

Why not? I do this all the time. What you can't do, is you can't access properties of a member of static properties such as DateTime.Now. So you couldn't, for example, do int rawtime = DateTime.Now.RawTime directly, because DateTime.Now is a static property. This is actually a known issue and not by convention.

However, whenever you're dealing with non-static properties such as TextBox.Text you can then call members of that property where applicable, such as TextBox.Text.AsInt.

Edit: Just as a test, I just started a new game project using the Empty Game template, added a new Room, a new GUI, and a new TextBox control. Then I added the following code:

function game_start()
{
  TextBox1.Text = "10";
  int val = TextBox1.Text.AsInt;
  Display("%d", val);
}


As expected, the value of 10 is displayed.
Title: Re: Text Box question
Post by: Gilbert on Wed 04/08/2010 07:42:56
Thanks for the explanation! It's been quite some time, but I think I got that impression when I tickled with DynamicSprites (or DrawingSurfaces, or Overlays as I cannot remember the details). The example DateTime.Now.RawTime is not very good though, as we already have the workaround DateTime.RawTime. I think there're other examples of static properties that exhibit this limitation but I'm too lazy to check.

Though still, I'm never fond of this OOP way of writing unnecessarily long stuff. I'd rather use the function-parameter approach.
Title: Re: Text Box question
Post by: monkey0506 on Wed 04/08/2010 09:01:52
I think you're misreading the manual. Although the property is listed as DateTime.RawTime it is not a static property. That means you still have to use a DateTime object to access the member. So, as in the example in the manual, you still have to use DateTime.Now before you can access the RawTime property.

Only properties listed in the manual as static are accessed directly on the class name as opposed to an instance of the class.

You do have a point that:

int rawtime = GetRawTime();

Is shorter than:

DateTime *dt = DateTime.Now;
int rawtime = dt.RawTime;


However, consider instead something like Character.ActiveInventory:

// non-OOP
InventoryItem *activeItem = GetCharacterActiveInventory(GetPlayerCharacter());

// OOP
InventoryItem *activeItem = player.ActiveInventory;


Not only is the code here shorter, it's also more to-the-point IMO. Let's take it a step further, and change the Graphic property of the character's active inventory.

// non-OOP
SetInventoryItemGraphic(GetCharacterActiveInventoryItem(GetPlayerCharacter()), 42);

// OOP
player.ActiveInventory.Graphic = 42;


The OOP code in this case is much easier to read and understand what is going on.

I'm getting completely off-topic here, but I just wanted to point out that OOP has advantages. Understandably it may not be perfect, but neither is "the function-parameter approach".
Title: Re: Text Box question
Post by: Khris on Wed 04/08/2010 09:21:32
If you added this to the applying rep_exe, you could prevent the player from entering characters other than digits:

function room_RepExec() {
  String t = tbInputNumber.Text;
  String l;
  if (String.IsNullOrEmpty(t)) return;
  if (t.Length > 0) {
    l = t.Substring(t.Length-1, 1);
    if (l.AsInt == 0 && l != "0") {
      t = t.Substring(0, t.Length-1);
      tbInputNumber.Text = t;
    }
  }
}


If does sort of work, the typed letter does flash for half a second though.
Title: Re: Text Box question
Post by: Gilbert on Wed 04/08/2010 09:23:26
Quote from: monkey_05_06 on Wed 04/08/2010 09:01:52
The OOP code in this case is much easier to read and understand what is going on.
I don't think so, but yeah it's just a personal preference, so there's no point in arguing this OT stuff anyway.
Title: Re: Text Box question
Post by: DrewCCU on Wed 04/08/2010 17:00:26
THanks for all of the input.  I still haven't had a chance to plug anything in yet but as soon as i can i will experiment with what you guys have suggest and i'm sure i can get it working. 

However, i believe in all of the discussion one of my questions was overlooked.  So i'll ask again:

Is there a way to set a maximum character length for a text box?

Title: Re: Text Box question
Post by: Atelier on Wed 04/08/2010 18:10:17
Adjust the text box width to the width of the font you're using, multiplied by how many characters you want, but it depends whether your font has monospaced digits. 123456 all look the same to me, so it saves some coding if it does work.
Title: Re: Text Box question
Post by: DrewCCU on Thu 05/08/2010 02:40:48
Quote from: AtelierGames on Wed 04/08/2010 18:10:17
Adjust the text box width to the width of the font you're using, multiplied by how many characters you want, but it depends whether your font has monospaced digits. 123456 all look the same to me, so it saves some coding if it does work.

I tried that but the problem is the font i want to use ISNT monospaced.  So in the text box you can type 100 (andno more) but you could also type 1111.  I want there to be a 3 digit maximum characters allowed.  So being able to type 1111 isn't good. (while its improbable the player will do that and probably not a big deal - i still would like to account for it if possible.)

EDIT:

Actually i believe i have gathered all the information i need from this thread.  Thanks everyone.  You guys helped me and taught me some things.
Title: Re: Text Box question [solved]
Post by: Khris on Thu 05/08/2010 06:50:42
Yeah, you can easily modify my code to also delete a fourth char, regardless of what it is.

Another way would be to use something else for input, e.g. a clickable numpad.